mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-12-19 05:05:44 +08:00
refactor: 重构eslint
This commit is contained in:
parent
52c3712200
commit
bde4319c4d
31
README.md
31
README.md
@ -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 | [](https://napneko.github.io/) | [](https://doc.napneko.icu/) | [](https://napcat.napneko.icu/) |
|
||||
|
||||
20
package.json
20
package.json
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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})`
|
||||
}]`;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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编码
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 ?? '';
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export class NodeIO3MiscListener {
|
||||
getOnAmgomDataPiece (...arg: unknown[]): any {
|
||||
getOnAmgomDataPiece (..._arg: unknown[]): any {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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(
|
||||
{
|
||||
|
||||
@ -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(
|
||||
{
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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(
|
||||
{
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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({
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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();
|
||||
},
|
||||
};
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -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 };
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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');
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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自己的消息则不为空
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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 };
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 += '"';
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user