mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 05:05:44 +08:00
Remove baseClient and simplify packet client selection
Deleted baseClient.ts and moved its logic into nativeClient.ts, making NativePacketClient a standalone class. Refactored PacketClientContext to always use NativePacketClient, removing support for multiple packet backends and related selection logic. Updated binary for napi2native.win32.x64.node.
This commit is contained in:
parent
0c88319248
commit
55ef040852
@ -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<string, (json: RecvPacketData) => Promise<any> | 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<void>;
|
||||
|
||||
async sendPacket(cmd: string, data: PacketHexStr, rsp = false, timeout = 5000): Promise<RecvPacketData> {
|
||||
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<RecvPacketData>((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<RecvPacketData> {
|
||||
return await this.sendPacket(pkt.cmd, pkt.data, rsp, timeout);
|
||||
}
|
||||
}
|
||||
@ -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<string, (json: RecvPacketData) => Promise<any> | 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<RecvPacketData> {
|
||||
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<RecvPacketData>((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<RecvPacketData> {
|
||||
return await this.sendPacket(pkt.cmd, pkt.data, rsp, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user