0.2.6-dev: the client fetches a served manifest's content-hashed audio as /media/~<hash>/… (download-manager route kept), and the token death sound derived beside charDie drops charDie's hash — host bandwidth layer 1.3; golden: unchanged
This commit is contained in:
1 parent
893d17e725
commit
35b09bb63b
7 files changed
+54
-5
No files matched your search
@@ -111,6 +111,11 @@ test('#4 audio classes (official ON_UNIT_DEAD/BORN defaults): only operators pla
|
||||
assert.equal(deathSfxUrl(manifest, bomb, { consumed: true }), null, 'used up ⇒ silent');
|
||||
assert.equal(deathSfxUrl(manifest, mapChar), SFX.battle.charDie, 'band map characters are operators');
|
||||
assert.equal(deathSfxUrl(manifest, crate), TOKEN_DEAD, 'act crate trap_1105 ⇒ b_char_tokendead');
|
||||
// a served manifest's charDie carries charDie's content hash (host bandwidth layer 1): the sound derived beside it
|
||||
// names another file, so it goes out without the segment (served plainly, cached a day) instead of a wrong hash
|
||||
const hashed = { ...manifest, audio: { ...manifest.audio, sfx: { ...SFX, battle: { ...SFX.battle, charDie: SFX.battle.charDie.replace(/^\/assets\//, '/assets/~0123456789abcdef/') } } } };
|
||||
assert.equal(deathSfxUrl(hashed, op), hashed.audio.sfx.battle.charDie);
|
||||
assert.equal(deathSfxUrl(hashed, tok), TOKEN_DEAD, 'b_char_tokendead without charDie\'s hash');
|
||||
assert.equal(deathSfxUrl(manifest, enemy), SFX.battle.enemyDie);
|
||||
assert.equal(deathSfxUrl(manifest, boss), SFX.battle.enemyDieHeavy);
|
||||
assert.equal(deathSfxUrl(manifest, op, { reason: 'retreat' }), null, 'a retreat is no knock-down');
|
||||
|
||||
@@ -23,6 +23,16 @@ describe('mediaUrl: 音频地址去掉扩展名(躲开下载器嗅探)', ()
|
||||
assert.equal(mediaUrl('/assets/audio/x/A.MP3', ORIGIN), '/media/x/A', '大小写不敏感');
|
||||
});
|
||||
|
||||
test('服务器下发的清单带内容哈希段(/assets/~<hash>/audio/…):改写后保留这一段', () => {
|
||||
const H = '0123456789abcdef';
|
||||
assert.equal(mediaUrl(`/assets/~${H}/audio/bgm/m_sys_act1autochess_loop.mp3`, ORIGIN), `/media/~${H}/bgm/m_sys_act1autochess_loop`);
|
||||
assert.equal(mediaUrl(`${ORIGIN}/assets/~${H}/audio/sfx/a.mp3`, ORIGIN), `/media/~${H}/sfx/a`);
|
||||
assert.doesNotMatch(mediaUrl(`/assets/~${H}/audio/bgm/a.mp3`, ORIGIN), /\.(mp3|m4a|aac|ogg|oga|opus|wav)(\?|$)/i);
|
||||
// 不是合法的哈希段(大写、长度不对)就不是我们的音频地址,原样返回
|
||||
assert.equal(mediaUrl(`/assets/~${H.toUpperCase()}/audio/a.mp3`, ORIGIN), `/assets/~${H.toUpperCase()}/audio/a.mp3`);
|
||||
assert.equal(mediaUrl(`/assets/~${H}/char/a.png`, ORIGIN), `/assets/~${H}/char/a.png`, '图片不改写');
|
||||
});
|
||||
|
||||
test('改写后的地址里不再有任何媒体扩展名(下载器就是按这个嗅探的)', () => {
|
||||
const out = mediaUrl('/assets/audio/bgm/m_bat_vtlionk_loop.mp3', ORIGIN);
|
||||
assert.equal(out.startsWith(MEDIA_PREFIX), true);
|
||||
|
||||
@@ -655,6 +655,27 @@ describe('AudioManager', () => {
|
||||
console.warn = origWarn;
|
||||
}
|
||||
});
|
||||
test('a served manifest\'s content-hashed audio URL is fetched as /media/~<hash>/…, falling back to the hashed .mp3 URL', async () => {
|
||||
const H = '0123456789abcdef';
|
||||
const raw = manifest.audio.bgm.prep.loop.replace(/^\/assets\//, `/assets/~${H}/`);
|
||||
const served = { ...manifest, audio: { ...manifest.audio, bgm: { ...manifest.audio.bgm, prep: { loop: raw } } } };
|
||||
const fw = fakeWindow();
|
||||
const urls = [];
|
||||
const origFetch = globalThis.fetch;
|
||||
globalThis.fetch = async (u) => { urls.push(u); return u.startsWith('/media/') ? { ok: false, status: 404 } : { ok: true, arrayBuffer: async () => new ArrayBuffer(8) }; };
|
||||
try {
|
||||
const a = new AudioManager({ win: fw.win, getManifest: () => served });
|
||||
a.install();
|
||||
fw.fire('pointerdown');
|
||||
a.playBgm('prep');
|
||||
await new Promise((r) => setTimeout(r, 20));
|
||||
assert.deepEqual(urls, [raw.replace(/^\/assets\/(~[0-9a-f]{16})\/audio\/(.+)\.mp3$/, '/media/$1/$2'), raw]);
|
||||
assert.match(urls[0], new RegExp(`^/media/~${H}/bgm/`));
|
||||
assert.equal(a.bgm?.loopUrl, raw);
|
||||
} finally {
|
||||
globalThis.fetch = origFetch;
|
||||
}
|
||||
});
|
||||
test('音频先走无扩展名的 /media/ 路由;只有它 404 才回退到带扩展名的原地址', async () => {
|
||||
const raw = manifest.audio.bgm.prep.loop;
|
||||
const media = mediaUrl(raw);
|
||||
|
||||
Reference in new issue
Block a user