no message

This commit is contained in:
2026-06-18 14:07:38 +08:00
parent d393302388
commit 18990deb2d
12 changed files with 910 additions and 116 deletions

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env node
/**
* 将 levels-database.json 拆为 index + 分片,首屏只下 index~几 KB
*
* 输出:
* <outDir>/levels-db-index.json (+ .br)
* <outDir>/StreamingAssets/aa/levels-db/<min>-<max>.json (+ .br)
*/
const fs = require('fs');
const path = require('path');
const { brotliCompressFile, formatBytes } = require('./package-optimize');
const DEFAULT_SHARD_SIZE = 100;
function mkdirp(p) { fs.mkdirSync(p, { recursive: true }); }
/**
* @param {string} srcPath assets/level-data/levels-database.json
* @param {string} outDir 运行时包根目录
* @param {{ shardSize?: number }} opts
*/
function splitLevelsDatabase(srcPath, outDir, opts = {}) {
const shardSize = opts.shardSize || DEFAULT_SHARD_SIZE;
const raw = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
const levels = raw.levels || {};
const ids = Object.keys(levels)
.map((k) => parseInt(k, 10))
.filter((n) => !Number.isNaN(n))
.sort((a, b) => a - b);
if (ids.length < 1) {
throw new Error(`关卡库为空: ${srcPath}`);
}
const min = ids[0];
const max = ids[ids.length - 1];
const shardDir = path.join(outDir, 'StreamingAssets', 'aa', 'levels-db');
mkdirp(shardDir);
const shards = [];
for (let start = min; start <= max; start += shardSize) {
const end = Math.min(start + shardSize - 1, max);
const slice = {};
for (const id of ids) {
if (id >= start && id <= end) {
slice[String(id)] = levels[String(id)];
}
}
if (!Object.keys(slice).length) continue;
const fileName = `${start}-${end}.json`;
const relFile = `levels-db/${fileName}`;
const absPath = path.join(shardDir, fileName);
fs.writeFileSync(absPath, JSON.stringify({ levels: slice }), 'utf8');
const br = brotliCompressFile(absPath, absPath + '.br');
console.log(`>>> levels-db/${fileName}: ${formatBytes(br.raw)} → .br ${formatBytes(br.br)}`);
shards.push({ min: start, max: end, file: relFile, count: Object.keys(slice).length });
}
const index = {
version: 2,
mode: 'sharded',
shardSize,
levelIdBase: raw.levelIdBase,
generatedAt: raw.generatedAt || new Date().toISOString(),
source: raw.source || 'split-levels-database',
total: ids.length,
min,
max,
stats: raw.stats,
shards,
};
const indexPath = path.join(outDir, 'levels-db-index.json');
fs.writeFileSync(indexPath, JSON.stringify(index), 'utf8');
const indexBr = brotliCompressFile(indexPath, indexPath + '.br');
console.log(`>>> levels-db-index.json: ${formatBytes(indexBr.raw)} → .br ${formatBytes(indexBr.br)}`);
console.log(`>>> 关卡库分片: ${shards.length} 片, ${ids.length} 关 (${min}${max})`);
return { index, shards, total: ids.length };
}
module.exports = { splitLevelsDatabase, DEFAULT_SHARD_SIZE };
if (require.main === module) {
const src = path.resolve(process.argv[2]);
const out = path.resolve(process.argv[3]);
if (!src || !out) {
console.error('Usage: split-levels-database.js <levels-database.json> <outDir>');
process.exit(1);
}
splitLevelsDatabase(src, out);
}