Upload via GUI (39 Dateien)

This commit is contained in:
Git Manager GUI
2026-08-02 20:18:36 +02:00
parent 176d20ae7b
commit 9e601b1962
8 changed files with 475 additions and 95 deletions
+37 -12
View File
@@ -227,10 +227,29 @@ const MODRINTH = 'https://api.modrinth.com/v2';
const MODRINTH_SORTS = ['relevance', 'downloads', 'follows', 'newest', 'updated'];
async function modrinthSearch({ query = '', gameVersion = '', loader = '', category = '', sort = 'relevance', limit = 30, offset = 0 } = {}) {
const facets = [['project_type:mod']];
/*
* Inhaltsarten, die der Launcher aus dem Modrinth-Katalog holen kann.
* ordner = Zielverzeichnis im Spielordner, loaderNoetig = braucht einen
* Mod-Loader (Ressourcenpakete laufen auch in Vanilla).
*/
const INHALTSARTEN = {
mod: { projectType: 'mod', ordner: 'mods', label: 'Mods', loaderNoetig: true },
resourcepack: { projectType: 'resourcepack', ordner: 'resourcepacks', label: 'Ressourcenpakete', loaderNoetig: false },
shader: { projectType: 'shader', ordner: 'shaderpacks', label: 'Shader', loaderNoetig: false },
};
function inhaltsArt(art) {
return INHALTSARTEN[art] || INHALTSARTEN.mod;
}
async function modrinthSearch({ query = '', gameVersion = '', loader = '', category = '', sort = 'relevance', limit = 30, offset = 0, art = 'mod' } = {}) {
const typ = inhaltsArt(art);
const facets = [['project_type:' + typ.projectType]];
if (gameVersion) facets.push(['versions:' + gameVersion]);
if (loader && loader !== 'vanilla') facets.push(['categories:' + loader]);
// Der Loader-Filter gilt nur für Mods. Ressourcenpakete und Shader werden
// bei Modrinth nicht nach Mod-Loader eingeordnet der Filter würde die
// Trefferliste leeren.
if (typ.loaderNoetig && loader && loader !== 'vanilla') facets.push(['categories:' + loader]);
if (category) facets.push(['categories:' + category]);
const url = new URL(MODRINTH + '/search');
url.searchParams.set('query', query);
@@ -258,10 +277,13 @@ async function modrinthSearch({ query = '', gameVersion = '', loader = '', categ
}
// findet die passende Datei-Version für Spielversion + Loader
async function modrinthResolveFile({ projectId, gameVersion, loader }) {
async function modrinthResolveFile({ projectId, gameVersion, loader, art = 'mod' }) {
const typ = inhaltsArt(art);
const url = new URL(MODRINTH + '/project/' + projectId + '/version');
if (gameVersion) url.searchParams.set('game_versions', JSON.stringify([gameVersion]));
if (loader && loader !== 'vanilla') url.searchParams.set('loaders', JSON.stringify([loader]));
// Nur Mods werden nach Loader eingeordnet; bei Ressourcenpaketen und
// Shadern würde der Filter alle Dateien ausschließen.
if (typ.loaderNoetig && loader && loader !== 'vanilla') url.searchParams.set('loaders', JSON.stringify([loader]));
const res = await fetch(url, { headers: { 'User-Agent': UA } });
if (!res.ok) throw new Error('Versionsabruf fehlgeschlagen: HTTP ' + res.status);
const versions = await res.json();
@@ -291,11 +313,14 @@ async function downloadFile(url, destPath, extraHeaders) {
}
// lädt eine Mod in <modsDir>; gibt Metadaten für die Instanz zurück
async function modrinthInstall({ projectId, title, gameVersion, loader, modsDir }) {
const file = await modrinthResolveFile({ projectId, gameVersion, loader });
async function modrinthInstall({ projectId, title, gameVersion, loader, modsDir, art = 'mod' }) {
const typ = inhaltsArt(art);
const file = await modrinthResolveFile({ projectId, gameVersion, loader, art });
if (!file) {
return { ok: false, reason: 'no-match',
message: `Keine passende Version für ${gameVersion} / ${loader} gefunden.` };
message: typ.loaderNoetig
? `Keine passende Version für ${gameVersion} / ${loader} gefunden.`
: `Keine passende Version für ${gameVersion} gefunden.` };
}
const dest = path.join(modsDir, file.filename);
const bytes = await downloadFile(file.url, dest);
@@ -322,7 +347,7 @@ async function modrinthInstall({ projectId, title, gameVersion, loader, modsDir
* für die weiß niemand, woher sie stammen.
* -> [{ projectId, title, alt: {...}, neu: {...} }]
*/
async function modrinthFindUpdates(mods, gameVersion, loader, onProgress) {
async function modrinthFindUpdates(mods, gameVersion, loader, onProgress, art = 'mod') {
const kandidaten = (mods || []).filter((m) => m && m.projectId);
const treffer = [];
let geprueft = 0;
@@ -333,8 +358,8 @@ async function modrinthFindUpdates(mods, gameVersion, loader, onProgress) {
await Promise.all(kandidaten.slice(i, i + GRUPPE).map(async (m) => {
let file = null;
try {
file = await modrinthResolveFile({ projectId: m.projectId, gameVersion, loader });
} catch { /* Netzfehler -> diese Mod überspringen */ }
file = await modrinthResolveFile({ projectId: m.projectId, gameVersion, loader, art });
} catch { /* Netzfehler -> diesen Eintrag überspringen */ }
geprueft++;
if (onProgress) onProgress({ geprueft, gesamt: kandidaten.length, titel: m.title || m.projectId });
if (!file || !file.versionId) return;
@@ -480,6 +505,6 @@ module.exports = {
scanJava, probeJava, setCacheDir, setManagedJavaDir, pruefeSpeicher,
getMcVersions,
modrinthSearch, modrinthResolveFile, modrinthInstall, modrinthProjectTitle,
modrinthFindUpdates, downloadFile,
modrinthFindUpdates, downloadFile, inhaltsArt, INHALTSARTEN,
curseforgeResolveFiles, forgeCdnUrl, curseforgeZugang,
};