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;