patchwork-mapconverter
Version:
Executable wrapper for https://github.com/ChiefOfGxBxL/WC3MapTranslator
198 lines • 20.1 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const LoggerFactory_1 = require("../logging/LoggerFactory");
const promises_1 = require("fs/promises");
const directory_tree_1 = __importDefault(require("directory-tree"));
const path_1 = __importDefault(require("path"));
const TranslatorRecord_1 = require("./TranslatorRecord");
const FileCopier_1 = require("./FileCopier");
const EnhancementManager_1 = __importDefault(require("../enhancements/EnhancementManager"));
const TriggerTranslator_1 = require("../translator/TriggerTranslator");
const CustomScriptsTranslator_1 = require("../translator/CustomScriptsTranslator");
const WriteAndCreatePath_1 = require("../util/WriteAndCreatePath");
const FileBlacklist_1 = require("../enhancements/FileBlacklist");
const TriggerComposer_1 = require("../enhancements/TriggerComposer");
const translators_1 = require("../wc3maptranslator/translators");
const FormatConverters_1 = require("./formats/FormatConverters");
const log = LoggerFactory_1.LoggerFactory.createLogger('War2Json');
let translatorCount = 0;
async function processFile(input, translator, output) {
const asyncLog = log.getSubLogger({ name: `${translator.constructor.name}-${translatorCount++}` });
asyncLog.info('Processing', input);
const buffer = await (0, promises_1.readFile)(input);
const result = translator.warToJson(buffer);
if (result.errors != null && result.errors.length > 0) {
for (const error of result.errors) {
asyncLog.error(error);
}
}
else {
await (0, WriteAndCreatePath_1.WriteAndCreatePath)(output, FormatConverters_1.FormatConverters[EnhancementManager_1.default.mapDataExtension].stringify(result.json), { encoding: 'utf8' });
asyncLog.info('Finished processing', output);
}
}
async function processImportsRegistry(importsFile) {
const translator = translators_1.ImportsTranslator.getInstance();
const asyncLog = log.getSubLogger({ name: `${translator.constructor.name}-${translatorCount++}` });
asyncLog.info('Reading war3map.imp file.');
const buffer = await (0, promises_1.readFile)(importsFile);
const result = translator.warToJson(buffer);
if (result.errors != null && result.errors.length > 0) {
for (const error of result.errors) {
asyncLog.error(error);
}
throw new Error('Failed reading imports file.');
}
else {
asyncLog.info('Read war3map.imp, found', result.json.length, 'imports');
return result.json;
}
}
async function processTriggers(triggersFile, customScriptsFile) {
const triggerTranslator = TriggerTranslator_1.TriggersTranslator.getInstance();
const customScriptTranslator = CustomScriptsTranslator_1.CustomScriptsTranslator.getInstance();
const asyncLog = log.getSubLogger({ name: `${triggerTranslator.constructor.name}-${translatorCount++}` });
asyncLog.info('Reading war3map.wtg file.');
const triggerBuffer = await (0, promises_1.readFile)(triggersFile);
const triggerResult = triggerTranslator.warToJson(triggerBuffer);
if (triggerResult.errors != null && triggerResult.errors.length > 0) {
for (const error of triggerResult.errors) {
asyncLog.error(error);
}
throw new Error('Failed reading triggers file.');
}
const triggerJson = triggerResult.json;
asyncLog.info('Read war3map.wtg file.');
if (customScriptsFile != null) {
asyncLog.info('Reading war3map.wct file.');
const csBuffer = await (0, promises_1.readFile)(customScriptsFile);
const csResults = customScriptTranslator.warToJson(csBuffer);
if (csResults.errors != null && csResults.errors.length > 0) {
for (const error of csResults.errors) {
asyncLog.error(error);
}
throw new Error('Failed reading custom scripts file.');
}
asyncLog.info('Read war3map.wct file, found', csResults.json.scripts.length, 'custom scripts.');
// Combine custom scripts into trigger JSON
for (let i = 0; i < triggerJson.scriptReferences.length; i++) {
const scriptRef = triggerJson.scriptReferences[i];
if (scriptRef != null) {
scriptRef.script = csResults.json.scripts[i];
}
}
for (let i = 0; i < csResults.json.headerComments.length; i++) {
triggerJson.roots[i].description = csResults.json.headerComments[i];
}
}
return triggerJson.roots;
}
const War2JsonService = {
convert: async function (inputPath, outputPath) {
log.info('Converting Warcraft III binaries in', inputPath, 'and outputting to', outputPath);
const promises = [];
const fileStack = [(0, directory_tree_1.default)(inputPath, { attributes: ['type', 'extension'] })];
const copyFiles = {};
let importFile = null;
let triggerFile = null;
let customScriptFile = null;
while (fileStack.length > 0) {
const file = fileStack.pop();
if (file == null)
break;
if (FileBlacklist_1.FileBlacklist.isDirectoryTreeBlacklisted(file))
continue;
if (file.type === 'directory') {
const children = file.children;
if (children != null) {
for (const child of children) {
fileStack.push(child);
}
}
}
else {
let translator = null;
for (const [extension, thisTranslator] of Object.entries(TranslatorRecord_1.translatorRecord)) {
if (file.name.includes(extension)) {
translator = thisTranslator;
break;
}
}
if (translator != null) {
if (EnhancementManager_1.default.smartImport && (translator instanceof translators_1.ImportsTranslator)) {
importFile = file.path;
}
else if (translator instanceof TriggerTranslator_1.TriggersTranslator) {
triggerFile = file.path;
}
else if (translator instanceof CustomScriptsTranslator_1.CustomScriptsTranslator) {
const outputFile = path_1.default.join(outputPath, path_1.default.relative(inputPath, file.path)) + EnhancementManager_1.default.mapDataExtension;
customScriptFile = { input: file.path, output: outputFile };
}
else {
const outputFile = path_1.default.join(outputPath, path_1.default.relative(inputPath, file.path)) + EnhancementManager_1.default.mapDataExtension;
promises.push(processFile(file.path, translator, outputFile));
}
}
else {
const outputFile = path_1.default.join(outputPath, path_1.default.relative(inputPath, file.path));
if (EnhancementManager_1.default.smartImport) {
copyFiles[file.path] = outputFile;
}
else {
promises.push((0, FileCopier_1.copyFileWithDirCreation)(file.path, outputFile));
}
}
}
}
if (triggerFile != null) {
promises.push(async function () {
const triggerJSON = await processTriggers(triggerFile, customScriptFile?.input);
if (EnhancementManager_1.default.composeTriggers) {
await TriggerComposer_1.TriggerComposer.explodeTriggersJsonIntoSource(outputPath, triggerJSON[0]);
}
else {
await (0, promises_1.writeFile)(path_1.default.join(outputPath, `triggers${EnhancementManager_1.default.mapDataExtension}`), FormatConverters_1.FormatConverters[EnhancementManager_1.default.mapDataExtension].stringify(triggerJSON), { encoding: 'utf8' });
}
}());
}
else if (customScriptFile != null) {
promises.push((0, FileCopier_1.copyFileWithDirCreation)(customScriptFile.input, customScriptFile.output));
}
if (EnhancementManager_1.default.smartImport) {
log.debug('SmartImports requested');
if (importFile != null) {
const imports = await processImportsRegistry(importFile);
for (const [input, output] of Object.entries(copyFiles)) {
const relativeInput = path_1.default.relative(inputPath, input);
let found = false;
for (const importEntry of imports) {
if (path_1.default.normalize(importEntry.path) === path_1.default.normalize(relativeInput)) {
found = true;
break;
}
}
if (found) {
const outputFile = path_1.default.join(outputPath, EnhancementManager_1.default.importFolder, relativeInput);
promises.push((0, FileCopier_1.copyFileWithDirCreation)(input, outputFile));
}
else {
promises.push((0, FileCopier_1.copyFileWithDirCreation)(input, output));
}
}
}
else {
log.error('File war3map.imp not found, unable to determine imports from map files, will copy-paste all non-translated files');
for (const [input, output] of Object.entries(copyFiles)) {
promises.push((0, FileCopier_1.copyFileWithDirCreation)(input, output));
}
}
}
return await Promise.all(promises);
}
};
exports.default = War2JsonService;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2FyMkpzb25TZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnZlcnRlci9XYXIySnNvblNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw0REFBd0Q7QUFDeEQsMENBQWlEO0FBQ2pELG9FQUFrRTtBQUNsRSxnREFBdUI7QUFDdkIseURBQXFEO0FBQ3JELDZDQUFzRDtBQUN0RCw0RkFBbUU7QUFDbkUsdUVBQW9FO0FBQ3BFLG1GQUErRTtBQUcvRSxtRUFBK0Q7QUFDL0QsaUVBQTZEO0FBQzdELHFFQUFpRTtBQUNqRSxpRUFBb0Y7QUFFcEYsaUVBQTZEO0FBRTdELE1BQU0sR0FBRyxHQUFHLDZCQUFhLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBRWxELElBQUksZUFBZSxHQUFHLENBQUMsQ0FBQTtBQUN2QixLQUFLLFVBQVUsV0FBVyxDQUFLLEtBQWEsRUFBRSxVQUF5QixFQUFFLE1BQWM7SUFDckYsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLGVBQWUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ2xHLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ2xDLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxtQkFBUSxFQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ3BDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDM0MsSUFBSSxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDckQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO1lBQ2pDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FB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