refactor: 重构eslint

This commit is contained in:
时瑾 2025-11-03 14:33:44 +08:00
parent 52c3712200
commit bde4319c4d
No known key found for this signature in database
GPG Key ID: 023F70A1B8F8C196
108 changed files with 637 additions and 730 deletions

View File

@ -43,6 +43,37 @@ _Modern protocol-side framework implemented based on NTQQ._
**首次使用**请务必查看如下文档看使用教程
> 项目非盈利,对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
## Development Guide
### 代码提交前检查
在提交代码前,**必须**执行以下命令进行代码检查:
```bash
# 1. 代码格式化修复
npm run lint:fix
# 2. TypeScript 类型检查
npm run tsc
```
#### 关于 TypeScript 类型检查
执行 `npm run tsc` 时,会出现 22 个已知的第三方库类型错误,**这是正常现象**
```
Found 22 errors in 3 files.
Errors Files
3 node_modules/@homebridge/node-pty-prebuilt-multiarch/src/eventEmitter2.ts:42
2 node_modules/@homebridge/node-pty-prebuilt-multiarch/src/terminal.ts:158
17 node_modules/@napneko/nap-proto-core/NapProto.ts:94
```
这些错误是由于启用了严格类型检查模式导致的第三方库内部类型问题,**不影响项目运行**。
⚠️ **注意**:除了上述 22 个已知错误外,不应该出现其他类型错误。如果有新的错误,请在提交前修复。
## Link
| Docs | [![Github.IO](https://img.shields.io/badge/docs%20on-Github.IO-orange)](https://napneko.github.io/) | [![Cloudflare.Worker](https://img.shields.io/badge/docs%20on-Cloudflare.Worker-black)](https://doc.napneko.icu/) | [![Cloudflare.HKServer](https://img.shields.io/badge/docs%20on-Cloudflare.HKServer-informational)](https://napcat.napneko.icu/) |

View File

@ -8,20 +8,20 @@
"build:framework": "npm run build:webui && npm run dev:framework || exit 1",
"build:shell": "npm run build:webui && npm run dev:shell || exit 1",
"build:webui": "cd napcat.webui && npm run build",
"dev:universal": "tsc --noEmit && vite build --mode universal",
"dev:framework": "tsc --noEmit && vite build --mode framework",
"dev:shell": "tsc --noEmit && vite build --mode shell",
"dev:shell-analysis": "tsc --noEmit && vite build --mode shell-analysis",
"dev:universal": "vite build --mode universal",
"dev:framework": "vite build --mode framework",
"dev:shell": "vite build --mode shell",
"dev:shell-analysis": "vite build --mode shell-analysis",
"dev:webui": "cd napcat.webui && npm run dev",
"tsc": "npm run tsc:core && npm run tsc:webui",
"tsc": "npm run tsc:webui && npm run tsc:core",
"tsc:core": "tsc --noEmit",
"tsc:webui": "cd napcat.webui && tsc --noEmit",
"lint": "npm run lint:core && npm run lint:webui",
"lint:fix": "npm run lint:fix:core && npm run lint:fix:webui",
"lint:core": "eslint src/**/*.{js,ts}",
"lint:fix:core": "eslint --fix src/**/*.{js,ts,vue}",
"lint:webui": "cd napcat.webui && eslint src/**/*.{js,ts}",
"lint:fix:webui": "cd napcat.webui && eslint --fix src/**/*.{js,ts,tsx}",
"lint:core": "eslint src/**/*",
"lint:fix:core": "eslint --fix src/**/*",
"lint:webui": "cd napcat.webui && eslint src/**/*",
"lint:fix:webui": "cd napcat.webui && eslint --fix src/**/*",
"depend": "cd dist && npm install --omit=dev",
"dev:depend": "npm i && cd napcat.webui && npm i"
},
@ -73,4 +73,4 @@
"silk-wasm": "^3.6.1",
"ws": "^8.18.3"
}
}
}

View File

@ -54,7 +54,7 @@ class CleanupQueue {
private fileExists (filePath: string): boolean {
try {
return fs.existsSync(filePath);
} catch (error) {
} catch (_error) {
// console.log(`检查文件存在出错: ${filePath}`, error);
return false;
}

View File

@ -63,7 +63,7 @@ async function findAvailableUrl (): Promise<string | null> {
if (available) {
return url;
}
} catch (error) {
} catch (_error) {
// 忽略错误
}
}
@ -106,8 +106,8 @@ async function downloadFile (url: string, destPath: string, progressCallback?: (
// 2. 距离上次报告至少500毫秒
// 3. 确保报告100%完成
if ((currentPercent !== lastReportedPercent &&
(currentPercent - lastReportedPercent >= 1 || currentPercent === 100)) &&
(now - lastReportTime >= 1000 || currentPercent === 100)) {
(currentPercent - lastReportedPercent >= 1 || currentPercent === 100)) &&
(now - lastReportTime >= 1000 || currentPercent === 100)) {
progressCallback(currentPercent);
lastReportedPercent = currentPercent;
lastReportTime = now;
@ -146,60 +146,56 @@ async function downloadFile (url: string, destPath: string, progressCallback?: (
* @param extractDir
*/
async function extractBinDirectory (zipPath: string, extractDir: string): Promise<void> {
try {
// 确保目标目录存在
if (!fs.existsSync(extractDir)) {
fs.mkdirSync(extractDir, { recursive: true });
}
// 解压文件
const zipStream = new compressing.zip.UncompressStream({ source: zipPath });
return new Promise<void>((resolve, reject) => {
// 监听条目事件
zipStream.on('entry', (header, stream, next) => {
// 获取文件路径
const filePath = header.name;
// 匹配内层bin目录中的文件
// 例如ffmpeg-n7.1.1-6-g48c0f071d4-win64-lgpl-7.1/bin/ffmpeg.exe
if (filePath.includes('/bin/') && filePath.endsWith('.exe')) {
// 提取文件名
const fileName = path.basename(filePath);
const targetPath = path.join(extractDir, fileName);
// 创建写入流
const writeStream = fs.createWriteStream(targetPath);
// 将流管道连接到文件
stream.pipe(writeStream);
// 监听写入完成事件
writeStream.on('finish', () => {
next();
});
writeStream.on('error', () => {
next();
});
} else {
// 跳过不需要的文件
stream.resume();
next();
}
});
zipStream.on('error', (err) => {
reject(err);
});
zipStream.on('finish', () => {
resolve();
});
});
} catch (err) {
throw err;
// 确保目标目录存在
if (!fs.existsSync(extractDir)) {
fs.mkdirSync(extractDir, { recursive: true });
}
// 解压文件
const zipStream = new compressing.zip.UncompressStream({ source: zipPath });
return new Promise<void>((resolve, reject) => {
// 监听条目事件
zipStream.on('entry', (header, stream, next) => {
// 获取文件路径
const filePath = header.name;
// 匹配内层bin目录中的文件
// 例如ffmpeg-n7.1.1-6-g48c0f071d4-win64-lgpl-7.1/bin/ffmpeg.exe
if (filePath.includes('/bin/') && filePath.endsWith('.exe')) {
// 提取文件名
const fileName = path.basename(filePath);
const targetPath = path.join(extractDir, fileName);
// 创建写入流
const writeStream = fs.createWriteStream(targetPath);
// 将流管道连接到文件
stream.pipe(writeStream);
// 监听写入完成事件
writeStream.on('finish', () => {
next();
});
writeStream.on('error', () => {
next();
});
} else {
// 跳过不需要的文件
stream.resume();
next();
}
});
zipStream.on('error', (err) => {
reject(err);
});
zipStream.on('finish', () => {
resolve();
});
});
}
/**
@ -270,7 +266,7 @@ export async function downloadFFmpeg (
if (progressCallback) progressCallback(95, '清理临时文件');
try {
fs.unlinkSync(zipFilePath);
} catch (err) {
} catch (_err) {
// 忽略清理临时文件失败的错误
}
@ -281,7 +277,7 @@ export async function downloadFFmpeg (
} else {
return null;
}
} catch (err) {
} catch (_err) {
return null;
}
}
@ -307,7 +303,7 @@ function findExecutableInPath (executable: string): string | null {
if (fs.existsSync(filePath)) {
return filePath;
}
} catch (error) {
} catch (_error) {
continue;
}
}

View File

@ -12,10 +12,10 @@ interface InternalMapKey {
type EnsureFunc<T> = T extends (...args: any) => any ? T : never;
type FuncKeys<T> = Extract<
{
[K in keyof T]: EnsureFunc<T[K]> extends never ? never : K;
}[keyof T],
string
{
[K in keyof T]: EnsureFunc<T[K]> extends never ? never : K;
}[keyof T],
string
>;
export type ListenerClassBase = Record<string, string>;
@ -51,41 +51,41 @@ export class NTEventWrapper {
}
createEventFunction<
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
T extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
>(eventName: `${Service}/${ServiceMethod}`): T | undefined {
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
T extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
> (eventName: `${Service}/${ServiceMethod}`): T | undefined {
const eventNameArr = eventName.split('/');
type eventType = {
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> };
};
if (eventNameArr.length > 1) {
const serviceName = 'get' + (eventNameArr[0]?.replace('NodeIKernel', '') ?? '');
const eventName = eventNameArr[1];
const services = (this.WrapperSession as unknown as eventType)[serviceName]?.();
if (!services || !eventName) {
return undefined;
}
let event = services[eventName];
// 重新绑定this
event = event?.bind(services);
if (event) {
return event as T;
}
return undefined;
}
type eventType = {
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>>; };
};
if (eventNameArr.length > 1) {
const serviceName = 'get' + (eventNameArr[0]?.replace('NodeIKernel', '') ?? '');
const eventName = eventNameArr[1];
const services = (this.WrapperSession as unknown as eventType)[serviceName]?.();
if (!services || !eventName) {
return undefined;
}
let event = services[eventName];
// 重新绑定this
event = event?.bind(services);
if (event) {
return event as T;
}
return undefined;
}
return undefined;
}
createListenerFunction<T>(listenerMainName: string, uniqueCode: string = ''): T {
createListenerFunction<T> (listenerMainName: string, uniqueCode: string = ''): T {
const existListener = this.listenerManager.get(listenerMainName + uniqueCode);
if (!existListener) {
const Listener = this.createProxyDispatch(listenerMainName);
const ServiceSubName = /^NodeIKernel(.*?)Listener$/.exec(listenerMainName)![1];
const Service = `NodeIKernel${ServiceSubName}Service/addKernel${ServiceSubName}Listener`;
// eslint-disable-next-line
// @ts-ignore
// @ts-ignore
this.createEventFunction(Service)(Listener as T);
this.listenerManager.set(listenerMainName + uniqueCode, Listener);
return Listener as T;
@ -109,10 +109,10 @@ export class NTEventWrapper {
}
async callNoListenerEvent<
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
>(
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
> (
serviceAndMethod: `${Service}/${ServiceMethod}`,
...args: Parameters<EventType>
): Promise<Awaited<ReturnType<EventType>>> {
@ -120,10 +120,10 @@ export class NTEventWrapper {
}
async registerListen<
Listener extends keyof ListenerNamingMapping,
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
>(
Listener extends keyof ListenerNamingMapping,
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
> (
listenerAndMethod: `${Listener}/${ListenerMethod}`,
checker: (...args: Parameters<ListenerType>) => boolean,
waitTimes = 1,
@ -138,7 +138,7 @@ export class NTEventWrapper {
let retData: Parameters<ListenerType> | undefined;
function sendDataCallback () {
if (complete == 0) {
if (complete === 0) {
reject(new Error(' ListenerName:' + listenerAndMethod + ' timeout'));
} else {
resolve(retData!);
@ -171,13 +171,13 @@ export class NTEventWrapper {
}
async callNormalEventV2<
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
Listener extends keyof ListenerNamingMapping,
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>,
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
>(
Service extends keyof ServiceNamingMapping,
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
Listener extends keyof ListenerNamingMapping,
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>,
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
> (
serviceAndMethod: `${Service}/${ServiceMethod}`,
listenerAndMethod: `${Listener}/${ListenerMethod}`,
args: Parameters<EventType>,
@ -192,16 +192,16 @@ export class NTEventWrapper {
let retEvent: any = {};
function sendDataCallback (resolve: any, reject: any) {
if (complete == 0) {
if (complete === 0) {
reject(
new Error(
'Timeout: NTEvent serviceAndMethod:' +
serviceAndMethod +
' ListenerName:' +
listenerAndMethod +
' EventRet:\n' +
JSON.stringify(retEvent, null, 4) +
'\n'
serviceAndMethod +
' ListenerName:' +
listenerAndMethod +
' EventRet:\n' +
JSON.stringify(retEvent, null, 4) +
'\n'
)
);
} else {
@ -248,12 +248,12 @@ export class NTEventWrapper {
reject(
new Error(
'EventChecker Failed: NTEvent serviceAndMethod:' +
serviceAndMethod +
' ListenerName:' +
listenerAndMethod +
' EventRet:\n' +
JSON.stringify(retEvent, null, 4) +
'\n'
serviceAndMethod +
' ListenerName:' +
listenerAndMethod +
' EventRet:\n' +
JSON.stringify(retEvent, null, 4) +
'\n'
)
);
}

View File

@ -37,7 +37,7 @@ export class FFmpegExecAdapter implements IFFmpegAdapter {
private ffprobePath: string = 'ffprobe',
private binaryPath?: string,
private logger?: LogWrapper
) {}
) { }
/**
* FFmpeg
@ -122,7 +122,7 @@ export class FFmpegExecAdapter implements IFFmpegAdapter {
if (existsSync(thumbnailPath)) {
thumbnail = readFileSync(thumbnailPath);
}
} catch (error) {
} catch (_error) {
// 使用默认值
}
@ -157,7 +157,7 @@ export class FFmpegExecAdapter implements IFFmpegAdapter {
/**
* PCM
*/
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number; }> {
try {
ensureDirExists(pcmPath);

View File

@ -93,7 +93,7 @@ export class FFmpegService {
/**
* PCM
*/
public static async convert (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
public static async convert (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number; }> {
const adapter = await this.getAdapter();
return adapter.convertToPCM(filePath, pcmPath);
}
@ -126,7 +126,7 @@ export class FFmpegService {
};
return result;
} catch (error) {
} catch (_error) {
// 降级处理:返回默认值
const fileType = await fileTypeFromFile(videoPath).catch(() => null);
const fileSize = statSync(videoPath).size;

View File

@ -13,7 +13,7 @@ type Uri2LocalRes = {
success: boolean,
errMsg: string,
fileName: string,
path: string
path: string;
};
// 定义一个异步函数来检查文件是否存在
@ -47,7 +47,7 @@ export async function checkFileExistV2 (path: string, timeout: number = 3000): P
// 转换超时时间至 Promise
function timeoutPromise (timeout: number, errorMsg: string): Promise<void> {
return new Promise((_, reject) => {
return new Promise((_resolve, reject) => {
setTimeout(() => {
reject(new Error(errorMsg));
}, timeout);
@ -59,7 +59,7 @@ async function checkFile (path: string): Promise<void> {
try {
await stat(path);
} catch (error: unknown) {
if ((error as Error & { code: string }).code === 'ENOENT') {
if ((error as Error & { code: string; }).code === 'ENOENT') {
// 如果文件不存在,则抛出一个错误
throw new Error(`文件不存在: ${path}`);
} else {
@ -169,6 +169,7 @@ export async function checkUriType (Uri: string) {
const data = uri.split(',')[1];
if (data) return { Uri: data, Type: FileUriType.Base64 };
}
return undefined;
}, Uri);
if (OtherFileRet) return OtherFileRet;

View File

@ -30,7 +30,7 @@ export function sleep (ms: number): Promise<void> {
}
export function PromiseTimer<T> (promise: Promise<T>, ms: number): Promise<T> {
const timeoutPromise = new Promise<T>((_, reject) =>
const timeoutPromise = new Promise<T>((_resolve, reject) =>
setTimeout(() => reject(new Error('PromiseTimer: Operation timed out')), ms)
);
return Promise.race([promise, timeoutPromise]);
@ -46,7 +46,7 @@ export async function runAllWithTimeout<T> (tasks: Promise<T>[], timeout: number
const results = await Promise.all(wrappedTasks);
return results
.filter((result) => result.status === 'fulfilled')
.map((result) => (result as { status: 'fulfilled'; value: T }).value);
.map((result) => (result as { status: 'fulfilled'; value: T; }).value);
}
export function isNull (value: any) {

View File

@ -139,7 +139,7 @@ export class LogWrapper {
});
}
setLogSelfInfo (selfInfo: { nick: string; uid: string }) {
setLogSelfInfo (selfInfo: { nick: string; uid: string; }) {
const userInfo = `${selfInfo.nick}`;
this.logger.defaultMeta = { userInfo };
}
@ -226,16 +226,16 @@ export function rawMessageToText (msg: RawMessage, recursiveLevel = 0): string {
const tokens: string[] = [];
if (msg.chatType == ChatType.KCHATTYPEC2C) {
if (msg.chatType === ChatType.KCHATTYPEC2C) {
tokens.push(`私聊 (${msg.peerUin})`);
} else if (msg.chatType == ChatType.KCHATTYPEGROUP) {
} else if (msg.chatType === ChatType.KCHATTYPEGROUP) {
if (recursiveLevel < 1) {
tokens.push(`群聊 [${msg.peerName}(${msg.peerUin})]`);
}
if (msg.senderUin !== '0') {
tokens.push(`[${msg.sendMemberName || msg.sendRemarkName || msg.sendNickName}(${msg.senderUin})]`);
}
} else if (msg.chatType == ChatType.KCHATTYPEDATALINE) {
} else if (msg.chatType === ChatType.KCHATTYPEDATALINE) {
tokens.push('移动设备');
} else {
tokens.push(`临时消息 (${msg.peerUin})`);
@ -314,8 +314,8 @@ function textElementToText (textElement: any): string {
function replyElementToText (replyElement: any, msg: RawMessage, recursiveLevel: number): string {
const recordMsgOrNull = msg.records.find((record) => replyElement.sourceMsgIdInRecords === record.msgId);
return `[回复消息 ${recordMsgOrNull && recordMsgOrNull.peerUin != '284840486' && recordMsgOrNull.peerUin != '1094950020'
? rawMessageToText(recordMsgOrNull, recursiveLevel + 1)
: `未找到消息记录 (MsgId = ${replyElement.sourceMsgIdInRecords})`
return `[回复消息 ${recordMsgOrNull && recordMsgOrNull.peerUin !== '284840486' && recordMsgOrNull.peerUin !== '1094950020'
? rawMessageToText(recordMsgOrNull, recursiveLevel + 1)
: `未找到消息记录 (MsgId = ${replyElement.sourceMsgIdInRecords})`
}]`;
}

View File

@ -15,9 +15,9 @@ export class QQBasicInfoWrapper {
QQPackageInfo: QQPackageInfoType | undefined;
QQVersionAppid: string | undefined;
QQVersionQua: string | undefined;
context: { logger: LogWrapper };
context: { logger: LogWrapper; };
constructor (context: { logger: LogWrapper }) {
constructor (context: { logger: LogWrapper; }) {
// 基础目录获取
this.context = context;
this.QQMainPath = process.execPath;
@ -49,7 +49,7 @@ export class QQBasicInfoWrapper {
requireMinNTQQBuild (buildStr: string) {
const currentBuild = +(this.getQQBuildStr() ?? '0');
if (currentBuild == 0) throw new Error('QQBuildStr获取失败');
if (currentBuild === 0) throw new Error('QQBuildStr获取失败');
return currentBuild >= parseInt(buildStr);
}
@ -72,7 +72,7 @@ export class QQBasicInfoWrapper {
return platformMapping[systemPlatform] ?? '537246092';
}
getAppidV2 (): { appid: string; qua: string } {
getAppidV2 (): { appid: string; qua: string; } {
// 通过已有表 性能好
const appidTbale = AppidTable as unknown as QQAppidTableType;
const fullVersion = this.getFullQQVersion();

View File

@ -141,12 +141,12 @@ export class NTQQGroupApi {
const param = createGroupDetailInfoV2Param(groupCode);
// 设置要修改的目标
param.filter.addOption = 1;
if (option.addOption == 4 || option.addOption == 5) {
if (option.addOption === 4 || option.addOption === 5) {
// 4 问题进入答案 5 问题管理员批准
param.filter.groupQuestion = 1;
param.filter.groupAnswer = option.addOption == 4 ? 1 : 0;
param.filter.groupAnswer = option.addOption === 4 ? 1 : 0;
param.modifyInfo.groupQuestion = option.groupQuestion || '';
param.modifyInfo.groupAnswer = option.addOption == 4 ? option.groupAnswer || '' : '';
param.modifyInfo.groupAnswer = option.addOption === 4 ? option.groupAnswer || '' : '';
}
param.modifyInfo.addOption = option.addOption;
return this.context.session.getGroupService().modifyGroupDetailInfoV2(param, 0);
@ -418,7 +418,7 @@ export class NTQQGroupApi {
const ret = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelGroupService/getGroupRecommendContactArkJson',
groupCode
) as GeneralCallResult & { arkJson: string };
) as GeneralCallResult & { arkJson: string; };
return ret.arkJson;
}
@ -449,7 +449,7 @@ export class NTQQGroupApi {
return this.context.session.getGroupService().kickMember(groupCode, kickUids, refuseForever, kickReason);
}
async banMember (groupCode: string, memList: Array<{ uid: string, timeStamp: number }>) {
async banMember (groupCode: string, memList: Array<{ uid: string, timeStamp: number; }>) {
// timeStamp为秒数, 0为解除禁言
return this.context.session.getGroupService().setMemberShutUp(groupCode, memList);
}
@ -473,7 +473,7 @@ export class NTQQGroupApi {
async publishGroupBulletin (groupCode: string, content: string, picInfo: {
id: string,
width: number,
height: number
height: number;
} | undefined = undefined, pinned: number = 0, confirmRequired: number = 0) {
const psKey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com');
// text是content内容url编码

View File

@ -43,7 +43,7 @@ export class NTQQMsgApi {
}
async getMultiMsg (peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
msgList: RawMessage[]
msgList: RawMessage[];
} | undefined> {
return this.context.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId);
}
@ -288,7 +288,7 @@ export class NTQQMsgApi {
() => true,
(msgRecords) => msgRecords.some(
msgRecord => msgRecord.peerUid === destPeer.peerUid &&
msgRecord.senderUid === this.core.selfInfo.uid
msgRecord.senderUid === this.core.selfInfo.uid
)
);
for (const msg of msgList) {
@ -296,11 +296,11 @@ export class NTQQMsgApi {
if (!arkElement) {
continue;
}
const forwardData: { app: string } = JSON.parse(arkElement.arkElement?.bytesData ?? '');
if (forwardData.app != 'com.tencent.multimsg') {
const forwardData: { app: string; } = JSON.parse(arkElement.arkElement?.bytesData ?? '');
if (forwardData.app !== 'com.tencent.multimsg') {
continue;
}
if (msg.peerUid == destPeer.peerUid && msg.senderUid == this.core.selfInfo.uid) {
if (msg.peerUid === destPeer.peerUid && msg.senderUid === this.core.selfInfo.uid) {
return msg;
}
}

View File

@ -60,7 +60,7 @@ export class NTQQUserApi {
return this.context.session.getBuddyService().getBuddyRecommendContactArkJson(uin, sencenID);
}
async like (uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> {
async like (uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number; }> {
return this.context.session.getProfileLikeService().setBuddyProfileLike({
friendUid: uid,
sourceId: 71,
@ -134,9 +134,9 @@ export class NTQQUserApi {
async getCookies (domain: string) {
const ClientKeyData = await this.forceFetchClientKey();
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin +
'&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27';
'&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27';
const data = await RequestUtil.HttpsGetCookies(requestUrl);
if (!data['p_skey'] || data['p_skey'].length == 0) {
if (!data['p_skey'] || data['p_skey'].length === 0) {
try {
const pskey = (await this.getPSkey([domain])).domainPskeyMap.get(domain);
if (pskey) data['p_skey'] = pskey;
@ -194,11 +194,11 @@ export class NTQQUserApi {
}
const fallback =
new Fallback<string | undefined>((uid) => FallbackUtil.boolchecker(uid, uid !== undefined && uid.indexOf('*') === -1 && uid !== ''))
.add(() => this.context.session.getUixConvertService().getUid([uin]).then((data) => data.uidInfo.get(uin)))
.add(() => this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [uin]).get(uin))
.add(() => this.context.session.getGroupService().getUidByUins([uin]).then((data) => data.uids.get(uin)))
.add(() => this.getUserDetailInfoByUin(uin).then((data) => data.detail.uid));
new Fallback<string | undefined>((uid) => FallbackUtil.boolchecker(uid, uid !== undefined && uid.indexOf('*') === -1 && uid !== ''))
.add(() => this.context.session.getUixConvertService().getUid([uin]).then((data) => data.uidInfo.get(uin)))
.add(() => this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [uin]).get(uin))
.add(() => this.context.session.getGroupService().getUidByUins([uin]).then((data) => data.uids.get(uin)))
.add(() => this.getUserDetailInfoByUin(uin).then((data) => data.detail.uid));
const uid = await fallback.run().catch(() => '');
return uid ?? '';

View File

@ -59,7 +59,7 @@ export function loadQQWrapper (QQVersion: string): WrapperNodeApi {
if (!fs.existsSync(wrapperNodePath)) {
wrapperNodePath = path.join(path.dirname(process.execPath), `./resources/app/versions/${QQVersion}/wrapper.node`);
}
const nativemodule: { exports: WrapperNodeApi } = { exports: {} as WrapperNodeApi };
const nativemodule: { exports: WrapperNodeApi; } = { exports: {} as WrapperNodeApi };
process.dlopen(nativemodule, wrapperNodePath);
return nativemodule.exports;
}
@ -178,7 +178,7 @@ export class NapCatCore {
}
};
profileListener.onSelfStatusChanged = (Info: SelfStatusInfo) => {
if (Info.status == 20) {
if (Info.status === 20) {
this.selfInfo.online = false;
this.context.logger.log('账号状态变更为离线');
} else {
@ -273,5 +273,5 @@ export interface StableNTApiWrapper {
FriendApi: NTQQFriendApi,
MsgApi: NTQQMsgApi,
UserApi: NTQQUserApi,
GroupApi: NTQQGroupApi
GroupApi: NTQQGroupApi;
}

View File

@ -1,5 +1,5 @@
export class NodeIKernelFileAssistantListener {
onFileStatusChanged (fileStatus: {
onFileStatusChanged (_fileStatus: {
id: string,
fileStatus: number,
fileProgress: `${number}`,
@ -10,16 +10,16 @@ export class NodeIKernelFileAssistantListener {
}): any {
}
onSessionListChanged (...args: unknown[]): any {
onSessionListChanged (..._args: unknown[]): any {
}
onSessionChanged (...args: unknown[]): any {
onSessionChanged (..._args: unknown[]): any {
}
onFileListChanged (...args: unknown[]): any {
onFileListChanged (..._args: unknown[]): any {
}
onFileSearch (searchResult: SearchResultWrapper): any {
onFileSearch (_searchResult: SearchResultWrapper): any {
}
}

View File

@ -1,85 +1,85 @@
import { DataSource, Group, GroupDetailInfo, GroupListUpdateType, GroupMember, GroupNotify, ShutUpGroupMember } from '@/core/types';
export class NodeIKernelGroupListener {
onGroupListInited (listEmpty: boolean): any { }
onGroupListInited (_listEmpty: boolean): any { }
// 发现于Win 9.9.9 23159
onGroupMemberLevelInfoChange (...args: unknown[]): any {
onGroupMemberLevelInfoChange (..._args: unknown[]): any {
}
onGetGroupBulletinListResult (...args: unknown[]): any {
onGetGroupBulletinListResult (..._args: unknown[]): any {
}
onGroupAllInfoChange (...args: unknown[]): any {
onGroupAllInfoChange (..._args: unknown[]): any {
}
onGroupBulletinChange (...args: unknown[]): any {
onGroupBulletinChange (..._args: unknown[]): any {
}
onGroupBulletinRemindNotify (...args: unknown[]): any {
onGroupBulletinRemindNotify (..._args: unknown[]): any {
}
onGroupArkInviteStateResult (...args: unknown[]): any {
onGroupArkInviteStateResult (..._args: unknown[]): any {
}
onGroupBulletinRichMediaDownloadComplete (...args: unknown[]): any {
onGroupBulletinRichMediaDownloadComplete (..._args: unknown[]): any {
}
onGroupConfMemberChange (...args: unknown[]): any {
onGroupConfMemberChange (..._args: unknown[]): any {
}
onGroupDetailInfoChange (detailInfo: GroupDetailInfo): any {
onGroupDetailInfoChange (_detailInfo: GroupDetailInfo): any {
}
onGroupExtListUpdate (...args: unknown[]): any {
onGroupExtListUpdate (..._args: unknown[]): any {
}
onGroupFirstBulletinNotify (...args: unknown[]): any {
onGroupFirstBulletinNotify (..._args: unknown[]): any {
}
onGroupListUpdate (updateType: GroupListUpdateType, groupList: Group[]): any {
onGroupListUpdate (_updateType: GroupListUpdateType, _groupList: Group[]): any {
}
onGroupNotifiesUpdated (dboubt: boolean, notifies: GroupNotify[]): any {
onGroupNotifiesUpdated (_dboubt: boolean, _notifies: GroupNotify[]): any {
}
onGroupBulletinRichMediaProgressUpdate (...args: unknown[]): any {
onGroupBulletinRichMediaProgressUpdate (..._args: unknown[]): any {
}
onGroupNotifiesUnreadCountUpdated (...args: unknown[]): any {
onGroupNotifiesUnreadCountUpdated (..._args: unknown[]): any {
}
onGroupSingleScreenNotifies (doubt: boolean, seq: string, notifies: GroupNotify[]): any {
onGroupSingleScreenNotifies (_doubt: boolean, _seq: string, _notifies: GroupNotify[]): any {
}
onGroupsMsgMaskResult (...args: unknown[]): any {
onGroupsMsgMaskResult (..._args: unknown[]): any {
}
onGroupStatisticInfoChange (...args: unknown[]): any {
onGroupStatisticInfoChange (..._args: unknown[]): any {
}
onJoinGroupNotify (...args: unknown[]): any {
onJoinGroupNotify (..._args: unknown[]): any {
}
onJoinGroupNoVerifyFlag (...args: unknown[]): any {
onJoinGroupNoVerifyFlag (..._args: unknown[]): any {
}
onMemberInfoChange (groupCode: string, dateSource: DataSource, members: Map<string, GroupMember>): any {
onMemberInfoChange (_groupCode: string, _dateSource: DataSource, _members: Map<string, GroupMember>): any {
}
onMemberListChange (arg: {
onMemberListChange (_arg: {
sceneId: string,
ids: string[],
infos: Map<string, GroupMember>, // uid -> GroupMember
hasPrev: boolean,
hasNext: boolean,
hasRobot: boolean
hasRobot: boolean;
}): any {
}
onSearchMemberChange (...args: unknown[]): any {
onSearchMemberChange (..._args: unknown[]): any {
}
onShutUpMemberListChanged (groupCode: string, members: Array<ShutUpGroupMember>): any {
onShutUpMemberListChanged (_groupCode: string, _members: Array<ShutUpGroupMember>): any {
}
}

View File

@ -2,56 +2,56 @@ export class NodeIKernelLoginListener {
onLoginConnected (): Promise<void> | void {
}
onLoginDisConnected (...args: any[]): any {
onLoginDisConnected (..._args: any[]): any {
}
onLoginConnecting (...args: any[]): any {
onLoginConnecting (..._args: any[]): any {
}
onQRCodeGetPicture (arg: { pngBase64QrcodeData: string, qrcodeUrl: string }): any {
onQRCodeGetPicture (_arg: { pngBase64QrcodeData: string, qrcodeUrl: string; }): any {
// let base64Data: string = arg.pngBase64QrcodeData
// base64Data = base64Data.split("data:image/png;base64,")[1]
// let buffer = Buffer.from(base64Data, 'base64')
// console.log("onQRCodeGetPicture", arg);
}
onQRCodeLoginPollingStarted (...args: any[]): any {
onQRCodeLoginPollingStarted (..._args: any[]): any {
}
onQRCodeSessionUserScaned (...args: any[]): any {
onQRCodeSessionUserScaned (..._args: any[]): any {
}
onQRCodeLoginSucceed (arg: QRCodeLoginSucceedResult): any {
onQRCodeLoginSucceed (_arg: QRCodeLoginSucceedResult): any {
}
onQRCodeSessionFailed (...args: any[]): any {
onQRCodeSessionFailed (..._args: any[]): any {
}
onLoginFailed (...args: any[]): any {
onLoginFailed (..._args: any[]): any {
}
onLogoutSucceed (...args: any[]): any {
onLogoutSucceed (..._args: any[]): any {
}
onLogoutFailed (...args: any[]): any {
onLogoutFailed (..._args: any[]): any {
}
onUserLoggedIn (...args: any[]): any {
onUserLoggedIn (..._args: any[]): any {
}
onQRCodeSessionQuickLoginFailed (...args: any[]): any {
onQRCodeSessionQuickLoginFailed (..._args: any[]): any {
}
onPasswordLoginFailed (...args: any[]): any {
onPasswordLoginFailed (..._args: any[]): any {
}
OnConfirmUnusualDeviceFailed (...args: any[]): any {
OnConfirmUnusualDeviceFailed (..._args: any[]): any {
}
onQQLoginNumLimited (...args: any[]): any {
onQQLoginNumLimited (..._args: any[]): any {
}
onLoginState (...args: any[]): any {
onLoginState (..._args: any[]): any {
}
}

View File

@ -1,71 +1,71 @@
import { User, UserDetailInfoListenerArg } from '@/core/types';
export class NodeIKernelProfileListener {
onUserDetailInfoChanged (arg: UserDetailInfoListenerArg): void {
onUserDetailInfoChanged (_arg: UserDetailInfoListenerArg): void {
}
onProfileSimpleChanged (...args: unknown[]): any {
onProfileSimpleChanged (..._args: unknown[]): any {
}
onProfileDetailInfoChanged (profile: User): any {
onProfileDetailInfoChanged (_profile: User): any {
}
onStatusUpdate (...args: unknown[]): any {
onStatusUpdate (..._args: unknown[]): any {
}
onSelfStatusChanged (...args: unknown[]): any {
onSelfStatusChanged (..._args: unknown[]): any {
}
onStrangerRemarkChanged (...args: unknown[]): any {
onStrangerRemarkChanged (..._args: unknown[]): any {
}
onMemberListChange (...args: unknown[]): any {
onMemberListChange (..._args: unknown[]): any {
}
onMemberInfoChange (...args: unknown[]): any {
onMemberInfoChange (..._args: unknown[]): any {
}
onGroupListUpdate (...args: unknown[]): any {
onGroupListUpdate (..._args: unknown[]): any {
}
onGroupAllInfoChange (...args: unknown[]): any {
onGroupAllInfoChange (..._args: unknown[]): any {
}
onGroupDetailInfoChange (...args: unknown[]): any {
onGroupDetailInfoChange (..._args: unknown[]): any {
}
onGroupConfMemberChange (...args: unknown[]): any {
onGroupConfMemberChange (..._args: unknown[]): any {
}
onGroupExtListUpdate (...args: unknown[]): any {
onGroupExtListUpdate (..._args: unknown[]): any {
}
onGroupNotifiesUpdated (...args: unknown[]): any {
onGroupNotifiesUpdated (..._args: unknown[]): any {
}
onGroupNotifiesUnreadCountUpdated (...args: unknown[]): any {
onGroupNotifiesUnreadCountUpdated (..._args: unknown[]): any {
}
onGroupMemberLevelInfoChange (...args: unknown[]): any {
onGroupMemberLevelInfoChange (..._args: unknown[]): any {
}
onGroupBulletinChange (...args: unknown[]): any {
onGroupBulletinChange (..._args: unknown[]): any {
}
}

View File

@ -1,25 +1,25 @@
export class NodeIKernelRecentContactListener {
onDeletedContactsNotify (...args: unknown[]): any {
onDeletedContactsNotify (..._args: unknown[]): any {
}
onRecentContactNotification (msgList: any, arg0: { msgListUnreadCnt: string }, arg1: number): any {
onRecentContactNotification (_msgList: any, _arg0: { msgListUnreadCnt: string; }, _arg1: number): any {
}
onMsgUnreadCountUpdate (...args: unknown[]): any {
onMsgUnreadCountUpdate (..._args: unknown[]): any {
}
onGuildDisplayRecentContactListChanged (...args: unknown[]): any {
onGuildDisplayRecentContactListChanged (..._args: unknown[]): any {
}
onRecentContactListChanged (...args: unknown[]): any {
onRecentContactListChanged (..._args: unknown[]): any {
}
onRecentContactListChangedVer2 (...args: unknown[]): any {
onRecentContactListChangedVer2 (..._args: unknown[]): any {
}
}

View File

@ -1,13 +1,13 @@
export class NodeIKernelRobotListener {
onRobotFriendListChanged (...args: unknown[]): any {
onRobotFriendListChanged (..._args: unknown[]): any {
}
onRobotListChanged (...args: unknown[]): any {
onRobotListChanged (..._args: unknown[]): any {
}
onRobotProfileChanged (...args: unknown[]): any {
onRobotProfileChanged (..._args: unknown[]): any {
}
}

View File

@ -1,25 +1,25 @@
export class NodeIKernelSessionListener {
onNTSessionCreate (args: unknown): any {
onNTSessionCreate (_args: unknown): any {
}
onGProSessionCreate (args: unknown): any {
onGProSessionCreate (_args: unknown): any {
}
onSessionInitComplete (args: unknown): any {
onSessionInitComplete (_args: unknown): any {
}
onOpentelemetryInit (info: { is_init: boolean, is_report: boolean }): any {
onOpentelemetryInit (_info: { is_init: boolean, is_report: boolean; }): any {
}
onUserOnlineResult (args: unknown): any {
onUserOnlineResult (_args: unknown): any {
}
onGetSelfTinyId (args: unknown): any {
onGetSelfTinyId (_args: unknown): any {
}
}

View File

@ -1,21 +1,21 @@
export class NodeIKernelStorageCleanListener {
onCleanCacheProgressChanged (args: unknown): any {
onCleanCacheProgressChanged (_args: unknown): any {
}
onScanCacheProgressChanged (args: unknown): any {
onScanCacheProgressChanged (_args: unknown): any {
}
onCleanCacheStorageChanged (args: unknown): any {
onCleanCacheStorageChanged (_args: unknown): any {
}
onFinishScan (args: unknown): any {
onFinishScan (_args: unknown): any {
}
onChatCleanDone (args: unknown): any {
onChatCleanDone (_args: unknown): any {
}
}

View File

@ -1,5 +1,5 @@
export class NodeIO3MiscListener {
getOnAmgomDataPiece (...arg: unknown[]): any {
getOnAmgomDataPiece (..._arg: unknown[]): any {
}
}

View File

@ -8,13 +8,13 @@ import { PacketLogger } from '@/core/packet/context/loggerContext';
import { OidbPacket, PacketBuf } from '@/core/packet/transformer/base';
export interface RecvPacket {
type: string, // 仅recv
data: RecvPacketData
data: RecvPacketData;
}
export interface RecvPacketData {
seq: number
cmd: string
data: Buffer
seq: number;
cmd: string;
data: Buffer;
}
// 0 send 1 recv
@ -29,7 +29,7 @@ export class NativePacketClient {
logStack: LogStack;
available: boolean = false;
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) {
this.napcore = napCore;
@ -73,7 +73,7 @@ export class NativePacketClient {
.sendSsoCmdReqByContend(cmd, data)
.catch(err =>
this.logger.error(
`[PacketClient] sendPacket 无响应命令发送失败 cmd=${cmd} err=${err}`
`[PacketClient] sendPacket 无响应命令发送失败 cmd=${cmd} err=${err}`
)
);
return { seq: 0, cmd, data: Buffer.alloc(0) };
@ -84,15 +84,15 @@ export class NativePacketClient {
.then(ret => ({
seq: 0,
cmd,
data: (ret as { rspbuffer: Buffer }).rspbuffer,
data: (ret as { rspbuffer: Buffer; }).rspbuffer,
}));
const timeoutPromise = new Promise<RecvPacketData>((_, reject) => {
const timeoutPromise = new Promise<RecvPacketData>((_resolve, reject) => {
setTimeout(
() =>
reject(
new Error(
`[PacketClient] sendPacket 超时 cmd=${cmd} timeout=${timeout}ms`
`[PacketClient] sendPacket 超时 cmd=${cmd} timeout=${timeout}ms`
)
),
timeout

View File

@ -21,16 +21,16 @@ import { PacketClientContext } from '@/core/packet/context/clientContext';
export const BlockSize = 1024 * 1024;
interface HighwayServerAddr {
ip: string
port: number
ip: string;
port: number;
}
export interface PacketHighwaySig {
uin: string;
uid: string;
sigSession: Uint8Array | null
sessionKey: Uint8Array | null
serverAddr: HighwayServerAddr[]
sigSession: Uint8Array | null;
sessionKey: Uint8Array | null;
serverAddr: HighwayServerAddr[];
}
export class PacketHighwayContext {
@ -142,7 +142,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = UploadGroupImage.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadGroupImageReq get upload ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const sha1 = Buffer.from(index.info.fileSha1, 'hex');
@ -179,7 +179,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = trans.UploadPrivateImage.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadC2CImageReq get upload ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const sha1 = Buffer.from(index.info.fileSha1, 'hex');
@ -217,7 +217,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = trans.UploadGroupVideo.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadGroupVideoReq get upload video ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');
@ -244,7 +244,7 @@ export class PacketHighwayContext {
this.logger.debug(`[Highway] uploadGroupVideoReq get upload invalid ukey ${ukey}, don't need upload!`);
}
const subFile = preRespData.upload.subFileInfos[0];
if (subFile!.uKey && subFile!.uKey != '') {
if (subFile!.uKey && subFile!.uKey !== '') {
this.logger.debug(`[Highway] uploadGroupVideoReq get upload video thumb ukey: ${subFile!.uKey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[1]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');
@ -282,7 +282,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = trans.UploadPrivateVideo.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadC2CVideoReq get upload video ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');
@ -309,7 +309,7 @@ export class PacketHighwayContext {
this.logger.debug(`[Highway] uploadC2CVideoReq get upload invalid ukey ${ukey}, don't need upload!`);
}
const subFile = preRespData.upload.subFileInfos[0];
if (subFile!.uKey && subFile!.uKey != '') {
if (subFile!.uKey && subFile!.uKey !== '') {
this.logger.debug(`[Highway] uploadC2CVideoReq get upload video thumb ukey: ${subFile!.uKey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[1]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');
@ -345,7 +345,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = trans.UploadGroupPtt.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadGroupPttReq get upload ptt ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');
@ -381,7 +381,7 @@ export class PacketHighwayContext {
const resp = await this.client.sendOidbPacket(req, true);
const preRespData = trans.UploadPrivatePtt.parse(resp);
const ukey = preRespData.upload.uKey;
if (ukey && ukey != '') {
if (ukey && ukey !== '') {
this.logger.debug(`[Highway] uploadC2CPttReq get upload ptt ukey: ${ukey}, need upload!`);
const index = preRespData.upload.msgInfo.msgInfoBody[0]!.index;
const md5 = Buffer.from(index.info.fileHash, 'hex');

View File

@ -60,7 +60,7 @@ export class HighwayTcpUploader extends IHighwayUploader {
socket.end();
reject(new Error('Upload aborted due to timeout'));
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [head, _] = Frame.unpack(chunk);
handleRspHeader(head);
});

View File

@ -1,4 +1,4 @@
import * as tea from '@/core/packet/utils/crypto/tea';
// import * as tea from '@/core/packet/utils/crypto/tea';
import { NapProtoMsg } from '@napneko/nap-proto-core';
import { PacketHighwayTrans } from '@/core/packet/highway/client';
import { PacketLogger } from '@/core/packet/context/loggerContext';
@ -13,13 +13,14 @@ export abstract class IHighwayUploader {
this.logger = logger;
}
private encryptTransExt (key: Uint8Array) {
if (!this.trans.encrypt) return;
this.trans.ext = tea.encrypt(Buffer.from(this.trans.ext), Buffer.from(key));
}
// TODO: 没用到的加密方法先注释掉
// private encryptTransExt (key: Uint8Array) {
// if (!this.trans.encrypt) return;
// this.trans.ext = tea.encrypt(Buffer.from(this.trans.ext), Buffer.from(key));
// }
protected timeout (): Promise<void> {
return new Promise<void>((_, reject) => {
return new Promise<void>((_resolve, reject) => {
setTimeout(() => {
reject(new Error(`[Highway] timeout after ${this.trans.timeout}s`));
}, (this.trans.timeout ?? Infinity) * 1000

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
class FetchAiVoiceList extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0X929D_0Resp> {
constructor () {
super();
}
build (groupUin: number, chatType: AIVoiceChatType): OidbPacket {
const data = new NapProtoMsg(proto.OidbSvcTrpcTcp0X929D_0).encode({
groupUin,

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { AIVoiceChatType } from '@/core/packet/entities/aiChat';
class GetAiVoice extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0X929B_0Resp> {
constructor () {
super();
}
build (groupUin: number, voiceId: string, text: string, sessionId: number, chatType: AIVoiceChatType): OidbPacket {
const data = new NapProtoMsg(proto.OidbSvcTrpcTcp0X929B_0).encode({
groupUin,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/t
import { MiniAppReqParams } from '@/core/packet/entities/miniApp';
class GetMiniAppAdaptShareInfo extends PacketTransformer<typeof proto.MiniAppAdaptShareInfoResp> {
constructor () {
super();
}
build (req: MiniAppReqParams): OidbPacket {
const data = new NapProtoMsg(proto.MiniAppAdaptShareInfoReq).encode({
appId: req.sdkId,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class GetStrangerInfo extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0XFE1_2RSP> {
constructor () {
super();
}
build (uin: number): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0XFE1_2).encode({
uin,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class GroupSign extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase> {
constructor () {
super();
}
build (uin: number, groupCode: number): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0XEB7).encode(
{

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class ImageOCR extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0xE07_0_Response> {
constructor () {
super();
}
build (url: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0xE07_0).encode(
{

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class MoveGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor () {
super();
}
build (groupUin: number, fileUUID: string, currentParentDirectory: string, targetParentDirectory: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
move: {

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class RenameGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor () {
super();
}
build (groupUin: number, fileUUID: string, currentParentDirectory: string, newName: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
rename: {

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class SendPoke extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase> {
constructor () {
super();
}
build (is_group: boolean, peer: number, target: number): OidbPacket {
const payload = {
uin: target,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class SetGroupTodo extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase> {
constructor () {
super();
}
build (peer: number, msgSeq: string): OidbPacket {
const data = new NapProtoMsg(proto.OidbSvcTrpcTcp0XF90_1).encode({
groupUin: peer,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class SetSpecialTitle extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase> {
constructor () {
super();
}
build (groupCode: number, uid: string, title: string): OidbPacket {
const oidb_0x8FC_2 = new NapProtoMsg(proto.OidbSvcTrpcTcp0X8FC_2).encode({
groupUin: +groupCode,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class DownloadGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor () {
super();
}
build (groupUin: number, fileUUID: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
download: {

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { IndexNode } from '@/core/packet/transformer/proto';
class DownloadGroupImage extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (group_uin: number, node: NapProtoEncodeStructType<typeof IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class DownloadGroupPtt extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (groupUin: number, node: NapProtoEncodeStructType<typeof proto.IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { IndexNode } from '@/core/packet/transformer/proto';
class DownloadGroupVideo extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (groupUin: number, node: NapProtoEncodeStructType<typeof IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { IndexNode } from '@/core/packet/transformer/proto';
class DownloadImage extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class DownloadOfflineFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0XE37Response> {
constructor () {
super();
}
build (fileUUID: string, fileHash: string, senderUid: string, receiverUid: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0XE37_800).encode({
subCommand: 800,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class DownloadPrivateFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0XE37_1200Response> {
constructor () {
super();
}
build (selfUid: string, fileUUID: string, fileHash: string): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0XE37_1200).encode({
subCommand: 1200,

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { IndexNode } from '@/core/packet/transformer/proto';
class DownloadPtt extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { IndexNode } from '@/core/packet/transformer/proto';
class DownloadVideo extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (selfUid: string, node: NapProtoEncodeStructType<typeof IndexNode>): OidbPacket {
const body = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -3,10 +3,6 @@ import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/transformer/base';
class FetchSessionKey extends PacketTransformer<typeof proto.HttpConn0x6ff_501Response> {
constructor () {
super();
}
build (): OidbPacket {
const req = new NapProtoMsg(proto.HttpConn0x6ff_501).encode({
httpConn: {

View File

@ -5,10 +5,6 @@ import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
import { PacketMsgFileElement } from '@/core/packet/message/element';
class UploadGroupFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0x6D6Response> {
constructor () {
super();
}
build (groupUin: number, file: PacketMsgFileElement): OidbPacket {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0x6D6).encode({
file: {

View File

@ -6,10 +6,6 @@ import crypto from 'node:crypto';
import { PacketMsgPicElement } from '@/core/packet/message/element';
class UploadGroupImage extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (groupUin: number, img: PacketMsgPicElement): OidbPacket {
const data = new NapProtoMsg(proto.NTV2RichMediaReq).encode(
{

View File

@ -6,10 +6,6 @@ import crypto from 'node:crypto';
import { PacketMsgVideoElement } from '@/core/packet/message/element';
class UploadGroupVideo extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (groupUin: number, video: PacketMsgVideoElement): OidbPacket {
if (!video.fileSize || !video.thumbSize) throw new Error('video.fileSize or video.thumbSize is empty');
const data = new NapProtoMsg(proto.NTV2RichMediaReq).encode({

View File

@ -6,10 +6,6 @@ import { PacketMsgFileElement } from '@/core/packet/message/element';
import { computeMd5AndLengthWithLimit } from '@/core/packet/utils/crypto/hash';
class UploadPrivateFile extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0XE37Response> {
constructor () {
super();
}
async build (selfUid: string, peerUid: string, file: PacketMsgFileElement): Promise<OidbPacket> {
const body = new NapProtoMsg(proto.OidbSvcTrpcTcp0XE37_1700).encode({
command: 1700,

View File

@ -6,10 +6,6 @@ import crypto from 'node:crypto';
import { PacketMsgPicElement } from '@/core/packet/message/element';
class UploadPrivateImage extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (peerUin: string, img: PacketMsgPicElement): OidbPacket {
const data = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -6,10 +6,6 @@ import crypto from 'node:crypto';
import { PacketMsgPttElement } from '@/core/packet/message/element';
class UploadPrivatePtt extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (peerUin: string, ptt: PacketMsgPttElement): OidbPacket {
const data = new NapProtoMsg(proto.NTV2RichMediaReq).encode({
reqHead: {

View File

@ -6,10 +6,6 @@ import crypto from 'node:crypto';
import { PacketMsgVideoElement } from '@/core/packet/message/element';
class UploadPrivateVideo extends PacketTransformer<typeof proto.NTV2RichMediaResp> {
constructor () {
super();
}
build (peerUin: string, video: PacketMsgVideoElement): OidbPacket {
if (!video.fileSize || !video.thumbSize) throw new Error('video.fileSize or video.thumbSize is empty');
const data = new NapProtoMsg(proto.NTV2RichMediaReq).encode({

View File

@ -3,10 +3,6 @@ import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/transformer/base';
class DownloadForwardMsg extends PacketTransformer<typeof proto.RecvLongMsgResp> {
constructor () {
super();
}
build (uid: string, resId: string): OidbPacket {
const req = new NapProtoMsg(proto.RecvLongMsgReq).encode({
info: {

View File

@ -3,10 +3,6 @@ import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/transformer/base';
class FetchC2CMessage extends PacketTransformer<typeof proto.SsoGetC2cMsgResponse> {
constructor () {
super();
}
build (targetUid: string, startSeq: number, endSeq: number): OidbPacket {
const req = new NapProtoMsg(proto.SsoGetC2cMsg).encode({
friendUid: targetUid,

View File

@ -3,10 +3,6 @@ import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/transformer/base';
class FetchGroupMessage extends PacketTransformer<typeof proto.SsoGetGroupMsgResponse> {
constructor () {
super();
}
build (groupUin: number, startSeq: number, endSeq: number): OidbPacket {
const req = new NapProtoMsg(proto.SsoGetGroupMsg).encode({
info: {

View File

@ -5,10 +5,6 @@ import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/t
import { PacketMsg } from '@/core/packet/message/message';
class UploadForwardMsg extends PacketTransformer<typeof proto.SendLongMsgResp> {
constructor () {
super();
}
build (selfUid: string, msg: PacketMsg[], groupUin: number = 0): OidbPacket {
const msgBody = this.msgBuilder.buildFakeMsg(selfUid, msg);
const longMsgResultData = new NapProtoMsg(proto.LongMsgResult).encode(

View File

@ -3,10 +3,6 @@ import { NapProtoMsg } from '@napneko/nap-proto-core';
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/core/packet/transformer/base';
class OidbBase extends PacketTransformer<typeof proto.OidbSvcTrpcTcpBase> {
constructor () {
super();
}
build (cmd: number, subCmd: number, body: Uint8Array, isUid: boolean = true, _isLafter: boolean = false): OidbPacket {
const data = new NapProtoMsg(proto.OidbSvcTrpcTcpBase).encode({
command: cmd,

View File

@ -4,10 +4,6 @@ import { OidbPacket, PacketTransformer } from '@/core/packet/transformer/base';
import OidbBase from '@/core/packet/transformer/oidb/oidbBase';
class FetchRkey extends PacketTransformer<typeof proto.OidbSvcTrpcTcp0X9067_202_Rsp_Body> {
constructor () {
super();
}
build (): OidbPacket {
const data = new NapProtoMsg(proto.OidbSvcTrpcTcp0X9067_202).encode({
reqHead: {

View File

@ -1,19 +1,19 @@
//LiteLoader需要提供部分IPC接口以便于其他插件调用
// LiteLoader需要提供部分IPC接口以便于其他插件调用
const { ipcMain, BrowserWindow } = require('electron');
const napcat = require('./napcat.cjs');
const { shell } = require('electron');
ipcMain.handle('napcat_get_webui', async () => {
return napcat.NCgetWebUiUrl();
return napcat.NCgetWebUiUrl();
});
ipcMain.on('open_external_url', (event, url) => {
shell.openExternal(url);
shell.openExternal(url);
});
ipcMain.on('napcat_open_inner_url', (event, url) => {
const win = new BrowserWindow({
autoHideMenuBar: true,
});
win.loadURL(url);
win.webContents.setWindowOpenHandler(details => {
win.loadURL(details.url)
})
});
const win = new BrowserWindow({
autoHideMenuBar: true,
});
win.loadURL(url);
win.webContents.setWindowOpenHandler(details => {
win.loadURL(details.url);
});
});

View File

@ -1,6 +1,6 @@
let process = require('process');
let os = require('os');
let path = require('path');
const process = require('process');
const os = require('os');
const path = require('path');
// 保存原始dlopen
const dlopenOrig = process.dlopen;
@ -12,82 +12,81 @@ let getWebUiUrlFunc;
let ncCallback = () => { };
let napCatInitialized = false; // 添加一个标志
function createServiceProxy(ServiceName) {
return new Proxy(() => { }, {
get: (target, FunctionName) => {
if (ServiceName === 'NodeIQQNTWrapperSession' && FunctionName === 'create') {
return () => new Proxy({}, {
get: function (target, ClassFunName, receiver) {
return function () {
if (ClassFunName === 'init') {
let origin = arguments[3].onOpentelemetryInit;
arguments[3].onOpentelemetryInit = function (result) {
origin(...arguments);
if (result.is_init) {
ncCallback();
}
}
}
let ret = wrapperSession[ClassFunName](...arguments);
return ret;
}
}
});
}
if (ServiceName === 'NodeIKernelLoginService' && FunctionName === 'get') {
return () => wrapperLoginService;
}
return wrapperNodeApi[ServiceName][FunctionName];
}
});
function createServiceProxy (ServiceName) {
return new Proxy(() => { }, {
get: (target, FunctionName) => {
if (ServiceName === 'NodeIQQNTWrapperSession' && FunctionName === 'create') {
return () => new Proxy({}, {
get: function (target, ClassFunName, receiver) {
return function () {
if (ClassFunName === 'init') {
const origin = arguments[3].onOpentelemetryInit;
arguments[3].onOpentelemetryInit = function (result) {
origin(...arguments);
if (result.is_init) {
ncCallback();
}
};
}
const ret = wrapperSession[ClassFunName](...arguments);
return ret;
};
},
});
}
if (ServiceName === 'NodeIKernelLoginService' && FunctionName === 'get') {
return () => wrapperLoginService;
}
return wrapperNodeApi[ServiceName][FunctionName];
},
});
}
function clearHook() {
process.dlopen = dlopenOrig;
function clearHook () {
process.dlopen = dlopenOrig;
}
async function initializeNapCat() {
console.log('[NapCat] [Info] 开始初始化NapCat');
try {
const currentPath = path.dirname(__filename);
const { NCoreInitFramework, getWebUiUrl } = await import('file://' + path.join(currentPath, './napcat.mjs'));
getWebUiUrlFunc = getWebUiUrl;
await NCoreInitFramework(wrapperSession, wrapperLoginService, (callback) => { ncCallback = callback });
} catch (error) {
console.log('[NapCat] [Error] 初始化NapCat', error);
}
async function initializeNapCat () {
console.log('[NapCat] [Info] 开始初始化NapCat');
try {
const currentPath = path.dirname(__filename);
const { NCoreInitFramework, getWebUiUrl } = await import('file://' + path.join(currentPath, './napcat.mjs'));
getWebUiUrlFunc = getWebUiUrl;
await NCoreInitFramework(wrapperSession, wrapperLoginService, (callback) => { ncCallback = callback; });
} catch (error) {
console.log('[NapCat] [Error] 初始化NapCat', error);
}
}
process.dlopen = function (module, filename, flags = os.constants.dlopen.RTLD_LAZY) {
const dlopenRet = dlopenOrig(module, filename, flags);
if (!filename.includes('wrapper.node') || napCatInitialized) return dlopenRet;
napCatInitialized = true; // 初始化完成后设置标志
clearHook();
wrapperNodeApi = module.exports;
wrapperLoginService = wrapperNodeApi.NodeIKernelLoginService.get();
wrapperSession = wrapperNodeApi.NodeIQQNTWrapperSession.create();
const dlopenRet = dlopenOrig(module, filename, flags);
if (!filename.includes('wrapper.node') || napCatInitialized) return dlopenRet;
napCatInitialized = true; // 初始化完成后设置标志
clearHook();
wrapperNodeApi = module.exports;
wrapperLoginService = wrapperNodeApi.NodeIKernelLoginService.get();
wrapperSession = wrapperNodeApi.NodeIQQNTWrapperSession.create();
initializeNapCat().then().catch();
initializeNapCat().then().catch();
module.exports = new Proxy({}, {
get: (target, ServiceName) => {
if (ServiceName === 'NodeIKernelLoginService' || ServiceName === 'NodeIQQNTWrapperSession') {
return createServiceProxy(ServiceName);
}
return wrapperNodeApi[ServiceName];
}
});
module.exports = new Proxy({}, {
get: (target, ServiceName) => {
if (ServiceName === 'NodeIKernelLoginService' || ServiceName === 'NodeIQQNTWrapperSession') {
return createServiceProxy(ServiceName);
}
return wrapperNodeApi[ServiceName];
},
});
return dlopenRet;
return dlopenRet;
};
module.exports = {
NCgetWebUiUrl: async () => {
if (!getWebUiUrlFunc) {
console.log('[NapCat] [Error] 未初始化完成');
return '';
}
return await getWebUiUrlFunc();
NCgetWebUiUrl: async () => {
if (!getWebUiUrlFunc) {
console.log('[NapCat] [Error] 未初始化完成');
return '';
}
};
return await getWebUiUrlFunc();
},
};

View File

@ -54,13 +54,13 @@ export async function NCoreInitFramework (
// nick: '',
// online: true
// }
const selfInfo = await new Promise<SelfInfo>((resolveSelfInfo) => {
const selfInfo = await new Promise<SelfInfo>((resolve) => {
const loginListener = new NodeIKernelLoginListener();
loginListener.onQRCodeLoginSucceed = async (loginResult) => {
await new Promise<void>(resolvePendingInit => {
registerInitCallback(() => resolvePendingInit());
await new Promise<void>(resolve => {
registerInitCallback(() => resolve());
});
resolveSelfInfo({
resolve({
uid: loginResult.uid,
uin: loginResult.uin,
nick: '', // 获取不到
@ -69,9 +69,9 @@ export async function NCoreInitFramework (
};
loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger));
});
// 过早进入会导致addKernelMsgListener等Listener添加失败
// await sleep(2500);
// 初始化 NapCatFramework
// 过早进入会导致addKernelMsgListener等Listener添加失败
// await sleep(2500);
// 初始化 NapCatFramework
const loaderObject = new NapCatFramework(wrapper, session, logger, loginService, selfInfo, basicInfoWrapper, pathWrapper, nativePacketHandler);
await loaderObject.core.initCore();

View File

@ -1,26 +1,25 @@
const fs = require('fs');
// const fs = require('fs');
const path = require('path');
async function initializeNapCat(session, loginService, registerCallback) {
//const logFile = path.join(currentPath, 'napcat.log');
async function initializeNapCat (session, loginService, registerCallback) {
// const logFile = path.join(currentPath, 'napcat.log');
console.log('[NapCat] [Info] 开始初始化NapCat');
console.log('[NapCat] [Info] 开始初始化NapCat');
//fs.writeFileSync(logFile, '', { flag: 'w' });
// fs.writeFileSync(logFile, '', { flag: 'w' });
//fs.writeFileSync(logFile, '[NapCat] [Info] NapCat 初始化成功\n', { flag: 'a' });
// fs.writeFileSync(logFile, '[NapCat] [Info] NapCat 初始化成功\n', { flag: 'a' });
try {
const currentPath = path.dirname(__filename);
const { NCoreInitFramework } = await import('file://' + path.join(currentPath, './napcat.mjs'));
await NCoreInitFramework(session, loginService, (callback) => { registerCallback(callback) });
} catch (error) {
console.log('[NapCat] [Error] 初始化NapCat', error);
//fs.writeFileSync(logFile, `[NapCat] [Error] 初始化NapCat失败: ${error.message}\n`, { flag: 'a' });
}
try {
const currentPath = path.dirname(__filename);
const { NCoreInitFramework } = await import('file://' + path.join(currentPath, './napcat.mjs'));
await NCoreInitFramework(session, loginService, (callback) => { registerCallback(callback); });
} catch (error) {
console.log('[NapCat] [Error] 初始化NapCat', error);
// fs.writeFileSync(logFile, `[NapCat] [Error] 初始化NapCat失败: ${error.message}\n`, { flag: 'a' });
}
}
module.exports = {
initializeNapCat: initializeNapCat
};
initializeNapCat,
};

View File

@ -1,14 +1,14 @@
const { contextBridge, ipcRenderer } = require('electron');
const napcat = {
getWebUiUrl: async () => {
return ipcRenderer.invoke('napcat_get_webui');
},
openExternalUrl: async (url) => {
ipcRenderer.send('open_external_url', url);
},
openInnerUrl: async (url) => {
ipcRenderer.send('napcat_open_inner_url', url);
}
getWebUiUrl: async () => {
return ipcRenderer.invoke('napcat_get_webui');
},
openExternalUrl: async (url) => {
ipcRenderer.send('open_external_url', url);
},
openInnerUrl: async (url) => {
ipcRenderer.send('napcat_open_inner_url', url);
},
};
// 在window对象下导出只读对象
contextBridge.exposeInMainWorld('napcat', napcat);
contextBridge.exposeInMainWorld('napcat', napcat);

View File

@ -32,6 +32,7 @@ export const onSettingWindowCreated = async (view) => {
view.querySelector('.nc_webui').addEventListener('click', async () => {
try {
await navigator.clipboard.writeText(webui);
// eslint-disable-next-line no-undef
alert('WebUi URL 已复制到剪贴板');
} catch (err) {
console.error('复制到剪贴板失败: ', err);

View File

@ -20,7 +20,7 @@ export default class SetGroupAddOption extends OneBotAction<Payload, null> {
groupQuestion: payload.group_question,
groupAnswer: payload.group_answer,
});
if (ret.result != 0) {
if (ret.result !== 0) {
throw new Error(`设置群添加选项失败, ${ret.result}:${ret.errMsg}`);
}
return null;

View File

@ -15,7 +15,7 @@ export default class SetGroupKickMembers extends OneBotAction<Payload, null> {
override payloadSchema = SchemaData;
async _handle (payload: Payload): Promise<null> {
const rejectReq = payload.reject_add_request?.toString() == 'true';
const rejectReq = payload.reject_add_request?.toString() === 'true';
const uids: string[] = await Promise.all(payload.user_id.map(async uin => await this.core.apis.UserApi.getUidByUinV2(uin)));
await this.core.apis.GroupApi.kickMember(payload.group_id.toString(), uids.filter(uid => !!uid), rejectReq);
return null;

View File

@ -14,7 +14,7 @@ export default class SetGroupRemark extends OneBotAction<Payload, null> {
override payloadSchema = SchemaData;
async _handle (payload: Payload): Promise<null> {
const ret = await this.core.apis.GroupApi.setGroupRemark(payload.group_id, payload.remark);
if (ret.result != 0) {
if (ret.result !== 0) {
throw new Error(`设置群备注失败, ${ret.result}:${ret.errMsg}`);
}
return null;

View File

@ -19,7 +19,7 @@ export default class SetGroupRobotAddOption extends OneBotAction<Payload, null>
payload.robot_member_switch,
payload.robot_member_examine
);
if (ret.result != 0) {
if (ret.result !== 0) {
throw new Error(`设置群机器人添加选项失败, ${ret.result}:${ret.errMsg}`);
}
return null;

View File

@ -18,7 +18,7 @@ export default class SetGroupSearch extends OneBotAction<Payload, null> {
noCodeFingerOpenFlag: payload.no_code_finger_open,
noFingerOpenFlag: payload.no_finger_open,
});
if (ret.result != 0) {
if (ret.result !== 0) {
throw new Error(`设置群搜索失败, ${ret.result}:${ret.errMsg}`);
}
return null;

View File

@ -26,9 +26,9 @@ export default class SetAvatar extends OneBotAction<Payload, null> {
throw new Error(`头像${payload.file}设置失败,api无返回`);
}
// log(`头像设置返回:${JSON.stringify(ret)}`)
if (ret.result as number == 1004022) {
if (ret.result as number === 1004022) {
throw new Error(`头像${payload.file}设置失败,文件可能不是图片格式`);
} else if (ret.result != 0) {
} else if (ret.result !== 0) {
throw new Error(`头像${payload.file}设置失败,未知的错误,${ret.result}:${ret.errMsg}`);
}
} else {

View File

@ -10,7 +10,17 @@ const SchemaData = Type.Object({
type Payload = Static<typeof SchemaData>;
export class GetGroupHonorInfo extends OneBotAction<Payload, Array<unknown>> {
interface HonorInfo {
group_id: number;
current_talkative: Record<string, unknown>;
talkative_list: unknown[];
performer_list: unknown[];
legend_list: unknown[];
emotion_list: unknown[];
strong_newbie_list: unknown[];
}
export class GetGroupHonorInfo extends OneBotAction<Payload, HonorInfo> {
override actionName = ActionName.GetGroupHonorInfo;
override payloadSchema = SchemaData;

View File

@ -21,7 +21,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
override actionName = ActionName.GoCQHTTP_SendGroupNotice;
override payloadSchema = SchemaData;
async _handle (payload: Payload) {
let UploadImage: { id: string, width: number, height: number } | undefined;
let UploadImage: { id: string, width: number, height: number; } | undefined;
if (payload.image) {
// 公告图逻辑
const {
@ -36,7 +36,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
}
await checkFileExist(path, 5000);
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
if (ImageUploadResult.errCode != 0) {
if (ImageUploadResult.errCode !== 0) {
throw new Error(`群公告${payload.image}设置失败,图片上传失败`);
}
@ -56,7 +56,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
UploadImage?.width,
UploadImage?.height
);
if (!publishGroupBulletinResult || publishGroupBulletinResult.ec != 0) {
if (!publishGroupBulletinResult || publishGroupBulletinResult.ec !== 0) {
throw new Error(`设置群公告失败,错误信息:${publishGroupBulletinResult?.em}`);
}
return null;

View File

@ -27,9 +27,9 @@ export default class SetGroupPortrait extends OneBotAction<Payload, GeneralCallR
if (!ret) {
throw new Error(`头像${payload.file}设置失败,api无返回`);
}
if (ret.result as number == 1004022) {
if (ret.result as number === 1004022) {
throw new Error(`头像${payload.file}设置失败,文件可能不是图片格式或权限不足`);
} else if (ret.result != 0) {
} else if (ret.result !== 0) {
throw new Error(`头像${payload.file}设置失败,未知的错误,${ret.result}:${ret.errMsg}`);
}
return ret;

View File

@ -15,7 +15,7 @@ class GetGroupInfo extends OneBotAction<Payload, OB11Group> {
override payloadSchema = SchemaData;
async _handle (payload: Payload) {
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode === payload.group_id.toString());
if (!group) {
const data = await this.core.apis.GroupApi.fetchGroupDetail(payload.group_id.toString());
if (data.ownerUid && data.ownerUin === '0') {

View File

@ -42,11 +42,11 @@ export default class SetGroupAddRequest extends OneBotAction<Payload, null> {
private async findNotify (flag: string, count: number = 100): Promise<{
doubt: boolean,
notify: GroupNotify | undefined
notify: GroupNotify | undefined;
}> {
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, count)).find(e => e.seq == flag);
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, count)).find(e => e.seq === flag);
if (!notify) {
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, count)).find(e => e.seq == flag);
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, count)).find(e => e.seq === flag);
return { doubt: true, notify };
}
return { doubt: false, notify };

View File

@ -15,7 +15,7 @@ export default class SetGroupKick extends OneBotAction<Payload, null> {
override payloadSchema = SchemaData;
async _handle (payload: Payload): Promise<null> {
const rejectReq = payload.reject_add_request?.toString() == 'true';
const rejectReq = payload.reject_add_request?.toString() === 'true';
const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error');
await this.core.apis.GroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq);

View File

@ -2,7 +2,6 @@ import { OB11Message } from '@/onebot';
import { OneBotAction } from '@/onebot/action/OneBotAction';
import { ActionName } from '@/onebot/action/router';
import { MessageUnique } from '@/common/message-unique';
import { RawMessage } from '@/core';
import { Static, Type } from '@sinclair/typebox';
import { NetworkAdapterConfig } from '@/onebot/config/config';
@ -29,11 +28,10 @@ class GetMsg extends OneBotAction<Payload, OB11Message> {
}
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
// const orimsg = this.obContext.recallMsgCache.get(msgIdWithPeer.MsgId);
let msg: RawMessage | undefined;
// if (orimsg) {
// msg = orimsg;
// } else {
msg = (await this.core.apis.MsgApi.getMsgsByMsgId(peer, [msgIdWithPeer?.MsgId || payload.message_id.toString()])).msgList[0];
const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(peer, [msgIdWithPeer?.MsgId || payload.message_id.toString()])).msgList[0];
// }
if (!msg) throw Error('消息不存在');
const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg, config.messagePostFormat);

View File

@ -40,7 +40,7 @@ class MarkMsgAsRead extends OneBotAction<PlayloadType, null> {
async _handle (payload: PlayloadType): Promise<null> {
const ret = await this.core.apis.MsgApi.setMsgRead(await this.getPeer(payload));
if (ret.result != 0) {
if (ret.result !== 0) {
throw new Error('设置已读失败,' + ret.errMsg);
}
return null;

View File

@ -101,7 +101,7 @@ export async function createContext (core: NapCatCore, payload: OB11PostContext
function getSpecialMsgNum (payload: OB11PostSendMsg, msgType: OB11MessageDataType): number {
if (Array.isArray(payload.message)) {
return payload.message.filter(msg => msg.type == msgType).length;
return payload.message.filter(msg => msg.type === msgType).length;
}
return 0;
}
@ -110,7 +110,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
protected override async check (payload: OB11PostSendMsg): Promise<BaseCheckResult> {
const messages = normalize(payload.message);
const nodeElementLength = getSpecialMsgNum(payload, OB11MessageDataType.node);
if (nodeElementLength > 0 && nodeElementLength != messages.length) {
if (nodeElementLength > 0 && nodeElementLength !== messages.length) {
return {
valid: false,
message: '转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素',
@ -135,7 +135,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
if (getSpecialMsgNum(payload, OB11MessageDataType.node)) {
const packetMode = this.core.apis.PacketApi.packetStatus;
let returnMsgAndResId: { message: RawMessage | null, res_id?: string } | null;
let returnMsgAndResId: { message: RawMessage | null, res_id?: string; } | null;
try {
returnMsgAndResId = packetMode
? await this.handleForwardedNodesPacket(peer, messages as OB11MessageNode[], payload.source, payload.news, payload.summary, payload.prompt)
@ -175,7 +175,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
}
private async uploadForwardedNodesPacket (msgPeer: Peer, messageNodes: OB11MessageNode[], source?: string, news?: {
text: string
text: string;
}[], summary?: string, prompt?: string, parentMeta?: {
user_id: string,
nickname: string,
@ -259,10 +259,10 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
}
private async handleForwardedNodesPacket (msgPeer: Peer, messageNodes: OB11MessageNode[], source?: string, news?: {
text: string
text: string;
}[], summary?: string, prompt?: string): Promise<{
message: RawMessage | null,
res_id?: string
res_id?: string;
}> {
const uploadReturnData = await this.uploadForwardedNodesPacket(msgPeer, messageNodes, source, news, summary, prompt);
const res_id = uploadReturnData?.res_id;
@ -274,7 +274,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
private async handleForwardedNodes (destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<{
message: RawMessage | null,
res_id?: string
res_id?: string;
}> {
const selfPeer = {
chatType: ChatType.KCHATTYPEC2C,
@ -334,6 +334,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
nodeMsgIds.push(result.value.msgId);
MessageUnique.createUniqueMsgId(selfPeer, result.value.msgId);
}
return result;
});
} catch (e: unknown) {
this.core.context.logger.logDebug('生成转发消息节点失败', (e as Error).stack);
@ -406,6 +407,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements);
} catch (e: unknown) {
this.core.context.logger.logError((e as Error)?.stack, '克隆转发消息失败,将忽略本条消息', msg);
return undefined;
}
}
}

View File

@ -16,7 +16,7 @@ export default class SetFriendAddRequest extends OneBotAction<Payload, null> {
async _handle (payload: Payload): Promise<null> {
const approve = payload.approve?.toString() !== 'false';
const notify = (await this.core.apis.FriendApi.getBuddyReq()).buddyReqs.find(e => e.reqTime == payload.flag.toString());
const notify = (await this.core.apis.FriendApi.getBuddyReq()).buddyReqs.find(e => e.reqTime === payload.flag.toString());
if (!notify) {
throw new Error('No such request');
}

View File

@ -13,10 +13,10 @@ export class OneBotFriendApi {
// 使用前预先判断 busiId 1061
async parsePrivatePokeEvent (grayTipElement: GrayTipElement, uin: number) {
const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr);
const pokedetail: Array<{ uid: string }> = json.items;
const pokedetail: Array<{ uid: string; }> = json.items;
// 筛选item带有uid的元素
const poke_uid = pokedetail.filter(item => item.uid);
if (poke_uid.length == 2 && poke_uid[0]?.uid && poke_uid[1]?.uid) {
if (poke_uid.length === 2 && poke_uid[0]?.uid && poke_uid[1]?.uid) {
return new OB11FriendPokeEvent(
this.core,
uin,

View File

@ -176,10 +176,10 @@ export class OneBotGroupApi {
const json = JSON.parse(jsonStr);
// 判断业务类型
// Poke事件
const pokedetail: Array<{ uid: string }> = json.items;
const pokedetail: Array<{ uid: string; }> = json.items;
// 筛选item带有uid的元素
const poke_uid = pokedetail.filter(item => item.uid);
if (poke_uid.length == 2 && poke_uid[0]?.uid && poke_uid[1]?.uid) {
if (poke_uid.length === 2 && poke_uid[0]?.uid && poke_uid[1]?.uid) {
return new OB11GroupPokeEvent(
this.core,
parseInt(msg.peerUid),
@ -210,6 +210,7 @@ export class OneBotGroupApi {
} else {
context.logger.logWarn('收到未知的灰条消息', json);
}
return undefined;
}
async parseEssenceMsg (msg: RawMessage, jsonStr: string) {
@ -217,7 +218,7 @@ export class OneBotGroupApi {
const searchParams = new URL(json.items[0].jp).searchParams;
const msgSeq = searchParams.get('msgSeq')!;
const Group = searchParams.get('groupCode');
if (!Group) return;
if (!Group) return undefined;
// const businessId = searchParams.get('businessid');
const Peer = {
guildId: '',
@ -226,7 +227,7 @@ export class OneBotGroupApi {
};
const msgData = await this.core.apis.MsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list);
const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq);
const realMsg = msgList.find((e) => e.msg_seq.toString() === msgSeq);
if (msgData.msgList[0]) {
return new OB11GroupEssenceEvent(
this.core,
@ -236,7 +237,7 @@ export class OneBotGroupApi {
parseInt(realMsg?.add_digest_uin ?? '0')
);
}
return undefined;
// 获取MsgSeq+Peer可获取具体消息
}
@ -270,7 +271,7 @@ export class OneBotGroupApi {
return event;
} else if (element.type === TipGroupElementType.KMEMBERADD) {
// 自己的通知 协议推送为type->85 在这里实现为了避免邀请出现问题
if (element.memberUid == this.core.selfInfo.uid) {
if (element.memberUid === this.core.selfInfo.uid) {
await this.core.apis.GroupApi.refreshGroupMemberCache(msg.peerUid, true);
return new OB11GroupIncreaseEvent(
this.core,
@ -281,6 +282,7 @@ export class OneBotGroupApi {
);
}
}
return undefined;
}
async parseSelfInviteEvent (msg: RawMessage, inviterUin: string, inviteeUin: string) {
@ -299,7 +301,7 @@ export class OneBotGroupApi {
if (grayTipElement.jsonGrayTipElement.jsonStr) {
const json: {
align: string,
items: Array<{ txt: string, type: string }>
items: Array<{ txt: string, type: string; }>;
} = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr);
if (json.items.length === 1 && json.items[0]?.txt.endsWith('加入群')) {
const old_members = structuredClone(this.core.apis.GroupApi.groupMemberCache.get(msg.peerUid));
@ -308,7 +310,7 @@ export class OneBotGroupApi {
if (!new_members_map) return;
const new_members = Array.from(new_members_map.values());
// 对比members查找新成员
const new_member = new_members.find((member) => old_members.get(member.uid) == undefined);
const new_member = new_members.find((member) => old_members.get(member.uid) === undefined);
if (!new_member) return;
return new OB11GroupIncreaseEvent(
this.core,
@ -319,6 +321,7 @@ export class OneBotGroupApi {
);
}
}
return undefined;
}
async parseGrayTipElement (msg: RawMessage, grayTipElement: GrayTipElement) {
@ -346,13 +349,13 @@ export class OneBotGroupApi {
} else {
// return await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement);
}
} else if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
} else if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
// 解析json事件
if (grayTipElement.jsonGrayTipElement.busiId == 1061) {
if (grayTipElement.jsonGrayTipElement.busiId === 1061) {
return await this.parsePaiYiPai(msg, grayTipElement.jsonGrayTipElement.jsonStr);
} else if (grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) {
} else if (grayTipElement.jsonGrayTipElement.busiId === JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) {
return await this.parseEssenceMsg(msg, grayTipElement.jsonGrayTipElement.jsonStr);
} else if (+(grayTipElement.jsonGrayTipElement.busiId ?? 0) == 51) {
} else if (+(grayTipElement.jsonGrayTipElement.busiId ?? 0) === 51) {
// 51是什么{"align":"center","items":[{"txt":"下一秒起床通过王者荣耀加入群","type":"nor"}]
return await this.parse51TypeEvent(msg, grayTipElement);
} else {

View File

@ -59,20 +59,20 @@ type RawToOb11Converters = {
type Ob11ToRawConverters = {
[Key in OB11MessageDataType]: (
sendMsg: Extract<OB11MessageData, { type: Key }>,
sendMsg: Extract<OB11MessageData, { type: Key; }>,
context: SendMessageContext,
) => Promise<SendMessageElement | undefined>
};
export type SendMessageContext = {
deleteAfterSentFiles: string[],
peer: Peer
peer: Peer;
};
export type RecvMessageContext = {
parseMultMsg: boolean,
disableGetUrl: boolean,
quick_reply: boolean
quick_reply: boolean;
};
function keyCanBeParsed (key: string, parser: RawToOb11Converters): key is keyof RawToOb11Converters {
@ -138,6 +138,7 @@ export class OneBotMsgApi {
};
} catch (e) {
this.core.context.logger.logError('获取图片url失败', (e as Error).stack);
return null;
}
},
@ -167,7 +168,7 @@ export class OneBotMsgApi {
maxHealthCheckFailures: 3,
}
);
} catch (error) {
} catch (_error) {
url = '';
}
if (url) {
@ -194,7 +195,7 @@ export class OneBotMsgApi {
faceElement: async element => {
const faceIndex = element.faceIndex;
if (element.faceType == FaceType.Poke) {
if (element.faceType === FaceType.Poke) {
return {
type: OB11MessageDataType.poke,
data: {
@ -574,7 +575,7 @@ export class OneBotMsgApi {
};
}
if (!context.peer || !atQQ || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined; // 过滤掉空atQQ
if (!context.peer || !atQQ || context.peer.chatType === ChatType.KCHATTYPEC2C) return undefined; // 过滤掉空atQQ
if (atQQ === 'all') return at(atQQ, atQQ, NTMsgAtType.ATTYPEALL, '全体成员');
const atMember = await this.core.apis.GroupApi.getGroupMember(context.peer.peerUid, atQQ);
if (atMember) {
@ -861,7 +862,7 @@ export class OneBotMsgApi {
parseTextWithJson (text: string) {
// 匹配<{...}>格式的JSON
const regex = /<(\{.*?\})>/g;
const parts: Array<{ type: 'text' | 'json', content: string | object }> = [];
const parts: Array<{ type: 'text' | 'json', content: string | object; }> = [];
let lastIndex = 0;
let match;
@ -882,7 +883,7 @@ export class OneBotMsgApi {
type: 'json',
content: jsonContent,
});
} catch (e) {
} catch (_e) {
// 如果JSON解析失败作为普通文本处理
parts.push({
type: 'text',
@ -905,16 +906,17 @@ export class OneBotMsgApi {
}
async parsePrivateMsgEvent (msg: RawMessage, grayTipElement: GrayTipElement) {
if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
if (grayTipElement.jsonGrayTipElement.busiId == 1061) {
if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
if (grayTipElement.jsonGrayTipElement.busiId === 1061) {
const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
if (PokeEvent) {
return PokeEvent;
}
} else if (grayTipElement.jsonGrayTipElement.busiId == 19324 && msg.peerUid !== '') {
} else if (grayTipElement.jsonGrayTipElement.busiId === 19324 && msg.peerUid !== '') {
return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
}
}
return undefined;
}
private async getMultiMessages (msg: RawMessage, parentMsgPeer: Peer) {
@ -967,20 +969,20 @@ export class OneBotMsgApi {
disableGetUrl: boolean = false,
quick_reply: boolean = false
) {
if (msg.senderUin == '0' || msg.senderUin == '') return;
if (msg.peerUin == '0' || msg.peerUin == '') return;
if (msg.senderUin === '0' || msg.senderUin === '') return;
if (msg.peerUin === '0' || msg.peerUin === '') return;
const resMsg = this.initializeMessage(msg);
if (this.core.selfInfo.uin == msg.senderUin) {
if (this.core.selfInfo.uin === msg.senderUin) {
resMsg.message_sent_type = 'self';
}
if (msg.chatType == ChatType.KCHATTYPEGROUP) {
if (msg.chatType === ChatType.KCHATTYPEGROUP) {
await this.handleGroupMessage(resMsg, msg);
} else if (msg.chatType == ChatType.KCHATTYPEC2C) {
} else if (msg.chatType === ChatType.KCHATTYPEC2C) {
await this.handlePrivateMessage(resMsg, msg);
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
} else if (msg.chatType === ChatType.KCHATTYPETEMPC2CFROMGROUP) {
await this.handleTempGroupMessage(resMsg, msg);
} else {
return undefined;
@ -1003,7 +1005,7 @@ export class OneBotMsgApi {
message_seq: msg.id!,
real_id: msg.id!,
real_seq: msg.msgSeq,
message_type: msg.chatType == ChatType.KCHATTYPEGROUP ? 'group' : 'private',
message_type: msg.chatType === ChatType.KCHATTYPEGROUP ? 'group' : 'private',
sender: {
user_id: +(msg.senderUin ?? 0),
nickname: msg.sendNickName,
@ -1014,7 +1016,7 @@ export class OneBotMsgApi {
sub_type: 'friend',
message: [],
message_format: 'array',
post_type: this.core.selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
post_type: this.core.selfInfo.uin === msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE,
};
}
@ -1059,7 +1061,7 @@ export class OneBotMsgApi {
private async parseMessageSegments (msg: RawMessage, parseMultMsg: boolean, disableGetUrl: boolean = false, quick_reply: boolean = false): Promise<OB11MessageData[]> {
const msgSegments = await Promise.allSettled(msg.elements.map(
async (element) => {
async (element): Promise<OB11MessageData | null> => {
for (const key in element) {
if (keyCanBeParsed(key, this.rawToOb11Converters) && element[key]) {
const converters = this.rawToOb11Converters[key] as (
@ -1080,6 +1082,7 @@ export class OneBotMsgApi {
return parsedElement;
}
}
return null;
}
));
@ -1119,10 +1122,10 @@ export class OneBotMsgApi {
continue;
}
const converter = this.ob11ToRawConverters[sendMsg.type] as ((
sendMsg: Extract<OB11MessageData, { type: OB11MessageData['type'] }>,
sendMsg: Extract<OB11MessageData, { type: OB11MessageData['type']; }>,
context: SendMessageContext,
) => Promise<SendMessageElement | undefined>) | undefined;
if (converter == undefined) {
if (converter === undefined) {
throw new Error('未知的消息类型:' + sendMsg.type);
}
const callResult = converter(
@ -1175,8 +1178,6 @@ export class OneBotMsgApi {
peerUid: peer.peerUid,
}, returnMsg.msgId);
return returnMsg;
} catch (error) {
throw error;
} finally {
cleanTaskQueue.addFiles(deleteAfterSentFiles, timeout);
// setTimeout(async () => {
@ -1228,12 +1229,12 @@ export class OneBotMsgApi {
let url = '';
if (mixElement?.picElement && rawMessage) {
const tempData =
await this.obContext.apis.MsgApi.rawToOb11Converters.picElement?.(mixElement?.picElement, rawMessage, mixElement, { parseMultMsg: false, disableGetUrl: false, quick_reply: false }) as OB11MessageImage | undefined;
await this.obContext.apis.MsgApi.rawToOb11Converters.picElement?.(mixElement?.picElement, rawMessage, mixElement, { parseMultMsg: false, disableGetUrl: false, quick_reply: false }) as OB11MessageImage | undefined;
url = tempData?.data.url ?? '';
}
if (mixElement?.videoElement && rawMessage) {
const tempData =
await this.obContext.apis.MsgApi.rawToOb11Converters.videoElement?.(mixElement?.videoElement, rawMessage, mixElement, { parseMultMsg: false, disableGetUrl: false, quick_reply: false }) as OB11MessageVideo | undefined;
await this.obContext.apis.MsgApi.rawToOb11Converters.videoElement?.(mixElement?.videoElement, rawMessage, mixElement, { parseMultMsg: false, disableGetUrl: false, quick_reply: false }) as OB11MessageVideo | undefined;
url = tempData?.data.url ?? '';
}
return url !== '' ? url : await this.core.apis.FileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
@ -1282,7 +1283,7 @@ export class OneBotMsgApi {
async parseSysMessage (msg: number[]) {
const SysMessage = new NapProtoMsg(PushMsgBody).decode(Uint8Array.from(msg));
// 邀请需要解grayTipElement
if (SysMessage.contentHead.type == 33 && SysMessage.body?.msgContent) {
if (SysMessage.contentHead.type === 33 && SysMessage.body?.msgContent) {
const groupChange = new NapProtoMsg(GroupChange).decode(SysMessage.body.msgContent);
await this.core.apis.GroupApi.refreshGroupMemberCache(groupChange.groupUin.toString(), true);
const operatorUid = await this.waitGroupNotify(
@ -1295,9 +1296,9 @@ export class OneBotMsgApi {
groupChange.groupUin,
groupChange.memberUid ? +await this.core.apis.UserApi.getUinByUidV2(groupChange.memberUid) : 0,
operatorUid ? +await this.core.apis.UserApi.getUinByUidV2(operatorUid) : 0,
groupChange.decreaseType == 131 ? 'invite' : 'approve'
groupChange.decreaseType === 131 ? 'invite' : 'approve'
);
} else if (SysMessage.contentHead.type == 34 && SysMessage.body?.msgContent) {
} else if (SysMessage.contentHead.type === 34 && SysMessage.body?.msgContent) {
const groupChange = new NapProtoMsg(GroupChange).decode(SysMessage.body.msgContent);
let operator_uid_parse: string | undefined;
@ -1307,14 +1308,14 @@ export class OneBotMsgApi {
// 可能是protobuf尝试解析
try {
operator_uid_parse = new NapProtoMsg(GroupChangeInfo).decode(groupChange.operatorInfo).operator?.operatorUid;
} catch (error) {
} catch (_error) {
// protobuf解析失败fallback到字符串解析
try {
const decoded = new TextDecoder('utf-8').decode(groupChange.operatorInfo);
// 检查是否包含非ASCII字符如果包含则丢弃
const isAsciiOnly = [...decoded].every(char => char.charCodeAt(0) >= 32 && char.charCodeAt(0) <= 126);
operator_uid_parse = isAsciiOnly ? decoded : '';
} catch (e2) {
} catch (_e2) {
operator_uid_parse = '';
}
}
@ -1325,7 +1326,7 @@ export class OneBotMsgApi {
// 检查是否包含非ASCII字符如果包含则丢弃
const isAsciiOnly = [...decoded].every(char => char.charCodeAt(0) >= 32 && char.charCodeAt(0) <= 126);
operator_uid_parse = isAsciiOnly ? decoded : '';
} catch (e) {
} catch (_e) {
operator_uid_parse = '';
}
}
@ -1351,7 +1352,7 @@ export class OneBotMsgApi {
operatorUid ? +await this.core.apis.UserApi.getUinByUidV2(operatorUid) : 0,
this.groupChangDecreseType2String(groupChange.decreaseType)
);
} else if (SysMessage.contentHead.type == 44 && SysMessage.body?.msgContent) {
} else if (SysMessage.contentHead.type === 44 && SysMessage.body?.msgContent) {
const groupAmin = new NapProtoMsg(GroupAdmin).decode(SysMessage.body.msgContent);
await this.core.apis.GroupApi.refreshGroupMemberCache(groupAmin.groupUin.toString(), true);
let enabled = false;
@ -1369,7 +1370,7 @@ export class OneBotMsgApi {
+await this.core.apis.UserApi.getUinByUidV2(uid),
enabled ? 'set' : 'unset'
);
} else if (SysMessage.contentHead.type == 87 && SysMessage.body?.msgContent) {
} else if (SysMessage.contentHead.type === 87 && SysMessage.body?.msgContent) {
const groupInvite = new NapProtoMsg(GroupInvite).decode(SysMessage.body.msgContent);
let request_seq = '';
try {
@ -1435,7 +1436,7 @@ export class OneBotMsgApi {
'',
request_seq
);
} else if (SysMessage.contentHead.type == 528 && SysMessage.contentHead.subType == 39 && SysMessage.body?.msgContent) {
} else if (SysMessage.contentHead.type === 528 && SysMessage.contentHead.subType === 39 && SysMessage.body?.msgContent) {
return await this.obContext.apis.UserApi.parseLikeEvent(SysMessage.body?.msgContent);
}
// else if (SysMessage.contentHead.type == 732 && SysMessage.contentHead.subType == 16 && SysMessage.body?.msgContent) {

View File

@ -31,8 +31,8 @@ export class OneBotQuickActionApi {
.catch(e => this.core.context.logger.logError(e));
}
if (eventContext.post_type === 'request') {
const friendRequest = eventContext as OB11FriendRequestEvent;
const groupRequest = eventContext as OB11GroupRequestEvent;
const friendRequest = eventContext as unknown as OB11FriendRequestEvent;
const groupRequest = eventContext as unknown as OB11GroupRequestEvent;
if ((friendRequest).request_type === 'friend') {
await this.handleFriendRequest(friendRequest, quickAction)
.catch(e => this.core.context.logger.logError(e));
@ -45,7 +45,7 @@ export class OneBotQuickActionApi {
async handleMsg (msg: OB11Message, quickAction: QuickAction) {
const reply = quickAction.reply;
const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group;
const peerContextMode = msg.message_type === 'private' ? ContextMode.Private : ContextMode.Group;
const peer: Peer = await createContext(this.core, {
group_id: msg.group_id?.toString(),
user_id: msg.user_id?.toString(),
@ -55,7 +55,7 @@ export class OneBotQuickActionApi {
// let group: Group | undefined;
let replyMessage: OB11MessageData[] = [];
if (msg.message_type == 'group') {
if (msg.message_type === 'group') {
// group = await core.apis.GroupApi.getGroup(msg.group_id!.toString());
replyMessage.push({
type: 'reply',
@ -82,9 +82,9 @@ export class OneBotQuickActionApi {
}
async findNotify (flag: string) {
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, 100)).find(e => e.seq == flag);
let notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(false, 100)).find(e => e.seq === flag);
if (!notify) {
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, 100)).find(e => e.seq == flag);
notify = (await this.core.apis.GroupApi.getSingleScreenNotifies(true, 100)).find(e => e.seq === flag);
return { doubt: true, notify };
}
return { doubt: false, notify };
@ -105,7 +105,7 @@ export class OneBotQuickActionApi {
}
async handleFriendRequest (request: OB11FriendRequestEvent, quickAction: QuickActionFriendRequest) {
const notify = (await this.core.apis.FriendApi.getBuddyReq()).buddyReqs.find(e => e.reqTime == request.flag.toString());
const notify = (await this.core.apis.FriendApi.getBuddyReq()).buddyReqs.find(e => e.reqTime === request.flag.toString());
if (!isNull(quickAction.approve) && notify) {
this.core.apis.FriendApi.handleFriendRequest(notify, !!quickAction.approve).then().catch(e => this.core.context.logger.logError(e));
}

View File

@ -3,7 +3,7 @@ import { NapCatCore } from '@/core';
export interface MsgEmojiLike {
emoji_id: string,
count: number
count: number;
}
export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent {
@ -13,7 +13,7 @@ export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent {
is_add: boolean;
message_seq?: string;
constructor (core: NapCatCore, groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[], isAdd: boolean, messageSeq?: string) {
constructor (core: NapCatCore, groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[], isAdd: boolean, _messageSeq?: string) {
super(core, groupId, userId);
this.group_id = groupId;
this.user_id = userId; // 可为空表示是对别人的消息操作如果是对bot自己的消息则不为空

View File

@ -31,7 +31,7 @@ export class OB11Construct {
nickname: rawFriend.coreInfo.nick ?? '',
remark: rawFriend.coreInfo.remark ?? rawFriend.coreInfo.nick,
sex: this.sex(rawFriend.baseInfo.sex),
level: rawFriend.qqLevel && calcQQLevel(rawFriend.qqLevel) || 0,
level: (rawFriend.qqLevel && calcQQLevel(rawFriend.qqLevel)) || 0,
}));
}
@ -80,7 +80,7 @@ export class OB11Construct {
age: member.age ?? 0,
area: '',
level: member.memberRealLevel?.toString() ?? '0',
qq_level: member.qqLevel && calcQQLevel(member.qqLevel) || 0,
qq_level: (member.qqLevel && calcQQLevel(member.qqLevel)) || 0,
join_time: +member.joinTime,
last_sent_time: +member.lastSpeakTime,
title_expire_time: 0,

View File

@ -262,6 +262,7 @@ export class NapCatOneBot11Adapter {
await this.networkManager.closeSomeAdaterWhenOpen([existingAdapter]);
}
} else if (adapterConfig.enable) {
// eslint-disable-next-line new-cap
const newAdapter = new adapterClass(adapterConfig.name, adapterConfig as CT, this.core, this, this.actions);
await this.networkManager.registerAdapterAndOpen(newAdapter);
}
@ -314,17 +315,17 @@ export class NapCatOneBot11Adapter {
};
msgListener.onAddSendMsg = async (msg) => {
try {
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SENDING) {
if (msg.sendStatus === SendStatusType.KSEND_STATUS_SENDING) {
const [updatemsgs] = await this.core.eventWrapper.registerListen('NodeIKernelMsgListener/onMsgInfoListUpdate', (msgList: RawMessage[]) => {
const report = msgList.find((e) =>
e.senderUin == this.core.selfInfo.uin && e.sendStatus !== SendStatusType.KSEND_STATUS_SENDING && e.msgId === msg.msgId
e.senderUin === this.core.selfInfo.uin && e.sendStatus !== SendStatusType.KSEND_STATUS_SENDING && e.msgId === msg.msgId
);
return !!report;
}, 1, 10 * 60 * 1000);
// 10分钟 超时
const updatemsg = updatemsgs.find((e) => e.msgId === msg.msgId);
// updatemsg?.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS_NOSEQ NOSEQ一般是服务器未下发SEQ 这意味着这条消息不应该推送network
if (updatemsg?.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS) {
if (updatemsg?.sendStatus === SendStatusType.KSEND_STATUS_SUCCESS) {
updatemsg.id = MessageUnique.createUniqueMsgId(
{
chatType: updatemsg.chatType,
@ -346,7 +347,7 @@ export class NapCatOneBot11Adapter {
peerUid: uid,
guildId: '',
};
let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType == NTMsgType.KMSGTYPEGRAYTIPS);
let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType === NTMsgType.KMSGTYPEGRAYTIPS);
const element = msg?.elements.find(e => !!e.grayTipElement?.revokeElement);
if (msg && element?.grayTipElement?.revokeElement.isSelfOperate) {
const isSelfDevice = this.recallEventCache.has(msg.msgId);
@ -552,7 +553,7 @@ export class NapCatOneBot11Adapter {
ob11Msg.stringMsg.target_id = parseInt(message.peerUin);
ob11Msg.arrayMsg.target_id = parseInt(message.peerUin);
}
if ('messagePostFormat' in e && e.messagePostFormat == 'string') {
if ('messagePostFormat' in e && e.messagePostFormat === 'string') {
msgMap.set(e.name, structuredClone(ob11Msg.stringMsg));
} else {
msgMap.set(e.name, structuredClone(ob11Msg.arrayMsg));
@ -637,11 +638,12 @@ export class NapCatOneBot11Adapter {
private async emitRecallMsg (message: RawMessage, element: MessageElement) {
const peer: Peer = { chatType: message.chatType, peerUid: message.peerUid, guildId: '' };
const oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId) ?? MessageUnique.createUniqueMsgId(peer, message.msgId);
if (message.chatType == ChatType.KCHATTYPEC2C) {
if (message.chatType === ChatType.KCHATTYPEC2C) {
return await this.emitFriendRecallMsg(message, oriMessageId, element);
} else if (message.chatType == ChatType.KCHATTYPEGROUP) {
} else if (message.chatType === ChatType.KCHATTYPEGROUP) {
return await this.emitGroupRecallMsg(message, oriMessageId, element);
}
return undefined;
}
private async emitFriendRecallMsg (message: RawMessage, oriMessageId: number, element: MessageElement) {

View File

@ -1,26 +1,17 @@
import { OB11EmitEventContent, OB11NetworkReloadType } from '@/onebot/network/index';
import { createHmac } from 'crypto';
import { QuickAction, QuickActionEvent } from '@/onebot/types';
import { NapCatCore } from '@/core';
import { NapCatOneBot11Adapter } from '..';
import { RequestUtil } from '@/common/request';
import { HttpClientConfig } from '@/onebot/config/config';
import { ActionMap } from '@/onebot/action';
import { IOB11NetworkAdapter } from '@/onebot/network/adapter';
import json5 from 'json5';
export class OB11HttpClientAdapter extends IOB11NetworkAdapter<HttpClientConfig> {
constructor (
name: string, config: HttpClientConfig, core: NapCatCore, obContext: NapCatOneBot11Adapter, actions: ActionMap
) {
super(name, config, core, obContext, actions);
}
async onEvent<T extends OB11EmitEventContent>(event: T) {
async onEvent<T extends OB11EmitEventContent> (event: T) {
this.emitEventAsync(event).catch(e => this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败', e));
}
async emitEventAsync<T extends OB11EmitEventContent>(event: T) {
async emitEventAsync<T extends OB11EmitEventContent> (event: T) {
if (!this.isEnable) return;
const headers: Record<string, string> = {
'Content-Type': 'application/json',

View File

@ -1,25 +1,19 @@
import { OB11EmitEventContent, OB11NetworkReloadType } from './index';
import express, { Express, NextFunction, Request, Response } from 'express';
import http from 'http';
import { NapCatCore } from '@/core';
import { OB11Response } from '@/onebot/action/OneBotAction';
import { ActionMap } from '@/onebot/action';
import cors from 'cors';
import { HttpServerConfig } from '@/onebot/config/config';
import { NapCatOneBot11Adapter } from '@/onebot';
import { IOB11NetworkAdapter } from '@/onebot/network/adapter';
import json5 from 'json5';
import { isFinished } from 'on-finished';
import typeis from 'type-is';
export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig> {
private app: Express | undefined;
private server: http.Server | undefined;
constructor (name: string, config: HttpServerConfig, core: NapCatCore, obContext: NapCatOneBot11Adapter, actions: ActionMap) {
super(name, config, core, obContext, actions);
}
override async onEvent<T extends OB11EmitEventContent>(_event: T) {
override async onEvent<T extends OB11EmitEventContent> (_event: T) {
// http server is passive, no need to emit event
}
@ -71,7 +65,7 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
req.body = { ...json5.parse(rawData || '{}'), ...req.body };
next();
} catch {
return res.status(400).send('Invalid JSON');
res.status(400).send('Invalid JSON');
}
});
req.on('error', () => {
@ -89,7 +83,7 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
}
private authorize (token: string | undefined, req: Request, res: Response, next: NextFunction) {
if (!token || token.length == 0) return next();// 客户端未设置密钥
if (!token || token.length === 0) return next();// 客户端未设置密钥
const HeaderClientToken = req.headers.authorization?.split('Bearer ').pop() || '';
const QueryClientToken = req.query['access_token'];
const ClientToken = typeof (QueryClientToken) === 'string' && QueryClientToken !== '' ? QueryClientToken : HeaderClientToken;
@ -102,7 +96,7 @@ export class OB11HttpServerAdapter extends IOB11NetworkAdapter<HttpServerConfig>
async httpApiRequest (req: Request, res: Response, request_sse: boolean = false) {
let payload = req.body;
if (req.method == 'get') {
if (req.method === 'get') {
payload = req.query;
} else if (req.query) {
payload = { ...req.body, ...req.query };

View File

@ -4,10 +4,8 @@ import { OB11HeartbeatEvent } from '@/onebot/event/meta/OB11HeartbeatEvent';
import { NapCatCore } from '@/core';
import { ActionName } from '@/onebot/action/router';
import { OB11Response } from '@/onebot/action/OneBotAction';
import { ActionMap } from '@/onebot/action';
import { LifeCycleSubType, OB11LifeCycleEvent } from '@/onebot/event/meta/OB11LifeCycleEvent';
import { WebsocketClientConfig } from '@/onebot/config/config';
import { NapCatOneBot11Adapter } from '@/onebot';
import { IOB11NetworkAdapter } from '@/onebot/network/adapter';
import json5 from 'json5';
@ -15,11 +13,7 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
private connection: WebSocket | null = null;
private heartbeatRef: NodeJS.Timeout | null = null;
constructor (name: string, config: WebsocketClientConfig, core: NapCatCore, obContext: NapCatOneBot11Adapter, actions: ActionMap) {
super(name, config, core, obContext, actions);
}
async onEvent<T extends OB11EmitEventContent>(event: T) {
async onEvent<T extends OB11EmitEventContent> (event: T) {
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
this.connection.send(JSON.stringify(event));
}
@ -60,7 +54,7 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
}
}
private async checkStateAndReply<T>(data: T) {
private async checkStateAndReply<T> (data: T) {
return new Promise<void>((resolve, reject) => {
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
this.connection.send(JSON.stringify(data));
@ -134,7 +128,7 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
}
private async handleMessage (message: RawData) {
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any } = { action: ActionName.Unknown, params: {} };
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any; } = { action: ActionName.Unknown, params: {} };
let echo;
try {

View File

@ -1,5 +1,5 @@
import { OB11EmitEventContent, OB11NetworkReloadType } from './index';
import urlParse from 'url';
import { URL } from 'url';
import { RawData, WebSocket, WebSocketServer } from 'ws';
import { Mutex } from 'async-mutex';
import { OB11Response } from '@/onebot/action/OneBotAction';
@ -89,7 +89,7 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
}
}
async onEvent<T extends OB11EmitEventContent>(event: T) {
async onEvent<T extends OB11EmitEventContent> (event: T) {
this.wsClientsMutex.runExclusive(async () => {
const promises = this.wsClientWithEvent.map((wsClient) => {
return new Promise<void>((resolve, reject) => {
@ -154,8 +154,9 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
}
private authorize (token: string | undefined, wsClient: WebSocket, wsReq: IncomingMessage) {
if (!token || token.length == 0) return true;// 客户端未设置密钥
const QueryClientToken = urlParse.parse(wsReq?.url || '', true).query['access_token'];
if (!token || token.length === 0) return true;// 客户端未设置密钥
const url = new URL(wsReq?.url || '', `http://${wsReq.headers.host}`);
const QueryClientToken = url.searchParams.get('access_token');
const HeaderClientToken = wsReq.headers.authorization?.split('Bearer ').pop() || '';
const ClientToken = typeof (QueryClientToken) === 'string' && QueryClientToken !== '' ? QueryClientToken : HeaderClientToken;
if (ClientToken === token) {
@ -166,7 +167,7 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
return false;
}
private async checkStateAndReply<T>(data: T, wsClient: WebSocket) {
private async checkStateAndReply<T> (data: T, wsClient: WebSocket) {
return await new Promise<void>((resolve, reject) => {
if (wsClient.readyState === WebSocket.OPEN) {
wsClient.send(JSON.stringify(data));
@ -178,7 +179,7 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
}
private async handleMessage (wsClient: WebSocket, message: RawData) {
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any } = { action: ActionName.Unknown, params: {} };
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any; } = { action: ActionName.Unknown, params: {} };
let echo;
try {
receiveData = json5.parse(message.toString());

View File

@ -1,5 +1,6 @@
import type { ITerminal, IPtyOpenOptions, IPtyForkOptions, IWindowsPtyForkOptions } from '@homebridge/node-pty-prebuilt-multiarch/src/interfaces';
import type { ArgvOrCommandLine } from '@homebridge/node-pty-prebuilt-multiarch/src/types';
import type { ArgvOrCommandLine } from '../../node_modules/@homebridge/node-pty-prebuilt-multiarch/src/types';
// import type { ArgvOrCommandLine } from '@homebridge/node-pty-prebuilt-multiarch/src/types';
import { WindowsTerminal } from './windowsTerminal';
import { UnixTerminal } from './unixTerminal';
import { fileURLToPath } from 'node:url';
@ -14,6 +15,7 @@ if (process.platform === 'win32') {
}
export function spawn (file?: string, args?: ArgvOrCommandLine, opt?: IPtyForkOptions | IWindowsPtyForkOptions): ITerminal {
// eslint-disable-next-line new-cap
return new terminalCtor(file, args, opt);
}

View File

@ -265,11 +265,11 @@ export function argsToCommandLine (file: string, args: ArgvOrCommandLine): strin
const hasLopsidedEnclosingQuote = xOr((arg![0] !== '"'), (arg![arg!.length - 1] !== '"'));
const hasNoEnclosingQuotes = ((arg![0] !== '"') && (arg![arg!.length - 1] !== '"'));
const quote =
arg === '' ||
(arg!.indexOf(' ') !== -1 ||
arg!.indexOf('\t') !== -1) &&
((arg!.length > 1) &&
(hasLopsidedEnclosingQuote || hasNoEnclosingQuotes));
arg === '' ||
((arg!.indexOf(' ') !== -1 ||
arg!.indexOf('\t') !== -1) &&
((arg!.length > 1) &&
(hasLopsidedEnclosingQuote || hasNoEnclosingQuotes)));
if (quote) {
result += '"';
}

View File

@ -5,6 +5,7 @@
*/
import { Socket } from 'net';
// @ts-check
import { Terminal, DEFAULT_COLS, DEFAULT_ROWS } from '@homebridge/node-pty-prebuilt-multiarch/src/terminal';
import { WindowsPtyAgent } from './windowsPtyAgent';
import { IPtyOpenOptions, IWindowsPtyForkOptions } from '@homebridge/node-pty-prebuilt-multiarch/src/interfaces';
@ -173,7 +174,7 @@ export class WindowsTerminal extends Terminal {
// @ts-expect-error - This is a private method that is not part of the public API.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _deferNoArgs<A>(deferredFn: () => void): void {
private _deferNoArgs<A> (deferredFn: () => void): void {
// If the terminal is ready, execute.
if (this._isReady) {
deferredFn.call(this);
@ -186,7 +187,7 @@ export class WindowsTerminal extends Terminal {
});
}
private _defer<A>(deferredFn: (arg: A) => void, arg: A): void {
private _defer<A> (deferredFn: (arg: A) => void, arg: A): void {
// If the terminal is ready, execute.
if (this._isReady) {
deferredFn.call(this, arg);

View File

@ -167,7 +167,7 @@ async function handleLogin (
loginListener.onQRCodeSessionFailed = (errType: number, errCode: number) => {
if (!context.isLogined) {
logger.logError('[Core] [Login] Login Error,ErrType: ', errType, ' ErrCode:', errCode);
if (errType == 1 && errCode == 3) {
if (errType === 1 && errCode === 3) {
// 二维码过期刷新
}
loginService.getQRCodePicture();
@ -302,12 +302,12 @@ async function handleProxy (session: NodeIQQNTWrapperSession, logger: LogWrapper
async function waitForNetworkConnection (loginService: NodeIKernelLoginService, logger: LogWrapper) {
let network_ok = false;
let tryCount = 0;
let _tryCount = 0;
while (!network_ok) {
network_ok = loginService.getMsfStatus() !== 3;// win 11 0连接 1未连接
logger.log('等待网络连接...');
await sleep(500);
tryCount++;
_tryCount++;
}
logger.log('网络已连接');
return network_ok;

View File

@ -114,7 +114,7 @@ export async function InitWebUi (logger: LogWrapper, pathWrapper: NapCatPathWrap
const [host, port, token] = await InitPort(config);
webUiRuntimePort = port;
if (port == 0) {
if (port === 0) {
logger.log('[NapCat] [WebUi] Current WebUi is not run.');
return;
}

Some files were not shown because too many files have changed in this diff Show More