#!/usr/bin/env node const MSE = require("mse-translator"); const https = require("https"); const fs = require("fs"); const archiver = require("archiver"); var argv = require("yargs/yargs")(process.argv.slice(2)) .usage("\nMSE Minecraft language-pack generator \n\nUsage: $0 [options]") .help("help") .alias("help", "h") .version("version", "1.0.1") .alias("version", "V") .options({ descriptivefile: { alias: "f", description: 'descriptive output E.g. "en_gb-v1.19.1-en_MSE"', requiresArg: false, required: false, type: "boolean", }, lang: { alias: "l", description: " base language for pack generation", requiresArg: true, required: false, type: "string", }, // TODO: version: { // alias: "v", // description: " base version for pack generation", // requiresArg: true, // required: false, // type: "string", // }, manifest: { alias: "m", description: " custom manifest endpoint", requiresArg: true, required: false, type: "string", }, resources: { alias: "r", description: " custom resources endpoint", requiresArg: true, required: false, type: "string", }, }) .parse(); const urlReq = function (reqUrl, options, cb) { if (typeof options === "function") { cb = options; options = {}; } // incase no options passed in https .get(reqUrl, (res) => { let body = ""; res.on("data", (chunk) => { body += chunk; }); res.on("end", () => { try { cb(body, res); } catch (error) { console.error(error.message); } }); }) .on("error", (error) => { console.error(error.message); }); }; let piston = argv.manifest || "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"; urlReq(piston, function (body, res) { json = JSON.parse(body); let version = json.versions[0].id; // latest version let resources = argv.resources || "https://resources.download.minecraft.net/"; let baselang = argv.lang || "en_gb"; let filename = (argv.descriptivefile && `${baselang}-v${version}-en_MSE`) || // descriptive file name "Maoist-Standard-English"; // default let mcmeta_template = [ { text: `§cen_MSE§r\n`, }, { text: `§8(§f${baselang}§8)-<§f${version}§8>`, }, ]; console.log(`Using base language "${baselang}" from version (${version})`); urlReq(json.versions[1].url, function (body, res) { json = JSON.parse(body); urlReq(json.assetIndex.url, function (body, res) { json = JSON.parse(body); hash = json.objects[`minecraft/lang/${baselang}.json`].hash; urlReq( resources + `${hash.substring(0, 2)}/${hash}`, function (body, res) { pack = JSON.parse(body); var totals = { total: Object.keys(pack).length, translated: 0, }; console.log(`Translating ${totals.total} strings`); Object.keys(pack).forEach(function (key) { var translated = MSE.translate( pack[key] .replace(/\%s/gi, "%_") //mc patch .replace(/\$s/gi, "$_"), ) .replace(/\%_/gi, "%s") //mc patch back .replace(/\$_/gi, "$s"); if (translated != pack[key]) { totals.translated = totals.translated + 1; } pack[key] = translated; }); console.log( `Translated ${totals.translated} out of ${totals.total} strings`, ); var mcmeta = __dirname + "/template/pack.mcmeta"; var mcmeta_data = JSON.parse(fs.readFileSync(mcmeta)); mcmeta_data.pack.description = mcmeta_template; fs.writeFileSync(mcmeta, JSON.stringify(mcmeta_data)); fs.writeFile( __dirname + "/template/assets/minecraft/lang/en_mse.json", JSON.stringify(pack, null, 4), "utf8", function (err) { if (err) throw err; console.log( "en_mse.json generated, creating pack and compressing.", ); const output = fs.createWriteStream( __dirname + `/${filename}.zip`, ); const archive = archiver("zip", { zlib: { level: 9 }, // Sets the compression level. }); archive.on("error", function (err) { throw err; }); output.on("close", function () { console.log( "language-pack archive generated with a filesize of " + archive.pointer() + " bytes" + `\n(./${filename}.zip)`, ); }); archive.pipe(output); archive.directory("template/", false); archive.finalize(); }, ); }, ); }); }); });