gmll
Version:
A generic launcher core for building custom launchers
321 lines (320 loc) • 12.4 kB
JavaScript
;
/**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;