gmll
Version:
A generic launcher core for building custom launchers
432 lines (431 loc) • 16.6 kB
JavaScript
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;
;