Files
TankIC/3DTank/tools/parse_dsstore.js
T
TermiNexus fd0dffe31b feat(bundle): 迁移到新版 main.7cfa4058.js(重做拆分 + 移植 7 处针对性修改)
- 拆分:tools/split.js 重切新版(1347 模块 / 126 代码模块),主文件 main.7cfa4058.js,语法验证通过

- 修复 split.js 内自动刷新拦截的 \\n 转义:它在模板字符串里,必须写 \\\\n,否则生成的主文件字符串断行、语法报错

- 符号映射:map_symbols.js 对齐旧→新(qyr→ryz、w187→c18o、z4t→jtn、vgt→rkt、Bmt→Ezt、Qjt→Fjt、txt→Gjt、k15b→s15n、azi_1→vzr_1…)

- 移植 7 处针对性修改:炮塔摆头不回弹(vSt.ryz)、摆头不过冲(case 0)、精准跟手(case 1/2)、悬浮底盘 raw 两级(Ezt.n36 + Zmt 实际速度)、电磁炮蓄力时长(jtn.c18o)

- 重新打包 unpacked.pack.json(127 文件 / 版本 96833eb2b0cf8909)
2026-10-16 14:20:15 +08:00

59 lines
2.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// parse_dsstore.js - 从 macOS .DS_Store 里抽出目录项名字
// 用法: node parse_dsstore.js <file.ds_store> [--json out.json]
// 原理: DS_Store 是 B 树,文件/目录名记录以 [type=0x00000005][offset u32][len u32][len×UTF-16BE] 内联存放,
// 因此用滑动扫描定位 type 标记再读长度即可,无需完整解析 B 树。
const fs = require('fs');
const path = require('path');
const Argv = process.argv.slice(2);
const File = Argv[0];
const JsonOut = (() => {
const I = Argv.indexOf('--json');
return I >= 0 && Argv[I + 1] ? Argv[I + 1] : '';
})();
const Buf = fs.readFileSync(File);
const Names = new Set();
// 主路径:定位 type=5 记录
for (let I = 0; I + 12 <= Buf.length; I++) {
if (Buf[I] !== 0 || Buf[I + 1] !== 0 || Buf[I + 2] !== 0 || Buf[I + 3] !== 5) continue;
const Len = Buf.readUInt32BE(I + 8);
if (Len === 0 || Len > 1024) continue;
const Start = I + 12;
if (Start + Len * 2 > Buf.length) continue;
const Name = Buf.slice(Start, Start + Len * 2).toString('utf16le');
// 用 utf16le 读 BE 数据会字节交换;这里改回手工 BE 解码
let BeName = '';
for (let K = 0; K < Len; K++) BeName += String.fromCharCode(Buf.readUInt16BE(Start + K * 2));
if (!BeName || /[\x00-\x08\x0b-\x1f]/.test(BeName)) continue;
Names.add(BeName);
void Name;
}
// 兜底:任意可打印 UTF-16BE 串(长度 >= 3)
if (Names.size === 0) {
for (let I = 0; I + 6 <= Buf.length; I += 2) {
let S = '';
let J = I;
while (J + 2 <= Buf.length) {
const C = Buf.readUInt16BE(J);
if (C < 0x20 || C > 0x7e) break;
S += String.fromCharCode(C);
J += 2;
}
if (S.length >= 3) {
Names.add(S);
I = J - 2;
}
}
}
const List = [...Names].sort();
const Stat = fs.statSync(File);
console.log('文件: ' + path.basename(File) + ' ' + Stat.size + ' 字节');
console.log('条目: ' + List.length);
for (const N of List) console.log(' ' + N);
if (JsonOut) fs.writeFileSync(path.resolve(JsonOut), JSON.stringify({ File, Size: Stat.size, Entries: List }, null, 2), 'utf8');