Commit Graph
1068 Commits
Author SHA1 Message Date
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 19e3135e63 feat(onebot): expose friend remarks in stranger info
Return the already-decoded profile remark from fetched and cached get_stranger_info results, document its fallback shape, and regenerate the MCP action catalog.

Fixes #290
2026-07-28 23:59:25 +08:00
DrSmoothl eeaa5436fd fix(onebot): report private forwarded messages
Route both private forward actions through the existing self-sent echo callback while preserving the authoritative-receipt and canonical-echo guards.

Fixes #288
2026-07-28 23:58:48 +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 df3f8c5587 chore(release): v1.12.10 2026-07-26 19:29:28 +08:00
DrSmoothl 63abe98a84 fix(bridge): retry transient startup loading failures
Retry narrowly classified startup failures on later watcher ticks with a fixed attempt limit. Preserve permanent failures and record recovery, pending, and exhausted outcomes.

Add regression coverage for recovery, non-retry, and bounded exhaustion.
2026-07-26 16:04:57 +08:00
DrSmoothl d05bbe3551 fix(bridge): synchronize reconciled login state
Route recovered login state through the hook client before dependent services start. Add regression coverage to keep packet actions available after reconciliation.

Fixes #286.
2026-07-26 15:53:57 +08:00
DrSmoothl b5e10fefc2 feat(webui): configure login history backfill
Expose the per-account login history backfill switch in General settings and keep missing or legacy configuration disabled by default.

Document that changes apply on the next login, historical messages are stored locally without event replay or read-state changes, and fixed safety limits govern roster scanning, selected sessions, page size, request spacing, and retries.

Add WebUI normalization coverage so the optional setting survives save and restore without silently inheriting an enabled value. Refs #280.
2026-07-25 23:44:54 +08:00
DrSmoothl dc2ec1235a feat(onebot): backfill cloud history after login
Add an opt-in per-account login history backfill that waits for roster warmup and a 30-second grace period before silently filling local message history. The setting defaults to disabled and applies on the next account lifecycle.

Run one account at a time, prioritize known local gaps, and process at most three groups plus three friends with one 20-message page per session. Failures are logged and never retried during the same login.

Persist reconstructed history without dispatching OneBot events or changing QQ read state. Keep private metadata and event bodies atomic, honor recall tombstones, suppress live-only history side effects, avoid extra media requests, and stop queued, in-flight, or converting work when the account closes.

Share the persistence path with manual history actions and add lifecycle, cancellation, corruption, partial-failure, peer-identity, and storage-atomicity regression coverage. Refs #280.
2026-07-25 23:44:28 +08:00
DrSmoothl b71279dcc3 feat(core): add bounded login history queries
Expose a read-only cursor probe plus one-page group and private history methods for login backfill. Validate targets, ranges, response ordering, and page sizes before returning decoded events.

Serialize all history traffic through a process-wide gate. Automatic requests keep a two-second gap, accept at most 100 targets per kind and 20 sequence slots per session, and honor account cancellation before any queued network operation starts.

Keep the probe side-effect free by omitting read markers, and add focused tests for packet budgets, invalid responses, throttling, cancellation, and continued gate usability after failures. Refs #280.
2026-07-25 23:43:59 +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 5ad8027524 fix(onebot): report self-sent private files
Preserve authoritative receipts for private file sends and emit one message_sent event per actual QQ message. Split source uploads from chat publishing so failures surface instead of returning a synthetic zero-sequence receipt.

Fixes #282
2026-07-25 21:55:44 +08:00
DrSmoothl 3a7253315f feat(onebot): share HTTP listeners with WebSocket clients
Add an opt-in HTTP server setting that accepts OneBot WebSocket connections on the same port and access token while preserving standalone WebSocket server configurations.

Reuse the existing connection lifecycle for authentication, roles, events, heartbeat, streaming actions, token rotation, and shutdown. Expose the switch in WebUI and persist it through strict configuration validation and restore paths.

Refs: #281
2026-07-25 20:40:43 +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 c64f9d3078 chore(release): v1.12.9 2026-07-24 14:15:51 +08:00
DrSmoothl 87a604ecbd feat(storage): add managed storage controls
Enforce a global log quota with configurable retention and observable degradation. Add authenticated storage reporting and safe cleanup controls to the settings UI. Protect active stream transfers and isolate parallel test resources.
2026-07-24 12:58:57 +08:00
DrSmoothl b884a1c479 fix(onebot): unify message segment type normalization
Keep empty-placeholder detection aligned with strict segment parsing.
2026-07-23 12:18:02 +08:00
DrSmoothl edd2ac278a fix(onebot): trace empty text placeholder normalization
Document the compatibility rule in action metadata and regenerate the MCP catalog.
2026-07-23 12:14:01 +08:00
DrSmoothl a7b9ba14fb fix(onebot): accept empty text placeholders in arrays
Fixes #273.
2026-07-23 12:08:17 +08:00
DrSmoothl 120dda1d9d fix(group-album): fetch all legacy album pages
Follow AlbumService cursors in get_group_album_list so the legacy array response contains every album instead of only the first page.

Reject missing or repeated cursors when the server reports more data, preventing silent truncation and pagination loops. Add regression coverage for multi-page aggregation and malformed cursors.

Fixes #272
2026-07-22 21:51:33 +08:00
DrSmoothl 97ab8dc393 chore(release): v1.12.8 2026-07-22 20:03:54 +08:00
DrSmoothl aed15b9a3f fix(group-album): return video media metadata
Decode the QQ group album video payload, including cover, duration, and multi-resolution URLs. Add a wire-level regression test and update generated action documentation.

Fixes #270
2026-07-22 20:00:07 +08:00
DrSmoothl 7fb8aa1d42 fix(webui): keep node dialog actions visible
Separate the node editor into fixed header and footer rows with an independently scrollable form body, so short viewports cannot push the save action out of reach.
2026-07-22 00:02:48 +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 feb7fcac0e feat(group-album): expose cover and upload metadata
Decode the verified album cover response field and expose normalized cover details and last-upload timestamps through both album list actions. Preserve the legacy numeric timestamp shape, retain string timestamps for the native response, return null when no cover exists, and avoid additional network requests.

Document the new output contracts in the OneBot and MCP catalogs. Add independent wire fixtures and action-level regression tests for the protocol mapping and public response shapes.

Refs #257
2026-07-20 23:37:41 +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 88216ce644 chore(release): v1.12.7 2026-07-20 15:52:49 +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 2c8a8af514 test(protocol): centralize nested operator fixture
Name the GroupChange.decreaseType field explicitly and reuse one wire fixture across member-increase and member-decrease coverage.
2026-07-20 14:12:10 +08:00
DrSmoothl 2dbd321ef0 fix(protocol): decode nested group operators
Recognize both raw UTF-8 UIDs and nested OperatorInfo envelopes in GroupChange pushes while keeping self-kick and voluntary-leave semantics explicit.\n\nFixes #253.
2026-07-20 14:08:50 +08:00
DrSmoothl ae6093cf23 docs(mcp): document AI voice message IDs
Regenerate the MCP Action catalog so send_group_ai_record advertises the real OneBot message_id returned after a successful AI voice send.

Keep the generic MCP tool surface unchanged while making the corrected result contract visible to agents and clients.

Refs #250
2026-07-20 14:03:32 +08:00
DrSmoothl fc80a598c0 fix(onebot): return AI voice message IDs
Build send_group_ai_record results from the canonical group-message sequence returned by the Core receipt correlator, using the same message ID mapping as normal inbound events.

Stop reporting the historical placeholder value of zero and surface receipt failures through the standard Action error path. Preserve the existing get_ai_record URL response and update the SDK result documentation without changing its public shape.

Add Action-level coverage for canonical ID generation and missing-receipt failures.

Refs #250
2026-07-20 14:03:13 +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
DrSmoothl 06c26dee87 fix(group-album): use native QQ album service
Replace the lossy Qzone album-list endpoint with the QQ NT AlbumService protobuf request. Preserve creator nicknames and expose native pagination for get_qun_album_list.
2026-07-20 13:03:16 +08:00
DrSmoothl 8df62d6486 fix(onebot): report API-sent private messages
Emit message_sent.private after successful friend messages sent through OneBot actions or the WebUI debug console when QQ does not provide an inbound self echo.

Keep a later QQ echo as the canonical stored event while suppressing duplicate downstream delivery across both race orders. Match echoes by conversation, sequence, message ID, and a bounded time window; leave group messages, temporary sessions, split file sends, unreliable receipts, and messages sent manually from the QQ client unchanged.

Add regression coverage for action-only reporting, both echo race orders, hash collisions, cached-but-unreported events, temporary sessions, and incomplete receipts.

Fixes #251
2026-07-20 13:02:29 +08:00
DrSmoothl 810d72fa04 feat(onebot): implement collection list retrieval
Replace the get_collection_list placeholder with authenticated, read-only collection retrieval through the existing bridge API.

Add strict binary envelope validation, bounded pagination, accurate category filtering, preserved 64-bit identifiers, and explicit ticket, transport, service, and malformed-response failures. Cap item counts, page traversal, response bytes, per-request waits, and the total operation time.

Expose the compatible response model through Core, OneBot, the SDK, and the generated MCP catalog. Cover protocol framing, cursor behavior, filtered hasMore semantics, cleanup failures, bridge ticket acquisition, and Action validation with regression tests.

Verified with the live test bot without changing native components or adding any collection write behavior.
2026-07-19 20:22:16 +08:00
DrSmoothl 4e62fdc80b chore(release): v1.12.6 2026-07-19 19:38:13 +08:00
DrSmoothl 4520687fbe docs(webui): clarify custom pointer default
State in the appearance settings that the custom cursor and context-menu system is disabled by default.
2026-07-19 19:37:49 +08:00
DrSmoothl a9b8440731 fix(webui): disable custom pointer system by default
Default new and legacy-normalized appearance configs to native cursor and context-menu behavior while preserving explicit opt-in settings.
2026-07-19 19:33:26 +08:00
DrSmoothl f3bfec04a5 feat(onebot): implement online client queries
Replace the get_online_clients placeholder with the latest QQ online-device snapshot and return stable OneBot fields for client ID, device name, and localized device category.

Fail explicitly when no snapshot has been observed or when callers request an unsupported fresh refresh, while preserving an observed empty snapshot as a successful result. Update SDK types and generated MCP schemas, and add action-level coverage for every state.
2026-07-19 19:20:28 +08:00
DrSmoothl 168f414cd9 feat(core): retain online device snapshots
Store the latest online-device snapshot for each Bridge lifecycle and expose it through the bridge contract as an immutable, owned value.

Distinguish a snapshot that has not yet been observed from a valid empty snapshot, replace state atomically on each QQ update, clear it during disposal, and cover lifecycle, immutability, and cleanup behavior with focused tests.
2026-07-19 19:20:14 +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 e6a69b05a7 feat(onebot): expose group folder upload metadata
Decode the folder modifier metadata returned by group file listings and project it as last upload time, uploader ID, and uploader name for both folder listing actions.

Regenerate the MCP catalog and add protocol, bridge, OneBot projection, and action schema coverage for the new fields.

Closes #248
2026-07-19 18:34:53 +08:00
DrSmoothl f3e0c4e45a fix(onebot): allow clearing the self signature
Accept explicit empty strings from both longNick and long_nick when callers need to clear the bot signature. Missing and non-string values remain rejected before reaching the bridge.

Preserve the QQ-compatible clear representation by omitting the empty profile value, and add action-level and wire-level regression coverage. Live verification confirmed successful clearing and readback on the test bot.

Fixes #247
2026-07-19 18:12:48 +08:00