mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
refactor: 通过@实现定位
This commit is contained in:
parent
8edbe54456
commit
a5d4998933
@ -4,7 +4,7 @@ import path from 'node:path';
|
|||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { spawn } from 'node:child_process';
|
import { spawn } from 'node:child_process';
|
||||||
import { EncodeResult, getDuration, getWavFileInfo, isSilk, isWav } from 'silk-wasm';
|
import { EncodeResult, getDuration, getWavFileInfo, isSilk, isWav } from 'silk-wasm';
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/common/log';
|
||||||
import { EncodeArgs } from "@/common/audio-worker";
|
import { EncodeArgs } from "@/common/audio-worker";
|
||||||
|
|
||||||
const ALLOW_SAMPLE_RATE = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
const ALLOW_SAMPLE_RATE = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
||||||
|
@ -4,7 +4,20 @@ import crypto, { randomUUID } from 'crypto';
|
|||||||
import util from 'util';
|
import util from 'util';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import * as fileType from 'file-type';
|
import * as fileType from 'file-type';
|
||||||
import { solveProblem } from './helper';
|
import { solveProblem } from '@/common/helper';
|
||||||
|
|
||||||
|
export interface HttpDownloadOptions {
|
||||||
|
url: string;
|
||||||
|
headers?: Record<string, string> | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Uri2LocalRes = {
|
||||||
|
success: boolean,
|
||||||
|
errMsg: string,
|
||||||
|
fileName: string,
|
||||||
|
ext: string,
|
||||||
|
path: string
|
||||||
|
}
|
||||||
|
|
||||||
export function isGIF(path: string) {
|
export function isGIF(path: string) {
|
||||||
const buffer = Buffer.alloc(4);
|
const buffer = Buffer.alloc(4);
|
||||||
@ -15,7 +28,7 @@ export function isGIF(path: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 定义一个异步函数来检查文件是否存在
|
// 定义一个异步函数来检查文件是否存在
|
||||||
export function checkFileReceived(path: string, timeout: number = 3000): Promise<void> {
|
export function checkFileExist(path: string, timeout: number = 3000): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
@ -34,7 +47,7 @@ export function checkFileReceived(path: string, timeout: number = 3000): Promise
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 定义一个异步函数来检查文件是否存在
|
// 定义一个异步函数来检查文件是否存在
|
||||||
export async function checkFileReceived2(path: string, timeout: number = 3000): Promise<void> {
|
export async function checkFileExistV2(path: string, timeout: number = 3000): Promise<void> {
|
||||||
// 使用 Promise.race 来同时进行文件状态检查和超时计时
|
// 使用 Promise.race 来同时进行文件状态检查和超时计时
|
||||||
// Promise.race 会返回第一个解决(resolve)或拒绝(reject)的 Promise
|
// Promise.race 会返回第一个解决(resolve)或拒绝(reject)的 Promise
|
||||||
await Promise.race([
|
await Promise.race([
|
||||||
@ -75,18 +88,13 @@ export async function file2base64(path: string) {
|
|||||||
data: '',
|
data: '',
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
// 读取文件内容
|
|
||||||
// if (!fs.existsSync(path)){
|
|
||||||
// path = path.replace("\\Ori\\", "\\Thumb\\");
|
|
||||||
// }
|
|
||||||
try {
|
try {
|
||||||
await checkFileReceived(path, 5000);
|
await checkFileExist(path, 5000);
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
result.err = e.toString();
|
result.err = e.toString();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const data = await readFile(path);
|
const data = await readFile(path);
|
||||||
// 转换为Base64编码
|
|
||||||
result.data = data.toString('base64');
|
result.data = data.toString('base64');
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
result.err = err.toString();
|
result.err = err.toString();
|
||||||
@ -118,13 +126,7 @@ export function calculateFileMD5(filePath: string): Promise<string> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HttpDownloadOptions {
|
|
||||||
url: string;
|
|
||||||
headers?: Record<string, string> | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function tryDownload(options: string | HttpDownloadOptions, useReferer: boolean = false): Promise<Response> {
|
async function tryDownload(options: string | HttpDownloadOptions, useReferer: boolean = false): Promise<Response> {
|
||||||
// const chunks: Buffer[] = [];
|
|
||||||
let url: string;
|
let url: string;
|
||||||
let headers: Record<string, string> = {
|
let headers: Record<string, string> = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
|
||||||
@ -166,14 +168,6 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
|
|||||||
return Buffer.from(buffer);
|
return Buffer.from(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Uri2LocalRes = {
|
|
||||||
success: boolean,
|
|
||||||
errMsg: string,
|
|
||||||
fileName: string,
|
|
||||||
ext: string,
|
|
||||||
path: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function checkFileV2(filePath: string) {
|
export async function checkFileV2(filePath: string) {
|
||||||
try {
|
try {
|
||||||
const ext: string | undefined = (await fileType.fileTypeFromFile(filePath))?.ext;
|
const ext: string | undefined = (await fileType.fileTypeFromFile(filePath))?.ext;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/common/log';
|
||||||
|
|
||||||
export function proxyHandlerOf(logger: LogWrapper) {
|
export function proxyHandlerOf(logger: LogWrapper) {
|
||||||
return {
|
return {
|
||||||
|
@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|||||||
import { systemPlatform } from '@/common/system';
|
import { systemPlatform } from '@/common/system';
|
||||||
import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor } from './helper';
|
import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor } from './helper';
|
||||||
import AppidTable from '@/core/external/appid.json';
|
import AppidTable from '@/core/external/appid.json';
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/common/log';
|
||||||
import { getMajorPath } from '@/core';
|
import { getMajorPath } from '@/core';
|
||||||
|
|
||||||
export class QQBasicInfoWrapper {
|
export class QQBasicInfoWrapper {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName } from '@/onebot/action/router';
|
import { ActionName } from '@/onebot/action/router';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
import { checkFileReceived, uri2local } from '@/common/file';
|
import { checkFileExist, uri2local } from '@/common/file';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
@ -24,7 +24,7 @@ export class OCRImage extends OneBotAction<Payload, any> {
|
|||||||
throw new Error(`OCR ${payload.image}失败,image字段可能格式不正确`);
|
throw new Error(`OCR ${payload.image}失败,image字段可能格式不正确`);
|
||||||
}
|
}
|
||||||
if (path) {
|
if (path) {
|
||||||
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
await checkFileExist(path, 5000); // 避免崩溃
|
||||||
const ret = await this.core.apis.SystemApi.ocrImage(path);
|
const ret = await this.core.apis.SystemApi.ocrImage(path);
|
||||||
fs.unlink(path, () => { });
|
fs.unlink(path, () => { });
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName, BaseCheckResult } from '../router';
|
import { ActionName, BaseCheckResult } from '@/onebot/action/router';
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { checkFileReceived, uri2local } from '@/common/file';
|
import { checkFileExist, uri2local } from '@/common/file';
|
||||||
|
|
||||||
interface Payload {
|
interface Payload {
|
||||||
file: string;
|
file: string;
|
||||||
@ -29,7 +29,7 @@ export default class SetAvatar extends OneBotAction<Payload, null> {
|
|||||||
throw new Error(`头像${payload.file}设置失败,file字段可能格式不正确`);
|
throw new Error(`头像${payload.file}设置失败,file字段可能格式不正确`);
|
||||||
}
|
}
|
||||||
if (path) {
|
if (path) {
|
||||||
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
await checkFileExist(path, 5000);// 避免崩溃
|
||||||
const ret = await this.core.apis.UserApi.setQQAvatar(path);
|
const ret = await this.core.apis.UserApi.setQQAvatar(path);
|
||||||
fs.unlink(path, () => {
|
fs.unlink(path, () => {
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { checkFileReceived, uri2local } from '@/common/file';
|
import { checkFileExist, uri2local } from '@/common/file';
|
||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName } from '@/onebot/action/router';
|
import { ActionName } from '@/onebot/action/router';
|
||||||
import { unlink } from 'node:fs';
|
import { unlink } from 'node:fs';
|
||||||
@ -39,7 +39,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
|
|||||||
if (!path) {
|
if (!path) {
|
||||||
throw new Error(`群公告${payload.image}设置失败,获取资源失败`);
|
throw new Error(`群公告${payload.image}设置失败,获取资源失败`);
|
||||||
}
|
}
|
||||||
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
await checkFileExist(path, 5000);
|
||||||
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
|
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}设置失败,图片上传失败`);
|
throw new Error(`群公告${payload.image}设置失败,图片上传失败`);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
import { OneBotAction } from '@/onebot/action/OneBotAction';
|
||||||
import { ActionName, BaseCheckResult } from '../router';
|
import { ActionName, BaseCheckResult } from '@/onebot/action/router';
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import { checkFileReceived, uri2local } from '@/common/file';
|
import { checkFileExistV2, uri2local } from '@/common/file';
|
||||||
|
|
||||||
interface Payload {
|
interface Payload {
|
||||||
file: string,
|
file: string,
|
||||||
@ -30,7 +30,7 @@ export default class SetGroupPortrait extends OneBotAction<Payload, any> {
|
|||||||
throw new Error(`头像${payload.file}设置失败,file字段可能格式不正确`);
|
throw new Error(`头像${payload.file}设置失败,file字段可能格式不正确`);
|
||||||
}
|
}
|
||||||
if (path) {
|
if (path) {
|
||||||
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
await checkFileExistV2(path, 5000); // 文件不存在QQ会崩溃,需要提前判断
|
||||||
const ret = await this.core.apis.GroupApi.setGroupAvatar(payload.group_id.toString(), path);
|
const ret = await this.core.apis.GroupApi.setGroupAvatar(payload.group_id.toString(), path);
|
||||||
fs.unlink(path, () => { });
|
fs.unlink(path, () => { });
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -23,7 +23,6 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
this.config = structuredClone(config);
|
this.config = structuredClone(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onEvent<T extends OB11EmitEventContent>(event: T) {
|
onEvent<T extends OB11EmitEventContent>(event: T) {
|
||||||
if (!this.isEnable) {
|
if (!this.isEnable) {
|
||||||
return;
|
return;
|
||||||
|
@ -80,7 +80,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
headers: {
|
headers: {
|
||||||
'X-Self-ID': this.core.selfInfo.uin,
|
'X-Self-ID': this.core.selfInfo.uin,
|
||||||
'Authorization': `Bearer ${this.config.token}`,
|
'Authorization': `Bearer ${this.config.token}`,
|
||||||
'x-client-role': 'Universal', // koishi-adapter-onebot 需要这个字段
|
'x-client-role': 'Universal', // 为koishi adpter适配
|
||||||
'User-Agent': 'OneBot/11',
|
'User-Agent': 'OneBot/11',
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -144,11 +144,11 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
this.checkStateAndReply<any>(OB11Response.error('json解析失败,请检查数据格式', 1400, echo));
|
this.checkStateAndReply<any>(OB11Response.error('json解析失败,请检查数据格式', 1400, echo));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证
|
receiveData.params = (receiveData?.params) ? receiveData.params : {};// 兼容类型验证
|
||||||
const action = this.actions.get(receiveData.action);
|
const action = this.actions.get(receiveData.action);
|
||||||
if (!action) {
|
if (!action) {
|
||||||
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action);
|
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的Api ' + receiveData.action);
|
||||||
this.checkStateAndReply<any>(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo));
|
this.checkStateAndReply<any>(OB11Response.error('不支持的Api ' + receiveData.action, 1404, echo));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||||
|
@ -114,7 +114,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
|
|||||||
return res.json(OB11Response.error(error?.stack?.toString() || error?.message || 'Error Handle', 200));
|
return res.json(OB11Response.error(error?.stack?.toString() || error?.message || 'Error Handle', 200));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return res.json(OB11Response.error('不支持的api ' + actionName, 200));
|
return res.json(OB11Response.error('不支持的Api ' + actionName, 200));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,11 +180,11 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
this.checkStateAndReply<any>(OB11Response.error('json解析失败,请检查数据格式', 1400, echo), wsClient);
|
this.checkStateAndReply<any>(OB11Response.error('json解析失败,请检查数据格式', 1400, echo), wsClient);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证
|
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 不然类型校验爆炸
|
||||||
const action = this.actions.get(receiveData.action);
|
const action = this.actions.get(receiveData.action);
|
||||||
if (!action) {
|
if (!action) {
|
||||||
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action);
|
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的API ' + receiveData.action);
|
||||||
this.checkStateAndReply<any>(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo), wsClient);
|
this.checkStateAndReply<any>(OB11Response.error('不支持的API ' + receiveData.action, 1404, echo), wsClient);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name);
|
||||||
|
@ -12,7 +12,7 @@ export enum OB11MessageType {
|
|||||||
export interface OB11Message {
|
export interface OB11Message {
|
||||||
temp_source?: number;
|
temp_source?: number;
|
||||||
message_sent_type?: string;
|
message_sent_type?: string;
|
||||||
target_id?: number; // 自己发送的消息才有此字段
|
target_id?: number; // 自己发送消息/私聊消息
|
||||||
self_id?: number;
|
self_id?: number;
|
||||||
time: number;
|
time: number;
|
||||||
message_id: number;
|
message_id: number;
|
||||||
@ -255,7 +255,7 @@ export interface OB11PostSendMsg {
|
|||||||
user_id?: string;
|
user_id?: string;
|
||||||
group_id?: string;
|
group_id?: string;
|
||||||
message: OB11MessageMixType;
|
message: OB11MessageMixType;
|
||||||
messages?: OB11MessageMixType; // 兼容 go-cqhttp
|
messages?: OB11MessageMixType;
|
||||||
auto_escape?: boolean | string;
|
auto_escape?: boolean | string;
|
||||||
source?: string;
|
source?: string;
|
||||||
news?: { text: string }[];
|
news?: { text: string }[];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user