#!/usr/bin/env node function usage() { console.log("Usage:"); console.log(" tibia file1.json,file2.json,...filen.json template outDirectory"); console.log(" tibia --common template outDirectory"); console.log(" tibia --data file1.json,file2.json,...filen.json template outDirectory"); process.exit(1); } var jsonFiles, template, outputDir, outputCommon, outputData; if (process.argv[2] == "--common") { if (process.argv.length != 5) usage(); jsonFiles = []; template = process.argv[3]; outputDir = process.argv[4]; outputCommon = true; outputData = false; } else if (process.argv[2] == "--data") { if (process.argv.length != 6) usage(); jsonFiles = process.argv[3].split(","); template = process.argv[4]; outputDir = process.argv[5]; outputCommon = false; outputData = true; } else { if (process.argv.length != 5) usage(); jsonFiles = process.argv[2].split(","); template = process.argv[3]; outputDir = process.argv[4]; outputCommon = true; outputData = true; } var fs = require("fs"); var path = require("path"); /* var ajvValidate; if (outputData) { var schema = JSON.parse(fs.readFileSync(__dirname + path.sep + "schema.json", { encoding: "utf-8" })); var Ajv = require("ajv"); var ajv = new Ajv(); ajvValidate = ajv.compile(schema); } */ var data = {}; for (var i = 0; i < jsonFiles.length; i++) { var d = JSON.parse(fs.readFileSync(jsonFiles[i], { encoding: "utf-8" })); for (var k in d) data[k] = d[k]; } /* if (outputData) { var ajvValid = ajvValidate(data); if (!ajvValid) { console.log(ajvValidate.errors); process.exit(1); } } */ var doT = require("dot"); doT.templateSettings.strip = false; var api = { // https://coderrocketfuel.com/article/recursively-list-all-the-files-in-a-directory-using-node-js getAllFiles: function (dirPath, arrayOfFiles, relDir) { var files = fs.readdirSync(dirPath); var arrayOfFiles = arrayOfFiles || []; var relDir = relDir || ""; files.forEach(function(file) { if (fs.statSync(dirPath + path.sep + file).isDirectory()) arrayOfFiles = api.getAllFiles(dirPath + path.sep + file, arrayOfFiles, relDir + file + path.sep); else arrayOfFiles.push(relDir + file); }); return arrayOfFiles }, generateFileFromTemplateFile: function (templateFile, outFile, data) { if (!outputData) return; var dir = outputDir + path.sep + path.dirname(outFile); fs.mkdirSync(dir, { recursive: true }); var t = doT.template(fs.readFileSync(template + path.sep + templateFile, { encoding: "utf-8" })); fs.writeFileSync(outputDir + path.sep + outFile, t(data), { encoding: "utf-8" }); }, copyFile: function (inFile, outFile) { if (!outputCommon) return; var dir = outputDir + path.sep + path.dirname(outFile); fs.mkdirSync(dir, { recursive: true }); fs.copyFileSync(template + path.sep + inFile, outputDir + path.sep + outFile); } }; data.tibia = { CGetUTF8StringLiteral: function (string, maxLength) { if (!maxLength) maxLength = Infinity; var v = (new TextEncoder()).encode(string); var s = ""; for (var i = 0; i < maxLength && i < v.length; ) { if (!(v[i] & 0x80)) { if (v[i] < 0x20 || v[i] == 0x7f) { s += "\\" + v[i].toString(8).padStart(3, "0"); } else if (v[i] == 0x22) s += "\\\""; else if (v[i] == 0x5c) s += "\\\\"; else s += String.fromCharCode(v[i]); i++; } else if ((v[i] & 0xe0) == 0xc0) { if (maxLength - i < 2) break; for (var j = 0; j < 2; j++) { s += "\\" + v[i].toString(8).padStart(3, "0"); i++; } } else if ((v[i] & 0xf0) == 0xe0) { if (maxLength - i < 3) break; for (var j = 0; j < 3; j++) { s += "\\" + v[i].toString(8).padStart(3, "0"); i++; } } else if ((v[i] & 0xf8) == 0xf0) { if (maxLength - i < 4) break; for (var j = 0; j < 4; j++) { s += "\\" + v[i].toString(8).padStart(3, "0"); i++; } } } return s; } }; require(path.resolve(template + path.sep + "tibia-index.js"))(data, api, outputCommon, outputData);