1. 新增软著登记所需的源程序生成脚本、docx生成脚本与依赖配置 2. 新增像素大勇者游戏软件V1.0设计说明书与填表指引文档 3. 更新技能配置相关的prefab与meta文件,清理冗余的up状态预制件 4. 修复部分技能buff的颜色与精灵帧引用,更新动画资源引用 5. 新增两个技能图标资源文件
112 lines
3.7 KiB
JavaScript
112 lines
3.7 KiB
JavaScript
/**
|
||
* 软著源程序文档生成脚本
|
||
* 规则:每页 60 行有效代码;超过 60 页时取前 30 页 + 后 30 页;
|
||
* 自动清理文件头第三方署名/版权行;排除声明文件与空文件。
|
||
* 用法:node docs/软著/gen_source_doc.mjs
|
||
*/
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
|
||
const ROOT = path.resolve(import.meta.dirname, '../../assets/script');
|
||
const OUT_DIR = import.meta.dirname;
|
||
const OUT = path.join(OUT_DIR, '像素大勇者游戏软件_V1.0_源程序.txt');
|
||
const LINES_PER_PAGE = 60;
|
||
const KEEP = 30; // 前 30 页 + 后 30 页
|
||
const SOFTWARE = '像素大勇者游戏软件 V1.0';
|
||
|
||
/** 需要从文件头清除的第三方署名 / 编辑器元数据行 */
|
||
const BAD_PATTERNS = [
|
||
/dgflash/i,
|
||
/落日故人/,
|
||
/QQ\s*\d+/,
|
||
/Copyright \(c\)/i,
|
||
/@(Author|LastEditors?|Date|LastEditTime)/i,
|
||
];
|
||
|
||
function walk(dir) {
|
||
const out = [];
|
||
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
||
const p = path.join(dir, e.name);
|
||
if (e.isDirectory()) out.push(...walk(p));
|
||
else out.push(p);
|
||
}
|
||
return out;
|
||
}
|
||
|
||
const rel = (f) => path.relative(ROOT, f).replace(/\\/g, '/');
|
||
|
||
// 1. 收集源文件:仅 .ts,排除 .d.ts 声明文件、空文件、非脚本目录
|
||
let files = walk(ROOT).filter(
|
||
(f) =>
|
||
f.endsWith('.ts') &&
|
||
!f.endsWith('.d.ts') &&
|
||
!rel(f).includes('hit-flash-white/shaders') &&
|
||
fs.readFileSync(f, 'utf8').trim().length > 0
|
||
);
|
||
|
||
// 2. 排序:入口 Main.ts 优先,其次初始化模块,其余按路径字母序
|
||
files.sort((a, b) => {
|
||
const rank = (r) =>
|
||
r === 'Main.ts' ? 0 : r.startsWith('game/initialize') ? 1 : 2;
|
||
return rank(rel(a)) - rank(rel(b)) || rel(a).localeCompare(rel(b));
|
||
});
|
||
|
||
// 3. 清理文件头(前 40 行)中的第三方署名行,统一换行符与缩进
|
||
function cleanFile(content) {
|
||
const lines = content
|
||
.replace(/\r\n/g, '\n')
|
||
.replace(/\t/g, ' ')
|
||
.split('\n');
|
||
const head = lines.slice(0, 40).filter(
|
||
(l) => !BAD_PATTERNS.some((rx) => rx.test(l))
|
||
);
|
||
return [...head, ...lines.slice(40)];
|
||
}
|
||
|
||
const all = [];
|
||
for (const f of files) {
|
||
all.push(`// ===================== 文件: ${rel(f)} =====================`);
|
||
all.push(...cleanFile(fs.readFileSync(f, 'utf8')));
|
||
}
|
||
|
||
// 4. 统计(审校用)
|
||
const total = all.length;
|
||
const blank = all.filter((l) => l.trim() === '').length;
|
||
const comment = all.filter((l) => /^\s*(\/\/|\/\*|\*|\*\/)/.test(l)).length;
|
||
const tooLong = all.filter((l) => l.length > 84).length;
|
||
const totalPages = Math.ceil(total / LINES_PER_PAGE);
|
||
|
||
// 5. 分页:超过 60 页取前 30 + 后 30
|
||
const pageIdx =
|
||
totalPages > 60
|
||
? [
|
||
...Array.from({ length: KEEP }, (_, i) => i),
|
||
...Array.from({ length: KEEP }, (_, i) => totalPages - KEEP + i),
|
||
]
|
||
: Array.from({ length: totalPages }, (_, i) => i);
|
||
const submitPages = pageIdx.length;
|
||
|
||
// 6. 生成文档(页眉:左侧软件全称+版本号,右侧页码)
|
||
const out = [];
|
||
for (const pi of pageIdx) {
|
||
const pageNo = pageIdx.indexOf(pi) + 1;
|
||
const start = pi * LINES_PER_PAGE;
|
||
const body = all.slice(start, start + LINES_PER_PAGE);
|
||
out.push(`${SOFTWARE} 第 ${pageNo} 页 共 ${submitPages} 页`);
|
||
out.push('='.repeat(76));
|
||
out.push(...body);
|
||
out.push('');
|
||
}
|
||
|
||
fs.mkdirSync(OUT_DIR, { recursive: true });
|
||
fs.writeFileSync(OUT, out.join('\n'), 'utf8');
|
||
|
||
console.log('=== 源程序文档生成完成 ===');
|
||
console.log(`文件数: ${files.length}`);
|
||
console.log(`总行数: ${total}(含文件分隔行)`);
|
||
console.log(`总页数: ${totalPages},提交页数: ${submitPages}`);
|
||
console.log(`空行占比: ${((blank / total) * 100).toFixed(1)}%`);
|
||
console.log(`注释行占比: ${((comment / total) * 100).toFixed(1)}%`);
|
||
console.log(`超 84 字符行数: ${tooLong}`);
|
||
console.log(`输出: ${OUT}`);
|