@napuketto/adapter 0.0.22 → 0.2.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.
@@ -766,6 +766,11 @@ declare class NapukettoOneBot11Adapter extends BaseProtocolAdapter<OB11Config> {
766
766
  subscribeOnly(): Promise<void>;
767
767
  /** 仅退订(与 subscribeOnly 配对的进程级清理;传输关闭仍走 stop())。 */
768
768
  unsubscribeOnly(): void;
769
+ /**
770
+ * 单条 sysmsg 字节块:解码 → 识别 → 命中才广播,未识别打结构化校准日志
771
+ * (识别表为空时全部走日志路径,design.md §7.5)。
772
+ */
773
+ private handleSysMsgBlob;
769
774
  /**
770
775
  * 广播消息事件(P2-19:接收方向 ID 转换)。
771
776
  * 收集 at uid → 一次批量 uidToUin → 构造上下文 → 翻译广播。
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../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/types/index.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/helper/data.ts","../../src/onebot11/adapter.ts","../../src/onebot11/transport.ts"],"mappings":";;;;;;cAkBa;;mBAEQ;;mBAEA;;mBAEA;;UAET;;mBAES;;;;;EAMjB,MAAM,eAAe,OAAO;;EAmB5B,SAAS;;EAKT,aAAa;;EAKb,QAAQ,gBAAgB;;EAKxB,QAAQ;;UAYA;;;;;UCvDK;;EAEb;;EAEA,mBAAmB;;EAEnB;;EAEA;;EAEA,aAAa;;EAEb,gBAAgB;;;UAIH;EACb,QAAQ;EACR,UAAU;EACV,gBAAgB;EAChB,WAAW;EACX,WAAW;EACX,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,QAAQ;;EAER;IAAQ;IAAa;;;EAErB,QAAQ;;EAER,aAAa;;;;;;cAOJ;;WAEA,QAAQ;;WAER,UAAU;;WAEV,gBAAgB;;WAEhB,WAAW;;WAEX,WAAW;;WAEX,cAAc;;WAEd,YAAY;;WAEZ,gBAAgB;;WAEhB,QAAQ;;WAER,YAAY;;WAEZ,eAAe;;WAEf;IAAQ;IAAa;;;WAErB;;WAEA;;WAEA,mBAAmB;;WAEnB;;WAEA;;WAEA,aAAa;;WAEb,gBAAgB;EAEzB,YAAY,MAAM;;EAuBlB,SAAS,iBAAiB,QAAQ;;EAKlC,SAAS,iBAAiB,QAAQ;;;;;cCzHzB,kBAAkB;;;;UCMd;EACb;EACA;EACA;;;;;;;;;UCba,WAAW;EACxB;EACA;EACA,MAAM;EACN;EACA;;;KAIQ;EACJ;EAAc;IAAQ;;;EACtB;EAAY;IAAQ;IAAY;;;EAChC;EAAc;IAAQ;;;EACtB;EAAe;IAAQ;IAAc;;;EACrC;EAAgB;IAAQ;IAAc;;;EACtC;EAAe;IAAQ;IAAc;;;EACrC;EAAc;IAAQ;;;EACtB;EAAe;IAAQ;;;EACvB;EAAiB;IAAQ;;;EACzB;EAAc;IAAQ;;;EACtB;EAAa;IAAQ;;;EACrB;EAAgB;IAAQ;;;;KAGpB,uBAAuB;;UAGlB;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;;;UAIa;EACb;EACA;EACA;EACA;IACI;IACA;IACA;IACA;;EAEJ;EACA,SAAS;EACT;EACA;EACA;;;KAIQ;;UAGK;EACb;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA;EACA,MAAM;EACN;;EAEA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA,oBAAoB;EACpB,gBAAgB;EAChB,gBAAgB;EAChB,aAAa;EACb,oBAAoB;EACpB,cAAc;;;UAID;EACb;EACA;EACA;;EAEA;EACA;EACA;EACA,eAAe;EACf,gBAAgB;EAChB;;;;;;;;;;;;KCtJQ;;UAGK;;EAEb;;EAEA;;EAEA,WAAW;;;;;UCPE;EACb;EACA;EACA;;;UAIa,oBAAoB;EACjC;EACA;;;UAIa,8BAA8B;EAC3C;EACA;;EAEA;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA,QAAQ;EACR,YAAY;;;UAIC,gCAAgC;EAC7C;EACA;;EAEA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA,QAAQ;;EAER;;;KAIQ,mBAAmB,wBAAwB;;;;UC9CtC;EACb;EACA;GACC;;;UAIY,+BAA+B;EAC5C;EACA;EACA;;;UAIa,+BAA+B;EAC5C;EACA;;EAEA;EACA,QAAQ;;;KAIA,gBAAgB,yBAAyB;;;;UCvBpC;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA;EACA,MAAM;;;UAIO,kCAAkC;EAC/C;EACA;EACA;EACA;EACA;;;UAIa,qCAAqC;EAClD;EACA;EACA;EACA;EACA;EACA;;;UAIa,qCAAqC;EAClD;EACA;EACA;EACA;EACA;EACA;;;UAIa,gCAAgC;EAC7C;EACA;EACA;EACA;EACA;EACA;;EAEA;;;UAIa,iCAAiC;EAC9C;EACA;EACA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;;;UAIa,iCAAiC;EAC9C;EACA;EACA;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIa,8BAA8B;EAC3C;EACA;EACA;EACA;EACA;EACA;;EAEA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA,MAAM;;;UAIO,iCAAiC;EAC9C;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;EACA;EACA,OAAO;;;UAIM,kCAAkC;EAC/C;EACA;EACA;EACA;EACA;;;KAIQ,kBACN,6BACA,4BACA,+BACA,+BACA,0BACA,2BACA,6BACA,8BACA,2BACA,8BACA,wBACA,6BACA,2BACA,8BACA;;;;UCpLW,+BAA+B;EAC5C;EACA;EACA;;EAEA;;EAEA;;;UAIa,8BAA8B;EAC3C;EACA;;EAEA;EACA;EACA;EACA;EACA;;;KAIQ,mBAAmB,yBAAyB;;;;KCiB5C,YAAY,mBAAoB,kBAAmB,mBAAoB;;;;UCyDlE;;EAEb,KAAK;;;iBAIO,yBAAyB,MAAM,iBAAiB;;;;;;;;;;;;;;UC9E/C;EACb;EACA,QAAQ;;;iBAII,aAAa;;iBAKb,cAAc;;iBAKd,eAAe;;iBASf,aACZ,cACA,QAAQ;;iBAeI,eAAe,eAAe,eAAe;;iBAkB7C,iBAAiB,OAAO,eAAe;;;;iBCsHvC,oBAAoB,UAAU;;;;cCxJjC,kBAAgB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuB3B,EAAA,KAAA;;KAGU,aAAa,EAAE,aAAa;;;;iBC/DxB,oBAAoB,UAAU,qBAAqB;;iBAYnD,oBAAoB,UAAU,uBAAuB;;iBAoIrD,oBAAoB,eAAe;;iBAkBnC,qBAAqB,UAAU;;iBAK/B,qBAAqB,eAAe;;;;UCxInC;EACb,KAAK,cAAc;EACnB,KAAK,cAAc;;;UAIN,+BAA+B;;EAE5C,QAAQ,eAAe;;EAEvB,aAAa;;EAEb,YAAY;;EAEZ,eAAe;;EAEf,gBAAgB;;EAEhB,mBAAmB;;EAEnB,SAAS;;;cAIA,iCAAiC,oBAAoB;WACrD;mBAEQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;;WAER,UAAU;UACX;UACA;UACA;UACA;UACA;;UAEA;;UAEA;EAER,YAAY,MAAM;;;;;UAwBJ;;UAYA;;UAyCN;;UAiBM;;UAaN;;;;;;EA6FF,iBAAiB;;EAUvB;;;;;;UAUc;;UA2BA;;UAiBA;;UA4BA;;UAiBN;;;;;EAWF,cAAc,cAAc,UAAU,wBAAwB;;;;;UCtWvD;;EAEb,SAAS;;EAET,YAAY;;EAEZ,aAAa;;;UAIA;;EAEb,QAAQ;;EAER,aAAa;;EAEb,gBAAgB,cAAc,UAAU;;EAExC;;;iBAiBY,uBAAuB,MAAM,gCAAgC"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../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/types/index.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/helper/data.ts","../../src/onebot11/adapter.ts","../../src/onebot11/transport.ts"],"mappings":";;;;;;cAkBa;;mBAEQ;;mBAEA;;mBAEA;;UAET;;mBAES;;;;;EAMjB,MAAM,eAAe,OAAO;;EAmB5B,SAAS;;EAKT,aAAa;;EAKb,QAAQ,gBAAgB;;EAKxB,QAAQ;;UAYA;;;;;UCvDK;;EAEb;;EAEA,mBAAmB;;EAEnB;;EAEA;;EAEA,aAAa;;EAEb,gBAAgB;;;UAIH;EACb,QAAQ;EACR,UAAU;EACV,gBAAgB;EAChB,WAAW;EACX,WAAW;EACX,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,QAAQ;;EAER;IAAQ;IAAa;;;EAErB,QAAQ;;EAER,aAAa;;;;;;cAOJ;;WAEA,QAAQ;;WAER,UAAU;;WAEV,gBAAgB;;WAEhB,WAAW;;WAEX,WAAW;;WAEX,cAAc;;WAEd,YAAY;;WAEZ,gBAAgB;;WAEhB,QAAQ;;WAER,YAAY;;WAEZ,eAAe;;WAEf;IAAQ;IAAa;;;WAErB;;WAEA;;WAEA,mBAAmB;;WAEnB;;WAEA;;WAEA,aAAa;;WAEb,gBAAgB;EAEzB,YAAY,MAAM;;EAuBlB,SAAS,iBAAiB,QAAQ;;EAKlC,SAAS,iBAAiB,QAAQ;;;;;cCzHzB,kBAAkB;;;;UCMd;EACb;EACA;EACA;;;;;;;;;UCba,WAAW;EACxB;EACA;EACA,MAAM;EACN;EACA;;;KAIQ;EACJ;EAAc;IAAQ;;;EACtB;EAAY;IAAQ;IAAY;;;EAChC;EAAc;IAAQ;;;EACtB;EAAe;IAAQ;IAAc;;;EACrC;EAAgB;IAAQ;IAAc;;;EACtC;EAAe;IAAQ;IAAc;;;EACrC;EAAc;IAAQ;;;EACtB;EAAe;IAAQ;;;EACvB;EAAiB;IAAQ;;;EACzB;EAAc;IAAQ;;;EACtB;EAAa;IAAQ;;;EACrB;EAAgB;IAAQ;;;;KAGpB,uBAAuB;;UAGlB;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;;;UAIa;EACb;EACA;EACA;EACA;IACI;IACA;IACA;IACA;;EAEJ;EACA,SAAS;EACT;EACA;EACA;;;KAIQ;;UAGK;EACb;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA;EACA,MAAM;EACN;;EAEA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA,oBAAoB;EACpB,gBAAgB;EAChB,gBAAgB;EAChB,aAAa;EACb,oBAAoB;EACpB,cAAc;;;UAID;EACb;EACA;EACA;;EAEA;EACA;EACA;EACA,eAAe;EACf,gBAAgB;EAChB;;;;;;;;;;;;KCtJQ;;UAGK;;EAEb;;EAEA;;EAEA,WAAW;;;;;UCPE;EACb;EACA;EACA;;;UAIa,oBAAoB;EACjC;EACA;;;UAIa,8BAA8B;EAC3C;EACA;;EAEA;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA,QAAQ;EACR,YAAY;;;UAIC,gCAAgC;EAC7C;EACA;;EAEA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA,QAAQ;;EAER;;;KAIQ,mBAAmB,wBAAwB;;;;UC9CtC;EACb;EACA;GACC;;;UAIY,+BAA+B;EAC5C;EACA;EACA;;;UAIa,+BAA+B;EAC5C;EACA;;EAEA;EACA,QAAQ;;;KAIA,gBAAgB,yBAAyB;;;;UCvBpC;EACb;EACA;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa;EACb;EACA;EACA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA;EACA,MAAM;;;UAIO,kCAAkC;EAC/C;EACA;EACA;EACA;EACA;;;UAIa,qCAAqC;EAClD;EACA;EACA;EACA;EACA;EACA;;;UAIa,qCAAqC;EAClD;EACA;EACA;EACA;EACA;EACA;;;UAIa,gCAAgC;EAC7C;EACA;EACA;EACA;EACA;EACA;;EAEA;;;UAIa,iCAAiC;EAC9C;EACA;EACA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;;;UAIa,iCAAiC;EAC9C;EACA;EACA;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;EACA;EACA;EACA;;;UAIa,8BAA8B;EAC3C;EACA;EACA;EACA;EACA;EACA;;EAEA;;;UAIa,mCAAmC;EAChD;EACA;EACA;EACA,MAAM;;;UAIO,iCAAiC;EAC9C;EACA;EACA;EACA;;;UAIa,oCAAoC;EACjD;EACA;EACA;EACA;EACA;EACA,OAAO;;;UAIM,kCAAkC;EAC/C;EACA;EACA;EACA;EACA;;;KAIQ,kBACN,6BACA,4BACA,+BACA,+BACA,0BACA,2BACA,6BACA,8BACA,2BACA,8BACA,wBACA,6BACA,2BACA,8BACA;;;;UCpLW,+BAA+B;EAC5C;EACA;EACA;;EAEA;;EAEA;;;UAIa,8BAA8B;EAC3C;EACA;;EAEA;EACA;EACA;EACA;EACA;;;KAIQ,mBAAmB,yBAAyB;;;;KCiB5C,YAAY,mBAAoB,kBAAmB,mBAAoB;;;;UCyDlE;;EAEb,KAAK;;;iBAIO,yBAAyB,MAAM,iBAAiB;;;;;;;;;;;;;;UC9E/C;EACb;EACA,QAAQ;;;iBAII,aAAa;;iBAKb,cAAc;;iBAKd,eAAe;;iBASf,aACZ,cACA,QAAQ;;iBAeI,eAAe,eAAe,eAAe;;iBAkB7C,iBAAiB,OAAO,eAAe;;;;iBCsHvC,oBAAoB,UAAU;;;;cCxJjC,kBAAgB,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuB3B,EAAA,KAAA;;KAGU,aAAa,EAAE,aAAa;;;;iBC/DxB,oBAAoB,UAAU,qBAAqB;;iBAYnD,oBAAoB,UAAU,uBAAuB;;iBAoIrD,oBAAoB,eAAe;;iBAkBnC,qBAAqB,UAAU;;iBAK/B,qBAAqB,eAAe;;;;UChInC;EACb,KAAK,cAAc;EACnB,KAAK,cAAc;;;UAIN,+BAA+B;;EAE5C,QAAQ,eAAe;;EAEvB,aAAa;;EAEb,YAAY;;EAEZ,eAAe;;EAEf,gBAAgB;;EAEhB,mBAAmB;;EAEnB,SAAS;;;cAIA,iCAAiC,oBAAoB;WACrD;mBAEQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;;WAER,UAAU;UACX;UACA;UACA;UACA;UACA;;UAEA;;UAEA;EAER,YAAY,MAAM;;;;;UAwBJ;;UAYA;;UAyCN;;UAiBM;;UAaN;;;;;;EAmJF,iBAAiB;;EAUvB;;;;;UASQ;;;;;;UAyCM;;UA2BA;;UAiBA;;UA4BA;;UAiBN;;;;;EAWF,cAAc,cAAc,UAAU,wBAAwB;;;;;UC5cvD;;EAEb,SAAS;;EAET,YAAY;;EAEZ,aAAa;;;UAIA;;EAEb,QAAQ;;EAER,aAAa;;EAEb,gBAAgB,cAAc,UAAU;;EAExC;;;iBAiBY,uBAAuB,MAAM,gCAAgC"}
@@ -1869,7 +1869,7 @@ function cqMessageToCanonical(text) {
1869
1869
  //#endregion
1870
1870
  //#region src/onebot11/helper/message-info.ts
1871
1871
  /** 毫秒 → 秒(Unix 时间戳)。 */
1872
- const MS_TO_SEC$4 = 1e3;
1872
+ const MS_TO_SEC$5 = 1e3;
1873
1873
  /** RawMessage → OB11 消息信息(message_id 经 MessageUnique 映射)。
1874
1874
  * ctx(可选):接收方向 ID 转换上下文(at uid→uin、reply NT msgId→OB11 id,P2-19)。 */
1875
1875
  function toOb11MessageInfo(msg, unique, ctx = {}) {
@@ -1886,7 +1886,7 @@ function toOb11MessageInfo(msg, unique, ctx = {}) {
1886
1886
  user_id: Number(msg.senderUin),
1887
1887
  nickname: msg.sendNickName
1888
1888
  },
1889
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
1889
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$5),
1890
1890
  message: canonicalToSegments(elements),
1891
1891
  raw_message: canonicalToCqMessage(elements)
1892
1892
  };
@@ -1901,7 +1901,7 @@ function toOb11MessageInfo(msg, unique, ctx = {}) {
1901
1901
  //#endregion
1902
1902
  //#region src/onebot11/helper/notice.ts
1903
1903
  /** 毫秒 → 秒(Unix 时间戳)。 */
1904
- const MS_TO_SEC$3 = 1e3;
1904
+ const MS_TO_SEC$4 = 1e3;
1905
1905
  /** 群文件业务类型(group_upload 的 file.busid,与 kernel 群文件系列同源语义)。 */
1906
1906
  const GROUP_FILE_BUS_ID = 102;
1907
1907
  /** 检查消息是否含文件元素(group_upload 开关分支判定)。 */
@@ -1920,7 +1920,7 @@ function toUin$1(uid, ctx) {
1920
1920
  /** 基础字段(time/self_id/post_type)。 */
1921
1921
  function base(msg, ctx) {
1922
1922
  return {
1923
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$3),
1923
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
1924
1924
  self_id: Number(ctx.selfUin),
1925
1925
  post_type: "notice",
1926
1926
  group_id: Number(msg.peerUid)
@@ -1931,7 +1931,7 @@ function toRecall(msg, g, ctx) {
1931
1931
  if (g?.revokeElement === void 0) return null;
1932
1932
  const revoke = g.revokeElement;
1933
1933
  if (msg.chatType === ChatType.C2C) return {
1934
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$3),
1934
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
1935
1935
  self_id: Number(ctx.selfUin),
1936
1936
  post_type: "notice",
1937
1937
  notice_type: "friend_recall",
@@ -1959,7 +1959,7 @@ function toPoke(msg, g, ctx) {
1959
1959
  ctx.logger?.warn({ raw: JSON.stringify(g)?.slice(0, 2e3) }, "ob11: poke grayTip raw(待真实事件校准)");
1960
1960
  const isGroup = msg.chatType === ChatType.GROUP;
1961
1961
  return {
1962
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$3),
1962
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
1963
1963
  self_id: Number(ctx.selfUin),
1964
1964
  post_type: "notice",
1965
1965
  notice_type: "notify",
@@ -1974,7 +1974,7 @@ function toGroupChange(msg, g, ctx) {
1974
1974
  const grp = g?.groupElement;
1975
1975
  if (grp === void 0 || grp.type === void 0) return null;
1976
1976
  const common = {
1977
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$3),
1977
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
1978
1978
  selfId: Number(ctx.selfUin),
1979
1979
  groupId: Number(msg.peerUid),
1980
1980
  memberUid: grp.memberUid ?? "",
@@ -2054,7 +2054,7 @@ function toBan(common, grp, ctx) {
2054
2054
  function toFriendAdd(entry, selfUin) {
2055
2055
  const uin = entry.coreInfo?.uin ?? entry.uin ?? "";
2056
2056
  return {
2057
- time: Math.floor(Date.now() / MS_TO_SEC$3),
2057
+ time: Math.floor(Date.now() / MS_TO_SEC$4),
2058
2058
  self_id: Number(selfUin),
2059
2059
  post_type: "notice",
2060
2060
  notice_type: "friend_add",
@@ -2071,7 +2071,7 @@ function toGroupUpload(msg, selfUin) {
2071
2071
  const file = msg.elements.find((e) => e.fileElement !== void 0)?.fileElement;
2072
2072
  if (file === void 0) return null;
2073
2073
  return {
2074
- time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$3),
2074
+ time: Math.floor(Number(msg.msgTime) / MS_TO_SEC$4),
2075
2075
  self_id: Number(selfUin),
2076
2076
  post_type: "notice",
2077
2077
  notice_type: "group_upload",
@@ -2126,7 +2126,7 @@ function toOb11NoticeEvent(msg, ctx) {
2126
2126
  * narrowBuddyReqs 防御性收窄,未知形状返回 null 由调用方打 raw 日志积累校准数据。
2127
2127
  */
2128
2128
  /** 毫秒 → 秒(Unix 时间戳)。 */
2129
- const MS_TO_SEC$2 = 1e3;
2129
+ const MS_TO_SEC$3 = 1e3;
2130
2130
  /** uid → uin(上下文映射缺省时:数字 uid 直取数值,非数字 uid 返回 0 表示未知)。 */
2131
2131
  function toUin(uid, ctx) {
2132
2132
  if (uid === void 0 || uid === "") return 0;
@@ -2156,7 +2156,7 @@ function toOb11GroupRequestEvent(notify, ctx) {
2156
2156
  default: return null;
2157
2157
  }
2158
2158
  return {
2159
- time: Math.floor(Date.now() / MS_TO_SEC$2),
2159
+ time: Math.floor(Date.now() / MS_TO_SEC$3),
2160
2160
  self_id: Number(ctx.selfUin),
2161
2161
  post_type: "request",
2162
2162
  request_type: "group",
@@ -2192,7 +2192,7 @@ function narrowBuddyReqs(arg) {
2192
2192
  function toOb11FriendRequestEvent(req, ctx) {
2193
2193
  const words = req["words"];
2194
2194
  return {
2195
- time: Math.floor(Date.now() / MS_TO_SEC$2),
2195
+ time: Math.floor(Date.now() / MS_TO_SEC$3),
2196
2196
  self_id: Number(ctx.selfUin),
2197
2197
  post_type: "request",
2198
2198
  request_type: "friend",
@@ -3567,14 +3567,14 @@ var OneBotApi = class {
3567
3567
  //#endregion
3568
3568
  //#region src/onebot11/helper/message-event.ts
3569
3569
  /** 毫秒 → 秒(Unix 时间戳)。 */
3570
- const MS_TO_SEC$1 = 1e3;
3570
+ const MS_TO_SEC$2 = 1e3;
3571
3571
  /** RawMessage → OB11 消息事件(message_id 经 MessageUnique 映射并记录 peer)。
3572
3572
  * messageFormat 决定 message 字段格式:array = 消息段数组(标准),string = CQ 码字符串。
3573
3573
  * ctx(可选):接收方向 ID 转换上下文(at uid→uin、reply NT msgId→OB11 id,P2-19)。 */
3574
3574
  function toOb11MessageEvent(msg, selfUin, unique, messageFormat = "array", ctx = {}) {
3575
3575
  const elements = applyReceiveContext(toCanonicalElements(msg), ctx);
3576
3576
  const segments = canonicalToSegments(elements);
3577
- const time = Math.floor(Number(msg.msgTime) / MS_TO_SEC$1);
3577
+ const time = Math.floor(Number(msg.msgTime) / MS_TO_SEC$2);
3578
3578
  const selfId = Number(selfUin);
3579
3579
  const userId = Number(msg.senderUin);
3580
3580
  const base = {
@@ -3620,6 +3620,325 @@ function toOb11MessageEvent(msg, selfUin, unique, messageFormat = "array", ctx =
3620
3620
  };
3621
3621
  }
3622
3622
  //#endregion
3623
+ //#region src/onebot11/helper/notice-extra.ts
3624
+ /** 毫秒 → 秒(Unix 时间戳)。 */
3625
+ const MS_TO_SEC$1 = 1e3;
3626
+ /** 候选 uin 字段(按优先级取第一个数字串;uid 串不硬转——待校准)。 */
3627
+ function pickUin(item) {
3628
+ for (const key of [
3629
+ "senderUin",
3630
+ "fromUin",
3631
+ "peerUin"
3632
+ ]) {
3633
+ const v = item[key];
3634
+ if (typeof v === "string" && v !== "" && Number.isFinite(Number(v))) return v;
3635
+ }
3636
+ return "0";
3637
+ }
3638
+ /** 候选 url 字段(fileUrl / url;未知为空串)。 */
3639
+ function pickUrl(item) {
3640
+ for (const key of ["fileUrl", "url"]) {
3641
+ const v = item[key];
3642
+ if (typeof v === "string" && v !== "") return v;
3643
+ }
3644
+ return "";
3645
+ }
3646
+ /** 单个候选对象 → 归一化项(不可识别返回 null)。接受两类形状:
3647
+ * ① RawMessage 型(elements[].fileElement——离线文件以消息推送到达的假设,
3648
+ * 与 onRecvOfflineFileMsg 挂在 MsgService、UpdateC2CFileMsg 字符串一致)
3649
+ * ② 专用实体型(顶层 fileName 或 fileInfo.fileName——getNewOfflineFileList 族) */
3650
+ function narrowItem(item) {
3651
+ if (typeof item !== "object" || item === null) return null;
3652
+ const obj = item;
3653
+ if (Array.isArray(obj["elements"])) {
3654
+ const file = obj["elements"].find((e) => typeof e === "object" && e !== null && "fileElement" in e)?.fileElement;
3655
+ if (file === void 0) return null;
3656
+ return {
3657
+ senderUin: pickUin(obj),
3658
+ name: typeof file["fileName"] === "string" ? file["fileName"] : "",
3659
+ size: Number(file["fileSize"] ?? 0),
3660
+ url: pickUrl(file)
3661
+ };
3662
+ }
3663
+ const file = obj["fileInfo"] ?? obj;
3664
+ if (typeof file["fileName"] !== "string") return null;
3665
+ return {
3666
+ senderUin: pickUin(obj),
3667
+ name: file["fileName"],
3668
+ size: Number(file["fileSize"] ?? 0),
3669
+ url: pickUrl(file)
3670
+ };
3671
+ }
3672
+ /**
3673
+ * onRecvOfflineFileMsg 参数 → 归一化项列表(防御性收窄)。
3674
+ * 接受数组 / 单对象;全部不可识别返回 null(调用方打 raw 日志)。
3675
+ * 空数组同样返回 null(无文件可翻译,与未知形状同走日志路径无害)。
3676
+ */
3677
+ function narrowOfflineFiles(arg) {
3678
+ const narrowed = (Array.isArray(arg) ? arg : [arg]).map(narrowItem).filter((v) => v !== null);
3679
+ return narrowed.length > 0 ? narrowed : null;
3680
+ }
3681
+ /** 归一化项 → OB11 offline_file notice(time 取当前时刻,friend_add 同款)。 */
3682
+ function toOfflineFileNotice(item, selfUin) {
3683
+ return {
3684
+ time: Math.floor(Date.now() / MS_TO_SEC$1),
3685
+ self_id: Number(selfUin),
3686
+ post_type: "notice",
3687
+ notice_type: "offline_file",
3688
+ user_id: Number(item.senderUin),
3689
+ file: {
3690
+ name: item.name,
3691
+ size: item.size,
3692
+ url: item.url
3693
+ }
3694
+ };
3695
+ }
3696
+ //#endregion
3697
+ //#region src/onebot11/helper/sysmsg.ts
3698
+ /** 递归深度上限(防御:恶意/畸形字节防栈溢出)。 */
3699
+ const MAX_DEPTH = 16;
3700
+ /** 单层字段数上限。 */
3701
+ const MAX_FIELDS = 256;
3702
+ /** 单个 varint 最大字节数(64 位 + 1 冗余)。 */
3703
+ const MAX_VARINT_BYTES = 10;
3704
+ /** 读 varint:成功返回 [值, 下一偏移],越界/超长返回 null。 */
3705
+ function readVarint(data, start) {
3706
+ let value = 0n;
3707
+ let shift = 0n;
3708
+ let i = start;
3709
+ while (true) {
3710
+ if (i >= data.length || i - start >= MAX_VARINT_BYTES) return null;
3711
+ const byte = data[i];
3712
+ if (byte === void 0) return null;
3713
+ i += 1;
3714
+ value |= BigInt(byte & 127) << shift;
3715
+ if ((byte & 128) === 0) return [value, i];
3716
+ shift += 7n;
3717
+ }
3718
+ }
3719
+ /** wire 2:length-delimited 字段(递归 try-parse 子树,失败 → 不透明字节)。 */
3720
+ function decodeLengthDelimited(data, afterTag, no, depth) {
3721
+ const len = readVarint(data, afterTag);
3722
+ if (len === null) return null;
3723
+ const payloadStart = len[1];
3724
+ const end = payloadStart + Number(len[0]);
3725
+ if (end > data.length) return null;
3726
+ const slice = data.slice(payloadStart, end);
3727
+ return {
3728
+ field: {
3729
+ no,
3730
+ kind: "bytes",
3731
+ value: slice,
3732
+ children: decodeProtoTree(slice, depth + 1)
3733
+ },
3734
+ next: end
3735
+ };
3736
+ }
3737
+ /** 解码单个带 tag 字段;畸形(field 0 / group / 截断 / 越界)返回 null。 */
3738
+ function decodeTaggedField(data, start, depth) {
3739
+ const tag = readVarint(data, start);
3740
+ if (tag === null) return null;
3741
+ const [tagValue, afterTag] = tag;
3742
+ const no = Number(tagValue >> 3n);
3743
+ const wireType = Number(tagValue & 7n);
3744
+ if (no === 0) return null;
3745
+ if (wireType === 0) {
3746
+ const v = readVarint(data, afterTag);
3747
+ if (v === null) return null;
3748
+ return {
3749
+ field: {
3750
+ no,
3751
+ kind: "varint",
3752
+ value: v[0]
3753
+ },
3754
+ next: v[1]
3755
+ };
3756
+ }
3757
+ if (wireType === 2) return decodeLengthDelimited(data, afterTag, no, depth);
3758
+ if (wireType === 1 || wireType === 5) {
3759
+ const next = afterTag + (wireType === 1 ? 8 : 4);
3760
+ return next > data.length ? null : {
3761
+ field: void 0,
3762
+ next
3763
+ };
3764
+ }
3765
+ return null;
3766
+ }
3767
+ /**
3768
+ * 解码 protobuf wire-format 为递归字段树(不维护字段重复/顺序语义以外的信息)。
3769
+ *
3770
+ * - wire 0 varint / wire 2 length-delimited:支持;wire 2 递归 try-parse,
3771
+ * 子解析失败按不透明字节挂树(ASCII 串偶发误判嵌套无实害——树仅用于观测)。
3772
+ * - wire 1/5(fixed64/32):跳过(QQ NT blob 未观测到,防御性兼容)。
3773
+ * - wire 3/4(group)、截断、field 0、超限:判失败返回 null。
3774
+ */
3775
+ function decodeProtoTree(data, depth = 0) {
3776
+ if (depth > MAX_DEPTH) return null;
3777
+ const fields = [];
3778
+ let i = 0;
3779
+ while (i < data.length) {
3780
+ if (fields.length >= MAX_FIELDS) return null;
3781
+ const decoded = decodeTaggedField(data, i, depth);
3782
+ if (decoded === null) return null;
3783
+ if (decoded.field !== void 0) fields.push(decoded.field);
3784
+ i = decoded.next;
3785
+ }
3786
+ return fields;
3787
+ }
3788
+ /** 取字段号首个命中的节点。 */
3789
+ function firstField(tree, no) {
3790
+ return tree.find((f) => f.no === no);
3791
+ }
3792
+ /** varint → number(超安全整数返回 null,调用方按缺字段处理)。 */
3793
+ function varintToNumber(value) {
3794
+ return value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : null;
3795
+ }
3796
+ /** UTF-8 严格解码 + 可打印检查(含控制字符判不可解码,返回 null)。 */
3797
+ function decodeText(bytes) {
3798
+ try {
3799
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
3800
+ for (const ch of text) {
3801
+ const code = ch.codePointAt(0) ?? 0;
3802
+ if (code < 32 && code !== 9) return null;
3803
+ }
3804
+ return text;
3805
+ } catch {
3806
+ return null;
3807
+ }
3808
+ }
3809
+ /** 递归收集树内全部可打印字符串(校准观测用;先序遍历,空字节段跳过)。 */
3810
+ function collectStrings(tree) {
3811
+ const out = [];
3812
+ for (const f of tree) {
3813
+ if (f.kind === "varint") continue;
3814
+ const text = decodeText(f.value);
3815
+ if (text !== null && text.length > 0) out.push(text);
3816
+ if (f.children !== null) out.push(...collectStrings(f.children));
3817
+ }
3818
+ return out;
3819
+ }
3820
+ /** 单个候选块 → Uint8Array(number[] -128..255 / TypedArray;其余 null)。 */
3821
+ function toBlob(item) {
3822
+ if (item instanceof Uint8Array) return new Uint8Array(item);
3823
+ if (item instanceof Int8Array) return Uint8Array.from(item, (b) => b & 255);
3824
+ if (Array.isArray(item) && item.length > 0) {
3825
+ const out = new Uint8Array(item.length);
3826
+ for (let i = 0; i < item.length; i += 1) {
3827
+ const b = item[i];
3828
+ if (typeof b !== "number" || !Number.isInteger(b) || b < -128 || b > 255) return null;
3829
+ out[i] = b & 255;
3830
+ }
3831
+ return out;
3832
+ }
3833
+ return null;
3834
+ }
3835
+ /**
3836
+ * onRecvSysMsg 参数 → sysmsg 字节块列表(防御性收窄)。
3837
+ * 接受批数组(实测形状)/ 单块裸数组 / TypedArray;零有效块返回 null
3838
+ * (调用方打 raw 日志,与 narrowOfflineFiles 同模式)。
3839
+ */
3840
+ function narrowSysMsgBlobs(arg) {
3841
+ if (Array.isArray(arg)) {
3842
+ const blobs = arg.map(toBlob).filter((b) => b !== null);
3843
+ if (blobs.length > 0) return blobs;
3844
+ const single = toBlob(arg);
3845
+ return single === null ? null : [single];
3846
+ }
3847
+ const single = toBlob(arg);
3848
+ return single === null ? null : [single];
3849
+ }
3850
+ /** 顶层 f1 块的字段(uin/uid 对)。 */
3851
+ function extractActorBlock(block) {
3852
+ const empty = {
3853
+ uin: null,
3854
+ uid: null,
3855
+ uin2: null,
3856
+ uid2: null
3857
+ };
3858
+ if (block === null) return empty;
3859
+ const f1 = firstField(block, 1);
3860
+ const f2 = firstField(block, 2);
3861
+ const f5 = firstField(block, 5);
3862
+ const f6 = firstField(block, 6);
3863
+ return {
3864
+ uin: f1?.kind === "varint" ? varintToNumber(f1.value) : null,
3865
+ uid: f2?.kind === "bytes" ? decodeText(f2.value) : null,
3866
+ uin2: f5?.kind === "varint" ? varintToNumber(f5.value) : null,
3867
+ uid2: f6?.kind === "bytes" ? decodeText(f6.value) : null
3868
+ };
3869
+ }
3870
+ /** 顶层 f2 块 → 信封数值字段。 */
3871
+ function extractEnvelopeBlock(block) {
3872
+ const empty = {
3873
+ msgType: null,
3874
+ subType: null,
3875
+ subTypeAlt: null,
3876
+ groupCodes: null,
3877
+ time: null
3878
+ };
3879
+ if (block === null) return empty;
3880
+ const num = (no) => {
3881
+ const f = firstField(block, no);
3882
+ return f?.kind === "varint" ? varintToNumber(f.value) : null;
3883
+ };
3884
+ const code4 = num(4);
3885
+ const code5 = num(5);
3886
+ return {
3887
+ msgType: num(1),
3888
+ subType: num(2),
3889
+ subTypeAlt: num(3),
3890
+ groupCodes: code4 !== null && code5 !== null ? [code4, code5] : null,
3891
+ time: num(6)
3892
+ };
3893
+ }
3894
+ /** 字段树 → 信封(design.md §7.3;任何字段缺失/非法 = null,不抛错)。 */
3895
+ function extractSysMsgEnvelope(tree) {
3896
+ const actor = extractActorBlock(getChildren(firstField(tree, 1)));
3897
+ return {
3898
+ actorUin: actor.uin,
3899
+ actorUid: actor.uid,
3900
+ targetUin: actor.uin2,
3901
+ targetUid: actor.uid2,
3902
+ ...extractEnvelopeBlock(getChildren(firstField(tree, 2))),
3903
+ strings: collectStrings(tree)
3904
+ };
3905
+ }
3906
+ /** bytes 节点的子树(非 bytes/不透明 → null)。 */
3907
+ function getChildren(field) {
3908
+ return field?.kind === "bytes" ? field.children : null;
3909
+ }
3910
+ /**
3911
+ * (msgType, subType) → 规则表,主键 `"${msgType}:${subType}"`(原生分发键,
3912
+ * design.md §7.1)。
3913
+ *
3914
+ * ⚠️ 当前为空:c3 以来的全部真实样本(2 条)均为 528/382 未命名类型,
3915
+ * card/title/sign 的判别值没有样本支撑——在此登记规则前不会广播任何 sysmsg
3916
+ * notice。拿到真实样本后登记 extract 规则即可(规则实现参考
3917
+ * notice-extra.ts 防御性收窄风格)。
3918
+ */
3919
+ const KIND_TABLE = /* @__PURE__ */ new Map();
3920
+ /** 已观测但未命名的 (msgType, subType):c3 双样本 528/382(语义未知)。 */
3921
+ const OBSERVED_UNNAMED = /* @__PURE__ */ new Set(["528:382"]);
3922
+ /**
3923
+ * (msgType, subType) → 识别结果。table 参数供单测注入合成规则(生产走
3924
+ * KIND_TABLE)。
3925
+ */
3926
+ function recognizeSysMsg(msgType, subType, table = KIND_TABLE) {
3927
+ if (msgType === null || subType === null) return { kind: "unknown" };
3928
+ const rule = table.get(`${msgType}:${subType}`);
3929
+ if (rule !== void 0) return {
3930
+ kind: "notice",
3931
+ rule
3932
+ };
3933
+ return OBSERVED_UNNAMED.has(`${msgType}:${subType}`) ? { kind: "observed_unnamed" } : { kind: "unknown" };
3934
+ }
3935
+ /** 字节块 → 小写 hex(校准日志用;超长由调用方截断)。 */
3936
+ function toHex(bytes) {
3937
+ let out = "";
3938
+ for (const b of bytes) out += b.toString(16).padStart(2, "0");
3939
+ return out;
3940
+ }
3941
+ //#endregion
3623
3942
  //#region src/onebot11/transport.ts
3624
3943
  /**
3625
3944
  * OB11 传输装配(P2-5,2026-08-05)
@@ -3909,10 +4228,34 @@ var NapukettoOneBot11Adapter = class extends BaseProtocolAdapter {
3909
4228
  this.broadcastMessageEvent(msg);
3910
4229
  });
3911
4230
  }));
3912
- if (this.groupChannel !== void 0) this.unsubscribes.push(this.groupChannel.on("Group/onGroupNotifiesUpdated", (doubt, notifies) => {
3913
- if (doubt || !Array.isArray(notifies)) return;
3914
- this.broadcastGroupRequests(notifies);
4231
+ this.unsubscribes.push(this.msgChannel.on("Msg/onRecvOfflineFileMsg", (arg) => {
4232
+ const items = narrowOfflineFiles(arg);
4233
+ if (items === null) {
4234
+ this.calibLogger?.warn({ raw: JSON.stringify(arg)?.slice(0, 2e3) }, "ob11: onRecvOfflineFileMsg 未知参数形状");
4235
+ return;
4236
+ }
4237
+ for (const item of items) this.broadcastEvent(toOfflineFileNotice(item, this.selfUin));
4238
+ }));
4239
+ this.unsubscribes.push(this.msgChannel.on("Msg/onRecvSysMsg", (arg) => {
4240
+ const blobs = narrowSysMsgBlobs(arg);
4241
+ if (blobs === null) {
4242
+ this.calibLogger?.warn({ raw: JSON.stringify(arg)?.slice(0, 2e3) }, "ob11: onRecvSysMsg 未知参数形状");
4243
+ return;
4244
+ }
4245
+ for (const blob of blobs) this.handleSysMsgBlob(blob);
4246
+ }));
4247
+ this.unsubscribes.push(this.msgChannel.on("Msg/onRecvOnlineFileMsg", (arg) => {
4248
+ this.calibLogger?.info({ raw: JSON.stringify(arg)?.slice(0, 2e3) }, "ob11: onRecvOnlineFileMsg raw(校准数据)");
3915
4249
  }));
4250
+ if (this.groupChannel !== void 0) {
4251
+ this.unsubscribes.push(this.groupChannel.on("Group/onGroupNotifiesUpdated", (doubt, notifies) => {
4252
+ if (doubt || !Array.isArray(notifies)) return;
4253
+ this.broadcastGroupRequests(notifies);
4254
+ }));
4255
+ this.unsubscribes.push(this.groupChannel.on("Group/onGroupEssenceListChange", (arg) => {
4256
+ this.calibLogger?.info({ raw: JSON.stringify(arg)?.slice(0, 2e3) }, "ob11: onGroupEssenceListChange raw(group_essence 校准数据)");
4257
+ }));
4258
+ }
3916
4259
  if (this.friendChannel !== void 0) {
3917
4260
  this.unsubscribes.push(this.friendChannel.on("Buddy/onBuddyReqChange", (arg) => {
3918
4261
  const reqs = narrowBuddyReqs(arg);
@@ -3949,6 +4292,38 @@ var NapukettoOneBot11Adapter = class extends BaseProtocolAdapter {
3949
4292
  this.unsubscribeAll();
3950
4293
  }
3951
4294
  /**
4295
+ * 单条 sysmsg 字节块:解码 → 识别 → 命中才广播,未识别打结构化校准日志
4296
+ * (识别表为空时全部走日志路径,design.md §7.5)。
4297
+ */
4298
+ handleSysMsgBlob(blob) {
4299
+ const tree = decodeProtoTree(blob);
4300
+ if (tree === null) {
4301
+ this.calibLogger?.warn({ raw: toHex(blob).slice(0, 1024) }, "ob11: onRecvSysMsg protobuf 解码失败");
4302
+ return;
4303
+ }
4304
+ const env = extractSysMsgEnvelope(tree);
4305
+ const rec = recognizeSysMsg(env.msgType, env.subType);
4306
+ if (rec.kind === "notice") {
4307
+ const event = rec.rule.extract(tree, env);
4308
+ if (event !== null) {
4309
+ this.broadcastEvent(event);
4310
+ return;
4311
+ }
4312
+ }
4313
+ this.calibLogger?.info({
4314
+ verdict: rec.kind,
4315
+ msgType: env.msgType,
4316
+ subType: env.subType,
4317
+ subTypeAlt: env.subTypeAlt,
4318
+ groupCodes: env.groupCodes,
4319
+ time: env.time,
4320
+ actorUin: env.actorUin,
4321
+ actorUid: env.actorUid,
4322
+ strings: env.strings,
4323
+ raw: toHex(blob).slice(0, 1024)
4324
+ }, "ob11: onRecvSysMsg 校准数据(未识别,不广播)");
4325
+ }
4326
+ /**
3952
4327
  * 广播消息事件(P2-19:接收方向 ID 转换)。
3953
4328
  * 收集 at uid → 一次批量 uidToUin → 构造上下文 → 翻译广播。
3954
4329
  * 翻译失败退化为原样(不阻塞上报)。