mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
refactor: getfile
This commit is contained in:
@@ -8,6 +8,27 @@ import * as fsPromise from 'node:fs/promises';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
//下面这个类是用于将uid+msgid合并的类
|
||||
export class UUIDConverter {
|
||||
static encode(highStr: string, lowStr: string): string {
|
||||
const high = BigInt(highStr);
|
||||
const low = BigInt(lowStr);
|
||||
const highHex = high.toString(16).padStart(16, '0');
|
||||
const lowHex = low.toString(16).padStart(16, '0');
|
||||
const combinedHex = highHex + lowHex;
|
||||
const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring(12, 16)}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`;
|
||||
return uuid;
|
||||
}
|
||||
static decode(uuid: string): { high: string, low: string } {
|
||||
const hex = uuid.replace(/-/g, '');
|
||||
const high = BigInt('0x' + hex.substring(0, 16));
|
||||
const low = BigInt('0x' + hex.substring(16));
|
||||
return { high: high.toString(), low: low.toString() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ import { sessionConfig } from '@/core/sessionConfig';
|
||||
import { rkeyManager } from '../utils/rkey';
|
||||
import { NTEventDispatch } from '@/common/utils/EventTask';
|
||||
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
|
||||
import { selfInfo } from '../data';
|
||||
|
||||
|
||||
export class NTQQFileApi {
|
||||
@@ -67,7 +68,9 @@ export class NTQQFileApi {
|
||||
ext
|
||||
};
|
||||
}
|
||||
|
||||
static async downloadMediaByUuid() {
|
||||
//napCatCore.session.getRichMediaService().downloadFileForFileUuid();
|
||||
}
|
||||
static async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
|
||||
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
|
||||
// 用于下载收到的消息中的图片等
|
||||
|
@@ -1,15 +1,12 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import fs from 'fs/promises';
|
||||
import { ob11Config } from '@/onebot11/config';
|
||||
import { log, logDebug } from '@/common/utils/log';
|
||||
import { sleep } from '@/common/utils/helper';
|
||||
import { uri2local } from '@/common/utils/file';
|
||||
import { UUIDConverter } from '@/common/utils/helper';
|
||||
import { ActionName, BaseCheckResult } from '../types';
|
||||
import { ChatType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
|
||||
import { NTQQFileApi, NTQQMsgApi } from '@/core/apis';
|
||||
import { ChatType, ElementType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import Ajv from 'ajv';
|
||||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||||
import { getGroup } from '@/core/data';
|
||||
|
||||
export interface GetFilePayload {
|
||||
file: string; // 文件名或者fileUuid
|
||||
@@ -46,6 +43,65 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
}
|
||||
protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
|
||||
const { enableLocalFile2Url } = ob11Config;
|
||||
let UuidData: {
|
||||
high: string;
|
||||
low: string;
|
||||
} | undefined;
|
||||
try {
|
||||
UuidData = UUIDConverter.decode(payload.file);
|
||||
if (UuidData) {
|
||||
let peerUin = UuidData.high;
|
||||
let msgId = UuidData.low;
|
||||
let isGroup = await getGroup(peerUin);
|
||||
let peer: Peer | undefined;
|
||||
//识别Peer
|
||||
if (isGroup) {
|
||||
peer = { chatType: ChatType.group, peerUid: peerUin };
|
||||
}
|
||||
let PeerUid = await NTQQUserApi.getUidByUin(peerUin);
|
||||
if (PeerUid) {
|
||||
let isBuddy = await NTQQFriendApi.isBuddy(PeerUid);
|
||||
if (isBuddy) {
|
||||
peer = { chatType: ChatType.friend, peerUid: PeerUid };
|
||||
} else {
|
||||
peer = { chatType: ChatType.temp, peerUid: PeerUid };
|
||||
}
|
||||
}
|
||||
if (!peer) {
|
||||
throw new Error('chattype not support');
|
||||
}
|
||||
let msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
|
||||
if (msgList.msgList.length == 0) {
|
||||
throw new Error('msg not found');
|
||||
}
|
||||
let msg = msgList.msgList[0];
|
||||
let findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT);
|
||||
if (!findEle) {
|
||||
throw new Error('element not found');
|
||||
}
|
||||
let downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
|
||||
let fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
|
||||
let fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || '';
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
file_size: fileSize,
|
||||
file_name: fileName
|
||||
};
|
||||
if (enableLocalFile2Url) {
|
||||
try {
|
||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||
} catch (e) {
|
||||
throw new Error('文件下载失败. ' + e);
|
||||
}
|
||||
}
|
||||
//不手动删除?文件持久化了
|
||||
return res;
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
||||
const NTSearchNameResult = (await NTQQFileApi.searchfile([payload.file])).resultItems;
|
||||
if (NTSearchNameResult.length !== 0) {
|
||||
const MsgId = NTSearchNameResult[0].msgId;
|
||||
@@ -69,7 +125,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||
file_name: NTSearchNameResult[0].fileName
|
||||
};
|
||||
if (enableLocalFile2Url) {
|
||||
@@ -82,7 +138,6 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
//不手动删除?文件持久化了
|
||||
return res;
|
||||
}
|
||||
//下面逻辑是有UUID的情况
|
||||
throw new Error('file not found');
|
||||
// let cache = await dbUtil.getFileCacheByName(payload.file);
|
||||
// if (!cache) {
|
||||
|
@@ -35,7 +35,7 @@ import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent';
|
||||
|
||||
import { calcQQLevel } from '../common/utils/qqlevel';
|
||||
import { log, logDebug, logError, logWarn } from '../common/utils/log';
|
||||
import { sleep } from '../common/utils/helper';
|
||||
import { sleep, UUIDConverter } from '../common/utils/helper';
|
||||
import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent';
|
||||
import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent';
|
||||
import { OB11GroupDecreaseEvent } from './event/notice/OB11GroupDecreaseEvent';
|
||||
@@ -185,13 +185,12 @@ export class OB11Constructor {
|
||||
message_data['data']['file_size'] = element.picElement.fileSize;
|
||||
}
|
||||
else if (element.fileElement) {
|
||||
|
||||
const FileElement = element.fileElement;
|
||||
message_data['type'] = OB11MessageDataType.file;
|
||||
message_data['data']['file'] = FileElement.fileName;
|
||||
message_data['data']['path'] = FileElement.filePath;
|
||||
message_data['data']['url'] = FileElement.filePath;
|
||||
message_data['data']['file_id'] = FileElement.fileUuid;
|
||||
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||
message_data['data']['file_size'] = FileElement.fileSize;
|
||||
await NTQQFileApi.addFileCache({
|
||||
peerUid: msg.peerUid,
|
||||
@@ -237,7 +236,7 @@ export class OB11Constructor {
|
||||
message_data['data']['file'] = videoElement.fileName;
|
||||
message_data['data']['path'] = videoDownUrl;
|
||||
message_data['data']['url'] = videoDownUrl;
|
||||
message_data['data']['file_id'] = videoElement.fileUuid;
|
||||
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||
message_data['data']['file_size'] = videoElement.fileSize;
|
||||
|
||||
await NTQQFileApi.addFileCache({
|
||||
@@ -258,19 +257,9 @@ export class OB11Constructor {
|
||||
message_data['type'] = OB11MessageDataType.voice;
|
||||
message_data['data']['file'] = element.pttElement.fileName;
|
||||
message_data['data']['path'] = element.pttElement.filePath;
|
||||
message_data['data']['file_id'] = element.pttElement.fileUuid;
|
||||
//message_data['data']['file_id'] = element.pttElement.fileUuid;
|
||||
message_data['data']['file_id'] = UUIDConverter.encode(msg.peerUin, msg.msgId);
|
||||
message_data['data']['file_size'] = element.pttElement.fileSize;
|
||||
// dbUtil.addFileCache({
|
||||
// name: element.pttElement.fileName,
|
||||
// path: element.pttElement.filePath,
|
||||
// size: parseInt(element.pttElement.fileSize) || 0,
|
||||
// url: '',
|
||||
// uuid: element.pttElement.fileUuid || '',
|
||||
// msgId: msg.msgId,
|
||||
// element: element.pttElement,
|
||||
// elementType: ElementType.PTT,
|
||||
// elementId: element.elementId
|
||||
// }).then();
|
||||
await NTQQFileApi.addFileCache({
|
||||
peerUid: msg.peerUid,
|
||||
chatType: msg.chatType,
|
||||
@@ -350,6 +339,7 @@ export class OB11Constructor {
|
||||
if (element.grayTipElement) {
|
||||
if (element.grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) {
|
||||
const json = JSON.parse(element.grayTipElement.jsonGrayTipElement.jsonStr);
|
||||
|
||||
if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
|
||||
//判断业务类型
|
||||
//Poke事件
|
||||
@@ -358,7 +348,7 @@ export class OB11Constructor {
|
||||
pokedetail = pokedetail.filter(item => item.uid);
|
||||
//console.log("[NapCat] 群拍一拍 群:", pokedetail, parseInt(msg.peerUid), " ", await NTQQUserApi.getUinByUid(pokedetail[0].uid), "拍了拍", await NTQQUserApi.getUinByUid(pokedetail[1].uid));
|
||||
if (pokedetail.length == 2) {
|
||||
return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!));
|
||||
return new OB11FriendPokeEvent(parseInt((await NTQQUserApi.getUinByUid(pokedetail[0].uid))!), parseInt((await NTQQUserApi.getUinByUid(pokedetail[1].uid))!), pokedetail);
|
||||
}
|
||||
}
|
||||
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||
|
Reference in New Issue
Block a user