UNPKG

gmll

Version:

A generic launcher core for building custom launchers

321 lines (320 loc) 12.4 kB
"use strict"; /**The internal java and version manifest handler for GMLL */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getNeoForgeVersions = exports.installNeoForge = exports.installModernForge = exports.getForgeVersions = exports.getJavaPath = exports.installForge = exports.getLatest = exports.getManifest = exports.getManifests = void 0; const tslib_1 = require("tslib"); const config_js_1 = require("./config.js"); const downloader_js_1 = require("./downloader.js"); const util_js_1 = require("./internal/util.js"); const child_process_1 = require("child_process"); const gfsl_1 = require("gfsl"); const node_fetch_1 = tslib_1.__importDefault(require("node-fetch")); function getManifests() { (0, config_js_1.isInitialized)(); const versionManifest = []; const root = (0, config_js_1.getMeta)().manifests; root.ls().forEach((e) => { if (e.sysPath().endsWith("json") && e instanceof gfsl_1.File) { const v = e.toJSON(); if (v instanceof Array) versionManifest.push(...v); else versionManifest.push(v); } }); return versionManifest; } exports.getManifests = getManifests; const forgiacCodes = { 100: "Could not create virtual folder", 101: "Could not create junction link", 102: "Please use Windows Vista or later", 200: "User cancelled request", 201: "Invalid installation jar", 202: "Forge failed to install", 300: "Parameter error", }; function findManifest(version, manifests) { const v = version.toLocaleLowerCase().trim(); let manifest = manifests.find((e) => { try { return e.id.toLocaleLowerCase().trim() == v; } catch { return false; } }); //|| { id: version, type: "unknown" }; if (!manifest) { (0, config_js_1.emit)("debug.warn", "attempting to generate manifest files"); const root = (0, config_js_1.getMeta)().manifests; const versionJson = (0, config_js_1.getVersions)().getFile(version, `${version}.json`); if (versionJson.exists()) { let f = root.getFile(`${version}.json`); let i = 1; while (f.exists()) f = root.getFile(`${version}_${i++}.json`); try { const vj = versionJson.toJSON(); let base = vj.inheritsFrom; if (base) { const baseManifest = findManifest(base, manifests); base = baseManifest.base || baseManifest.id; } const mf = { id: vj.id || versionJson.name.split(".")[0], base: base, releaseTime: vj.releaseTime, time: vj.time, type: vj.type || "generated", }; f.write(mf); } catch (e) { (0, config_js_1.emit)("debug.error", "failed to compile manifest from version json"); } } else { (0, config_js_1.emit)("debug.warn", `no version json (at ${versionJson.sysPath()}) found, I hope you know what you are doing!`); } manifest = { id: version, type: "unknown" }; } if (manifest.base) { const man2 = findManifest(manifest.base, manifests); manifest.releaseTime = man2.releaseTime; manifest.time = man2.time; manifest.complianceLevel = man2.complianceLevel; } return manifest; } const spTag = ["latest", "latest:release", "latest:snapshot"]; /**Gets a specific version manifest based on the version ID provided * @param version the version ID * @returns a version manifest. It will be of type "unknown" if the specific manifest is not in the manifest database. */ function getManifest(version) { if (spTag.includes(version)) { const lt = getLatest(); switch (version) { case "latest:snapshot": version = lt.snapshot; break; case "latest:release": case "latest": version = lt.release; break; } } (0, config_js_1.isInitialized)(); const manifests = getManifests(); return findManifest(version, manifests); } exports.getManifest = getManifest; /**Gets the latest release and snapshot builds.*/ function getLatest() { (0, config_js_1.isInitialized)(); const file = (0, config_js_1.getMeta)().index.getFile("latest.json"); if (file.exists()) return file.toJSON(); else return { release: "1.17.1", snapshot: "21w42a" }; } exports.getLatest = getLatest; async function installForge(forgeInstaller, forgiacArgs = ["--virtual", (0, config_js_1.getVersions)().sysPath()]) { if (forgeInstaller instanceof Object && !(forgeInstaller instanceof gfsl_1.File)) { const { type, forge, game } = forgeInstaller; if (type == "modern") { return await installModernForge(forge); } const id = "forge-" + forge; const manifest = { id: "forge-" + forge, type: "forge", base: game, }; (0, config_js_1.getMeta)() .manifests.getFile(id + ".json") .write(manifest); const jarname = type == "ancient" ? `forge-${forge}-client.zip` : `forge-${forge}-universal.zip`; const shaRequest = await (0, node_fetch_1.default)(`https://maven.minecraftforge.net/net/minecraftforge/forge/${forge}/${jarname}.sha1`); let sha1; if (shaRequest.status == 200) sha1 = await shaRequest.text(); const versionJson = { id: id, inheritsFrom: game, jarmods: [ { sha1, url: `https://maven.minecraftforge.net/net/minecraftforge/forge/${forge}/${jarname}`, id: `forge-${forge}`, path: `forge-${forge}.jar`, }, ], type: "forge", }; (0, config_js_1.getVersions)() .getDir(game) .mkdir() .getFile(id + ".json") .write(versionJson); return manifest; } const path = (0, config_js_1.getInstances)().getDir(".forgiac"); const manifest = path.getDir(".manifest_" + Date.now()).mkdir(); if (typeof forgeInstaller == "string") forgeInstaller = new gfsl_1.File(forgeInstaller); const fRun = "java-runtime-delta"; await (0, downloader_js_1.runtime)(fRun); const javaPath = getJavaPath(fRun); const logFile = path.getFile("log.txt"); const args = [ "-jar", (await (0, downloader_js_1.getForgiac)()).sysPath(), " --log", logFile.sysPath(), ...forgiacArgs, (0, config_js_1.getlibraries)().sysPath(), "--mk_manifest", manifest.sysPath(), ]; if (forgeInstaller) { args.push("--installer", forgeInstaller.sysPath()); } path.mkdir(); (0, config_js_1.emit)("jvm.start", "Forgiac", path.sysPath()); const s = (0, child_process_1.spawn)(javaPath.sysPath(), args, { cwd: path.sysPath() }); s.stdout.on("data", (chunk) => (0, config_js_1.emit)("jvm.stdout", "Forgiac", chunk)); s.stderr.on("data", (chunk) => (0, config_js_1.emit)("jvm.stderr", "Forgiac", chunk)); const err = (await new Promise((e) => s.on("exit", e))); if (err != 0) { throw { Error: "forge.install.failure", code: err, message: forgiacCodes[err] || "unknown error", }; } const forgeManifest = manifest.ls(); if (forgeManifest.length < 1) { throw { Error: "manifest.not.found", code: 400, message: "Manifest file not found?", }; } const manifestFile = forgeManifest[0]; if (!(manifestFile instanceof gfsl_1.File)) { throw { Error: "manifest.is.folder", code: 401, message: "Manifest file is a directory?", }; } const result = manifestFile.toJSON(); manifestFile.moveTo((0, config_js_1.getMeta)().manifests.getFile(manifestFile.getName())); manifest.rm(); return result; } exports.installForge = installForge; /** * Gets the path to an installed version of Java. GMLL manages these versions and they're not provided by the system. * @param java the name of the Java runtime. Based on the names Mojang gave them. * @returns The location of the have executable. */ function getJavaPath(java = "jre-legacy") { if ((0, util_js_1.getOS)() == "osx") { return (0, config_js_1.getRuntimes)().getFile(java, "jre.bundle", "Contents", "Home", "bin", "java"); } if ((0, util_js_1.getOS)() == "windows") { const f = (0, config_js_1.getRuntimes)().getFile(java, "bin", "javaw.exe"); return f.exists() ? f : (0, config_js_1.getRuntimes)().getFile(java, "bin", "java.exe"); } return (0, config_js_1.getRuntimes)().getFile(java, "bin", "java"); } exports.getJavaPath = getJavaPath; /** * The auto forge installer. * To stop forge from breaking this, * please add a link to donate to the forge project at https://www.patreon.com/LexManos * * I am not affiliated with forge in any way, I just want to support them. So they can keep making forge...and so they don't break this. * - Hanro50 * * @Warning They may break this at any time. I will try to keep this up to date, but I can't guarantee anything. So...yeah. Add a link to donate to them. */ async function getForgeVersions() { const data = await (0, node_fetch_1.default)("https://files.minecraftforge.net/net/minecraftforge/forge/maven-metadata.json"); const json = (await data.json()); const results = {}; const ancient = ["1.1", "1.2.3", "1.2.4", "1.2.5"]; const old = [ "1.3.2", "1.4.0", "1.4.1", "1.4.2", "1.4.3", "1.4.5", "1.4.6", "1.4.7", "1.5", "1.5.1", "1.5.2", ]; Object.entries(json).forEach((o) => { const mc = o[0]; const forge = o[1]; let type; if (ancient.includes(mc)) type = "ancient"; else if (old.includes(mc)) type = "old"; else type = "modern"; results[mc] = forge.map((version) => { return { type, forge: version, game: mc, install: () => installForge({ type, forge: version, game: mc }), }; }); }); console.log("[GMLL]: Please support the forge project by donating at https://www.patreon.com/LexManos"); return results; } exports.getForgeVersions = getForgeVersions; async function installModernForge(version) { const path = (0, config_js_1.getMeta)().scratch.getDir("forge").mkdir(); const url = `https://maven.minecraftforge.net/net/minecraftforge/forge/${version}/forge-${version}-installer.jar`; const installer = await path.getFile(version + ".jar").download(url); return await installForge(installer); } exports.installModernForge = installModernForge; async function installNeoForge(version) { const path = (0, config_js_1.getMeta)().scratch.getDir("neo-forge").mkdir(); const url = `https://maven.neoforged.net/releases/net/neoforged/neoforge/${version}/neoforge-${version}-installer.jar`; const installer = await path.getFile(version + ".jar").download(url); return await installForge(installer); } exports.installNeoForge = installNeoForge; /**The auto neoforge installer.*/ async function getNeoForgeVersions(version) { let data; if (version?.startsWith("1.")) { version = version.substring(2); data = await (0, node_fetch_1.default)("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge?filter=" + version); } else { data = await (0, node_fetch_1.default)("https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge"); } const json = (await data.json()); return json.versions.map((neoforge) => { return { version: neoforge, install: () => installNeoForge(neoforge), }; }); } exports.getNeoForgeVersions = getNeoForgeVersions;