UNPKG

gmll

Version:

A generic launcher core for building custom launchers

432 lines (431 loc) 16.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.forceCommonJsWorker = exports.getLauncherVersion = exports.setLauncherVersion = exports.getLauncherName = exports.setLauncherName = exports.resolvePath = exports.initialize = exports.initializationListener = exports.getUpdateConfig = exports.addUpdateConfig = exports.clrUpdateConfig = exports.getEventListener = exports.setEventListener = exports.emit = exports.getNatives = exports.getMeta = exports.getRuntimes = exports.getVersions = exports.getInstances = exports.getlibraries = exports.getAssets = exports.setNatives = exports.setLauncher = exports.setRuntimes = exports.setVersions = exports.setInstances = exports.setLibraries = exports.setAssets = exports.setRoot = exports.isInitialized = exports.set7zipRepo = exports.setArmfixRepo = exports.setForgeRepo = exports.setMavenRepo = exports.getRepositories = exports.setMultiCoreMode = exports.getMultiCoreMode = exports.spawnDownloadWorker = exports.setDownloadWorkerSpawner = void 0; const events_1 = require("events"); const downloader_js_1 = require("./downloader.js"); const util_js_1 = require("./internal/util.js"); const gfsl_1 = require("gfsl"); let workerSpawner = async (options) => { try { return (await import("./internal/worker.mjs")).makeWorker(options); } catch (e) { emit("debug.warn", "Falling back to commonjs worker. Run 'forceCommonJsWorker()' beforehand to silence this warning"); workerSpawner = cjsWokerSpawner; return cjsWokerSpawner(options); } }; const cjsWokerSpawner = async (options) => { // eslint-disable-next-line @typescript-eslint/no-var-requires return require("./internal/worker.cjs").makeWorker(options); }; /**Internal function. Used to set the spawner for the workers the downloader uses */ function setDownloadWorkerSpawner(func) { workerSpawner = func; } exports.setDownloadWorkerSpawner = setDownloadWorkerSpawner; /**Internal function. Used to get the spawner for the workers the downloader uses */ function spawnDownloadWorker(options) { return workerSpawner(options); } exports.spawnDownloadWorker = spawnDownloadWorker; const repositories = { maven: "https://download.hanro50.net.za/maven", forge: "https://download.hanro50.net.za/fmllibs", armFix: "https://download.hanro50.net.za/java", z7Repo: "https://download.hanro50.net.za/7-zip", }; let multiCoreMode = true; /**is multicore downloads currently enabled? */ function getMultiCoreMode() { return multiCoreMode; } exports.getMultiCoreMode = getMultiCoreMode; /**Should GMLL use it's multithreaded downloader? * @default true */ function setMultiCoreMode(enabled) { multiCoreMode = enabled; } exports.setMultiCoreMode = setMultiCoreMode; /** * The repositories GMLL uses for some of it's self hosted files. * By default these are hosted on https://download.hanro50.net.za/ * * #### More information: * * maven => ({@link setMavenRepo}) The maven repo GMLL should pull Agenta and forgiac from * * forge => ({@link setForgeRepo}) The forge archive GMLL should redirect requests to https://files.minecraftforge.net/fmllibs towards * * armFix => ({@link setArmfixRepo}) The location serving the resources needed for the arm fix to function * * z7Repo => ({@link set7zipRepo}) The location serving a local version of 7zip */ function getRepositories() { Object.keys(repositories).forEach((key) => { if (!repositories[key].endsWith("/")) repositories[key] += "/"; }); return JSON.parse(JSON.stringify(repositories)); } exports.getRepositories = getRepositories; /**The maven repo GMLL should pull Agenta and forgiac from */ function setMavenRepo(maven) { repositories.maven = maven; } exports.setMavenRepo = setMavenRepo; /**The forge archive GMLL should redirect requests to https://files.minecraftforge.net/fmllibs towards*/ function setForgeRepo(forge) { repositories.forge = forge; } exports.setForgeRepo = setForgeRepo; /**The location serving the resources needed for the arm fix to function * (allows for running Minecraft on arm on non mac platforms) */ function setArmfixRepo(armFix) { repositories.armFix = armFix; } exports.setArmfixRepo = setArmfixRepo; /**The location serving 7zip binaries*/ function set7zipRepo(z7Repo) { repositories.z7Repo = z7Repo; } exports.set7zipRepo = set7zipRepo; let initialized = false; const _packageFile = new gfsl_1.File("package.json"); const _packageJSON = _packageFile.exists() ? new gfsl_1.File("package.json").toJSON() : {}; let version = _packageJSON.version || "0.0.0"; let launcherName = _packageJSON.name || "GMLL"; const startUpCalls = []; /**Checks if GMLL is initialized and throws an error if it is not */ function isInitialized() { if (!initialized) { (0, util_js_1.throwErr)('GMLL is not initialized!\nPlease run "init()" or wait for the manifest files to redownload when changing the launcher directory.\nThis error is here to prevent unexpected errors'); } } exports.isInitialized = isInitialized; let defEvents = new events_1.EventEmitter(); defEvents.on("debug.info", (message) => console.log(`[GMLL:info]: ${message}`)); defEvents.on("debug.warn", (message) => console.warn(`[GMLL:warn]: ${message}`)); defEvents.on("debug.error", (message) => { console.warn(`[GMLL:error]: ${message}`); console.trace(); }); //Encode Manager defEvents.on("parser.start", (type, int) => console.log(`[GMLL:parser]: Parsing ${type}s of instance ${int.getName()}`)); defEvents.on("parser.progress", (key, index, total, left) => console.log(`[GMLL:parser]: Done with ${index} of ${total} : ${left} : ${key}`)); defEvents.on("parser.done", (type, int) => console.log(`[GMLL:parser]: Done parsing ${type}s of instance ${int.getName()}`)); defEvents.on("parser.fail", (type, err, path) => { console.error(`[GMLL:parser]: Error parsing ${type} => ${path.sysPath()}`); if (typeof err == "string") console.warn(`[GMLL:parser]: Reason => ${err}`); else console.trace(err); }); //Encode Manager defEvents.on("encode.start", () => console.log("[GMLL:encode]: Starting to encode files")); defEvents.on("encode.progress", (key, index, total, left) => console.log(`[GMLL:encode]: Done with ${index} of ${total} : ${left} : ${key}`)); defEvents.on("encode.done", () => console.log("[GMLL:encode]: Done with encoding files")); //Download Manager defEvents.on("download.setup", (cores) => console.log(`[GMLL:download]: Dividing out work to ${cores} cores`)); defEvents.on("download.start", () => console.log("[GMLL:download]: Starting download")); defEvents.on("download.progress", (key, index, total, left) => console.log(`[GMLL:download]: Done with ${index} of ${total} : ${left} : ${key}`)); defEvents.on("download.done", () => console.log("[GMLL:download]: Done with download")); defEvents.on("download.fail", (key, type, err) => { switch (type) { case "retry": console.log("[GMLL:download]: Trying to download " + key + " again"); break; case "fail": console.log((0, util_js_1.getErr)("Failed to download " + key)); break; case "system": console.log((0, util_js_1.getErr)("Failed to download " + key + " due to an error \n" + err)); break; } }); //JVM events defEvents.on("jvm.start", (app, cwd) => console.log(`[${app}]: Starting in directory <${cwd}>`.trim())); defEvents.on("jvm.stdout", (app, out) => console.log(`[${app}:out]: ${out}`.trim())); defEvents.on("jvm.stderr", (app, out) => console.log(`\x1b[31m\x1b[1m[${app}:err]: ${out}`.trim() + "\x1b[0m")); let updateConf = [ "fabric", "runtime", "agent", "quilt", "legacy-fabric", ]; let files; /** * Resets the root folder path and all of it's sub folders * @param {String} _root Essentially where you want to create a new .minecraft folder */ function setRoot(_root) { if (typeof _root == "string") _root = new gfsl_1.Dir(_root); if (_root.sysPath().includes("\x00")) { console.error("[GMLL:crit]: Path should not contain a NULL character!"); } initialized = false; const platform = _root.getDir("platform", (0, util_js_1.getOS)(), (0, util_js_1.getCpuArch)()); files = { assets: _root.getDir("assets"), libraries: _root.getDir("libraries"), instances: _root.getDir("instances"), versions: _root.getDir("versions"), launcher: _root.getDir("launcher"), _platform: platform, runtimes: platform.getDir("runtimes"), natives: gfsl_1.Dir.tmpdir().getDir("gmll", "natives", (0, util_js_1.getOS)(), (0, util_js_1.getCpuArch)()), }; } exports.setRoot = setRoot; setRoot(new gfsl_1.Dir(".minecraft")); /** * The location of the asset directory. Used to store textures, music and sounds. * @param _assets The location you want the asset directory to be at */ function setAssets(_assets) { if (typeof _assets == "string") _assets = new gfsl_1.Dir(_assets); files.assets = _assets; files.assets.mkdir(); } exports.setAssets = setAssets; /** * Used to store dependencies various versions of Minecraft and modloaders need in order to function. * @param _libraries The location you want the library directory to be at */ function setLibraries(_libraries) { if (typeof _libraries == "string") _libraries = new gfsl_1.Dir(_libraries); files.libraries = _libraries; files.libraries.mkdir(); } exports.setLibraries = setLibraries; /** * The default location to store new instances at. * @param _instances The location you want the instance directory to be at */ function setInstances(_instances) { if (typeof _instances == "string") _instances = new gfsl_1.Dir(_instances); files.instances = _instances; files.instances.mkdir(); } exports.setInstances = setInstances; /** * Used to store version.json files and client jars GMLL uses to download the dependencies a * set version of minecraft or a set modeloader needs in order to function properly * @param _versions The location you want the version directory to be at */ function setVersions(_versions) { if (typeof _versions == "string") _versions = new gfsl_1.Dir(_versions); files.versions = _versions; files.versions.mkdir(); } exports.setVersions = setVersions; /** * Runtimes are the various different versions of Java minecraft needs to function. * - Java 8 for pre-1.17 builds of the game * - Java 16 for 1.17 * - Java 17 for 1.18+ * - Java 17 for 1.18+ * @param _runtimes The location you want the runtime directory to be at */ function setRuntimes(_runtimes) { if (typeof _runtimes == "string") _runtimes = new gfsl_1.Dir(_runtimes); files.runtimes = _runtimes; files.runtimes.mkdir(); } exports.setRuntimes = setRuntimes; /** * GMLL uses this folder to store meta data GMLL uses to control and manage minecraft. * @param _launcher The location you want the meta directory to be at */ async function setLauncher(_launcher) { if (typeof _launcher == "string") _launcher = new gfsl_1.Dir(_launcher); initialized = false; files.launcher = _launcher; await initialize(); } exports.setLauncher = setLauncher; /** * Natives are binary blobs and DLL files various minecraft versions use to function. * Essentially used to access functionality outside the scope of what the Java JVM provides * @param _natives The location you want the bin directory to be at */ function setNatives(_natives) { if (typeof _natives == "string") _natives = new gfsl_1.Dir(_natives); files.natives = _natives; _natives.mkdir(); } exports.setNatives = setNatives; /** * Gets the root of the asset database. * @see the {@link setAssets set} method for more info */ function getAssets() { return files.assets; } exports.getAssets = getAssets; /** * Get the location of the library files. * @see the {@link setLibraries set} method for more info */ function getlibraries() { return files.libraries; } exports.getlibraries = getlibraries; /** * Use to get the instance directory * @see the {@link setInstances set} method for more info */ function getInstances() { return files.instances; } exports.getInstances = getInstances; /** * Use to get the version directory * @see the {@link setVersions set} method for more info */ function getVersions() { return files.versions; } exports.getVersions = getVersions; /** * Used to get the runtime directory * @see the {@link setRuntimes set} method for more info */ function getRuntimes() { return files.runtimes.mkdir(); } exports.getRuntimes = getRuntimes; /** * Returns a set of directories GMLL uses to store meta data. * Mostly used for version manifests and runtime manifests that act as pointers to help GMLL to locate other files stored on Mojang's servers. * It also stores miscellaneous files GMLL uses to optimize the retrieval of certian pieces of information needed for GMLL to function properly */ function getMeta() { //.getDir(getOS(), getCpuArch()) const meta = { bin: files._platform.getDir("bin"), runtimes: files.runtimes.getDir("runtimes", "meta"), lzma: files.launcher.getDir("lzma"), scratch: files.launcher.getDir("scratch"), manifests: files.launcher.getDir("manifests"), index: files.launcher.getDir("index"), profiles: files.launcher.getDir("profiles"), }; return meta; } exports.getMeta = getMeta; /** * Used to get the bin directory * @see the {@link setNatives set} method for more info */ function getNatives() { files.natives.mkdir(); return files.natives; } exports.getNatives = getNatives; /** * For internal use only */ function emit(tag, ...args) { defEvents.emit(tag, ...args); } exports.emit = emit; /**Replaces the current event Listener */ function setEventListener(events) { defEvents = events; } exports.setEventListener = setEventListener; /**Gets the current even Listener */ function getEventListener() { return defEvents; } exports.getEventListener = getEventListener; /** Clears all settings*/ function clrUpdateConfig() { updateConf = []; } exports.clrUpdateConfig = clrUpdateConfig; /**Adds a setting to the list of things GMLL should update*/ function addUpdateConfig(item) { updateConf.push(item); } exports.addUpdateConfig = addUpdateConfig; /**Gets the current list of things GMLL will update upon initialization */ function getUpdateConfig() { return updateConf; } exports.getUpdateConfig = getUpdateConfig; /**Used for GMLL plugins. */ function initializationListener(func) { startUpCalls.push(func); } exports.initializationListener = initializationListener; /**Does the basic pre flight checks. */ async function initialize() { Object.values(files).forEach((e) => { e.mkdir(); }); Object.values(getMeta()).forEach((e) => { e.mkdir(); }); await (0, downloader_js_1.manifests)(); for (let i = 0; i < startUpCalls.length; i++) { await startUpCalls[i](); } initialized = true; } exports.initialize = initialize; /**Used to resolve relative files in GMLL */ function resolvePath(file) { // return file .replace(/<assets>/g, getAssets().sysPath()) .replace(/<instance>/g, getInstances().sysPath()) .replace(/<libraries>/g, getlibraries().sysPath()) .replace(/<runtimes>/g, getRuntimes().sysPath()) .replace(/<versions>/g, getVersions().sysPath()); } exports.resolvePath = resolvePath; /** * Used to set the reported launcher name reported by GMLL to Minecraft * @param _version Any version string */ function setLauncherName(_name = "GMLL") { launcherName = _name; } exports.setLauncherName = setLauncherName; /** * Used to get the currently reported launcher name reported by GMLL to Minecraft */ function getLauncherName() { return launcherName || "GMLL"; } exports.getLauncherName = getLauncherName; /** * Used to set the reported launcher version reported by GMLL to Minecraft * @param _version Any version string */ function setLauncherVersion(_version = "0.0.0") { version = _version; } exports.setLauncherVersion = setLauncherVersion; /** * Used to get the currently reported launcher version reported by GMLL to Minecraft */ function getLauncherVersion() { return version || "0.0.0"; } exports.getLauncherVersion = getLauncherVersion; function forceCommonJsWorker() { workerSpawner = cjsWokerSpawner; } exports.forceCommonJsWorker = forceCommonJsWorker;