@napuketto/adapter 0.8.4 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { i as ProtocolConfig, n as BaseProtocolAdapter, s as ActionRegistry, u as ErrorCodeMap } from "../index-CDKj-jus.mjs";
1
+ import { D as ErrorCodeMap, w as ActionRegistry, x as ProtocolConfig, y as BaseProtocolAdapter } from "../index-h-tsUu0j.mjs";
2
2
  import "../gray-tip-8zPh4d9W.mjs";
3
3
  import { BuddyCacheEventChannel, BuddyEventChannel, CanonicalElement, ChatType, FriendApi, GroupApi, GroupCache, GroupEventChannel, GroupNotifyApi, MsgApi, MsgEventChannel, Peer, ProfileApi, ProfileLikeApi, RawMessage, RichMediaApi, TicketApi, WebApi } from "@napuketto/kernel";
4
4
  import { z } from "zod";
@@ -795,8 +795,11 @@ declare class NapukettoOneBot11Adapter extends BaseProtocolAdapter<OB11Config> {
795
795
  unsubscribeOnly(): void;
796
796
  /**
797
797
  * 单条 sysmsg 字节块:解码 → 识别 → 命中才广播,未识别打结构化校准日志
798
- * (识别表为空时全部走日志路径,design.md §7.5)。
798
+ * (识别表 2026-11-01 起含 732:21 group_card;design.md §7.5)。
799
+ * 规则声明 collectUids 时先批量 uid→uin 再提取(异步 fire-and-forget)。
799
800
  */
801
+ /** sysmsg 规则的 uid→uin 解析器(collectUids 声明才批量转换;失败/缺省恒 0)。 */
802
+ private sysMsgUinResolver;
800
803
  private handleSysMsgBlob;
801
804
  /**
802
805
  * 广播消息事件(P2-19:接收方向 ID 转换)。
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/onebot11/types/index.ts","../../src/onebot11/helper/data.ts","../../src/onebot11/helper/message-unique.ts","../../src/onebot11/api/one-bot-api.ts","../../src/onebot11/action/error-map.ts","../../src/onebot11/action/group/get-group-at-all-remain.ts","../../src/onebot11/event/base.ts","../../src/onebot11/event/message.ts","../../src/onebot11/event/meta.ts","../../src/onebot11/event/notice.ts","../../src/onebot11/event/request.ts","../../src/onebot11/event/index.ts","../../src/onebot11/action/index.ts","../../src/onebot11/helper/codec/cqcode.ts","../../src/onebot11/helper/codec/segment.ts","../../src/onebot11/helper/config.ts","../../src/onebot11/adapter.ts","../../src/onebot11/transport.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/onebot11/types/index.ts","../../src/onebot11/helper/data.ts","../../src/onebot11/helper/message-unique.ts","../../src/onebot11/api/one-bot-api.ts","../../src/onebot11/action/error-map.ts","../../src/onebot11/action/group/get-group-at-all-remain.ts","../../src/onebot11/event/base.ts","../../src/onebot11/event/message.ts","../../src/onebot11/event/meta.ts","../../src/onebot11/event/notice.ts","../../src/onebot11/event/request.ts","../../src/onebot11/event/index.ts","../../src/onebot11/action/index.ts","../../src/onebot11/helper/codec/cqcode.ts","../../src/onebot11/helper/codec/segment.ts","../../src/onebot11/helper/config.ts","../../src/onebot11/adapter.ts","../../src/onebot11/transport.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as BaseAction, o as ActionRegistry, r as BaseProtocolAdapter, t as ensureSilk } from "../core-DyXyDUcU.mjs";
1
+ import { _ as BaseProtocolAdapter, b as ActionRegistry, d as toHex, h as ensureSilk, i as extractSysMsgEnvelope, l as recognizeSysMsg, n as decodeProtoTree, s as narrowSysMsgBlobs, v as BaseAction } from "../core-DW5i42XH.mjs";
2
2
  import { n as createWsServerSchema, t as createHttpServerSchema } from "../transport-schema-CpPxyRK0.mjs";
3
3
  import { n as firstUntranslatedGrayTip, t as collectGrayTipUids } from "../gray-tip-LwBee5mo.mjs";
4
4
  import { n as MS_TO_SEC$5, r as resolveUin, t as narrowBuddyReqs } from "../buddy-req-Q7Q4bVuz.mjs";
@@ -3726,248 +3726,58 @@ function toOfflineFileNotice(item, selfUin) {
3726
3726
  }
3727
3727
  //#endregion
3728
3728
  //#region src/onebot11/helper/sysmsg.ts
3729
- /** 递归深度上限(防御:恶意/畸形字节防栈溢出)。 */
3730
- const MAX_DEPTH = 16;
3731
- /** 单层字段数上限。 */
3732
- const MAX_FIELDS = 256;
3733
- /** 单个 varint 最大字节数(64 位 + 1 冗余)。 */
3734
- const MAX_VARINT_BYTES = 10;
3735
- /** 读 varint:成功返回 [值, 下一偏移],越界/超长返回 null。 */
3736
- function readVarint(data, start) {
3737
- let value = 0n;
3738
- let shift = 0n;
3739
- let i = start;
3740
- while (true) {
3741
- if (i >= data.length || i - start >= MAX_VARINT_BYTES) return null;
3742
- const byte = data[i];
3743
- if (byte === void 0) return null;
3744
- i += 1;
3745
- value |= BigInt(byte & 127) << shift;
3746
- if ((byte & 128) === 0) return [value, i];
3747
- shift += 7n;
3748
- }
3749
- }
3750
- /** wire 2:length-delimited 字段(递归 try-parse 子树,失败 → 不透明字节)。 */
3751
- function decodeLengthDelimited(data, afterTag, no, depth) {
3752
- const len = readVarint(data, afterTag);
3753
- if (len === null) return null;
3754
- const payloadStart = len[1];
3755
- const end = payloadStart + Number(len[0]);
3756
- if (end > data.length) return null;
3757
- const slice = data.slice(payloadStart, end);
3758
- return {
3759
- field: {
3760
- no,
3761
- kind: "bytes",
3762
- value: slice,
3763
- children: decodeProtoTree(slice, depth + 1)
3764
- },
3765
- next: end
3766
- };
3767
- }
3768
- /** 解码单个带 tag 字段;畸形(field 0 / group / 截断 / 越界)返回 null。 */
3769
- function decodeTaggedField(data, start, depth) {
3770
- const tag = readVarint(data, start);
3771
- if (tag === null) return null;
3772
- const [tagValue, afterTag] = tag;
3773
- const no = Number(tagValue >> 3n);
3774
- const wireType = Number(tagValue & 7n);
3775
- if (no === 0) return null;
3776
- if (wireType === 0) {
3777
- const v = readVarint(data, afterTag);
3778
- if (v === null) return null;
3779
- return {
3780
- field: {
3781
- no,
3782
- kind: "varint",
3783
- value: v[0]
3784
- },
3785
- next: v[1]
3786
- };
3787
- }
3788
- if (wireType === 2) return decodeLengthDelimited(data, afterTag, no, depth);
3789
- if (wireType === 1 || wireType === 5) {
3790
- const next = afterTag + (wireType === 1 ? 8 : 4);
3791
- return next > data.length ? null : {
3792
- field: void 0,
3793
- next
3794
- };
3795
- }
3796
- return null;
3797
- }
3798
3729
  /**
3799
- * 解码 protobuf wire-format 为递归字段树(不维护字段重复/顺序语义以外的信息)。
3730
+ * OB11 sysmsg 识别表(2026-11-01 自 helper/sysmsg.ts 瘦身——解码层上移
3731
+ * core/sysmsg.ts 共享,milky.md §0.8.3/§0.8.6)
3800
3732
  *
3801
- * - wire 0 varint / wire 2 length-delimited:支持;wire 2 递归 try-parse,
3802
- * 子解析失败按不透明字节挂树(ASCII 串偶发误判嵌套无实害——树仅用于观测)。
3803
- * - wire 1/5(fixed64/32):跳过(QQ NT blob 未观测到,防御性兼容)。
3804
- * - wire 3/4(group)、截断、field 0、超限:判失败返回 null。
3805
- */
3806
- function decodeProtoTree(data, depth = 0) {
3807
- if (depth > MAX_DEPTH) return null;
3808
- const fields = [];
3809
- let i = 0;
3810
- while (i < data.length) {
3811
- if (fields.length >= MAX_FIELDS) return null;
3812
- const decoded = decodeTaggedField(data, i, depth);
3813
- if (decoded === null) return null;
3814
- if (decoded.field !== void 0) fields.push(decoded.field);
3815
- i = decoded.next;
3816
- }
3817
- return fields;
3818
- }
3819
- /** 取字段号首个命中的节点。 */
3820
- function firstField(tree, no) {
3821
- return tree.find((f) => f.no === no);
3822
- }
3823
- /** varint → number(超安全整数返回 null,调用方按缺字段处理)。 */
3824
- function varintToNumber(value) {
3825
- return value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : null;
3826
- }
3827
- /** UTF-8 严格解码 + 可打印检查(含控制字符判不可解码,返回 null)。 */
3828
- function decodeText(bytes) {
3829
- try {
3830
- const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
3831
- for (const ch of text) {
3832
- const code = ch.codePointAt(0) ?? 0;
3833
- if (code < 32 && code !== 9) return null;
3834
- }
3835
- return text;
3836
- } catch {
3837
- return null;
3838
- }
3839
- }
3840
- /** 递归收集树内全部可打印字符串(校准观测用;先序遍历,空字节段跳过)。 */
3841
- function collectStrings(tree) {
3842
- const out = [];
3843
- for (const f of tree) {
3844
- if (f.kind === "varint") continue;
3845
- const text = decodeText(f.value);
3846
- if (text !== null && text.length > 0) out.push(text);
3847
- if (f.children !== null) out.push(...collectStrings(f.children));
3848
- }
3849
- return out;
3850
- }
3851
- /** 单个候选块 → Uint8Array(number[] -128..255 / TypedArray;其余 null)。 */
3852
- function toBlob(item) {
3853
- if (item instanceof Uint8Array) return new Uint8Array(item);
3854
- if (item instanceof Int8Array) return Uint8Array.from(item, (b) => b & 255);
3855
- if (Array.isArray(item) && item.length > 0) {
3856
- const out = new Uint8Array(item.length);
3857
- for (let i = 0; i < item.length; i += 1) {
3858
- const b = item[i];
3859
- if (typeof b !== "number" || !Number.isInteger(b) || b < -128 || b > 255) return null;
3860
- out[i] = b & 255;
3861
- }
3862
- return out;
3863
- }
3864
- return null;
3865
- }
3866
- /**
3867
- * onRecvSysMsg 参数 → sysmsg 字节块列表(防御性收窄)。
3868
- * 接受批数组(实测形状)/ 单块裸数组 / TypedArray;零有效块返回 null
3869
- * (调用方打 raw 日志,与 narrowOfflineFiles 同模式)。
3870
- */
3871
- function narrowSysMsgBlobs(arg) {
3872
- if (Array.isArray(arg)) {
3873
- const blobs = arg.map(toBlob).filter((b) => b !== null);
3874
- if (blobs.length > 0) return blobs;
3875
- const single = toBlob(arg);
3876
- return single === null ? null : [single];
3877
- }
3878
- const single = toBlob(arg);
3879
- return single === null ? null : [single];
3880
- }
3881
- /** 顶层 f1 块的字段(uin/uid 对)。 */
3882
- function extractActorBlock(block) {
3883
- const empty = {
3884
- uin: null,
3885
- uid: null,
3886
- uin2: null,
3887
- uid2: null
3888
- };
3889
- if (block === null) return empty;
3890
- const f1 = firstField(block, 1);
3891
- const f2 = firstField(block, 2);
3892
- const f5 = firstField(block, 5);
3893
- const f6 = firstField(block, 6);
3894
- return {
3895
- uin: f1?.kind === "varint" ? varintToNumber(f1.value) : null,
3896
- uid: f2?.kind === "bytes" ? decodeText(f2.value) : null,
3897
- uin2: f5?.kind === "varint" ? varintToNumber(f5.value) : null,
3898
- uid2: f6?.kind === "bytes" ? decodeText(f6.value) : null
3899
- };
3900
- }
3901
- /** 顶层 f2 块 → 信封数值字段。 */
3902
- function extractEnvelopeBlock(block) {
3903
- const empty = {
3904
- msgType: null,
3905
- subType: null,
3906
- subTypeAlt: null,
3907
- groupCodes: null,
3908
- time: null
3909
- };
3910
- if (block === null) return empty;
3911
- const num = (no) => {
3912
- const f = firstField(block, no);
3913
- return f?.kind === "varint" ? varintToNumber(f.value) : null;
3914
- };
3915
- const code4 = num(4);
3916
- const code5 = num(5);
3917
- return {
3918
- msgType: num(1),
3919
- subType: num(2),
3920
- subTypeAlt: num(3),
3921
- groupCodes: code4 !== null && code5 !== null ? [code4, code5] : null,
3922
- time: num(6)
3923
- };
3924
- }
3925
- /** 字段树 → 信封(design.md §7.3;任何字段缺失/非法 = null,不抛错)。 */
3926
- function extractSysMsgEnvelope(tree) {
3927
- const actor = extractActorBlock(getChildren(firstField(tree, 1)));
3928
- return {
3929
- actorUin: actor.uin,
3930
- actorUid: actor.uid,
3931
- targetUin: actor.uin2,
3932
- targetUid: actor.uid2,
3933
- ...extractEnvelopeBlock(getChildren(firstField(tree, 2))),
3934
- strings: collectStrings(tree)
3935
- };
3936
- }
3937
- /** bytes 节点的子树(非 bytes/不透明 → null)。 */
3938
- function getChildren(field) {
3939
- return field?.kind === "bytes" ? field.children : null;
3940
- }
3941
- /**
3942
- * (msgType, subType) → 规则表,主键 `"${msgType}:${subType}"`(原生分发键,
3943
- * design.md §7.1)。
3733
+ * 本模块只保留 OB11 侧内容:
3734
+ * - SysMsgNoticeKind:sysmsg 可映射的 OB11 notice 种类(event/notice.ts 既有类型)
3735
+ * - KIND_TABLE:(msgType, subType) → 规则(键 = 原生分发键)
3736
+ * - OBSERVED_UNNAMED:已观测但未命名的键(不广播,防校准日志噪音)
3737
+ * - recognizeSysMsg:绑定 OB11 表的识别入口
3944
3738
  *
3945
- * ⚠️ 当前为空:c3 以来的全部真实样本(2 条)均为 528/382 未命名类型,
3946
- * card/title/sign 的判别值没有样本支撑——在此登记规则前不会广播任何 sysmsg
3947
- * notice。拿到真实样本后登记 extract 规则即可(规则实现参考
3948
- * notice-extra.ts 防御性收窄风格)。
3739
+ * 解码原语(decodeProtoTree / extractSysMsgEnvelope / narrowSysMsgBlobs 等)
3740
+ * 从 `core/sysmsg.js` 导入使用。
3949
3741
  */
3950
- const KIND_TABLE = /* @__PURE__ */ new Map();
3951
- /** 已观测但未命名的 (msgType, subType):c3 双样本 528/382(语义未知)。 */
3952
- const OBSERVED_UNNAMED = /* @__PURE__ */ new Set(["528:382"]);
3742
+ /** 群号判别(strings[0] 必须是数字串)。 */
3743
+ const NUMERIC_RE = /^\d+$/;
3953
3744
  /**
3954
- * (msgType, subType) → 识别结果。table 参数供单测注入合成规则(生产走
3955
- * KIND_TABLE)。
3745
+ * (msgType, subType) → 规则表(键 = 原生分发键,design.md §7.1)。
3746
+ *
3747
+ * 2026-11-01 起不再是空表:732:21(群名片变更)为批次三轮录制取得的首个
3748
+ * 实证条目。card/title 等其余判别值仍无样本支撑,宁可漏报不错报;未识别
3749
+ * 一律走结构化校准日志,不广播。
3956
3750
  */
3957
- function recognizeSysMsg(msgType, subType, table = KIND_TABLE) {
3958
- if (msgType === null || subType === null) return { kind: "unknown" };
3959
- const rule = table.get(`${msgType}:${subType}`);
3960
- if (rule !== void 0) return {
3961
- kind: "notice",
3962
- rule
3963
- };
3964
- return OBSERVED_UNNAMED.has(`${msgType}:${subType}`) ? { kind: "observed_unnamed" } : { kind: "unknown" };
3965
- }
3966
- /** 字节块 → 小写 hex(校准日志用;超长由调用方截断)。 */
3967
- function toHex(bytes) {
3968
- let out = "";
3969
- for (const b of bytes) out += b.toString(16).padStart(2, "0");
3970
- return out;
3751
+ const KIND_TABLE = /* @__PURE__ */ new Map([["732:21", {
3752
+ kind: "group_card",
3753
+ collectUids: (_tree, env) => {
3754
+ const subject = env.strings[1];
3755
+ return subject?.startsWith("u_") === true ? [subject] : [];
3756
+ },
3757
+ extract: (_tree, env, uinOf, ctx) => {
3758
+ const [groupCode, subject, cardNew, cardOld] = env.strings;
3759
+ if (groupCode === void 0 || subject === void 0 || !NUMERIC_RE.test(groupCode) || !subject.startsWith("u_")) return null;
3760
+ return {
3761
+ time: ctx.time,
3762
+ self_id: ctx.selfUin,
3763
+ post_type: "notice",
3764
+ notice_type: "group_card",
3765
+ group_id: Number(groupCode),
3766
+ user_id: uinOf(subject),
3767
+ card_new: cardNew ?? "",
3768
+ card_old: cardOld ?? ""
3769
+ };
3770
+ }
3771
+ }]]);
3772
+ /** 已观测但未命名的 (msgType, subType)(语义未知,不广播)。 */
3773
+ const OBSERVED_UNNAMED = /* @__PURE__ */ new Set([
3774
+ "528:382",
3775
+ "528:349",
3776
+ "528:381"
3777
+ ]);
3778
+ /** (msgType, subType) → 识别结果(绑定 OB11 表;table 参数供单测注入合成规则)。 */
3779
+ function recognizeOb11SysMsg(msgType, subType, table = KIND_TABLE) {
3780
+ return recognizeSysMsg(msgType, subType, table, OBSERVED_UNNAMED);
3971
3781
  }
3972
3782
  //#endregion
3973
3783
  //#region src/onebot11/transport.ts
@@ -4333,18 +4143,36 @@ var NapukettoOneBot11Adapter = class extends BaseProtocolAdapter {
4333
4143
  }
4334
4144
  /**
4335
4145
  * 单条 sysmsg 字节块:解码 → 识别 → 命中才广播,未识别打结构化校准日志
4336
- * (识别表为空时全部走日志路径,design.md §7.5)。
4146
+ * (识别表 2026-11-01 起含 732:21 group_card;design.md §7.5)。
4147
+ * 规则声明 collectUids 时先批量 uid→uin 再提取(异步 fire-and-forget)。
4337
4148
  */
4338
- handleSysMsgBlob(blob) {
4149
+ /** sysmsg 规则的 uid→uin 解析器(collectUids 声明才批量转换;失败/缺省恒 0)。 */
4150
+ async sysMsgUinResolver(rule, tree, env) {
4151
+ if (rule.collectUids === void 0) return () => 0;
4152
+ const uids = rule.collectUids(tree, env).filter((uid) => uid !== "");
4153
+ if (uids.length === 0) return () => 0;
4154
+ try {
4155
+ const map = await this.oneBotApi.uidToUin(uids);
4156
+ return (uid) => Number(map.get(uid) ?? 0);
4157
+ } catch {
4158
+ return () => 0;
4159
+ }
4160
+ }
4161
+ async handleSysMsgBlob(blob) {
4339
4162
  const tree = decodeProtoTree(blob);
4340
4163
  if (tree === null) {
4341
4164
  this.calibLogger?.warn({ raw: truncRaw(toHex(blob).slice(0, 1024)) }, "ob11: onRecvSysMsg protobuf 解码失败");
4342
4165
  return;
4343
4166
  }
4344
4167
  const env = extractSysMsgEnvelope(tree);
4345
- const rec = recognizeSysMsg(env.msgType, env.subType);
4168
+ const rec = recognizeOb11SysMsg(env.msgType, env.subType);
4346
4169
  if (rec.kind === "notice") {
4347
- const event = rec.rule.extract(tree, env);
4170
+ const uinOf = await this.sysMsgUinResolver(rec.rule, tree, env);
4171
+ const ctx = {
4172
+ selfUin: Number(this.selfUin),
4173
+ time: env.time ?? Math.floor(Date.now() / 1e3)
4174
+ };
4175
+ const event = rec.rule.extract(tree, env, uinOf, ctx);
4348
4176
  if (event !== null) {
4349
4177
  this.broadcastEvent(event);
4350
4178
  return;