Commit Graph
175 Commits
Author SHA1 Message Date
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 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 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 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 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 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 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
DrSmoothl 1e0c91e74d feat(onebot): configure group member permissions
Fixes #335
2026-08-09 12:56:05 +08:00
DrSmoothl e08613062e feat(onebot): configure group history visibility
Fixes #336
2026-08-09 12:53:45 +08:00
DrSmoothl cd6fcadea4 feat(onebot): configure group invite policy
Add validated group member invite policy updates with post-write verification.

Fixes #334
2026-08-09 11:46:04 +08:00
DrSmoothl 597a4c05f3 feat(onebot): fetch custom face details
Add packet-backed custom face detail retrieval and expose the result through the OneBot action.

Fixes #333
2026-08-09 11:45:43 +08:00
DrSmoothl 49439370e1 fix(onebot): decode user status property list (#330) 2026-08-09 11:28:14 +08:00
DrSmoothl c404974e75 fix(protocol): support cross-pack system face overlaps (#324) 2026-08-08 19:26:09 +08:00
DrSmoothl 39d5a50d5f fix(protocol): accept Unicode system face identifiers (#324) 2026-08-08 17:42:14 +08:00
DrSmoothl 1646f265ec fix(protocol): skip non-addressable system face entries 2026-08-07 21:24:05 +08:00
DrSmoothl c0e73cd738 fix(protocol): handle empty group essence lists
Return an empty result when a successful, completed group essence response omits its message list instead of reporting a malformed response.

Keep upstream errors and incomplete pagination responses explicit, and cover omitted and null list variants with regression tests.

Fixes #320.
2026-08-06 22:36:05 +08:00
DrSmoothl 634097460c feat(onebot): expose group-wide mute status
Report whether group-wide mute is enabled through the existing group list and group information responses.

Keep standard and extended queries aligned, support explicit refreshes in the SDK, and update the generated action documentation without adding another endpoint.

Preserve established compatibility values, isolate cached non-member results by account, and add coverage across the request, mapping, action, and client layers.

Closes #313
2026-08-04 23:27:58 +08:00
DrSmoothl 8e9a4d878e feat(protocol): complete system face catalog lifecycle
Persist and validate the shared system face catalog, refresh it once when the first account connects, and coalesce concurrent loads. Resolve outgoing face metadata from the catalog so startup races, unknown IDs, and incomplete entries fail before sending.
2026-08-04 23:13:32 +08:00
DrSmoothl 672802b424 fix(group-album): validate image upload inputs
Reject unsupported media with a clear error before processing begins. Existing image upload behavior remains unchanged.

Refs #310
2026-08-04 15:25:23 +08:00
DrSmoothl 185ba8353b fix(message): preserve passive temporary session context
Keep passive replies associated with the correct conversation when the same contact is shared across groups. Active temporary conversations remain unsupported.

Fixes #308
2026-08-04 00:20:56 +08:00
DrSmoothl fb4d7716a1 fix(core): restore group remarks in queries
Request and retain the group remark information needed by group list and group detail queries while preserving the existing safeguards for large rosters.

Synchronize confirmed group remark changes with the local identity roster and persistent cache. Remote failures leave local state untouched, and missing roster entries remain observable without creating phantom groups.

Add regression coverage for query mapping, request scope, persistence, failed updates, unknown groups, and closed identity stores.

Fixes #304
2026-08-01 21:11:02 +08:00
DrSmoothl 659e0bd3d0 fix(friend): verify and synchronize remark updates
Validate the service result before reporting friend remark changes as successful. Rejected, incomplete, or contradictory confirmations now reach callers instead of being reported as completed.

Keep confirmed remarks synchronized in the identity cache and consume cross-client remark updates without exposing a new OneBot event. Local cache failures remain observable without turning an already completed remote change into a retryable failure.

Preserve friend remarks exactly across restarts and add request, response, persistence, receive-pipeline, and action-level regression coverage.

Fixes #303.
2026-07-31 23:21:05 +08:00
DrSmoothl f6e2410dae fix(onebot): normalize group essence message results
Translate group essence responses into the established OneBot shape instead of exposing the upstream digest payload.

Return validated sender, operator, timestamp, message identifier, and message segment fields for text, face, image, and video entries. Retain the authoritative message metadata in one transaction so returned identifiers can be used by later essence actions without partial cache state.

Reject malformed, cross-group, incomplete, or unknown digest entries, and surface pagination or upstream failures instead of returning truncated success results.

Fixes #300.
2026-07-31 15:40:53 +08:00
DrSmoothl 8dd986a565 style(repo): clear workspace lint violations
Align existing managed source with the repository lint rules so the workspace can adopt one reliable root validation command.

This normalizes the private file upload block, removes stale test suppressions, makes an error boundary explicit, and records a stable settings dependency without changing user-facing behavior.

The cleanup creates a deterministic baseline before lint becomes a required pull request gate.
2026-07-31 13:08:33 +08:00
DrSmoothl a67614fa09 feat(logging): complete runtime trace diagnostics
Complete byte-level diagnostics for network, upload, runtime lifecycle, authenticated write, and background operation paths.

Preserve streaming behavior, file-storage boundaries, and default log volume while making failures, retries, cancellation, and final outcomes independently diagnosable.

Add focused regression coverage for correlation, partial data, resource context ownership, and terminal-state accuracy.
2026-07-31 11:21:12 +08:00
DrSmoothl 0d14408b6f feat(protocol): add byte-complete packet tracing
Capture complete packet request, reply, and push payloads during temporary TRACE sessions while preserving the existing non-persistent logging boundary.

Correlate transport, parser, enrichment, drop, dispatch, timeout, and terminal outcomes with their real identifiers so exported logs can explain packet failures without relying on user descriptions.

Lock byte completeness, lazy disabled behavior, concurrency, context propagation, and truthful terminal outcomes with regression coverage.
2026-07-30 20:11:02 +08:00
DrSmoothl f0ff8da2fa feat(onebot): support moving friends between categories
Add the set_friends_category action with either an existing category ID or an exact unique category name.

Validate the current friend and category roster before applying a change, reject missing or ambiguous targets, and surface failed updates instead of reporting false success. Expose the action through the SDK types and cover validation, successful updates, repeat requests, service rejection, and registry completeness.

Closes #297
2026-07-30 10:37:16 +08:00
DrSmoothl 5d1dbecf2e fix(protocol): scope system dedup to native routes
Derive QQ NT's peerUid_chatType_msg_seq_random identity from its reverse-engineered static routing table before event dispatch. Unknown routes and incomplete identities fail open, while C2C and group peers use their native namespaces.

Refines #266
2026-07-29 01:25:54 +08:00
DrSmoothl 5eb5aaf0a3 fix(protocol): suppress big-face compatibility text
Identify QQ's service-37 fallback by its byte-exact nested Text reserve so compatibility descriptions are removed without consuming user-authored sibling text or malformed payload fallbacks.

Fixes #289
2026-07-29 01:06:59 +08:00
DrSmoothl 3d7c4f5dc3 fix(protocol): align system message dedup identity
Match QQ NT's reverse-engineered peer, sequence, and random key so duplicate system events cannot bypass filtering through a different outer package type.

Fixes #266
2026-07-28 23:59:56 +08:00
DrSmoothl 52a3c49752 fix(protocol): avoid duplicate private voice elements
Prefer a successfully decoded modern voice record over the empty legacy voice placeholder that can accompany private message pushes.

Preserve legacy-only voice messages and add a protobuf round-trip regression covering the duplicate segment reported in #291.

Fixes #291
2026-07-28 22:49:06 +08:00
DrSmoothl 95debcf34b fix(protocol): harden history response decoding
Share packet response validation across group and private history fetches so transport failures and empty responses cannot masquerade as empty pages.

Reject malformed group records and mismatched private-peer responses while preserving explicit QQ control-message filters. Mark fetched contexts as historical so old invite cards cannot overwrite live approval state.

Add wire-level regression coverage for failed responses, malformed entries, peer mismatches, ordering, and live-only identity observations. Refs #280.
2026-07-25 23:43:30 +08:00
DrSmoothl e16fa78b55 fix(onebot): distinguish private poke conversations
Preserve the private conversation peer separately from the poke sender and target. Emit NapCat-compatible user_id and sender_id fields while keeping group notices unchanged.

Add MsgPush and event-converter regression coverage for self-pokes across multiple friend sessions.

Fixes #285.
2026-07-25 20:28:28 +08:00
DrSmoothl 13a32a2865 fix(protocol): harden friend dress queries
Require the dress page to identify the requested account and every returned item before exposing the result. Reject malformed nested media metadata instead of silently degrading it.

Bound the HTML request to a 10-second redirect-chain deadline and a 2 MiB response body. Secure redirects by closing previous connections, stripping cross-origin credentials, rejecting cross-origin write forwarding, and surfacing malformed locations.

Replace the captured page with a minimal sanitized fixture and add protocol plus OneBot Action regression coverage for resource limits, redirect safety, response ownership, and structured failures.
2026-07-25 20:22:49 +08:00
H3CoF6 3517257aa6 feat(onebot): expose friend dress queries (#277)
Add a read-only action for querying QQ profile decorations from the authenticated web page.

Validate and classify page responses, expose structured errors, and cover parsing with a sanitized fixture.
2026-07-25 19:53:24 +08:00
H3CoF6 679756d1a7 fix(protocol): correct collection summary protobuf fields (#269)
Correct type 2 link and type 8 rich-media summary field mappings so collection responses no longer fail with unterminated groups.

Add wire-level regression coverage for both layouts.
2026-07-25 19:53:11 +08:00
DrSmoothl dff4b3b032 fix(friend): align remark and delete protocols
Route friend remark updates and clears through the commands used by current QQ clients. Emit the required delete flags and surface post-delete cache refresh failures.

Add byte-exact regression coverage for all affected requests.

Fixes #284.
2026-07-25 15:41:02 +08:00
DrSmoothl 622c90d418 fix(protocol): transcode QQ AI voice recordings
Normalize the observed AI SILK container marker at the shared audio transcode boundary before invoking the bundled decoder. Preserve caller-owned bytes and leave ordinary SILK, AMR, and unrelated inputs unchanged.

Add unit and packaged-addon regression coverage for MP3 conversion, payload preservation, and input immutability.

Fixes #268
2026-07-21 23:29:28 +08:00
DrSmoothl eed2e692b1 fix(onebot): expose robot status for group members
Fetch QQ's versioned robot UIN ranges, classify and persist member status, and surface is_robot from both group member actions.

Preserve unknown legacy cache entries and fail visibly when classification is unavailable.

Closes #265
2026-07-21 23:27:01 +08:00
DrSmoothl ff60221330 feat(onebot): support private window shake messages
Encode poke message segments as private window shake messages while keeping the dedicated send_poke action unchanged.

Restrict window shakes to a single ordinary private-chat segment. Reject group, temporary-session, mixed-message, and forwarded usage before identity lookup, media upload, or packet transmission.

Add full outbound request coverage, OneBot action regressions, and live private-chat verification for issue #259.

Closes #259
2026-07-21 19:28:17 +08:00
DrSmoothl 4aa2cd1693 fix(onebot): correct private message history (#256)
Use the C2C roam cursor and canonical NT sequence for bidirectional history. Persist direction-aware recall tombstones so recalled messages cannot reappear.
2026-07-20 22:25:13 +08:00
DrSmoothl 4ba2b27398 fix(onebot): keep synthetic sequences out of history
Distinguish QQ-authoritative message sequences from local message IDs so group files and reply placeholders cannot become history anchors or be reused by protocol actions.

Filter QQ null roam records and migrate previously stored synthetic rows.

Fixes #254
2026-07-20 15:33:28 +08:00
DrSmoothl 297f0428cc fix(core): correlate AI voice send receipts
Wait for the canonical self group-message event after AI voice synthesis instead of interpreting undocumented response fields as a message sequence.

Correlate receipts by exact media UUID, buffer response races, and claim each semantic message identity only once across concurrent calls and duplicate multi-process pushes. Reject missing identifiers, invalid sequences, bounded-buffer overflow, and receipt timeouts with explicit diagnostics.

Keep fetchAiVoice focused on returning the media node and add regression coverage for race ordering, unrelated events, identical concurrent audio, duplicate pushes, malformed receipts, and timeout cleanup.

Fixes #250
2026-07-20 14:02:48 +08:00