From 00a70b1cccc71cae45b4eb6458a94e3faf163e31 Mon Sep 17 00:00:00 2001 From: DrSmoothl <1787882683@qq.com> Date: Wed, 13 May 2026 22:19:45 +0800 Subject: [PATCH] fix(bridge): preserve full ext-biz-info on media upload round-trip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NTV2 upload-response decoder used stub schemas that omitted fields QQ NT echoes back (notably video.fromScene/toScene, pic.fromScene/ toScene/oldFileId, the ptt scene/waveform set), so finalizeMediaMsgInfo re-encoded the commonElem.pbElem with those fields missing. For c2c video this triggered `send private message rejected: result=79` on every send_private_msg [{type:'video'}] call — the upload itself fast-pathed fine but the follow-up SendMessage was rejected by NT. Drop the duplicate NTV2 placeholder schemas and route NTV2ExtBizInfo through the element-side PicExtBizInfo / VideoExtBizInfo / PttExtBizInfo, which are field-complete. Also zero out the main video sub-file's width/height/time/videoFormat in the upload request to mirror NapCat — those fields belong on the thumb, not the source mp4, and non-zero values trip schema validation on c2c sends. --- .../core/src/bridge/highway/video-upload.ts | 12 ++++-- packages/core/src/bridge/proto/highway.ts | 38 +++++-------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/packages/core/src/bridge/highway/video-upload.ts b/packages/core/src/bridge/highway/video-upload.ts index 4f60cb2c..94c8e743 100644 --- a/packages/core/src/bridge/highway/video-upload.ts +++ b/packages/core/src/bridge/highway/video-upload.ts @@ -460,10 +460,14 @@ export async function uploadVideoMsgInfo( fileHash: video.md5Hex, fileSha1: video.sha1Hex, fileName: 'nya.mp4', - type: { type: 2, picFormat: 0, videoFormat: video.videoFormat, voiceFormat: 0 }, - height: video.height, - width: video.width, - time: video.duration, + // NapCat sends type.videoFormat=0 and width/height/time=0 + // for the main video sub-file (only the thumb carries + // dimensions). The QQ NT server treats non-zero values + // here as a schema mismatch on c2c sends. + type: { type: 2, picFormat: 0, videoFormat: 0, voiceFormat: 0 }, + height: 0, + width: 0, + time: 0, original: 0, }, subFileType: 0, diff --git a/packages/core/src/bridge/proto/highway.ts b/packages/core/src/bridge/proto/highway.ts index 9f5a5d75..2346dc81 100644 --- a/packages/core/src/bridge/proto/highway.ts +++ b/packages/core/src/bridge/proto/highway.ts @@ -234,35 +234,17 @@ export const NTV2UploadInfoSchema = { subFileType: { field: 2, type: 'uint32' as const }, } satisfies ProtoSchema; -export const NTV2PicReserveC2CSchema = { - subType: { field: 1, type: 'uint32' as const }, -} satisfies ProtoSchema; - -export const NTV2PicReserveTroopSchema = { - subType: { field: 1, type: 'uint32' as const }, -} satisfies ProtoSchema; - -export const NTV2PicExtBizInfoSchema = { - bizType: { field: 1, type: 'uint32' as const }, - textSummary: { field: 2, type: 'string' as const }, - reserveC2c: { field: 11, type: 'message' as const, schema: NTV2PicReserveC2CSchema }, - reserveTroop: { field: 12, type: 'message' as const, schema: NTV2PicReserveTroopSchema }, -} satisfies ProtoSchema; - -export const NTV2VideoExtBizInfoSchema = { - bytesPbReserve: { field: 3, type: 'bytes' as const }, -} satisfies ProtoSchema; - -export const NTV2PttExtBizInfoSchema = { - bytesReserve: { field: 11, type: 'bytes' as const }, - bytesPbReserve: { field: 12, type: 'bytes' as const }, - bytesGeneralFlags: { field: 13, type: 'bytes' as const }, -} satisfies ProtoSchema; - +// The NTV2 upload request + response carry the same ExtBizInfo shape that +// element-side incoming-message decoding uses. Pulling those schemas in +// directly (instead of redefining stub copies) keeps the round-trip +// `server response → finalizeMediaMsgInfo → commonElem.pbElem` from +// silently dropping fields the QQ NT server later validates against — +// the video `fromScene`/`toScene` drop was already responsible for c2c +// `result=79` rejections on `send_private_msg [{type:'video'}]`. export const NTV2ExtBizInfoSchema = { - pic: { field: 1, type: 'message' as const, schema: NTV2PicExtBizInfoSchema }, - video: { field: 2, type: 'message' as const, schema: NTV2VideoExtBizInfoSchema }, - ptt: { field: 3, type: 'message' as const, schema: NTV2PttExtBizInfoSchema }, + pic: { field: 1, type: 'message' as const, schema: PicExtBizInfoSchema }, + video: { field: 2, type: 'message' as const, schema: VideoExtBizInfoSchema }, + ptt: { field: 3, type: 'message' as const, schema: PttExtBizInfoSchema }, busiType: { field: 10, type: 'uint32' as const }, } satisfies ProtoSchema;