Complete Cocos Creator port with level bundles, themes, and tooling.
Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
111
tools/write-deploy-manifest.js
Normal file
111
tools/write-deploy-manifest.js
Normal file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 为运行时包生成 OSS 上传清单(不复制文件 — 本地与 CDN 共用同一目录)。
|
||||
*
|
||||
* node tools/write-deploy-manifest.js [packDir] [--cdn-base URL] [--manifest-dir DIR] [--zip]
|
||||
*
|
||||
* 运行时包: build/mstest5/ ← 上传此目录全部内容到 unitycdndir
|
||||
* 清单输出: build/deploy/UPLOAD-MANIFEST.txt(不进 OSS)
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
const { dirSize, formatBytes } = require('./package-optimize');
|
||||
const { listRuntimeFiles, bundleNamesFromCatalog } = require('./runtime-pack');
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
const flags = new Set(argv.filter((a) => a.startsWith('--')));
|
||||
const positional = argv.filter((a) => !a.startsWith('--'));
|
||||
|
||||
const PROJECT = path.resolve(__dirname, '..');
|
||||
const packDir = path.resolve(positional[0] || path.join(PROJECT, 'build/mstest5'));
|
||||
const manifestDir = (() => {
|
||||
const i = argv.indexOf('--manifest-dir');
|
||||
return path.resolve(i >= 0 ? argv[i + 1] : path.join(PROJECT, 'build/deploy'));
|
||||
})();
|
||||
const cdnBase = (() => {
|
||||
const i = argv.indexOf('--cdn-base');
|
||||
return i >= 0 ? argv[i + 1] : '';
|
||||
})();
|
||||
const makeZip = flags.has('--zip');
|
||||
|
||||
if (!fs.existsSync(path.join(packDir, 'Build/mstest5.loader.js'))) {
|
||||
console.error('错误: 无效运行时包,请先 bash tools/package-for-project.sh');
|
||||
console.error(' 期望:', packDir);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = listRuntimeFiles(packDir);
|
||||
const catalogPath = path.join(packDir, 'StreamingAssets/aa/catalog.json');
|
||||
const bundleNames = bundleNamesFromCatalog(catalogPath);
|
||||
const base = (cdnBase || 'https://YOUR_CDN/unitycdndir').replace(/\/$/, '');
|
||||
|
||||
fs.mkdirSync(manifestDir, { recursive: true });
|
||||
|
||||
const manifestPath = path.join(manifestDir, 'UPLOAD-MANIFEST.txt');
|
||||
const readmePath = path.join(manifestDir, 'README.txt');
|
||||
|
||||
const lines = [
|
||||
'# OSS 上传清单(自动生成)',
|
||||
`# 生成时间: ${new Date().toISOString()}`,
|
||||
`# 运行时包目录: ${packDir}`,
|
||||
`# OSS 根路径 (unitycdndir): ${base}`,
|
||||
'#',
|
||||
'# 上传方式: 将「运行时包目录」内全部内容原样上传到 OSS',
|
||||
'# 本地 static/unity 与 OSS 文件完全一致,前端仅 config.js usecdn 切换根 URL',
|
||||
'#',
|
||||
`# ossutil cp -r "${packDir}/" oss://BUCKET/PATH/`,
|
||||
'',
|
||||
'## 运行时包文件(本地 = CDN)',
|
||||
...files.map((f) => `- ${f.rel}`),
|
||||
'',
|
||||
'## OSS 目标路径',
|
||||
...files.map((f) => `${base}/${f.rel}`),
|
||||
'',
|
||||
'## 上传后验证',
|
||||
`curl -I "${base}/Build/mstest5.loader.js"`,
|
||||
`curl -I "${base}/StreamingAssets/aa/catalog.json"`,
|
||||
`curl -I "${base}/levels-database.json"`,
|
||||
...bundleNames.map((n) => `curl -I "${base}/StreamingAssets/aa/WebGL/${n}"`),
|
||||
];
|
||||
fs.writeFileSync(manifestPath, lines.join('\n'), 'utf8');
|
||||
|
||||
const readme = [
|
||||
'部署说明',
|
||||
'========',
|
||||
'',
|
||||
`生成: ${new Date().toLocaleString('zh-CN')}`,
|
||||
'',
|
||||
'运行时包(本地与 OSS 相同):',
|
||||
` ${packDir}/`,
|
||||
' ├── Build/',
|
||||
' ├── StreamingAssets/',
|
||||
' └── levels-database.json(.br)',
|
||||
'',
|
||||
'本地: import-to-unity.sh → scratch-gui/static/unity/(同上结构)',
|
||||
'CDN: 上传运行时包全部内容 → config.js unitycdndir + usecdn:true',
|
||||
'',
|
||||
`包体积: ${formatBytes(dirSize(packDir))}`,
|
||||
`详细路径: ${manifestPath}`,
|
||||
'',
|
||||
'独立调试页(不进 OSS / static):',
|
||||
` ${path.join(path.dirname(packDir), 'standalone-player')}/index.html`,
|
||||
].join('\n');
|
||||
fs.writeFileSync(readmePath, readme, 'utf8');
|
||||
|
||||
let zipPath = '';
|
||||
if (makeZip) {
|
||||
zipPath = path.join(path.dirname(packDir), 'mstest5-runtime.zip');
|
||||
if (fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
|
||||
const items = ['Build', 'StreamingAssets'];
|
||||
if (fs.existsSync(path.join(packDir, 'levels-database.json'))) items.push('levels-database.json');
|
||||
if (fs.existsSync(path.join(packDir, 'levels-database.json.br'))) items.push('levels-database.json.br');
|
||||
execSync(`cd "${packDir}" && zip -0 -q -r "${zipPath}" ${items.join(' ')}`, { stdio: 'pipe' });
|
||||
}
|
||||
|
||||
console.log('>>> 运行时包:', packDir);
|
||||
console.log(`>>> 文件数: ${files.length}, 体积: ${formatBytes(dirSize(packDir))}`);
|
||||
console.log('>>> 上传清单:', manifestPath);
|
||||
if (zipPath) {
|
||||
console.log(`>>> ZIP: ${zipPath} (${formatBytes(fs.statSync(zipPath).size)})`);
|
||||
}
|
||||
Reference in New Issue
Block a user