Qiao
|
127f2cd2d6
|
feat(flash-transfer): QQ flash transfer (fileset) upload, share, download (#113)
* feat(proto-defs): add flash-transfer OIDB proto types
QQ 闪传(FlashTransfer / fileset)的 protobuf 类型定义:
- FlashFileEntry(0x93d2/0x93d3 文件条目)
- 0x93cf 申请 fileSet / 0x93d0 commit / 0x93db 完成 / 0x93d1 设状态
- 0x93d3 文件集详情 / 0x93d4 下载 URL(含主文件 fileId + 缩略图)
- 0x12a9 sub=100/103/200 prepare/apply/get-download
- sliceupload body + Sha1StateV
- 0x9407 删除 / 0x9427 重命名 / 0x93d7 发送
注册到 oidb-actions/index.ts,package.json 加 exports。
* feat(protocol): add flash-transfer OIDB services + sha1-stream
闪传协议层(OIDB namespace,复用 invokeOidb/OidbCallSpec):
- apply-fileset / commit-file / complete-fileset / set-status(上传流程)
- prepare-upload (0x12a9_100) / apply-upload (0x12a9_103)(sliceupload 凭证)
- get-fileset-detail (0x93d3) / list-filesets (0x93d2) / get-download-url (0x93d4)
- get-flash-download (0x12a9_200,主文件下载直链)
- delete-file (0x9407) / rename-file (0x9427,sub=0+uinForm) / send-flash (0x93d7)
- sha1-stream:SHA1 中间 state 计算器(sliceupload f107.f6 需要,Node crypto 不支持)
- byte-oracle 单测(apply/prepare/get-download-url/send-flash)+ sha1-stream 单测
package.json 加 exports。
* feat(core): add FlashTransferApi facade
FlashTransferApi 编排闪传全流程,复用 OIDB 基础设施(invokeOidb)+
computeHashes/loadBinarySource/fetch:
- createFlashTask:统一走 sub=100/103+sliceupload(含缩略图),不走小文件 PUT
(PUT 不上报主文件 sha1,fileset 卡在未完成;QQ 客户端小文件也走 sliceupload)
- buildFileId:主文件 appid=14901(进 f14.f1),缩略图 png=14903/jpg=14902
- uploadThumbnail:随机纯色 PNG 占位(手写编码,不引入图像库),关联主文件下载入口
- getFilesetInfo/getFlashFileList/getShareLink/getFlashFileUrl/downloadFileset
- sendFlashMsg(私聊 uid / 群聊 groupId)/ getFilesetIdByCode(网页解析)
- deleteFlashFile / renameFlashFile / listFilesets
注册到 ApiHub(flashTransfer 字段)+ export。
* feat(onebot): add flash-transfer actions
OneBot action(extended.ts)10 个:
create_flash_task / get_fileset_info / get_flash_file_list /
get_flash_file_url / get_share_link / download_fileset /
send_flash_msg(私聊 user_id / 群聊 group_id)/ get_fileset_id /
rename_flash_file / delete_flash_file
MCP catalog(生成文件)同步新增 action 元数据。
extended-actions 接线单测覆盖。
* fix(onebot): align flash file list field name with NapCat
flashFileInfoToJson 的文件大小字段从 file_size 改为 size,对齐 NapCat
get_flash_file_list 响应(NapCat 用 size)。get_fileset_info 的 file_list
复用同一映射,一并生效。便于 NapCat 客户端 drop-in 迁移。
* feat(proto-defs): support multi-file commit in flash-transfer
0x93d0 commit 的 f4 改为 repeated,一个请求携带 fileset 内全部文件条目。
FlashCommitFileInfo 的 f3/f5/f6/f7/f10/f12 用 pb_optional,强制 0 值上 wire
(服务端多文件时严格校验字段存在,省略 0 会导致后续文件不计入 fileset)。
* feat(protocol): parameterize flash-transfer upload for multi-file
CommitFile.Params 改为 entries 数组,serialize 输出 repeated f4,每条 f6=文件序号。
PrepareUpload/ApplyUpload 加 fileIndex + formatCode 参数:filesetWrap.f4 用 fileIndex
(与 commit f6 对齐),f7 用 formatCode(mp4=2 非 26),f9=1。
* feat(core): multi-file flash-transfer upload
createFlashTask 支持多文件共用一个 fileset。关键改动:
- ApplyFileset 多文件时 fileName 用「<首文件名>等N个文件」、fileSize 用总和,
服务端据此判定 fileset 为多文件,commit 的后续 entry 才被计入
- 一次性 CommitFile 提交所有文件元数据(f4 repeated)
- 两阶段上传:先全部 prepare+apply 注册 fileId,再全部 sliceupload 落盘
- 拆分原 uploadLargeFile 为 prepareAndApply + sliceuploadFile
- fileTypeCode mp4 formatCode 26→2(与 commit f7/filesetWrap.f7 一致)
* feat(onebot): multi-file create_flash_task + list_filesets action
create_flash_task 的 files 参数支持 string 或 string[],多文件共用一个 fileset。
新增 list_filesets action(facade.listFilesets 之前未暴露)。MCP catalog 同步更新
files schema(anyOf string/array)与 list_filesets 条目。
* fix(flash-transfer): multi-file download by fileIndex
0x93d4 响应 f1.f3 是 repeated fileInfo(多文件 fileset 每个文件一条,f6=序号、
f14=主文件 fileId),之前定义成单个导致多文件只能拿到第一个文件。
FlashDownloadEntry.fileInfo 改 pb_repeated,GetDownloadUrl 返回所有文件元信息,
download_fileset 按 fileIndex 选中目标文件走 0x12a9 sub=200 拿直链。
* test(protocol): inline byte-oracle hex fixtures
两个 flash-transfer byte-oracle 测试原先用 readFileSync 读仓库外的
.claude/reverse/scripts/proto/*.hex(本地逆向笔记目录),CI 上不存在导致失败。
把 hex 内容内联成常量,测试自包含。
* fix(flash-transfer): address review feedback
1. get_flash_file_url 接 file_index 参数并在 action 透传(之前漏接,多文件永远返回首文件)
2. getFileDownload 越界 fileIndex 不再静默回退首文件,找不到返回 null
3. postSliceupload status 缺失不再当成功,非 success 一律抛错
4. computeSha1StateV 改 O(n) 增量 update(之前每片 reset 重算整个前缀,O(n²))
5. get_flash_file_url 找不到文件抛错(之前返回空串当成功)
6. create_flash_task files 数组拒绝空字符串
|
2026-06-21 14:24:51 +08:00 |
|