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;