Commit Graph
316 Commits
Author SHA1 Message Date
DrSmoothl 5ba7c21c4b chore(release): v1.14.13 2026-08-22 20:15:29 +08:00
DrSmoothl a395577f77 fix(protocol): stop flooding logs when disk writes fail
After identity persistence is suspended, later observations were still
logged one-by-one. That filled Docker logs and made the WebUI log
stream unusable while the bot kept receiving messages. Report the skip
once, then at most once a minute with a count. Console write failures
must not throw into message handling.
2026-08-22 19:44:25 +08:00
DrSmoothl 2bd2643670 docs(onebot): document qidian flags on stranger info
Fill in the stranger-info action docs, catalog, and remaining profile
fixtures after the qidian flags landed. Ordinary accounts still
default to zero.

Refs #404
2026-08-22 12:41:47 +08:00
makotowu 83f643f01b feat(onebot): expose qidian account flags on stranger info
Return qidian master and crew flags from get_stranger_info so callers can tell a qidian account from a normal one. Ordinary accounts keep the flags at zero. Existing stranger fields are unchanged.

Refs #404
2026-08-22 12:36:22 +08:00
DrSmoothl 6782fd9cb3 fix(protocol): treat a successful group kick as success
QQ reports a per-member kick outcome in the command body. A zero
outcome means the member was removed; treat that as success instead
of a false failure. Still reject a non-zero outcome so callers do
not see success when the kick did not take effect.

Fixes #413
2026-08-22 11:12:58 +08:00
DrSmoothl 39e6b45b81 fix(onebot): restore image links inside merged forwards
get_forward_msg returned image segments with empty url and file when
the long-msg payload omitted a download path. Rebuild the URL from
the file fingerprint the payload still carries.

Fixes #412
2026-08-21 18:26:15 +08:00
DrSmoothl 6ec368f4b5 fix(onebot): restore doubt-request account ids from the native list
get_doubt_friends_add_request was rereading the uid as a number, so
uid came back empty and user_id was wrong. Keep the uid string and
the account number as separate fields.

Fixes #410
2026-08-21 18:26:02 +08:00
DrSmoothl 3045525e37 fix(onebot): restore emoji reaction users from the native list
get_msg_emoji_likes was asking the recent-used emoji catalog, so a
reacted message came back empty. Use the native reactor list and the
local reaction cache instead.

Fixes #409
2026-08-21 18:25:45 +08:00
DrSmoothl bc070eca1c chore(release): v1.14.12 2026-08-20 14:12:53 +08:00
H3CoF6 8fbddf67bf Feat: 发送图文ark卡片 (#355)
* feat(onebot): implement send tuwen ark

* test: add unit tests for send_ark action

* test(onebot): update canonical action docs count expectation to 191

* refactor(protocol,onebot): update 0xdc2_34 ark implementation and test coverage

- Rename action send_ark -> send_tuwen_ark to distinguish from structmsg and contact-share arks.
- Clarify SSO command mapping (OidbSvcTrpcTcp.0xdc2_34) and default param behavior in comments/docs.
- Adjust peerType, field3, and previewUrl to pb_optional to preserve 0/empty values during proton encoding.
- Update OneBot handler, tests, and auto-generated MCP tool catalog specs.

* style(protocol): fix indentation in rich-body-decoder tests
2026-08-20 12:12:39 +08:00
DrSmoothl e6aeef02b4 fix(protocol): apply member permission updates on the native group setting command
set_group_member_permissions was still rejected after the previous
command switch. Linux QQ writes these capabilities with the same
group-detail command as the other admin settings.

Closes #392
2026-08-19 21:46:44 +08:00
DrSmoothl d8521d4345 feat(onebot): set profile gender and return stranger online status
set_qq_profile accepts sex. get_stranger_info now returns the online
status, extended status, and custom status that QQ already provides
on the user profile.

Closes #397
Closes #398
2026-08-19 21:46:03 +08:00
DrSmoothl 8fdd41ea22 fix(onebot): restore group and doubt request accounts
get_group_system_msg now keeps join and invite records, reports the
inviter, and fills a missing requester nick from the user profile.
get_doubt_friends_add_request returns the QQ number plus the request
message, source, and time that QQ actually sends.

Closes #400
Closes #401
Closes #402
Closes #403
2026-08-19 21:45:15 +08:00
DrSmoothl 5a10fc4c9c feat(onebot): report the invited account on group invite events
request.group.invite already identified the inviter. The event now
also reports the invited account when QQ provides it.

Closes #394
2026-08-19 00:23:40 +08:00
DrSmoothl 0a924634b2 fix(protocol): return group join question and answer in admin settings
get_group_admin_settings reported the join mode correctly but left the
question and answer blank. The detail request now asks for those
strings the same way the official client does.

Closes #393
2026-08-19 00:15:32 +08:00
DrSmoothl b088ffaff0 fix(protocol): apply member permission updates on the correct group setting command
set_group_member_permissions was still rejected after the privilege
flag read was corrected. Album, temporary-session, and create-group
writes use a different 0x89A variant than invite policy.

Closes #392
2026-08-18 21:57:11 +08:00
DrSmoothl c86982610f chore(release): v1.14.11 2026-08-17 21:11:05 +08:00
DrSmoothl 29e6baac72 fix(protocol): drop leftover picture copies in robot messages
Some group-bot pictures arrive twice: one working download and one
unusable leftover for older clients. Only the working picture is kept.

Fixes #389
2026-08-17 20:08:48 +08:00
DrSmoothl b3bd68d48d fix(protocol): read group privilege from the matching detail field
Member invite and capability bits come from a different group-detail
field than the history-visibility switch. Reading the wrong one made
later writes carry leftover bits the server rejects.
2026-08-17 20:00:11 +08:00
DrSmoothl cc517080be fix(protocol): treat history visibility replies as an on/off flag
The group-detail reply reports whether new members can see history as
a simple yes/no value. The write still flips that setting; the read
no longer expects a multi-bit field.
2026-08-17 19:40:22 +08:00
DrSmoothl 3cb3024b39 feat(protocol): write join question and answer with add option
Question-and-answer join mode now sends the question and answer;
question-only mode sends the question and clears the answer.
2026-08-17 19:12:43 +08:00
DrSmoothl cfe61abce6 feat(protocol): read current group admin settings
Group detail and ext-info can now return the join option, search flags,
invite/permission/history bits, and robot-add switch so setters have a
matching read path.
2026-08-17 19:06:03 +08:00
DrSmoothl aec0c781b3 fix(onebot): approve pending group join requests that were rejected as gone
Closes #380.

An empty reject reason and a stale request type could make the server treat a still-pending join as already handled.
2026-08-17 18:40:08 +08:00
DrSmoothl 618dd52f46 fix(protocol): set group robot-add options when values are off
Closes #386.

Turning the options off no longer produces an empty request the server rejects.
2026-08-17 18:25:13 +08:00
DrSmoothl ecf0efc5e2 refactor(protocol): keep hasDecodableContent next to decodeRichBody
Move the body-shape predicate into RichBody so admission no longer
mirrors decode slots. C2C control stays a header check.
2026-08-16 23:22:28 +08:00
DrSmoothl 206727f823 refactor(protocol): move roster refresh into the packet pipeline
Replace the shallow refreshMemberCache adapter with fetchGroupList
and fetchGroupMemberList ports. Skip, swallow, and coalesce stay
next to the join/leave/admin trigger.
2026-08-16 23:18:04 +08:00
DrSmoothl 9772d4f0bf chore(release): v1.14.10 2026-08-16 21:57:59 +08:00
DrSmoothl 55a2a24fc2 refactor(protocol): compose group-file URLs in the OIDB namespaces
Move retCode checks and URL assembly into GetGroupFileUrl,
GetPrivateFileUrl, and ListGroupFilesPage so GroupFileApi only
loops pages and resolves display names.
2026-08-16 21:56:21 +08:00
DrSmoothl eee3c49f2d refactor(protocol): map friend and member pages to domain types
FetchFriendListPage and FetchGroupMemberListPage deserialized as
identity functions and leaked Oidb property codes into ContactsApi.

Each page now returns a domain page. Contacts keeps pagination,
category assembly, member cache, and robot classification.
2026-08-16 21:12:59 +08:00
DrSmoothl 23352dcad4 refactor(protocol): resolve like-list UINs through Identity
GetLike already filled cached UINs in deserialize. ProfileApi then
opened a second Contacts hop and threw on fetch failure.

Misses now go through Identity.resolveUin after invokeOidb, coalesced
by uid. ProfileApi.getLike is invoke-only. Unresolved rows stay
uin=0 and no longer fail the action.
2026-08-16 19:23:44 +08:00
DrSmoothl 226b48fd7a refactor(protocol): keep Decoder a pure parse of MsgPush events
Decoder used to write Identity: decodeGroupAdmin patched member roles
and decodeFriendMessage stashed invite-card msgseq. That split
observation with IncomingPacketPipeline.rememberEventIdentity and put
pending-application state on Identity.

Decoder now only returns events. Invite-card groupUin/msgseq ride on
FriendMessage; the live pipeline writes them to ContactsApi through
an optional port. Role self-heal for #93 stays in
rememberEventIdentity. History and forward decode do not write.
Identity no longer stores invite-card sequences.

Live #93 and #125 behavior is unchanged.
2026-08-16 18:22:41 +08:00
DrSmoothl fea1996e46 chore(release): v1.14.9 2026-08-16 15:18:30 +08:00
DrSmoothl 401f32d6b2 chore(release): v1.14.8 2026-08-14 14:55:28 +08:00
DrSmoothl 925d9c0ac7 feat(flash-file): expose cover URL as flash_file.thumb
Incoming flash cards already carry a cover link; map it to
flash_file.data.thumb. Older cards without a cover leave it empty.

Fixes #367
2026-08-14 14:00:18 +08:00
DrSmoothl e59f5e7c5b test(protocol): cover event and reply formatting 2026-08-14 11:09:22 +08:00
DrSmoothl 31bd8ea77b test(protocol): cover highway streaming hash and upload staging 2026-08-14 10:57:17 +08:00
DrSmoothl d46d8e4002 chore(release): v1.14.7 2026-08-13 19:47:25 +08:00
DrSmoothl b8b9be83c3 feat(core): stream flash-transfer uploads from disk
create_flash_task loaded every fileset file through loadBinarySource
and kept the bytes through hash, commit, and sliceupload, so a single
file over 1 GiB could not be sent. Stage to disk like group files,
stream MD5/SHA1/Sha1StateV, then POST 1 MiB chunks from FileChunkSource.

Do not reuse video sha1Blocks as Sha1StateV: an exact N-MiB file would
ship an extra un-finalized last-slice state. Local/HTTP sources use the
4 GiB group-file ceiling; inline base64 stays at 1 GiB because stage
still decodes it in RAM. Protocol order, seconds-pass, and multi-file
commit are unchanged.

Fixes #359
2026-08-13 18:34:27 +08:00
DrSmoothl e7322e2e72 fix(protocol): decode current NT flash-transfer cards
Current clients put fileset identity on markdown extInfo and the
open_fileset scheme, not data.fileSetId. Empty message arrays were
the old scraper missing those fields.

Fixes #358
2026-08-13 18:18:56 +08:00
DrSmoothl 7d5ca5523b refactor(protocol): own inbound UID-to-UIN resolution in Identity
Inbound person lookup used to be split across decoders, the packet
pipeline, and Bridge closures. Missing identities were filled from
unrelated packet headers, and "who is this person" was coupled to
roster refresh and pending-request enrichment.

Identity now owns both directions of resolution. The hot path stays
synchronous and emits unresolved events on a miss. Only the paths
that already waited before dispatch perform a network lookup, and
that lookup is a profile fetch by UID rather than a member-list
refresh. Pending-request comments and approval flags stay outside
Identity.

Decoders no longer invent a UIN from a group routing header. Private
chat routing still uses a hop's own wire UIN when the hop is named
that way. Inbound misses stay availability-first: they do not throw
and do not mark Identity degraded.
2026-08-13 14:37:56 +08:00
DrSmoothl d26aef86d8 chore(release): v1.14.6 2026-08-13 12:52:21 +08:00
DrSmoothl f100faaeb6 fix(protocol): read group mute expire from official proto tags (#356)
get_group_info / get_group_list mapped FE5 tag 31 and 88D tag 59 as
shutUpAllTimestamp, then treated any >0 value as muted. Official
wrapper.node maps those tags to internal 60259; the real expire
(60027 / groupShutupExpireTime) is FE5 tag 10 and 88D tag 45
(request mask 45). After a group had been muted, 60259 often stayed
nonzero so group_all_shut stuck at -1. Read the 60027 tags and treat
all-mute as expire > now (0xFFFFFFFF is permanent).

Fixes #356
2026-08-13 12:44:56 +08:00
DrSmoothl 2f5065545a fix(onebot): percent-decode file URL basenames on upload (#354)
send_group_msg / send_private_msg with a file segment that only has
file:// (no name/filename) used url.split('/').pop() as the upload
name, so percent-encoded CJK paths uploaded as
%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.xlsx. Derive the fallback through
guessFileNameFromUrl, which decodeURIComponent's the path basename
(invalid encodings are left as-is). An explicit name still wins.

Fixes #354
2026-08-13 11:02:02 +08:00
DrSmoothl 679f3b5b9f fix(highway): delay-retry 102902 instead of aborting the upload (#352)
upload_group_file of ~2 GiB files failed after a highway idle timeout
because the next decoded error_code=102902 was treated as a fatal
server reject. QQ's own BDH client (multi_uploader.cc NeedDelayRetry)
treats 102902 / 302902 as backpressure: wait, switch sender, and
re-PUT the same offset. Mirror that — drop the socket, wait 250 ms,
increment retryTimes, and retry the chunk up to 8 times. Definitive
codes such as 921 still fail immediately.

Fixes #352
2026-08-13 00:20:40 +08:00
DrSmoothl 8ded1065d4 fix(onebot): return profile like user details
Restore the interaction user lists returned by get_profile_like and keep self and other-user lookups consistent with the current client behavior.

Resolve missing account identities when needed, surface lookup failures, and update the public action catalog with the completed response shape. Add regression coverage for request selection, response decoding, identity enrichment, and malformed results.

Fixes #349
2026-08-11 23:46:46 +08:00
DrSmoothl 0357d136d8 chore(release): v1.14.5 2026-08-11 18:20:17 +08:00
DrSmoothl fe44a2f5bc fix(group-requests): normalize request retrieval and handling
Correct group-request retrieval so requester identities and action metadata remain usable across client and web-originated invitations.

Keep existing live-event behavior compatible, ensure returned requests carry the correct information for approval or rejection, and reject malformed request identifiers instead of emitting unusable flags.

Add regression coverage for both request inboxes and the supported invitation categories.
2026-08-10 00:26:01 +08:00
DrSmoothl dbf654ad57 chore(release): v1.14.4 2026-08-09 16:53:10 +08:00
DrSmoothl c08150fc0c feat(onebot): query group todo messages
Fixes #332
2026-08-09 13:36:41 +08:00
DrSmoothl 4aba81ec6b feat(onebot): decode bot markdown and keyboards
Fixes #337
2026-08-09 13:06:35 +08:00