refactor: getfile

This commit is contained in:
手瓜一十雪
2024-07-31 16:40:34 +08:00
parent b8daeef0c4
commit b3c7a91f3d
4 changed files with 96 additions and 27 deletions

View File

@@ -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));
}

View File

@@ -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);
// 用于下载收到的消息中的图片等

View File

@@ -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) {

View File

@@ -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