UNPKG

dmclc

Version:

Dolphin Minecraft Launcher Core

226 lines (225 loc) 10.5 kB
import StreamZip from "node-stream-zip"; import { ModInfo } from "../../mods/mod.js"; import { transformJSON } from "../../utils/transformJSON.js"; import { checkFabricDeps } from "../fabric.js"; import { FabricLikeLoader, checkMatch, formatDepVersion, normalizeVersion } from "../fabriclike/fabriclike.js"; import { VersionParser } from "../fabriclike/version/VersionParser.js"; import { ModLoadingIssue } from "../loader.js"; import * as streamPromises from "stream/promises"; let temp = (await import("temp")).track(); export class QuiltLoader extends FabricLikeLoader { metaURL = "https://meta.quiltmc.org/v3"; loaderMaven = "https://maven.quiltmc.org/repository/release/"; hashedMaven = "https://maven.quiltmc.org/repository/release/"; name = "quilt"; findInVersion(MCVersion) { let ret; MCVersion.libraries.forEach(i => { if (i.name.includes(":quilt-loader:")) { ret = i.name.split(":")[2]; } }); return ret; } async findModInfos(path) { const zip = new StreamZip.async({ file: path }); const entry = await zip.entry("quilt.mod.json"); if (entry === undefined) { try { return super.findModInfosInZip(zip); } finally { await zip.close(); } } const json = JSON.parse(transformJSON((await zip.entryData(entry)).toString())); const result = await super.findModInfosInZip(zip); if (json.quilt_loader.jars !== undefined) { for (const jar of json.quilt_loader.jars) { const file = temp.createWriteStream(); streamPromises.pipeline(await zip.stream(jar), file); file.close(); result.push(...await this.findModInfos(file.path)); } } const info = new ModInfo("quilt", json, this.launcher); info.data = json; result.push(info); await zip.close(); return result; } checkMods(mods, mc, loader) { const modIdVersions = { minecraft: normalizeVersion(mc), quilt_loader: loader, fabricloader: "Provided", java: "Provided" }; const issues = []; for (const mod of mods) { if ("quilt_loader" in mod.data) { if (!modIdVersions[mod.data.quilt_loader.id] || VersionParser.parse(modIdVersions[mod.data.quilt_loader.id], false).compareTo(VersionParser.parse(mod.data.quilt_loader.version, false)) <= 0) { modIdVersions[mod.data.quilt_loader.id] = mod.data.quilt_loader.version; } if (mod.data.quilt_loader.provides) { for (const provide of mod.data.quilt_loader.provides) { modIdVersions[provide.id] = provide.version; } } } else { if (!modIdVersions[mod.data.id] || VersionParser.parse(modIdVersions[mod.data.id], false).compareTo(VersionParser.parse(mod.data.version, false)) <= 0) { modIdVersions[mod.data.id] = mod.data.version; } if (mod.data.provides) { for (const provide of mod.data.provides) { modIdVersions[provide] = "Provided"; } } } } for (const mod of mods) { if ("quilt_loader" in mod.data) { const data = mod.data.quilt_loader; deps: for (const dep of processDeps(data.depends)) { const unlesses = processDeps(dep.unless); for (const unless of unlesses) { if (unless.id in modIdVersions && checkMatch(modIdVersions[unless.id], unless.versions ?? "*")) { break deps; } } if (unlesses.length !== 0) { if (!(dep.id in modIdVersions) || !checkMatch(modIdVersions[dep.id], dep.versions ?? "*")) { if (dep.reason) issues.push(new ModLoadingIssue("error", "dependencies.dependency_wrong_missing_reason_unless", { source: data.id, target: dep.id, targetVersion: formatDepVersion(dep.versions ?? "*", this.launcher), reason: dep.reason, unless: formatUnless(unlesses, this.launcher) })); else issues.push(new ModLoadingIssue("error", "dependencies.dependency_wrong_missing_unless", { source: data.id, target: dep.id, targetVersion: formatDepVersion(dep.versions ?? "*", this.launcher), unless: formatUnless(unlesses, this.launcher) })); } } else { if (!(dep.id in modIdVersions) || !checkMatch(modIdVersions[dep.id], dep.versions ?? "*")) { if (dep.reason) issues.push(new ModLoadingIssue("error", "dependencies.dependency_wrong_missing_reason", { source: data.id, target: dep.id, targetVersion: formatDepVersion(dep.versions ?? "*", this.launcher), reason: dep.reason })); else issues.push(new ModLoadingIssue("error", "dependencies.dependency_wrong_missing", { source: data.id, target: dep.id, targetVersion: formatDepVersion(dep.versions ?? "*", this.launcher) })); } } } brks: for (const brk of processDeps(data.breaks)) { const unlesses = processDeps(brk.unless); for (const unless of unlesses) { if (unless.id in modIdVersions && checkMatch(modIdVersions[unless.id], unless.versions ?? "*")) { break brks; } } if (unlesses.length !== 0) { if (brk.id in modIdVersions && checkMatch(modIdVersions[brk.id], brk.versions ?? "*")) { if (brk.reason) issues.push(new ModLoadingIssue("error", "dependencies.breaks_exists_reason_unless", { source: data.id, target: brk.id, targetVersion: formatDepVersion(brk.versions ?? "*", this.launcher), reason: brk.reason, unless: formatUnless(unlesses, this.launcher) })); else issues.push(new ModLoadingIssue("error", "dependencies.breaks_exists_unless", { source: data.id, target: brk.id, targetVersion: formatDepVersion(brk.versions ?? "*", this.launcher), unless: formatUnless(unlesses, this.launcher) })); } } else { if (brk.id in modIdVersions && checkMatch(modIdVersions[brk.id], brk.versions ?? "*")) { if (brk.reason) issues.push(new ModLoadingIssue("error", "dependencies.breaks_exists_reason", { source: data.id, target: brk.id, targetVersion: formatDepVersion(brk.versions ?? "*", this.launcher), reason: brk.reason })); else issues.push(new ModLoadingIssue("error", "dependencies.breaks_exists", { source: data.id, target: brk.id, targetVersion: formatDepVersion(brk.versions ?? "*", this.launcher) })); } } } } else { issues.push(...checkFabricDeps(mod.data, modIdVersions, this.launcher)); } } return issues; } getModInfo(modJson) { const meta = modJson.quilt_loader.metadata; const res = { id: modJson.quilt_loader.id, version: modJson.quilt_loader.version, isJIJLib: false }; if (meta) { if (meta.description) res.description = meta.description; if (meta.name) res.name = meta.name; if (meta.license instanceof Array) { res.license = meta.license.join(", "); } else if (!(meta.license instanceof Object)) { res.license = meta.license ?? "ARR"; } else { res.license = meta.license.name; } } return res; } } function processDeps(deps) { let ret = []; if (typeof (deps) === "string") { ret = [{ id: deps }]; } else { if (deps instanceof Array) { ret = deps.map(processDeps).flat(); } else if (deps instanceof Object) { ret = [deps]; } } return ret; } function formatUnless(unlesses, launcher) { return unlesses.map((v) => `${v.id} ${launcher.i18n("misc.version")} ${formatDepVersion(v.versions ?? "*", launcher)}`).join(`\n${launcher.i18n("misc.or")} `); }