From 652a8175688d5d53b007a1991bda496cfd655142 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Tue, 16 Jun 2026 18:15:56 +0800 Subject: [PATCH] chore(spike): retire KickNT force-offline probes, keep read-only body capture Conclude the spike on the inbound `trpc.qq_new_tech.status_svc.StatusService.KickNT` push and remove its throwaway instrumentation: - Bridge: drop the outbound send probe. - HookSession: drop the loggedIn-gate bypass; restore `if (!this.loggedIn) return;`. - HookManager: drop the disconnect-timing log. Keep one read-only `[KICK-BODY]` probe in Bridge that logs the KickNT push body (hex + utf8) so the reason fields (tipsTitle / tipsDesc) can be reversed for the upcoming notification reason-enrichment. Remove once captured. --- packages/bridge/src/hook-manager.ts | 1 - packages/bridge/src/hook-session.ts | 6 +----- packages/core/src/bridge/bridge.ts | 23 ++++++++++------------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/bridge/src/hook-manager.ts b/packages/bridge/src/hook-manager.ts index a54d0ae0..40a309dc 100644 --- a/packages/bridge/src/hook-manager.ts +++ b/packages/bridge/src/hook-manager.ts @@ -251,7 +251,6 @@ export class HookManager { this.bridgeManager.onHookLogin(pid, uin, sender); }); session.on('disconnected', (wasLoggedIn: boolean) => { - this.log.warn('[SPIKE] disconnected T2=%d PID=%d wasLoggedIn=%s', Date.now(), pid, wasLoggedIn); // SPIKE PROBE (亡语 Q2) — 验完即删 if (wasLoggedIn) this.bridgeManager.onPidDisconnected(pid); }); session.on('disposed', () => { diff --git a/packages/bridge/src/hook-session.ts b/packages/bridge/src/hook-session.ts index 2f08668b..2da5a150 100644 --- a/packages/bridge/src/hook-session.ts +++ b/packages/bridge/src/hook-session.ts @@ -402,11 +402,7 @@ export class HookSession extends EventEmitter { } private handlePacket(packet: QqHookPacket): void { - // ── SPIKE PROBE (亡语 Q2) — 验完即删: KickNT 必须在 loggedIn 翻 false 后仍放行 ── - const __spikeKick = packet.cmd === 'trpc.qq_new_tech.status_svc.StatusService.KickNT'; - if (__spikeKick) this.log.warn('[SPIKE] KickNT@pipe T0pipe=%d PID=%d loggedIn=%s', Date.now(), this.pid, this.loggedIn); - if (!this.loggedIn && !__spikeKick) return; // SPIKE: 原为 `if (!this.loggedIn) return;` - // ── /SPIKE PROBE ── + if (!this.loggedIn) return; const uin = packet.uin || this._uin; if (!isRealUin(uin)) return; if (!this.onPacket) return; diff --git a/packages/core/src/bridge/bridge.ts b/packages/core/src/bridge/bridge.ts index 52e5892a..40b0b25d 100644 --- a/packages/core/src/bridge/bridge.ts +++ b/packages/core/src/bridge/bridge.ts @@ -63,21 +63,18 @@ export class Bridge implements BridgeInterface { }, }); this.pipeline.registerCmd(MSG_PUSH_CMD, parseMsgPush); - // ── SPIKE PROBE (亡语 Q2) — 验完即删 ───────────────────────────── - // KickNT(被踢 push) 一到就同步试发一条带 T0 的私聊, 验 native teardown 前 - // 是否还有可写窗口. 目标: env SPIKE_DEATHRATTLE_TARGET(uin), 缺省发给自己. - this.pipeline.registerCmd('trpc.qq_new_tech.status_svc.StatusService.KickNT', () => { - const t0 = Date.now(); - const target = Number(process.env.SPIKE_DEATHRATTLE_TARGET) || Number(this.identity.uin) || 0; - log.warn('[SPIKE] KickNT@bridge T0=%d uin=%s target=%d', t0, this.identity.uin, target); - if (target > 0) { - this.apis.message.sendPrivate(target, [{ type: 'text', text: `亡语测试 T0=${t0}` }]) - .then(r => log.warn('[SPIKE] send OK T0=%d T1=%d Δ=%dms seq=%d msgId=%d', t0, Date.now(), Date.now() - t0, r.sequence, r.messageId)) - .catch(e => log.warn('[SPIKE] send FAIL T0=%d T1=%d Δ=%dms err=%s', t0, Date.now(), Date.now() - t0, e instanceof Error ? e.message : String(e))); - } + // ── PROBE (webhook 原因富化) — 验完即删 ────────────────────────── + // 亡语 Q2 已判死(服务器侧会话失效 → PbSendMsg 1006509, 见 + // docs/plans/spike-deathrattle-window.md). 留这一只只读 probe 抓 KickNT + // body, 给后续 webhook reason-enrichment 反 tipsTitle/tipsDesc 的字段 + // 布局. 不试发、不旁路 loggedIn 门. 抓到一次 body 后即删。 + this.pipeline.registerCmd('trpc.qq_new_tech.status_svc.StatusService.KickNT', (pkt) => { + const buf = Buffer.from(pkt.body); + log.warn('[KICK-BODY] uin=%s len=%dB hex=%s utf8=%s', + this.identity.uin, buf.length, buf.toString('hex'), JSON.stringify(buf.toString('utf8'))); return []; }); - // ── /SPIKE PROBE ──────────────────────────────────────────────── + // ── /PROBE ────────────────────────────────────────────────────── } dispose(): void {