Upload via GUI (28 Dateien)
This commit is contained in:
+123
-15
@@ -287,7 +287,29 @@ ipcMain.handle('mc:versions', () => services.getMcVersions(app.getPath('userData
|
||||
// IPC – Mods (Modrinth)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
ipcMain.handle('mods:search', (_e, opts) => services.modrinthSearch(opts));
|
||||
ipcMain.handle('curseforge:testKey', async (_e, apiKey) => {
|
||||
try { return await services.curseforgeTestKey(apiKey); }
|
||||
catch (err) { return { ok: false, message: err.message || String(err) }; }
|
||||
});
|
||||
|
||||
ipcMain.handle('mods:search', async (_e, opts) => {
|
||||
const o = opts || {};
|
||||
const source = o.source || 'modrinth';
|
||||
try {
|
||||
if (source === 'curseforge') {
|
||||
const zugang = services.curseforgeZugang(store.getSettings());
|
||||
return await services.curseforgeSearch(zugang, o);
|
||||
}
|
||||
return await services.modrinthSearch(o);
|
||||
} catch (err) {
|
||||
return {
|
||||
total: 0,
|
||||
hits: [],
|
||||
error: (err && err.message) ? err.message : String(err),
|
||||
needKey: !!(err && err.code === 'need-key'),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('mods:list', (_e, id, art) => store.listMods(id, art || 'mod'));
|
||||
|
||||
@@ -308,25 +330,46 @@ ipcMain.handle('mods:install', async (_e, id, project, art) => {
|
||||
const done = new Set(store.listMods(id, art || 'mod').map((m) => m.projectId));
|
||||
const added = [];
|
||||
let firstError = null;
|
||||
const istCf = !!(project && (project.source === 'curseforge' || String(project.projectId || '').startsWith('cf-')));
|
||||
const zugang = istCf ? services.curseforgeZugang(store.getSettings()) : null;
|
||||
|
||||
// installiert ein Projekt und rekursiv seine PFLICHT-Abhängigkeiten
|
||||
async function installOne(proj, isDep) {
|
||||
if (done.has(proj.projectId)) return;
|
||||
done.add(proj.projectId);
|
||||
try {
|
||||
const res = await services.modrinthInstall({
|
||||
projectId: proj.projectId, title: proj.title, gameVersion, loader, modsDir, art: art || 'mod',
|
||||
});
|
||||
if (!res.ok) {
|
||||
if (!isDep && !firstError) firstError = res.message;
|
||||
return;
|
||||
}
|
||||
store.addMod(id, res.entry, art || 'mod');
|
||||
added.push(res.entry);
|
||||
for (const dep of res.dependencies || []) {
|
||||
if (dep.dependency_type === 'required' && dep.project_id && !done.has(dep.project_id)) {
|
||||
const title = await services.modrinthProjectTitle(dep.project_id);
|
||||
await installOne({ projectId: dep.project_id, title }, true);
|
||||
let res;
|
||||
if (String(proj.projectId || '').startsWith('cf-') || proj.source === 'curseforge') {
|
||||
res = await services.curseforgeInstall({
|
||||
zugang, projectId: proj.projectId, title: proj.title,
|
||||
gameVersion, loader, modsDir, art: art || 'mod',
|
||||
});
|
||||
if (!res.ok) {
|
||||
if (!isDep && !firstError) firstError = res.message;
|
||||
return;
|
||||
}
|
||||
store.addMod(id, res.entry, art || 'mod');
|
||||
added.push(res.entry);
|
||||
for (const dep of res.dependencies || []) {
|
||||
if (dep.required && dep.projectId && !done.has(dep.projectId)) {
|
||||
await installOne({ projectId: dep.projectId, title: dep.projectId, source: 'curseforge' }, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = await services.modrinthInstall({
|
||||
projectId: proj.projectId, title: proj.title, gameVersion, loader, modsDir, art: art || 'mod',
|
||||
});
|
||||
if (!res.ok) {
|
||||
if (!isDep && !firstError) firstError = res.message;
|
||||
return;
|
||||
}
|
||||
store.addMod(id, res.entry, art || 'mod');
|
||||
added.push(res.entry);
|
||||
for (const dep of res.dependencies || []) {
|
||||
if (dep.dependency_type === 'required' && dep.project_id && !done.has(dep.project_id)) {
|
||||
const title = await services.modrinthProjectTitle(dep.project_id);
|
||||
await installOne({ projectId: dep.project_id, title }, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -384,6 +427,11 @@ ipcMain.handle('servers:remove', (_e, id, ip) => {
|
||||
return servers.entferne(store.gameDir(id), ip);
|
||||
});
|
||||
|
||||
ipcMain.handle('servers:rename', (_e, id, ip, neuerName) => {
|
||||
if (!store.getInstance(id)) return { ok: false, message: 'Instanz nicht gefunden.' };
|
||||
return servers.benenneUm(store.gameDir(id), ip, neuerName);
|
||||
});
|
||||
|
||||
// denselben Server in weitere Instanzen übertragen
|
||||
ipcMain.handle('servers:copyTo', (_e, zielIds, eintrag) => {
|
||||
const erledigt = [];
|
||||
@@ -612,6 +660,7 @@ function listDir(dir, dirsOnly) {
|
||||
|
||||
ipcMain.handle('instance:worlds', (_e, id) => listDir(path.join(store.gameDir(id), 'saves'), true));
|
||||
ipcMain.handle('instance:resourcepacks', (_e, id) => listDir(path.join(store.gameDir(id), 'resourcepacks'), false));
|
||||
ipcMain.handle('instance:datapacks', (_e, id) => listDir(path.join(store.gameDir(id), 'datapacks'), false));
|
||||
|
||||
function safeSub(id, sub, name) {
|
||||
const base = path.join(store.gameDir(id), sub);
|
||||
@@ -984,6 +1033,64 @@ async function importCurseForge(buf, zip, zugang) {
|
||||
};
|
||||
}
|
||||
|
||||
ipcMain.handle('modpack:search', async (_e, opts) => {
|
||||
try {
|
||||
const q = Object.assign({}, opts || {}, { art: 'modpack' });
|
||||
return await services.modrinthSearch(q);
|
||||
} catch (err) {
|
||||
return { total: 0, hits: [], error: err.message };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('modpack:installFromModrinth', async (_e, project) => {
|
||||
try {
|
||||
const projectId = project && (project.projectId || project.id);
|
||||
if (!projectId) return { ok: false, message: 'Kein Modpack gewählt.' };
|
||||
const gameVersion = (project && project.gameVersion) || '';
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('launch:progress', {
|
||||
phase: 'modpack', detail: 'Modpack-Version wird ermittelt …',
|
||||
});
|
||||
}
|
||||
const file = await services.modrinthResolveModpack({ projectId, gameVersion });
|
||||
if (!file) {
|
||||
return {
|
||||
ok: false,
|
||||
message: gameVersion
|
||||
? ('Keine Modpack-Version für Minecraft ' + gameVersion + ' gefunden.')
|
||||
: 'Keine Modpack-Version gefunden.',
|
||||
};
|
||||
}
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.webContents.send('launch:progress', {
|
||||
phase: 'modpack',
|
||||
detail: 'Lade ' + (file.filename || file.name || 'Modpack') + ' …',
|
||||
});
|
||||
}
|
||||
const buf = await services.downloadBuffer(file.url);
|
||||
const zip = forge.readZipIndex(buf);
|
||||
if (!zip['modrinth.index.json']) {
|
||||
return { ok: false, message: 'Die geladene Datei ist kein gültiges Modrinth-Modpack (.mrpack).' };
|
||||
}
|
||||
const result = await importMrpack(buf, zip);
|
||||
if (result && result.ok && result.instance) {
|
||||
// Herkunft mit aktueller Version-ID ergänzen, falls der Index sie nicht trägt
|
||||
const inst = result.instance;
|
||||
const mp = Object.assign({}, inst.modpack || {}, {
|
||||
projectId: projectId,
|
||||
versionId: file.versionId,
|
||||
versionNumber: file.versionNumber,
|
||||
title: (project && project.title) || (inst.modpack && inst.modpack.title) || inst.name,
|
||||
});
|
||||
store.updateInstance(inst.id, { modpack: mp });
|
||||
result.instance = store.getInstance(inst.id);
|
||||
}
|
||||
return result;
|
||||
} catch (err) {
|
||||
return { ok: false, message: 'Modpack-Installation fehlgeschlagen: ' + err.message };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('modpack:import', async () => {
|
||||
const res = await dialog.showOpenDialog(mainWindow, {
|
||||
title: 'Modpack importieren',
|
||||
@@ -1229,7 +1336,7 @@ function kontoSpieltNichtMehr(kontoId) {
|
||||
meldeKontenAenderung();
|
||||
}
|
||||
|
||||
ipcMain.handle('instances:launch', async (_e, id, accountId) => {
|
||||
ipcMain.handle('instances:launch', async (_e, id, accountId, launchOpts) => {
|
||||
const inst = store.getInstance(id);
|
||||
if (!inst) return { ok: false, message: 'Instanz nicht gefunden.' };
|
||||
if (!inst.minecraft.version) {
|
||||
@@ -1278,6 +1385,7 @@ ipcMain.handle('instances:launch', async (_e, id, accountId) => {
|
||||
auth: null,
|
||||
// fehlende Java-Fassung bei Bedarf selbst beschaffen (abschaltbar)
|
||||
ensureJava: settings.autoJava === false ? null : (major, onProgress) => javadl.ensureJava(major, onProgress),
|
||||
quickPlayServer: (launchOpts && launchOpts.quickPlayServer) ? String(launchOpts.quickPlayServer).trim() : '',
|
||||
};
|
||||
|
||||
// eingeloggtes Microsoft-Konto verwenden (gewähltes oder aktives) -> echter Start
|
||||
|
||||
Reference in New Issue
Block a user