UNPKG

arx-level-generator

Version:
129 lines 5.28 kB
import { exec } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { Readable } from 'node:stream'; import { fileURLToPath } from 'node:url'; import { promisify } from 'node:util'; import { DLF, FTS, LLF } from 'arx-convert'; import { getHeaderSize } from 'arx-header-size'; import { Compression, DictionarySize, implode, stream } from 'node-pkware'; const { through, transformSplitBy, splitAt, transformIdentity } = stream; const compileFTS = async (settings, fts) => { const ftsPath = path.join(settings.outputDir, `game/graph/levels/level${settings.levelIdx}`); if (settings.uncompressedFTS) { const repackedFts = FTS.save(fts, false); return fs.promises.writeFile(path.join(ftsPath, 'fast.fts'), repackedFts); } else { const repackedFts = FTS.save(fts, true); const { total: ftsHeaderSize } = getHeaderSize(repackedFts, 'fts'); return new Promise((resolve, reject) => { const writeStream = fs.createWriteStream(path.join(ftsPath, 'fast.fts')); writeStream .on('close', () => { resolve(true); }) .on('error', (e) => { reject(e); }); Readable.from(repackedFts) .pipe(through(transformSplitBy(splitAt(ftsHeaderSize), transformIdentity(), implode(Compression.Binary, DictionarySize.Large)))) .pipe(writeStream); }); } }; const compileLLF = async (settings, llf) => { const llfPath = path.join(settings.outputDir, `graph/levels/level${settings.levelIdx}`); const repackedLlf = LLF.save(llf); const { total: llfHeaderSize } = getHeaderSize(repackedLlf, 'llf'); return new Promise((resolve, reject) => { const writeStream = fs.createWriteStream(path.join(llfPath, `level${settings.levelIdx}.llf`)); writeStream .on('close', () => { resolve(true); }) .on('error', (e) => { reject(e); }); Readable.from(repackedLlf) .pipe(through(transformSplitBy(splitAt(llfHeaderSize), transformIdentity(), implode(Compression.Binary, DictionarySize.Large)))) .pipe(writeStream); }); }; const compileDLF = async (settings, dlf) => { const dlfPath = path.join(settings.outputDir, `graph/levels/level${settings.levelIdx}`); const repackedDlf = DLF.save(dlf); const { total: dlfHeaderSize } = getHeaderSize(repackedDlf, 'dlf'); return new Promise((resolve, reject) => { const writeStream = fs.createWriteStream(path.join(dlfPath, `level${settings.levelIdx}.dlf`)); writeStream .on('close', () => { resolve(true); }) .on('error', (e) => { reject(e); }); Readable.from(repackedDlf) .pipe(through(transformSplitBy(splitAt(dlfHeaderSize), transformIdentity(), implode(Compression.Binary, DictionarySize.Large)))) .pipe(writeStream); }); }; const hasDotnet6OrNewer = async () => { try { const { stdout } = await promisify(exec)(`dotnet --version`); const majorOfVersion = parseInt(stdout.trim().split('.')[0]); return majorOfVersion >= 6; } catch (e) { return false; } }; const calculateLighting = async (settings) => { const operatingSystem = os.platform(); if (operatingSystem !== 'win32' && operatingSystem !== 'linux') { console.error(`[error] compile: lighting generator: unsupported platform (expected "win32" or "linux", but got "${operatingSystem}")`); return; } if (!(await hasDotnet6OrNewer())) { console.error(`[error] compile: lighting generator: no compatible version found (expected "dotnet --version" to return 6.x.x, 7.x.x or newer)`); return; } const args = [ `--level "level${settings.levelIdx}"`, `--arx-data-dir "${settings.outputDir}"`, `--lighting-profile "${settings.lightingCalculatorMode}"`, ]; if (settings.uncompressedFTS) { args.push(`--dont-compress-fts`); } const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const libPath = path.resolve(__dirname, '../../lib'); let exeFile; switch (operatingSystem) { case 'win32': exeFile = path.resolve(libPath, `fredlllll-lighting-calculator/win/ArxLibertatisLightingCalculator.exe`); break; case 'linux': exeFile = path.resolve(libPath, `fredlllll-lighting-calculator/linux/ArxLibertatisLightingCalculator`); break; } try { const { stdout, stderr } = await promisify(exec)(`${exeFile} ${args.join(' ')}`); console.log(stdout); if (stderr !== '') { console.error(stderr); } } catch (e) { console.error(e); } }; export const compile = async (settings, { dlf, llf, fts }) => { await Promise.allSettled([compileFTS(settings, fts), compileLLF(settings, llf), compileDLF(settings, dlf)]); if (settings.calculateLighting && llf.lights.length > 0) { await calculateLighting(settings); } }; //# sourceMappingURL=compile.js.map