Upload via GUI (39 Dateien)

This commit is contained in:
Git Manager GUI
2026-08-03 21:00:24 +02:00
parent 129ab2d939
commit 54d248133c
7 changed files with 218 additions and 25 deletions
+56 -13
View File
@@ -21,6 +21,7 @@ const { spawn, spawnSync } = require('child_process');
const services = require('./services');
const loaders = require('./loaders');
const forge = require('./forge');
const processwatchdog = require('./processwatchdog');
const UA = 'AeroMC-Launcher/0.2';
const RESOURCES = 'https://resources.download.minecraft.net';
@@ -253,20 +254,28 @@ async function prepareAssets(vj, sharedDir, onProgress) {
// ---------------------------------------------------------------------------
function pickJava(vj, preferredPath) {
const required = (vj.javaVersion && vj.javaVersion.majorVersion) || 8;
let preferred = null;
if (preferredPath && preferredPath.trim()) {
const info = services.probeJava(preferredPath);
if (info) return { path: preferredPath, major: info.major, forced: true };
if (info) {
preferred = { path: preferredPath, major: info.major, forced: true };
if (info.major === required) return preferred;
}
}
const required = (vj.javaVersion && vj.javaVersion.majorVersion) || 8;
const jvms = services.scanJava();
// exakt passende oder nächsthöhere 64-bit-Version
// Mod-Loader und Mods unterstützen neuere Java-Versionen nicht automatisch.
// Deshalb ausschließlich die von Mojang angegebene Major-Version verwenden.
const x64 = jvms.filter((j) => j.arch === 'x64');
const exact = x64.find((j) => j.major === required);
if (exact) return { path: exact.path, major: exact.major };
const higher = x64.filter((j) => j.major >= required).sort((a, b) => a.major - b.major)[0];
if (higher) return { path: higher.path, major: higher.major };
const any = jvms[0];
return any ? { path: any.path, major: any.major, mismatch: required } : null;
const fallback = preferred || x64[0] || jvms[0];
return fallback ? {
path: fallback.path,
major: fallback.major,
forced: !!fallback.forced,
mismatch: required,
} : null;
}
// ---------------------------------------------------------------------------
@@ -387,6 +396,14 @@ async function prepareAndLaunch(opts, onProgress) {
}
}
if (!java) return { ok: false, message: 'Keine Java-Installation gefunden. Bitte in den Einstellungen Java festlegen.' };
if (java.mismatch) {
return {
ok: false,
requiredJava: java.mismatch,
message: `Minecraft ${vj.id} benötigt Java ${java.mismatch}, gefunden wurde nur Java ${java.major || 'unbekannt'}. `
+ 'Bitte Auto-Java aktivieren oder eine passende Java-Installation auswählen.',
};
}
// Mod-Loader
let effectiveVj = vj;
@@ -503,14 +520,33 @@ async function prepareAndLaunch(opts, onProgress) {
spawnArgs = [...w.slice(1), java.path, ...args];
}
const child = spawn(cmd, spawnArgs, { cwd: opts.gameDir, detached: false });
child.stdout.on('data', (d) => emit('log', { line: d.toString() }));
child.stderr.on('data', (d) => emit('log', { line: d.toString() }));
const shutdownWatchdog = opts.wrapperCommand && opts.wrapperCommand.trim()
? null
: processwatchdog.createProcessWatchdog({
isRunning: () => child.exitCode === null && child.signalCode === null,
kill: () => child.kill(),
onForce: (graceMs) => emit('log', {
line: `[Launcher] Regulärer Client-Shutdown war nach ${graceMs / 1000} Sekunden noch nicht beendet; `
+ 'verbliebenen Java-Prozess beendet.\n',
}),
onError: () => emit('log', {
line: '[Launcher] Der nach dem regulären Client-Shutdown verbliebene Java-Prozess konnte nicht beendet werden.\n',
}),
});
child.stdout.on('data', (d) => {
emit('log', { line: d.toString() });
if (shutdownWatchdog) shutdownWatchdog.feed(d, 'stdout');
});
child.stderr.on('data', (d) => {
emit('log', { line: d.toString() });
if (shutdownWatchdog) shutdownWatchdog.feed(d, 'stderr');
});
// Ende genau einmal melden 'exit' und 'error' können beide kommen
let beendetGemeldet = false;
const meldeEnde = (code) => {
const meldeEnde = (code, cleanShutdown) => {
if (beendetGemeldet) return;
beendetGemeldet = true;
emit('exit', { code });
emit('exit', { code, cleanShutdown: !!cleanShutdown });
// Post-Exit-Befehl
if (opts.postExitCommand && opts.postExitCommand.trim()) {
emit('log', { line: '[Post-Exit] ' + opts.postExitCommand + '\n' });
@@ -521,12 +557,19 @@ async function prepareAndLaunch(opts, onProgress) {
} catch { /* egal */ }
}
};
child.on('exit', (code) => meldeEnde(code));
child.on('exit', (code) => {
// vor end() lesen: sawCleanShutdown wird zwar nicht von end()/clear()
// zurückgesetzt, aber so bleibt die Reihenfolge unabhängig von internen Details
const cleanShutdown = !!(shutdownWatchdog && shutdownWatchdog.sawCleanShutdown);
if (shutdownWatchdog) shutdownWatchdog.end();
meldeEnde(shutdownWatchdog && shutdownWatchdog.forced ? 0 : code, cleanShutdown);
});
// ohne diesen Listener würde ein Fehlstart (z. B. falscher Java-Pfad) als
// unbehandeltes 'error'-Ereignis den Hauptprozess beenden
child.on('error', (err) => {
if (shutdownWatchdog) shutdownWatchdog.end();
emit('log', { line: '[Fehler] Minecraft konnte nicht gestartet werden: ' + err.message + '\n' });
meldeEnde(-1);
meldeEnde(-1, false);
});
return { ok: true, pid: child.pid, java };