feat(ui-migration): 源数据加载与校验
读取 gameabc_{Object,Layer,GroupList,Image}.json, 跳过 {} 占位槽,
校验多帧图的网格与帧数一致(不符即显式抛错, 不兜底)。
真实数据回归护栏: 991 对象 / 55 界面 / 80 组 / 439 图 / 139 多帧图。
引入 pngjs devDep 供后续切图使用(仅迁移工具, 不进框架运行时)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { readFileSync, existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
/** 源数据非法时抛出。第二准则:缺失/非法一律显式暴露,不兜底。 */
|
||||
export class SourceError extends Error {
|
||||
constructor(message) { super(message); this.name = 'SourceError'; }
|
||||
}
|
||||
|
||||
function readJson(dir, name) {
|
||||
const p = join(dir, name);
|
||||
if (!existsSync(p)) throw new SourceError(`缺少源数据文件: ${p}`);
|
||||
try {
|
||||
return JSON.parse(readFileSync(p, 'utf8'));
|
||||
} catch (e) {
|
||||
throw new SourceError(`源数据 JSON 解析失败: ${p} — ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取并校验 gameabc 导出数据。
|
||||
* 源数组用 `{}` 占位空槽(下标即 ID),须跳过。
|
||||
*/
|
||||
export function loadSource(outputDir) {
|
||||
const objects = new Map();
|
||||
for (const entry of readJson(outputDir, 'gameabc_Object.json').ObjectList ?? []) {
|
||||
if (!entry || !entry.Property) continue;
|
||||
const p = entry.Property;
|
||||
objects.set(p.ObjectID, { ...p, events: Object.keys(entry.Event ?? {}) });
|
||||
}
|
||||
|
||||
const images = new Map();
|
||||
for (const i of readJson(outputDir, 'gameabc_Image.json').ImageFileList ?? []) {
|
||||
if (!i || i.id === undefined) continue;
|
||||
if (i.w * i.h !== i.frame_all) {
|
||||
throw new SourceError(
|
||||
`图 ${i.bmp} 的网格与帧数不符: ${i.w}x${i.h}=${i.w * i.h} != frame_all=${i.frame_all}`,
|
||||
);
|
||||
}
|
||||
images.set(i.id, i);
|
||||
}
|
||||
|
||||
const layers = (readJson(outputDir, 'gameabc_Layer.json').LayerList ?? [])
|
||||
.filter((l) => l && l.Property)
|
||||
.map((l) => ({
|
||||
layerId: l.Property.LayerID,
|
||||
name: l.Property.LayerName,
|
||||
objectIds: l.ObjectList ?? [],
|
||||
}));
|
||||
|
||||
const groups = (readJson(outputDir, 'gameabc_GroupList.json').GroupList ?? [])
|
||||
.filter((g) => g && g.GroupID !== undefined)
|
||||
.map((g) => ({ groupId: g.GroupID, objectIds: g.ObjectList ?? [] }));
|
||||
|
||||
return { objects, images, layers, groups };
|
||||
}
|
||||
Reference in New Issue
Block a user