137 lines
6.6 KiB
JavaScript
137 lines
6.6 KiB
JavaScript
// Official battlefield scenes in the 0.2.5 asset pack (PR #533, GitHub #532).
|
|
// The repository never stores the bundles or the extracted files. The full release zip includes
|
|
// public/assets/local/scene when the maintainer extracted it; a lite zip and a source install do not,
|
|
// and setup may fetch + extract on that machine. Missing extractor dependencies keep the metal board.
|
|
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { artPlan, formatSummary, isPlayerFile, isRefused } from '../tools/package.mjs';
|
|
import { localGaps, sceneInstallPlan } from '../tools/setup.mjs';
|
|
|
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
test('sceneInstallPlan: fetch only with a client and extractor deps; otherwise the metal board', () => {
|
|
const present = sceneInstallPlan({ hasScenes: true, client: false });
|
|
assert.equal(present.run, false);
|
|
assert.equal(present.state, 'ok');
|
|
assert.match(present.detail, /金属地块/);
|
|
|
|
const check = sceneInstallPlan({ hasScenes: false, check: true, client: true, python: true });
|
|
assert.equal(check.run, false);
|
|
assert.equal(check.state, 'skip');
|
|
assert.match(check.detail, /--scenes/);
|
|
assert.match(check.detail, /金属地块/);
|
|
|
|
const noClient = sceneInstallPlan({ hasScenes: false, client: false, python: true });
|
|
assert.equal(noClient.run, false);
|
|
assert.equal(noClient.state, 'skip');
|
|
assert.match(noClient.detail, /完整包/);
|
|
assert.match(noClient.detail, /金属地块/);
|
|
|
|
const incomplete = sceneInstallPlan({ hasScenes: false, client: 'incomplete', python: true, force: true });
|
|
assert.equal(incomplete.run, false);
|
|
assert.equal(incomplete.state, 'warn');
|
|
assert.match(incomplete.detail, /金属地块/);
|
|
|
|
const noPy = sceneInstallPlan({ hasScenes: false, client: true, python: false });
|
|
assert.equal(noPy.run, false);
|
|
assert.equal(noPy.state, 'warn');
|
|
assert.match(noPy.detail, /Python/);
|
|
assert.match(noPy.detail, /金属地块/);
|
|
|
|
const noDeps = sceneInstallPlan({ hasScenes: false, client: true, python: true, deps: false });
|
|
assert.equal(noDeps.run, false);
|
|
assert.equal(noDeps.state, 'warn');
|
|
assert.match(noDeps.detail, /UnityPy/);
|
|
assert.match(noDeps.detail, /金属地块/);
|
|
|
|
const declined = sceneInstallPlan({ hasScenes: false, client: true, python: true, declined: true });
|
|
assert.equal(declined.run, false);
|
|
assert.equal(declined.state, 'skip');
|
|
|
|
const ask = sceneInstallPlan({ hasScenes: false, client: true, python: true });
|
|
assert.equal(ask.run, false);
|
|
assert.equal(ask.state, 'ask');
|
|
assert.match(ask.detail, /金属地块/);
|
|
|
|
for (const extra of [{ force: true, declined: true }, { yes: true }]) {
|
|
const go = sceneInstallPlan({ hasScenes: false, client: true, python: true, ...extra });
|
|
assert.equal(go.run, true, JSON.stringify(extra));
|
|
assert.match(go.detail, /金属地块/);
|
|
}
|
|
});
|
|
|
|
test('an older extraction is told it lacks the battlefield scenes', () => {
|
|
assert.equal(localGaps({ enemySpines: true, tokenSpines: true }), '');
|
|
assert.match(localGaps({ enemySpines: true, tokenSpines: true, scenes: false }), /各战场官方场景/);
|
|
assert.match(localGaps({ enemySpines: false, tokenSpines: false, scenes: false }), /各战场官方场景/);
|
|
});
|
|
|
|
test('official scene bundles and extracted scenes are not git files; the extractor scripts are', () => {
|
|
const gi = fs.readFileSync(path.join(ROOT, '.gitignore'), 'utf8');
|
|
assert.match(gi, /^public\/assets\/$/m);
|
|
assert.match(gi, /^data\/local-assets\.json$/m);
|
|
assert.match(gi, /^\.cache\/$/m);
|
|
assert.match(gi, /official-scenes/);
|
|
assert.equal(isRefused('.cache/official-scenes/26-04-13-12-31-42_e9b560/scenes/a.ab'), true);
|
|
assert.equal(isRefused('public/assets/local/scene/act2autochess_m02/scene.bin'), false);
|
|
assert.equal(isPlayerFile('public/assets/local/scene/act2autochess_m02/scene.bin'), false);
|
|
assert.equal(isPlayerFile('tools/local-extract/scenes.py'), true);
|
|
assert.equal(isPlayerFile('tools/local-extract/fetch_scenes.py'), true);
|
|
});
|
|
|
|
test('the full asset plan ships extracted scenes; the lite plan ships none', () => {
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-scenes-'));
|
|
try {
|
|
const sceneDir = path.join(dir, 'public/assets/local/scene/act2autochess_m02');
|
|
const texDir = path.join(dir, 'public/assets/local/scene/tex');
|
|
fs.mkdirSync(sceneDir, { recursive: true });
|
|
fs.mkdirSync(texDir, { recursive: true });
|
|
fs.mkdirSync(path.join(dir, 'data'), { recursive: true });
|
|
fs.writeFileSync(path.join(dir, 'data/assets.json'), '{}\n');
|
|
fs.writeFileSync(path.join(sceneDir, 'scene.bin'), 'mesh-bytes');
|
|
fs.writeFileSync(path.join(sceneDir, 'scene.json'), '{}\n');
|
|
fs.writeFileSync(path.join(texDir, 'TX_A.webp'), 'webp');
|
|
fs.writeFileSync(path.join(dir, 'data/local-assets.json'), JSON.stringify({
|
|
version: 1,
|
|
groups: {
|
|
'scene/act2autochess_m02': {
|
|
scene: { path: '/assets/local/scene/act2autochess_m02/scene.json' },
|
|
bin: { path: '/assets/local/scene/act2autochess_m02/scene.bin' },
|
|
},
|
|
'scene/tex': { TX_A: { path: '/assets/local/scene/tex/TX_A.webp' } },
|
|
},
|
|
}));
|
|
const full = artPlan(dir, { lite: false });
|
|
for (const f of [
|
|
'public/assets/local/scene/act2autochess_m02/scene.bin',
|
|
'public/assets/local/scene/act2autochess_m02/scene.json',
|
|
'public/assets/local/scene/tex/TX_A.webp',
|
|
'data/local-assets.json',
|
|
]) assert.ok(full.files.includes(f), f);
|
|
assert.ok(full.scenes.includes('public/assets/local/scene/act2autochess_m02/scene.bin'));
|
|
assert.equal(full.scenes.length, 3);
|
|
const lite = artPlan(dir, { lite: true });
|
|
assert.deepEqual(lite.files, []);
|
|
assert.deepEqual(lite.scenes, []);
|
|
const summary = formatSummary({
|
|
lite: false, version: '0.2.5-dev', tracked: [], art: [], localArt: true, generated: [], dropped: {}, orphans: [], held: [],
|
|
scanned: 0, names: 0, problems: [], scenes: { files: full.scenes, bytes: 9 + 3 + 4 },
|
|
bytes: { tracked: 0, art: 16, modules: 0, vendor: 0, total: 16, leftOut: 0, orphans: 0 },
|
|
});
|
|
assert.match(summary, /battlefield scenes: 3 files/);
|
|
const empty = formatSummary({
|
|
lite: false, version: '0.2.5-dev', tracked: [], art: [], localArt: true, generated: [], dropped: {}, orphans: [], held: [],
|
|
scanned: 0, names: 0, problems: [], scenes: { files: [], bytes: 0 },
|
|
bytes: { tracked: 0, art: 0, modules: 0, vendor: 0, total: 0, leftOut: 0, orphans: 0 },
|
|
});
|
|
assert.match(empty, /battlefield scenes: none/);
|
|
} finally {
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|