Files
TanTan fa9c73363d
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
Publish MCP to npm / Build, test, and publish MCP (push) Waiting to run
Publish SDK to npm / Build, test, and publish SDK (push) Waiting to run
Sync action catalog to docs / sync (push) Waiting to run
Publish UI to npm / Build and publish UI (push) Waiting to run
Build and Release / preflight (push) Waiting to run
SnowLuma v2.4.2 source snapshot
2026-11-13 09:02:00 +08:00

32 lines
5.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from 'vitest';
import { protobuf_decode } from '@snowluma/proton';
import type { OidbBase } from '@snowluma/proto-defs/oidb';
import type { FlashGetDownloadUrlResp } from '@snowluma/proto-defs/oidb-actions/flash-transfer';
import { GetDownloadUrl } from '@snowluma/protocol/oidb-services/flash-transfer/get-download-url';
// 0x93d4 真实响应(send_packet 抓于 QQ 9.9.26-44343, 2026-06-20, fileset e7453377 已发送)。
// byte-oracle:decode + deserialize 必须从 f1.f3.f14.f1 提取到主文件 fileId。
// 0x93d4 响应结构与 0x93d3 不同(downloadUrl 在深层嵌套,非 f9.fileIdWrap),这个测试
// 锁定该结构,防止 deserialize 退回错误的 FlashFileEntry 解读。
const RESP_HEX =
'08d4a7021001180022b8090ab50910011afa080a2465373435333337372d633865612d343034652d393238352d353361613566616431393832122466613038663938332d323337662d303833632d656536332d6139646164336161616565352801300138024222e5b18fe5b995e5bd95e588b620323032352d30352d3033203135313234312e6d70344a2162696e676d756c757a686920323032352d30352d3033203135313234312e6d703458bcf7e3036ae9050a6645685330442d4c3261494b306b74314d51424f764f5377746465753574426a7939774567746e516f724c6d736d5961566c514d794248427962325251674f704a5768424d3744724a3276364843594c766576376b6f30587565674d4d61502d4341514a6e656712a804080212a30468747470733a2f2f6d756c74696d656469612e7166696c652e71712e636f6d2f646f776e6c6f61643f61707069643d313439303226636c69656e745f747970653d77696e26636c69656e745f7665723d392e322e33342666696c6569643d45685330442d4c3261494b306b74314d51424f764f5377746465753574426a7939774567746e516f724c6d736d5961566c514d794248427962325251674f704a5768424d3744724a3276364843594c766576376b6f30587565674d4d61502d4341514a6e656726666c64633d696358456459355a6b5346395f59347239514f526e58562d6a6b31536d397753546b4a316a6876334f357a5f747331484966612d4c6a7662416b52494531526c4373704a4776336c453469635434467437414a794c33577242304b78696a555f423270386a75367a3371314d26726b65793d43414d5371414878697a55514532647437517975726675552d78446d3568666a4d727073325a69723764535f42354d55694349644e594c495167792d5264776d495a797a584a6f31714a687834464d756b346a337042306a5f37787850315a7a6748706469315f3158376178422d736541556c5f3646546f4679597638564d5337645a577036414275597a3875517a79306c487574676a6762714271477138336d70417a6465426475555833513043732d426b54676952767768664b3835696661774a3874477371576e70784871394f444c762d5f37566a78526e424456587046314f306343551a286234306665326636363838326234393264643463343031336166333932633264373565626239623420f2f7012a20393365643461306234383164623936343335323034363339626366393133313830800438c002726b0a674568512d63526273544d5338304c79484637745658626c38536c5a4e63426938392d4d44494c56304b497154305a6d476c5a55444d675277636d396b5549447153566f5156637648434d53585865556b54726c384e555f4a41586f444c6b625f676745435a336f18027a2466613038663938332d323337662d303833632d656536332d613964616433616161656535900103a2012833653731313665633463633462636430626338373137626235353564623937633461353634643730a801bcf7e303b2010308d547ca0120346365613333363331386338303864646431646630613333633938316339316122327b226f6666736574223a31382c22637572736f725f74696d65223a22303030312d30312d30315430303a30303a30305a227d28012a005a1d0a0f636c69656e745f636f6e6e5f736571120a313738313932393033395a200a1a747270632d6f632d7072696f726974792d706173732d6261636b12022d315a1c0a0e73736f5f647965696e675f6b6579120a323535303431393036385a160a0c73736f5f636c69656e74696412063133333034375a9c040a08747270632d73736f128f04000000147061d586907300000ba05fe3000207b7000001fb0073c9510000000e3235353034313930363820071b1b000008040000000000000000000003000000004c668066ca67e24ac9a81bd08aa343840338fa2f632ec020158218d5d2a35f1a2ab856dcbdcc486af66c8ba961db5532e2a065d882604a01539050c7ad17748f95521b4dac5e1834160000001b4f696462537663547270635463702e3078393364345f31000000188e0800005f3a366a000000008d0b00000000000000000000000000002462376234353837623661333666373535346564353235613563396230303166660000000000000000000000040000011d1a007a91020a047061d58610081a06392e322e333420c19e0c4220633165633037346532323533303539633230303530333039653965643932666552005a10b7b4587b6a36f7554ed525a5c9b001ff62206237623435383762366133366637353534656435323561356339623030316666688008720757696e646f7773820118755f6c5253732d3243757359575a6a455851707045694d518a01009001019a015208081248668066ca67e24ac9a81bd08aa343840338fa2f632ec020158218d5d2a35f1a2ab856dcbdcc486af66c8ba961db5532e2a065d882604a01539050c7ad17748f95521b4dac5e18341618c4acf8fa05a00100b80165c00100d201174f696462537663547270635463702e3078393364345f3190010d';
describe('GetDownloadUrl byte-oracle (0x93d4 deserialize)', () => {
it('extracts main file fileId from f1.f3.f14.f1', () => {
const bytes = Uint8Array.from(Buffer.from(RESP_HEX, 'hex'));
const env = protobuf_decode<OidbBase<FlashGetDownloadUrlResp>>(bytes);
const result = GetDownloadUrl.deserialize(null as never, env.body!);
// 0x93d4 f1.f3 是 repeated fileInfo,单文件场景返回一个元素的数组。
expect(result).toHaveLength(1);
const meta = result[0];
// 主文件 fileId(0x93d4 f14.f1),用于 0x12a9 sub=200 拿主文件下载直链。
expect(meta.fileId).toBe(
'EhQ-cRbsTMS80LyHF7tVXbl8SlZNcBi89-MDILV0KIqT0ZmGlZUDMgRwcm9kUIDqSVoQVcvHCMSXXeUkTrl8NU_JAXoDLkb_ggECZ3o',
);
expect(meta.filesetUuid).toBe('e7453377-c8ea-404e-9285-53aa5fad1982');
expect(meta.fileName).toContain('mp4');
expect(meta.fileSize).toBe(7928764);
expect(meta.fileIndex).toBe(1);
});
});