diff --git a/src/core/packet/context/operationContext.ts b/src/core/packet/context/operationContext.ts index e9c89cba..d69955c6 100644 --- a/src/core/packet/context/operationContext.ts +++ b/src/core/packet/context/operationContext.ts @@ -1,22 +1,22 @@ import * as crypto from 'crypto'; -import {PacketContext} from '@/core/packet/context/packetContext'; +import { PacketContext } from '@/core/packet/context/packetContext'; import * as trans from '@/core/packet/transformer'; -import {PacketMsg} from '@/core/packet/message/message'; +import { PacketMsg } from '@/core/packet/message/message'; import { PacketMsgFileElement, PacketMsgPicElement, PacketMsgPttElement, PacketMsgVideoElement } from '@/core/packet/message/element'; -import {ChatType, MsgSourceType, NTMsgType, RawMessage} from '@/core'; -import {MiniAppRawData, MiniAppReqParams} from '@/core/packet/entities/miniApp'; -import {AIVoiceChatType} from '@/core/packet/entities/aiChat'; -import {NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg} from '@napneko/nap-proto-core'; -import {IndexNode, LongMsgResult, MsgInfo} from '@/core/packet/transformer/proto'; -import {OidbPacket} from '@/core/packet/transformer/base'; -import {ImageOcrResult} from '@/core/packet/entities/ocrResult'; -import {gunzipSync} from 'zlib'; -import {PacketMsgConverter} from '@/core/packet/message/converter'; +import { ChatType, MsgSourceType, NTMsgType, RawMessage } from '@/core'; +import { MiniAppRawData, MiniAppReqParams } from '@/core/packet/entities/miniApp'; +import { AIVoiceChatType } from '@/core/packet/entities/aiChat'; +import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core'; +import { IndexNode, LongMsgResult, MsgInfo } from '@/core/packet/transformer/proto'; +import { OidbPacket } from '@/core/packet/transformer/base'; +import { ImageOcrResult } from '@/core/packet/entities/ocrResult'; +import { gunzipSync } from 'zlib'; +import { PacketMsgConverter } from '@/core/packet/message/converter'; export class PacketOperationContext { private readonly context: PacketContext; @@ -59,10 +59,10 @@ export class PacketOperationContext { const res = trans.GetStrangerInfo.parse(resp); const extBigInt = BigInt(res.data.status.value); if (extBigInt <= 10n) { - return {status: Number(extBigInt) * 10, ext_status: 0}; + return { status: Number(extBigInt) * 10, ext_status: 0 }; } status = Number((extBigInt & 0xff00n) + ((extBigInt >> 16n) & 0xffn)); - return {status: 10, ext_status: status}; + return { status: 10, ext_status: status }; } catch { return undefined; } @@ -79,13 +79,13 @@ export class PacketOperationContext { const reqList = msg.flatMap(m => m.msg.map(e => { if (e instanceof PacketMsgPicElement) { - return this.context.highway.uploadImage({chatType, peerUid}, e); + return this.context.highway.uploadImage({ chatType, peerUid }, e); } else if (e instanceof PacketMsgVideoElement) { - return this.context.highway.uploadVideo({chatType, peerUid}, e); + return this.context.highway.uploadVideo({ chatType, peerUid }, e); } else if (e instanceof PacketMsgPttElement) { - return this.context.highway.uploadPtt({chatType, peerUid}, e); + return this.context.highway.uploadPtt({ chatType, peerUid }, e); } else if (e instanceof PacketMsgFileElement) { - return this.context.highway.uploadFile({chatType, peerUid}, e); + return this.context.highway.uploadFile({ chatType, peerUid }, e); } return null; }).filter(Boolean) @@ -160,6 +160,12 @@ export class PacketOperationContext { const res = trans.DownloadGroupFile.parse(resp); return `https://${res.download.downloadDns}/ftn_handler/${Buffer.from(res.download.downloadUrl).toString('hex')}/?fname=`; } + async GetPrivateFileUrl(self_id: string, fileUUID: string, md5: string) { + const req = trans.DownloadPrivateFile.build(self_id, fileUUID, md5); + const resp = await this.context.client.sendOidbPacket(req, true); + const res = trans.DownloadPrivateFile.parse(resp); + return `http://${res.body?.result?.server}:${res.body?.result?.port}${res.body?.result?.url?.slice(8)}&isthumb=0`; + } async GetGroupPttUrl(groupUin: number, node: NapProtoEncodeStructType) { const req = trans.DownloadGroupPtt.build(groupUin, node); diff --git a/src/onebot/action/file/GetPrivateFileUrl.ts b/src/onebot/action/file/GetPrivateFileUrl.ts new file mode 100644 index 00000000..d808b2d1 --- /dev/null +++ b/src/onebot/action/file/GetPrivateFileUrl.ts @@ -0,0 +1,38 @@ +import { ActionName } from '@/onebot/action/router'; +import { FileNapCatOneBotUUID } from '@/common/file-uuid'; +import { GetPacketStatusDepends } from '@/onebot/action/packet/GetPacketStatus'; +import { Static, Type } from '@sinclair/typebox'; + +const SchemaData = Type.Object({ + file_id: Type.String(), +}); + +type Payload = Static; + +interface GetPrivateFileUrlResponse { + url?: string; +} + +export class GetPrivateFileUrl extends GetPacketStatusDepends { + override actionName = ActionName.NapCat_GetPrivateFileUrl; + override payloadSchema = SchemaData; + + async _handle(payload: Payload) { + const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file_id); + + if (contextMsgFile?.fileUUID && contextMsgFile.msgId) { + let msg = await this.core.apis.MsgApi.getMsgsByMsgId(contextMsgFile.peer, [contextMsgFile.msgId]); + let self_id = this.core.selfInfo.uid; + let file_hash = msg.msgList[0]?.elements.map(ele => ele.fileElement?.file10MMd5)[0]; + console.log(file_hash,msg) + if (file_hash) { + return { + url: await this.core.apis.PacketApi.pkt.operation.GetPrivateFileUrl(self_id, contextMsgFile.fileUUID, file_hash) + }; + } + + } + console.log(contextMsgFile); + throw new Error('real fileUUID not found!'); + } +} diff --git a/src/onebot/action/index.ts b/src/onebot/action/index.ts index a9044277..c28a838e 100644 --- a/src/onebot/action/index.ts +++ b/src/onebot/action/index.ts @@ -106,6 +106,7 @@ import { SendPoke } from '@/onebot/action/packet/SendPoke'; import { SetDiyOnlineStatus } from './extends/SetDiyOnlineStatus'; import { BotExit } from './extends/BotExit'; import { ClickInlineKeyboardButton } from './extends/ClickInlineKeyboardButton'; +import { GetPrivateFileUrl } from './file/GetPrivateFileUrl'; export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore) { @@ -225,6 +226,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo new GetGroupSystemMsg(obContext, core), new BotExit(obContext, core), new ClickInlineKeyboardButton(obContext, core), + new GetPrivateFileUrl(obContext,core) ]; type HandlerUnion = typeof actionHandlers[number]; diff --git a/src/onebot/action/router.ts b/src/onebot/action/router.ts index 7e065de9..6bed2aa0 100644 --- a/src/onebot/action/router.ts +++ b/src/onebot/action/router.ts @@ -10,6 +10,7 @@ export interface InvalidCheckResult { } export const ActionName = { + NapCat_GetPrivateFileUrl: 'get_private_file_url', ClickInlineKeyboardButton: 'click_inline_keyboard_button', GetUnidirectionalFriendList: 'get_unidirectional_friend_list', // onebot 11 diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 4f4a2e7b..d4f766fb 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -148,7 +148,7 @@ export class OneBotMsgApi { peerUid: msg.peerUid, guildId: '', }; - const file = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileName); + const file = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileUuid); return { type: OB11MessageDataType.file, data: {