Implement playable Mac client and rendering validation
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import crypto from 'node:crypto';
|
||||
import {execFileSync} from 'node:child_process';
|
||||
const assets = process.argv[2] ?? 'assets';
|
||||
const output = process.argv[3];
|
||||
const manifest = JSON.parse(fs.readFileSync(path.join(assets, 'TreeGeometry/manifest.json')));
|
||||
const normalize = s => s.replaceAll('\\', '/').toLowerCase().replace(/^.*?ymir work\//, 'ymir work/');
|
||||
const converted = new Set(Object.values(manifest.trees).map(r => normalize(r.source)));
|
||||
const list = pattern => execFileSync('rg', ['--files', assets, '-g', pattern], {encoding: 'utf8', maxBuffer: 8 * 1024 * 1024}).trim().split('\n').filter(Boolean);
|
||||
const references = new Set();
|
||||
const propertyReferences = new Map();
|
||||
for (const file of list('*.prt')) {
|
||||
const source = fs.readFileSync(file, 'utf8');
|
||||
for (const match of source.matchAll(/^\s*treefile\s+"([^"]+)"/gmi)) {
|
||||
const reference = normalize(match[1]);
|
||||
references.add(reference);
|
||||
propertyReferences.set(source.split(/\r?\n/)[1].trim(), reference);
|
||||
}
|
||||
}
|
||||
const placedReferences = new Set();
|
||||
for (const file of list('areadata.txt')) {
|
||||
const source = fs.readFileSync(file, 'utf8');
|
||||
for (const match of source.matchAll(/^Start Object\d+\r?\n[^\n]*\n\s*(\d+)/gm)) {
|
||||
const reference = propertyReferences.get(match[1]);
|
||||
if (reference) placedReferences.add(reference);
|
||||
}
|
||||
}
|
||||
const unmatched = [];
|
||||
let matched = 0;
|
||||
for (const file of list('*.spt')) {
|
||||
const hash = crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex');
|
||||
if (manifest.trees[hash]) matched++;
|
||||
else unmatched.push({file, source_sha256: hash, referenced_by_property: references.has(normalize(file))});
|
||||
}
|
||||
const missing_referenced = [...references].filter(r => !converted.has(r)).sort();
|
||||
const missing_placed = [...placedReferences].filter(r => !converted.has(r)).sort();
|
||||
const report = {matched_spt_files: matched, converted_species: converted.size, referenced_species: references.size,
|
||||
placed_species: placedReferences.size, missing_placed,
|
||||
missing_referenced, unconverted_spt: unmatched, scope: 'SPT inventory and text PRT/AreaData references; six-map runtime validation is separate'};
|
||||
if (output) fs.writeFileSync(output, JSON.stringify(report, null, 2) + '\n');
|
||||
console.log(JSON.stringify({matched, converted: converted.size, referenced: references.size, placed: placedReferences.size, missing_placed, missing_referenced, unconverted: unmatched.length}));
|
||||
if (!placedReferences.size || missing_placed.length) process.exitCode = 1;
|
||||
Reference in New Issue
Block a user