From 4d200de6b7fe2a45e025e0642a6a210440fbb6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 2 Sep 2025 22:24:53 +0800 Subject: [PATCH] Refactor packet client and update message history actions Replaced LRUCache with Map for callback and event management in packet clients, and standardized callback hash usage. Updated GetFriendMsgHistory and GetGroupMsgHistory actions to use snake_case for payload keys. Modified OneBotMsgApi to support disabling URL retrieval for ptt elements via a new parameter. --- src/core/packet/client/baseClient.ts | 32 ++++++++----------- src/core/packet/client/nativeClient.ts | 32 +++++++++++-------- .../action/go-cqhttp/GetFriendMsgHistory.ts | 6 ++-- .../action/go-cqhttp/GetGroupMsgHistory.ts | 6 ++-- src/onebot/api/msg.ts | 4 +-- src/onebot/index.ts | 1 - 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/core/packet/client/baseClient.ts b/src/core/packet/client/baseClient.ts index 9fd46496..a6025049 100644 --- a/src/core/packet/client/baseClient.ts +++ b/src/core/packet/client/baseClient.ts @@ -1,4 +1,3 @@ -import { LRUCache } from '@/common/lru-cache'; import crypto, { createHash } from 'crypto'; import { OidbPacket, PacketHexStr } from '@/core/packet/transformer/base'; import { LogStack } from '@/core/packet/context/clientContext'; @@ -7,7 +6,6 @@ import { PacketLogger } from '@/core/packet/context/loggerContext'; export interface RecvPacket { type: string, // 仅recv - trace_id_md5?: string, data: RecvPacketData } @@ -30,7 +28,7 @@ function randText(len: number): string { export abstract class IPacketClient { protected readonly napcore: NapCoreContext; protected readonly logger: PacketLogger; - protected readonly cb = new LRUCache Promise>(500); // trace_id-type callback + protected readonly cb = new Map Promise | any>(); // hash-type callback logStack: LogStack; available: boolean = false; @@ -44,24 +42,21 @@ export abstract class IPacketClient { abstract init(pid: number, recv: string, send: string): Promise; - abstract sendCommandImpl(cmd: string, data: string, trace_id: string): void; + abstract sendCommandImpl(cmd: string, data: string, hash: string, timeout: number): void; - private async registerCallback(trace_id: string, type: string, callback: (json: RecvPacketData) => Promise): Promise { - this.cb.put(createHash('md5').update(trace_id).digest('hex') + type, callback); - } - - private async sendCommand(cmd: string, data: string, trace_id: string, rsp: boolean = false, timeout: number = 20000, sendcb: (json: RecvPacketData) => void = () => { + private async sendCommand(cmd: string, data: string, trace_data: string, rsp: boolean = false, timeout: number = 20000, sendcb: (json: RecvPacketData) => void = () => { }): Promise { return new Promise((resolve, reject) => { if (!this.available) { reject(new Error('packetBackend 当前不可用!')); } - + let hash = createHash('md5').update(trace_data).digest('hex'); const timeoutHandle = setTimeout(() => { - reject(new Error(`sendCommand timed out after ${timeout} ms for ${cmd} with trace_id ${trace_id}`)); + this.cb.delete(hash + 'send'); + this.cb.delete(hash + 'recv'); + reject(new Error(`sendCommand timed out after ${timeout} ms for ${cmd} with hash ${hash}`)); }, timeout); - - this.registerCallback(trace_id, 'send', async (json: RecvPacketData) => { + this.cb.set(hash + 'send', async (json: RecvPacketData) => { sendcb(json); if (!rsp) { clearTimeout(timeoutHandle); @@ -70,21 +65,20 @@ export abstract class IPacketClient { }); if (rsp) { - this.registerCallback(trace_id, 'recv', async (json: RecvPacketData) => { + this.cb.set(hash + 'recv', async (json: RecvPacketData) => { clearTimeout(timeoutHandle); resolve(json); }); } - - this.sendCommandImpl(cmd, data, trace_id); + this.sendCommandImpl(cmd, data, hash, timeout); }); } async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 20000): Promise { const md5 = crypto.createHash('md5').update(data).digest('hex'); - const trace_id = (randText(4) + md5 + data).slice(0, data.length / 2); - return this.sendCommand(cmd, data, trace_id, rsp, timeout, async () => { - await this.napcore.sendSsoCmdReqByContend(cmd, trace_id); + const trace_data = (randText(4) + md5 + data).slice(0, data.length / 2);// trace_data + return this.sendCommand(cmd, data, trace_data, rsp, timeout, async () => { + await this.napcore.sendSsoCmdReqByContend(cmd, trace_data); }); } diff --git a/src/core/packet/client/nativeClient.ts b/src/core/packet/client/nativeClient.ts index 6be15231..1d08ded2 100644 --- a/src/core/packet/client/nativeClient.ts +++ b/src/core/packet/client/nativeClient.ts @@ -4,7 +4,6 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import { IPacketClient } from '@/core/packet/client/baseClient'; import { constants } from 'node:os'; -import { LRUCache } from '@/common/lru-cache'; import { LogStack } from '@/core/packet/context/clientContext'; import { NapCoreContext } from '@/core/packet/context/napCoreContext'; import { PacketLogger } from '@/core/packet/context/loggerContext'; @@ -18,7 +17,8 @@ export interface NativePacketExportType { export class NativePacketClient extends IPacketClient { private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64']; private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} }; - private readonly sendEvent = new LRUCache(500); // seq->trace_id + private readonly sendEvent = new Map(); // seq - hash + private readonly timeEvent = new Map(); // hash - timeout constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) { super(napCore, logger, logStack); @@ -45,25 +45,31 @@ export class NativePacketClient extends IPacketClient { process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY); this.MoeHooExport.exports.InitHook?.(send, recv, (type: number, _uin: string, cmd: string, seq: number, hex_data: string) => { - const trace_id = createHash('md5').update(Buffer.from(hex_data, 'hex')).digest('hex'); - if (type === 0 && this.cb.get(trace_id + 'recv')) { + const hash = createHash('md5').update(Buffer.from(hex_data, 'hex')).digest('hex'); + if (type === 0 && this.cb.get(hash + 'recv')) { //此时为send 提取seq - this.sendEvent.put(seq, trace_id); + this.sendEvent.set(seq, hash); + setTimeout(() => { + this.sendEvent.delete(seq); + this.timeEvent.delete(hash); + }, +(this.timeEvent.get(hash) ?? 20000)); + //正式send完成 无recv v + //均无异常 v } if (type === 1 && this.sendEvent.get(seq)) { - //此时为recv 调用callback - const trace_id = this.sendEvent.get(seq); - const callback = this.cb.get(trace_id + 'recv'); - // console.log('callback:', callback, trace_id); + const hash = this.sendEvent.get(seq); + const callback = this.cb.get(hash + 'recv'); callback?.({ seq, cmd, hex_data }); } }, this.napcore.config.o3HookMode == 1); this.available = true; } - sendCommandImpl(cmd: string, data: string, trace_id: string): void { - const trace_id_md5 = createHash('md5').update(trace_id).digest('hex'); - this.MoeHooExport.exports.SendPacket?.(cmd, data, trace_id_md5); - this.cb.get(trace_id_md5 + 'send')?.({ seq: 0, cmd, hex_data: '' }); + sendCommandImpl(cmd: string, data: string, hash: string, timeout: number): void { + this.timeEvent.set(hash, setTimeout(() => { + this.timeEvent.delete(hash);//考虑情况为正式send都没进 + }, timeout)); + this.MoeHooExport.exports.SendPacket?.(cmd, data, hash); + this.cb.get(hash + 'send')?.({ seq: 0, cmd, hex_data: '' }); } } diff --git a/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts b/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts index f071b25c..9514f434 100644 --- a/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts +++ b/src/onebot/action/go-cqhttp/GetFriendMsgHistory.ts @@ -15,8 +15,8 @@ const SchemaData = Type.Object({ message_seq: Type.Optional(Type.String()), count: Type.Number({ default: 20 }), reverseOrder: Type.Boolean({ default: false }), - disableGetUrl: Type.Boolean({ default: false }), - parseMultMsg: Type.Boolean({ default: true }) + disable_get_url: Type.Boolean({ default: false }), + parse_mult_msg: Type.Boolean({ default: true }) }); @@ -43,7 +43,7 @@ export default class GetFriendMsgHistory extends OneBotAction })); //烘焙消息 const ob11MsgList = (await Promise.all( - msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg, config.messagePostFormat, payload.parseMultMsg, payload.disableGetUrl))) + msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg, config.messagePostFormat, payload.parse_mult_msg, payload.disable_get_url))) ).filter(msg => msg !== undefined); return { 'messages': ob11MsgList }; } diff --git a/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts b/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts index 1697e364..cedec12c 100644 --- a/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts +++ b/src/onebot/action/go-cqhttp/GetGroupMsgHistory.ts @@ -15,8 +15,8 @@ const SchemaData = Type.Object({ message_seq: Type.Optional(Type.String()), count: Type.Number({ default: 20 }), reverseOrder: Type.Boolean({ default: false }), - disableGetUrl: Type.Boolean({ default: false }), - parseMultMsg: Type.Boolean({ default: true }), + disable_get_url: Type.Boolean({ default: false }), + parse_mult_msg: Type.Boolean({ default: true }), }); @@ -41,7 +41,7 @@ export default class GoCQHTTPGetGroupMsgHistory extends OneBotAction this.obContext.apis.MsgApi.parseMessage(msg, config.messagePostFormat, payload.parseMultMsg, payload.disableGetUrl))) + msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg, config.messagePostFormat, payload.parse_mult_msg, payload.disable_get_url))) ).filter(msg => msg !== undefined); return { 'messages': ob11MsgList }; } diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index ef202e21..a042ce50 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -444,7 +444,7 @@ export class OneBotMsgApi { }; }, - pttElement: async (element, msg, elementWrapper) => { + pttElement: async (element, msg, elementWrapper, { disableGetUrl }) => { const peer = { chatType: msg.chatType, peerUid: msg.peerUid, @@ -452,7 +452,7 @@ export class OneBotMsgApi { }; const fileCode = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, '', element.fileName); let pttUrl = ''; - if (this.core.apis.PacketApi.packetStatus) { + if (this.core.apis.PacketApi.packetStatus && !disableGetUrl) { try { pttUrl = await registerResource( 'ptt-url-get', diff --git a/src/onebot/index.ts b/src/onebot/index.ts index eef323bb..a66cf8b1 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -62,7 +62,6 @@ export class NapCatOneBot11Adapter { networkManager: OB11NetworkManager; actions: ActionMap; private readonly bootTime = Date.now() / 1000; - //recallMsgCache = new LRUCache(100); recallEventCache = new Map(); constructor(core: NapCatCore, context: InstanceContext, pathWrapper: NapCatPathWrapper) { this.core = core;