mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-23 16:30:07 +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 path, { dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { IPacketClient } from '@/core/packet/client/baseClient';
|
|
||||||
import { constants } from 'node:os';
|
import { constants } from 'node:os';
|
||||||
import { LogStack } from '@/core/packet/context/clientContext';
|
import { LogStack } from '@/core/packet/context/clientContext';
|
||||||
import { NapCoreContext } from '@/core/packet/context/napCoreContext';
|
import { NapCoreContext } from '@/core/packet/context/napCoreContext';
|
||||||
import { PacketLogger } from '@/core/packet/context/loggerContext';
|
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
|
// 0 send 1 recv
|
||||||
export interface NativePacketExportType {
|
export interface NativePacketExportType {
|
||||||
initHook?: (send: string, recv: string) => boolean;
|
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 supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
|
||||||
private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} };
|
private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} };
|
||||||
|
|
||||||
constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) {
|
constructor(napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) {
|
||||||
super(napCore, logger, logStack);
|
this.napcore = napCore;
|
||||||
|
this.logger = logger;
|
||||||
|
this.logStack = logStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
check(): boolean {
|
check(): boolean {
|
||||||
@ -43,4 +63,44 @@ export class NativePacketClient extends IPacketClient {
|
|||||||
this.available = true;
|
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 { NativePacketClient } from '@/core/packet/client/nativeClient';
|
||||||
import { OidbPacket } from '@/core/packet/transformer/base';
|
import { OidbPacket } from '@/core/packet/transformer/base';
|
||||||
import { PacketLogger } from '@/core/packet/context/loggerContext';
|
import { PacketLogger } from '@/core/packet/context/loggerContext';
|
||||||
import { NapCoreContext } from '@/core/packet/context/napCoreContext';
|
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 {
|
export class LogStack {
|
||||||
private stack: string[] = [];
|
private stack: string[] = [];
|
||||||
private readonly logger: PacketLogger;
|
private readonly logger: PacketLogger;
|
||||||
@ -52,7 +43,7 @@ export class PacketClientContext {
|
|||||||
private readonly napCore: NapCoreContext;
|
private readonly napCore: NapCoreContext;
|
||||||
private readonly logger: PacketLogger;
|
private readonly logger: PacketLogger;
|
||||||
private readonly logStack: LogStack;
|
private readonly logStack: LogStack;
|
||||||
private readonly _client: IPacketClient;
|
private readonly _client: NativePacketClient;
|
||||||
|
|
||||||
constructor(napCore: NapCoreContext, logger: PacketLogger) {
|
constructor(napCore: NapCoreContext, logger: PacketLogger) {
|
||||||
this.napCore = napCore;
|
this.napCore = napCore;
|
||||||
@ -78,45 +69,12 @@ export class PacketClientContext {
|
|||||||
return raw.data as T extends true ? Buffer : void;
|
return raw.data as T extends true ? Buffer : void;
|
||||||
}
|
}
|
||||||
|
|
||||||
private newClient(): IPacketClient {
|
private newClient(): NativePacketClient {
|
||||||
const prefer = this.napCore.config.packetBackend;
|
this.logger.info('使用 NativePacketClient 作为后端');
|
||||||
let client: IPacketClient | null;
|
const client = new NativePacketClient(this.napCore, this.logger, this.logStack);
|
||||||
switch (prefer) {
|
if (!client.check()) {
|
||||||
case 'native':
|
throw new Error('[Core] [Packet] NativePacketClient 不可用,NapCat.Packet将不会加载!');
|
||||||
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将不会加载!');
|
|
||||||
}
|
}
|
||||||
return client;
|
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