7 Commits
Author SHA1 Message Date
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +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 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 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 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 b92c8ad881 feat(protocol): decode online device snapshots
Decode Event 0x210 subtype 349 into typed online-device snapshots, including QQ-compatible low-byte client type normalization and one-entry-per-device-category projection.

Keep replacement snapshots outside system-message deduplication, reject malformed device identities observably, and add wire-level regressions for complete, packed, repeated, and invalid payloads. Live verification covered mobile account switching without requiring native changes.
2026-07-19 19:19:58 +08:00
DrSmoothl 1bdb8a40c4 fix(protocol): dedup duplicate system pushes (#137 official-robot double group_increase)
Inviting an official robot (e.g. 2854207029) into a group made QQ push the
group_member_increase notice twice, so SnowLuma emitted two
notice.group_increase events; a normal member produced one.

Root cause (RE of wrapper.linux.node): QQ NT dedups every received system
message in sys_msg_mgr.cc::ProcessRecvSysMsg (sub_37BADE0) by a global_key
`{peerUid}_{chatType}_{msg_seq}_{random}` (sub_37BC4E0) — an already-seen key
is dropped ("ignore dup msg") before any listener sees it. The per-message
discriminators msg_seq (attr 40003 = contentHead field 5) and random (attr
40002 = contentHead field 4) are exactly head.sequence and head.msgId
(msg_header_codec_helper.cc sub_37C8AD0). Kernel-based bots (NapCat/LLOneBot)
receive events after this dedup; SnowLuma reads the raw OlPush before it.

Mirror it: SysMsgDedup, a per-account bounded ring that drops a duplicate
system push by (msgType, subType, fromUin, sequence, msgId). Push-level (drops
the whole duplicate like NT), live path only (Bridge owns the tracker; the
forward re-parse passes none), system kinds only (chat messages excluded), and
never dedups a push lacking a server identity (sequence or msgId 0).
2026-06-23 20:36:24 +08:00