消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
48 KiB

1 week ago
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.onAfterBuild = exports.onBeforeBuild = exports.throwError = void 0;
/**
* 构建进程独立 worker加载的钩子脚本custom-builder configs.*.hooks 指向本文件
* custom-builder.ts re-export 本文件的钩子供编辑器校验通过
*/
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const lz4js_1 = __importDefault(require("lz4js"));
const terser_1 = require("terser");
exports.throwError = true;
function readJson(filePath) {
const raw = fs_1.default.readFileSync(filePath, 'utf8');
return JSON.parse(raw);
}
/** 解析 game.json;若尾部被旧内容污染则截取首个完整 JSON 对象 */
function readGameJsonSafe(filePath) {
const raw = fs_1.default.readFileSync(filePath, 'utf8').trim();
try {
return JSON.parse(raw);
}
catch (err) {
const start = raw.indexOf('{');
if (start < 0)
throw err;
let depth = 0;
let end = -1;
for (let i = start; i < raw.length; i++) {
const ch = raw[i];
if (ch === '{')
depth++;
else if (ch === '}') {
depth--;
if (depth === 0) {
end = i;
break;
}
}
}
if (end > start) {
const recovered = raw.slice(start, end + 1);
console.warn(`[tools] game.json 含脏数据,已自动截取有效 JSON: ${filePath}`);
return JSON.parse(recovered);
}
throw err;
}
}
function writeJsonFile(filePath, data) {
const content = `${JSON.stringify(data, null, 2)}\n`;
const tmp = `${filePath}.tmp`;
fs_1.default.writeFileSync(tmp, content, 'utf8');
fs_1.default.renameSync(tmp, filePath);
}
function resolveConfigNameVersion(projectPath) {
var _a, _b, _c, _d, _e, _f;
const sdkConfigPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'sdkConfig.ts');
const sdkConfigContent = fs_1.default.readFileSync(sdkConfigPath, 'utf8');
const importRegex = /import\s+\{\s*(\w+)\s*\}\s+from\s+["']\.\/config\/([^"']+)["'];?/g;
const importMap = new Map();
let m = null;
while ((m = importRegex.exec(sdkConfigContent))) {
importMap.set(m[1], m[2]);
}
const configAssign = sdkConfigContent.match(/static\s+readonly\s+config\s*:\s*IConfigData\s*=\s*(\w+)\s*;/);
const symbol = (_a = configAssign === null || configAssign === void 0 ? void 0 : configAssign[1]) !== null && _a !== void 0 ? _a : 'DefaultConfig';
const relConfig = (_b = importMap.get(symbol)) !== null && _b !== void 0 ? _b : 'DefaultConfig';
const configPath = path_1.default.join(projectPath, 'assets', 'script', 'sdk', 'config', `${relConfig}.ts`);
const configContent = fs_1.default.readFileSync(configPath, 'utf8');
const name = (_d = (_c = configContent.match(/name\s*:\s*["']([^"']+)["']/)) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : 'config';
const vsion = (_f = (_e = configContent.match(/vsion\s*:\s*["']([^"']+)["']/)) === null || _e === void 0 ? void 0 : _e[1]) !== null && _f !== void 0 ? _f : '0.0.0';
return { name, vsion };
}
function encodeForRuntime(jsonObj) {
const jsonString = JSON.stringify(jsonObj);
const uint8 = new TextEncoder().encode(jsonString);
const compressed = Uint8Array.from(lz4js_1.default.compress(uint8));
const binary = Buffer.from(compressed).toString('latin1');
const base64 = Buffer.from(binary, 'latin1').toString('base64');
return Buffer.from(base64, 'latin1');
}
const HOT_UPDATE_TABLE_FILES = [
{ tableKey: 'Chapter', fileName: 'Chapter.json' },
{ tableKey: 'BattleCube', fileName: 'BattleCube.json' },
{ tableKey: 'Skill_pool', fileName: 'Skill_pool.json' },
{ tableKey: 'skill_pool_use', fileName: 'skill_pool_use.json' },
{ tableKey: 'Const_weight', fileName: 'Const_weight.json' },
{ tableKey: 'TetriWaveWeight', fileName: 'TetriWaveWeight.json' },
{ tableKey: 'Weapon2', fileName: 'Weapon2.json' },
{ tableKey: 'Monster', fileName: 'Monster.json' },
{ tableKey: 'Monster2', fileName: 'Monster2.json' },
];
function generateConfigBin() {
const projectPath = Editor.Project.path;
const configDir = path_1.default.join(projectPath, 'assets', 'bundles', 'first', 'config');
const mergeJson = {};
for (const { tableKey, fileName } of HOT_UPDATE_TABLE_FILES) {
const fp = path_1.default.join(configDir, fileName);
if (!fs_1.default.existsSync(fp)) {
console.warn(`[tools] skip bin generate: missing ${fileName}`);
return;
}
mergeJson[tableKey] = readJson(fp);
}
const { name, vsion } = resolveConfigNameVersion(projectPath);
const safeName = `${name}${vsion}`.replace(/[<>:"/\\|?*]+/g, '_');
const outDir = path_1.default.join(projectPath, 'bin');
const outFile = path_1.default.join(outDir, `${safeName}.bin`);
fs_1.default.mkdirSync(outDir, { recursive: true });
fs_1.default.writeFileSync(outFile, encodeForRuntime(mergeJson));
console.log(`[tools] generated config bin: ${outFile}`);
}
function collectJsFiles(dir, acc) {
if (!fs_1.default.existsSync(dir))
return;
const st = fs_1.default.statSync(dir);
if (!st.isDirectory())
return;
const entries = fs_1.default.readdirSync(dir, { withFileTypes: true });
for (const e of entries) {
const full = path_1.default.join(dir, e.name);
if (e.isDirectory()) {
collectJsFiles(full, acc);
}
else if (e.isFile() && e.name.endsWith('.js')) {
acc.push(full);
}
}
}
function collectStripRoots(options, result) {
var _a, _b, _c, _d;
const roots = new Set();
const add = (p) => {
if (p == null || p === '')
return;
const s = path_1.default.normalize(String(p).replace(/\//g, path_1.default.sep));
try {
if (fs_1.default.existsSync(s)) {
const st = fs_1.default.statSync(s);
if (st.isDirectory())
roots.add(s);
}
}
catch (_a) {
/* ignore */
}
};
add(result === null || result === void 0 ? void 0 : result.dest);
add((_a = result === null || result === void 0 ? void 0 : result.paths) === null || _a === void 0 ? void 0 : _a.dir);
add((_b = result === null || result === void 0 ? void 0 : result.paths) === null || _b === void 0 ? void 0 : _b.assets);
add((_c = result === null || result === void 0 ? void 0 : result.paths) === null || _c === void 0 ? void 0 : _c.bundleScripts);
add((_d = result === null || result === void 0 ? void 0 : result.paths) === null || _d === void 0 ? void 0 : _d.subpackages);
const projectPath = Editor.Project.path;
if (projectPath && (options === null || options === void 0 ? void 0 : options.buildPath) && (options === null || options === void 0 ? void 0 : options.outputName)) {
let bp = String(options.buildPath);
if (bp.includes('project:')) {
bp = path_1.default.join(projectPath, bp.replace(/^project:\/\//, '').replace(/^project:/, ''));
}
add(path_1.default.join(bp, options.outputName));
}
return [...roots];
}
function collectAllJsFiles(roots) {
const files = new Set();
for (const root of roots) {
const acc = [];
collectJsFiles(root, acc);
for (const f of acc)
files.add(path_1.default.normalize(f));
}
return [...files];
}
async function minifyStripConsole(src) {
const base = {
compress: {
drop_console: true,
drop_debugger: true,
passes: 2,
},
mangle: false,
format: { comments: 'some' },
ecma: 2020,
};
let out = await (0, terser_1.minify)(src, base);
if (out.code != null)
return out.code;
out = await (0, terser_1.minify)(src, Object.assign(Object.assign({}, base), { module: true }));
if (out.code != null)
return out.code;
throw new Error('terser returned empty');
}
async function stripConsoleFromBuildOutput(roots) {
const files = collectAllJsFiles(roots);
if (files.length === 0) {
console.warn('[tools] stripConsole: no .js under roots', roots);
return;
}
let ok = 0;
let fail = 0;
for (const file of files) {
try {
const src = fs_1.default.readFileSync(file, 'utf8');
const code = await minifyStripConsole(src);
fs_1.default.writeFileSync(file, code, 'utf8');
ok++;
}
catch (err) {
fail++;
console.warn(`[tools] stripConsole skip (terser error): ${file}`, err);
}
}
console.log(`[tools] stripConsole done: ok=${ok}, fail=${fail}, roots=${roots.join('; ')}`);
}
const PARALLEL_PRELOAD_SUBPACKAGES = [
{ name: 'main' },
{ name: 'first' },
{ name: 'comm' },
];
/** 远程资源包:体积大,不计入微信 30M 包体,不得写入 subpackages */
const REMOTE_BUNDLE_NAMES = new Set(['audio', 'tetriMap']);
function resolveBuildDest(options, result) {
const candidates = [];
if (result === null || result === void 0 ? void 0 : result.dest)
candidates.push(String(result.dest));
const projectPath = Editor.Project.path;
if (projectPath && (options === null || options === void 0 ? void 0 : options.buildPath) && (options === null || options === void 0 ? void 0 : options.outputName)) {
let bp = String(options.buildPath);
if (bp.includes('project:')) {
bp = path_1.default.join(projectPath, bp.replace(/^project:\/\//, '').replace(/^project:/, ''));
}
candidates.push(path_1.default.join(bp, options.outputName));
}
for (const c of candidates) {
const normalized = path_1.default.normalize(c);
const gameJson = path_1.default.join(normalized, 'game.json');
if (fs_1.default.existsSync(gameJson))
return normalized;
}
return null;
}
function isWeChatGameJson(gameJson) {
var _a, _b;
const provider = (_b = (_a = gameJson === null || gameJson === void 0 ? void 0 : gameJson.plugins) === null || _a === void 0 ? void 0 : _a.cocos) === null || _b === void 0 ? void 0 : _b.provider;
return typeof provider === 'string' && provider.startsWith('wx');
}
/** 构建后校正 game.json:仅保留启动三分包并行预下载 */
function patchWeChatGameJson(buildDest) {
const gameJsonPath = path_1.default.join(buildDest, 'game.json');
if (!fs_1.default.existsSync(gameJsonPath))
return;
const gameJson = readGameJsonSafe(gameJsonPath);
gameJson.parallelPreloadSubpackages = PARALLEL_PRELOAD_SUBPACKAGES;
if (Array.isArray(gameJson.subpackages)) {
const before = gameJson.subpackages.length;
gameJson.subpackages = gameJson.subpackages.filter((sp) => { var _a; return !REMOTE_BUNDLE_NAMES.has((_a = sp === null || sp === void 0 ? void 0 : sp.name) !== null && _a !== void 0 ? _a : ''); });
if (gameJson.subpackages.length < before) {
console.log('[tools] removed remote bundles from subpackages:', [...REMOTE_BUNDLE_NAMES]);
}
}
// 未使用开放数据域时不要写 openDataContext;空字符串会导致微信开发者工具编译失败
const openDataContext = gameJson.openDataContext;
if (openDataContext == null
|| (typeof openDataContext === 'string' && !openDataContext.trim())) {
delete gameJson.openDataContext;
}
writeJsonFile(gameJsonPath, gameJson);
readGameJsonSafe(gameJsonPath);
console.log('[tools] patched game.json → parallelPreloadSubpackages main/first/comm, removed empty openDataContext');
}
function shouldStripConsole(options) {
var _a, _b;
const v = (_b = (_a = options === null || options === void 0 ? void 0 : options.packages) === null || _a === void 0 ? void 0 : _a.tools) === null || _b === void 0 ? void 0 : _b.stripConsole;
if (v === true)
return true;
if (v === 'true' || v === 1)
return true;
return false;
}
function onBeforeBuild(_options, _result) {
try {
console.log('[tools] onBeforeBuild: generate config bin');
generateConfigBin();
}
catch (err) {
console.error('[tools] onBeforeBuild generate config bin failed:', err);
}
return true;
}
exports.onBeforeBuild = onBeforeBuild;
async function onAfterBuild(options, result) {
try {
const buildDest = resolveBuildDest(options, result);
if (buildDest) {
const gameJsonPath = path_1.default.join(buildDest, 'game.json');
if (fs_1.default.existsSync(gameJsonPath)) {
if ((options === null || options === void 0 ? void 0 : options.platform) === 'wechatgame' || isWeChatGameJson(readGameJsonSafe(gameJsonPath))) {
patchWeChatGameJson(buildDest);
}
}
}
else if ((options === null || options === void 0 ? void 0 : options.platform) === 'wechatgame') {
console.warn('[tools] wechatgame build finished but build output dir was not resolved');
}
}
catch (err) {
console.error('[tools] onAfterBuild patch game.json failed:', err);
}
try {
if (shouldStripConsole(options)) {
const roots = collectStripRoots(options, result);
if (roots.length === 0) {
console.warn('[tools] stripConsole 已勾选但未能解析构建输出目录(检查 result.dest / paths / buildPath+outputName)');
}
else {
console.log('[tools] onAfterBuild stripConsole →', roots.join(' | '));
await stripConsoleFromBuildOutput(roots);
}
}
}
catch (err) {
console.error('[tools] onAfterBuild stripConsole failed:', err);
}
try {
console.log('[tools] onAfterBuild: generate config bin');
generateConfigBin();
}
catch (err) {
console.error('[tools] onAfterBuild generate config bin failed:', err);
}
return true;
}
exports.onAfterBuild = onAfterBuild;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQtaG9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2UvYnVpbGQtaG9va3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7OztHQUdHO0FBQ0gsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4QixrREFBd0I7QUFDeEIsbUNBQWdDO0FBRW5CLFFBQUEsVUFBVSxHQUFHLElBQUksQ0FBQztBQUUvQixTQUFTLFFBQVEsQ0FBQyxRQUFnQjtJQUM5QixNQUFNLEdBQUcsR0FBRyxZQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQUVELDRDQUE0QztBQUM1QyxTQUFTLGdCQUFnQixDQUFDLFFBQWdCO0lBQ3RDLE1BQU0sR0FBRyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JELElBQUk7UUFDQSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDMUI7SUFBQyxPQUFPLEdBQUcsRUFBRTtRQUNWLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsSUFBSSxLQUFLLEdBQUcsQ0FBQztZQUFFLE1BQU0sR0FBRyxDQUFDO1FBQ3pCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2IsS0FBSyxJQUFJLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDckMsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLElBQUksRUFBRSxLQUFLLEdBQUc7Z0JBQUUsS0FBSyxF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