diff --git a/src/core/packet/client/baseClient.ts b/src/core/packet/client/baseClient.ts deleted file mode 100644 index 6eb0f3b1..00000000 --- a/src/core/packet/client/baseClient.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { OidbPacket, PacketHexStr } from '@/core/packet/transformer/base'; -import { LogStack } from '@/core/packet/context/clientContext'; -import { NapCoreContext } from '@/core/packet/context/napCoreContext'; -import { PacketLogger } from '@/core/packet/context/loggerContext'; -import { CancelableTask } from '@/common/cancel-task'; - -export interface RecvPacket { - type: string, // 仅recv - data: RecvPacketData -} - -export interface RecvPacketData { - seq: number - cmd: string - data: Buffer -} - - -export abstract class IPacketClient { - protected readonly napcore: NapCoreContext; - protected readonly logger: PacketLogger; - protected readonly cb = new Map Promise | any>(); // hash-type callback - logStack: LogStack; - available: boolean = false; - - protected constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) { - this.napcore = napCore; - this.logger = logger; - this.logStack = logStack; - } - - abstract check(): boolean; - - abstract init(pid: number, recv: string, send: string): Promise; - - async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 5000): Promise { - if (!rsp) { - this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex')).catch(err => { - this.logger.error(`[PacketClient] sendPacket 无响应命令发送失败 cmd=${cmd} err=${err}`); - }); - return { seq: 0, cmd: cmd, data: Buffer.alloc(0) }; - } - - const task = new CancelableTask((resolve, reject, onCancel) => { - const timeoutId = setTimeout(() => { - reject(new Error(`[PacketClient] sendPacket 超时 cmd=${cmd} timeout=${timeout}ms`)); - }, timeout); - - onCancel(() => { - clearTimeout(timeoutId); - }); - - this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex')) - .then(ret => { - clearTimeout(timeoutId); - const result = ret as { rspbuffer: Buffer }; - resolve({ - seq: 0, - cmd: cmd, - data: result.rspbuffer - }); - }) - .catch(err => { - clearTimeout(timeoutId); - reject(err); - }); - }); - - return await task; - } - - async sendOidbPacket(pkt: OidbPacket, rsp = false, timeout = 5000): Promise { - return await this.sendPacket(pkt.cmd, pkt.data, rsp, timeout); - } -} diff --git a/src/core/packet/client/nativeClient.ts b/src/core/packet/client/nativeClient.ts index d92ff492..644b9b82 100644 --- a/src/core/packet/client/nativeClient.ts +++ b/src/core/packet/client/nativeClient.ts @@ -1,22 +1,42 @@ import path, { dirname } from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; -import { IPacketClient } from '@/core/packet/client/baseClient'; import { constants } from 'node:os'; import { LogStack } from '@/core/packet/context/clientContext'; import { NapCoreContext } from '@/core/packet/context/napCoreContext'; import { PacketLogger } from '@/core/packet/context/loggerContext'; +import { OidbPacket, PacketHexStr } from '@/core/packet/transformer/base'; +import { CancelableTask } from '@/common/cancel-task'; + +export interface RecvPacket { + type: string, // 仅recv + data: RecvPacketData +} + +export interface RecvPacketData { + seq: number + cmd: string + data: Buffer +} // 0 send 1 recv export interface NativePacketExportType { initHook?: (send: string, recv: string) => boolean; } -export class NativePacketClient extends IPacketClient { +export class NativePacketClient { + protected readonly napcore: NapCoreContext; + protected readonly logger: PacketLogger; + protected readonly cb = new Map Promise | any>(); // hash-type callback + logStack: LogStack; + available: boolean = false; private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64']; private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} }; + constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) { - super(napCore, logger, logStack); + this.napcore = napCore; + this.logger = logger; + this.logStack = logStack; } check(): boolean { @@ -43,4 +63,44 @@ export class NativePacketClient extends IPacketClient { this.available = true; } } + + async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 5000): Promise { + if (!rsp) { + this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex')).catch(err => { + this.logger.error(`[PacketClient] sendPacket 无响应命令发送失败 cmd=${cmd} err=${err}`); + }); + return { seq: 0, cmd: cmd, data: Buffer.alloc(0) }; + } + + const task = new CancelableTask((resolve, reject, onCancel) => { + const timeoutId = setTimeout(() => { + reject(new Error(`[PacketClient] sendPacket 超时 cmd=${cmd} timeout=${timeout}ms`)); + }, timeout); + + onCancel(() => { + clearTimeout(timeoutId); + }); + + this.napcore.sendSsoCmdReqByContend(cmd, Buffer.from(data, 'hex')) + .then(ret => { + clearTimeout(timeoutId); + const result = ret as { rspbuffer: Buffer }; + resolve({ + seq: 0, + cmd: cmd, + data: result.rspbuffer + }); + }) + .catch(err => { + clearTimeout(timeoutId); + reject(err); + }); + }); + + return await task; + } + + async sendOidbPacket(pkt: OidbPacket, rsp = false, timeout = 5000): Promise { + return await this.sendPacket(pkt.cmd, pkt.data, rsp, timeout); + } } diff --git a/src/core/packet/context/clientContext.ts b/src/core/packet/context/clientContext.ts index 4cef67ea..69f3ae1b 100644 --- a/src/core/packet/context/clientContext.ts +++ b/src/core/packet/context/clientContext.ts @@ -1,17 +1,8 @@ -import { IPacketClient } from '@/core/packet/client/baseClient'; import { NativePacketClient } from '@/core/packet/client/nativeClient'; import { OidbPacket } from '@/core/packet/transformer/base'; import { PacketLogger } from '@/core/packet/context/loggerContext'; import { NapCoreContext } from '@/core/packet/context/napCoreContext'; -type clientPriorityType = { - [key: number]: (napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) => IPacketClient; -} - -const clientPriority: clientPriorityType = { - 10: (napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) => new NativePacketClient(napCore, logger, logStack) -}; - export class LogStack { private stack: string[] = []; private readonly logger: PacketLogger; @@ -52,7 +43,7 @@ export class PacketClientContext { private readonly napCore: NapCoreContext; private readonly logger: PacketLogger; private readonly logStack: LogStack; - private readonly _client: IPacketClient; + private readonly _client: NativePacketClient; constructor(napCore: NapCoreContext, logger: PacketLogger) { this.napCore = napCore; @@ -78,45 +69,12 @@ export class PacketClientContext { return raw.data as T extends true ? Buffer : void; } - private newClient(): IPacketClient { - const prefer = this.napCore.config.packetBackend; - let client: IPacketClient | null; - switch (prefer) { - case 'native': - this.logger.info('使用指定的 NativePacketClient 作为后端'); - client = new NativePacketClient(this.napCore, this.logger, this.logStack); - break; - case 'auto': - case undefined: - client = this.judgeClient(); - break; - default: - this.logger.error(`未知的PacketBackend ${prefer},请检查配置文件!`); - client = null; - } - if (!client?.check()) { - throw new Error('[Core] [Packet] 无可用的后端,NapCat.Packet将不会加载!'); - } - if (!client) { - throw new Error('[Core] [Packet] 后端异常,NapCat.Packet将不会加载!'); + private newClient(): NativePacketClient { + this.logger.info('使用 NativePacketClient 作为后端'); + const client = new NativePacketClient(this.napCore, this.logger, this.logStack); + if (!client.check()) { + throw new Error('[Core] [Packet] NativePacketClient 不可用,NapCat.Packet将不会加载!'); } return client; } - - private judgeClient(): IPacketClient { - const sortedClients = Object.entries(clientPriority) - .map(([priority, clientFactory]) => { - const client = clientFactory(this.napCore, this.logger, this.logStack); - const score = +priority * +client.check(); - return { client, score }; - }) - .filter(({ score }) => score > 0) - .sort((a, b) => b.score - a.score); - const selectedClient = sortedClients[0]?.client; - if (!selectedClient) { - throw new Error('[Core] [Packet] 无可用的后端,NapCat.Packet将不会加载!'); - } - this.logger.info(`自动选择 ${selectedClient.constructor.name} 作为后端`); - return selectedClient; - } } diff --git a/src/native/packet/napi2native.win32.x64.node b/src/native/packet/napi2native.win32.x64.node index 5663bd8b..efa0c479 100644 Binary files a/src/native/packet/napi2native.win32.x64.node and b/src/native/packet/napi2native.win32.x64.node differ