Upload via GUI (324 Dateien)
This commit is contained in:
+59
-3
@@ -222,6 +222,45 @@ let letzterUpdateCheck = { checking: true };
|
|||||||
// Hauptfenster hat seine Empfänger registriert – erst dann den Update-Hinweis schicken
|
// Hauptfenster hat seine Empfänger registriert – erst dann den Update-Hinweis schicken
|
||||||
const hauptfensterBereit = new Promise((resolve) => ipcMain.once('renderer:ready', resolve));
|
const hauptfensterBereit = new Promise((resolve) => ipcMain.once('renderer:ready', resolve));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update und laufendes Spiel
|
||||||
|
* --------------------------
|
||||||
|
* Ein Update beendet den Launcher (und der Installer ersetzt dessen Dateien). Das darf nie
|
||||||
|
* passieren, solange Minecraft läuft: Das Update wird erst installiert, wenn kein Spiel mehr
|
||||||
|
* läuft. Damit es trotzdem nicht untergeht, bekommt der Spieler im Spiel eine Einblendung
|
||||||
|
* (wie bei den Freunde-Hinweisen), und nach dem letzten Spielende öffnet sich der Update-Dialog.
|
||||||
|
*/
|
||||||
|
const spielLaeuft = () => laufendeInstanzen.size > 0;
|
||||||
|
const SPIEL_LAEUFT_TEXT = 'Minecraft läuft noch – das Update wird erst installiert, wenn kein Spiel mehr läuft. Bitte zuerst das Spiel beenden.';
|
||||||
|
let updateWartetAufSpielende = false; // Hinweis kam im Spiel -> nach Spielende den Dialog zeigen
|
||||||
|
let angekuendigteVersion = null; // Dialog schon gezeigt, nicht bei jeder Prüfung wieder
|
||||||
|
const updateImSpielGemeldet = new Set(); // pid des Spiels, das den Hinweis schon bekam
|
||||||
|
|
||||||
|
// Einblendung auf dem Minecraft-Fenster, einmal je Spielstart
|
||||||
|
async function meldeUpdateImSpiel() {
|
||||||
|
const info = pendingUpdateInfo;
|
||||||
|
if (!info || !info.available || !spielLaeuft()) return;
|
||||||
|
for (const pid of [...laufendePid.values()]) {
|
||||||
|
if (updateImSpielGemeldet.has(pid)) continue;
|
||||||
|
// false, solange das Spielfenster noch nicht da ist – dann beim nächsten Durchlauf erneut
|
||||||
|
const gezeigt = await zeigeIngameOverlay('AeroMC-Update', [
|
||||||
|
`AeroMC ${info.latestVersion || 'Update'} ist verfügbar.`,
|
||||||
|
'Bitte nach dem Spiel installieren.',
|
||||||
|
], pid, 10000).catch(() => false);
|
||||||
|
// nur vermerken, wenn dieses Spiel noch läuft – sonst bliebe nach seinem Ende ein falscher Zustand zurück
|
||||||
|
if (gezeigt && spielLaeuft() && [...laufendePid.values()].includes(pid)) { updateImSpielGemeldet.add(pid); updateWartetAufSpielende = true; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialog zeigen – aber nie, während ein Spiel läuft (er würde dem Spiel den Fokus nehmen)
|
||||||
|
function kuendigeUpdateAn(info) {
|
||||||
|
if (!info || !info.available) return;
|
||||||
|
if (spielLaeuft()) { updateWartetAufSpielende = true; meldeUpdateImSpiel().catch(() => {}); return; }
|
||||||
|
if (info.latestVersion && info.latestVersion === angekuendigteVersion) return;
|
||||||
|
angekuendigteVersion = info.latestVersion || true;
|
||||||
|
broadcast('update:available', info);
|
||||||
|
}
|
||||||
|
|
||||||
async function pruefeAufUpdates() {
|
async function pruefeAufUpdates() {
|
||||||
letzterUpdateCheck = { checking: true };
|
letzterUpdateCheck = { checking: true };
|
||||||
broadcast('update:checked', letzterUpdateCheck);
|
broadcast('update:checked', letzterUpdateCheck);
|
||||||
@@ -357,7 +396,15 @@ ipcMain.handle('recording:getServer', (_e, id) => letzteQuickPlayServer.get(id)
|
|||||||
const laufendePid = new Map(); // instanceId -> pid des zuletzt gestarteten Minecraft-Prozesses
|
const laufendePid = new Map(); // instanceId -> pid des zuletzt gestarteten Minecraft-Prozesses
|
||||||
// Instanzen, deren Spiel gerade läuft (für den pulsierenden Rand der Karte)
|
// Instanzen, deren Spiel gerade läuft (für den pulsierenden Rand der Karte)
|
||||||
const laufendeInstanzen = new Set();
|
const laufendeInstanzen = new Set();
|
||||||
function meldeLaufende() { broadcast('game:laufend', [...laufendeInstanzen]); }
|
function meldeLaufende() {
|
||||||
|
broadcast('game:laufend', [...laufendeInstanzen]);
|
||||||
|
// letztes Spiel beendet und ein Update wartet -> jetzt den Update-Dialog zeigen
|
||||||
|
if (!spielLaeuft() && updateWartetAufSpielende) {
|
||||||
|
updateWartetAufSpielende = false;
|
||||||
|
updateImSpielGemeldet.clear();
|
||||||
|
kuendigeUpdateAn(pendingUpdateInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
ipcMain.handle('game:laufend', () => [...laufendeInstanzen]);
|
ipcMain.handle('game:laufend', () => [...laufendeInstanzen]);
|
||||||
const kontoPid = new Map(); // kontoId -> pid, für den Ingame-Toast: der muss auf DEM Fenster
|
const kontoPid = new Map(); // kontoId -> pid, für den Ingame-Toast: der muss auf DEM Fenster
|
||||||
// des prüfenden Kontos erscheinen, nicht auf irgendeinem laufenden Minecraft-Fenster
|
// des prüfenden Kontos erscheinen, nicht auf irgendeinem laufenden Minecraft-Fenster
|
||||||
@@ -1169,8 +1216,13 @@ app.whenReady().then(() => {
|
|||||||
pruefeAufUpdates().then(async (info) => {
|
pruefeAufUpdates().then(async (info) => {
|
||||||
if (!info.available) return;
|
if (!info.available) return;
|
||||||
await hauptfensterBereit;
|
await hauptfensterBereit;
|
||||||
broadcast('update:available', info);
|
kuendigeUpdateAn(info);
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
|
// Der Launcher bleibt oft tagelang offen: alle 3 Stunden erneut prüfen. Läuft ein Spiel,
|
||||||
|
// gibt es nur die Einblendung im Spiel, den Dialog erst nach Spielende.
|
||||||
|
setInterval(() => { pruefeAufUpdates().then(kuendigeUpdateAn).catch(() => {}); }, 3 * 60 * 60 * 1000);
|
||||||
|
// Hinweis im Spiel, sobald das Spielfenster da ist (auch für ein später gestartetes Spiel)
|
||||||
|
setInterval(() => { meldeUpdateImSpiel().catch(() => {}); }, 30000);
|
||||||
|
|
||||||
// Anmelde-Dienste automatisch überwachen (sofort + alle 2 Minuten)
|
// Anmelde-Dienste automatisch überwachen (sofort + alle 2 Minuten)
|
||||||
setTimeout(() => checkAuthServices(), 2500);
|
setTimeout(() => checkAuthServices(), 2500);
|
||||||
@@ -1230,7 +1282,7 @@ ipcMain.handle('settings:save', (_e, patch) => {
|
|||||||
// Beta-Teilnahme umgeschaltet -> gleich neu nach Updates suchen
|
// Beta-Teilnahme umgeschaltet -> gleich neu nach Updates suchen
|
||||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'betaTeilnahme') && !!patch.betaTeilnahme !== betaStand) {
|
if (patch && Object.prototype.hasOwnProperty.call(patch, 'betaTeilnahme') && !!patch.betaTeilnahme !== betaStand) {
|
||||||
betaStand = !!patch.betaTeilnahme;
|
betaStand = !!patch.betaTeilnahme;
|
||||||
pruefeAufUpdates().then((info) => { if (info.available) broadcast('update:available', info); }).catch(() => {});
|
pruefeAufUpdates().then((info) => { if (info.available) { angekuendigteVersion = null; kuendigeUpdateAn(info); } }).catch(() => {});
|
||||||
}
|
}
|
||||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'friendsEnabled')) {
|
if (patch && Object.prototype.hasOwnProperty.call(patch, 'friendsEnabled')) {
|
||||||
aktualisiereFreundeTastenkuerzel();
|
aktualisiereFreundeTastenkuerzel();
|
||||||
@@ -5575,11 +5627,15 @@ ipcMain.handle('update:lastCheck', () => letzterUpdateCheck);
|
|||||||
// beliebige Datei als "Update" ausführen lassen.
|
// beliebige Datei als "Update" ausführen lassen.
|
||||||
ipcMain.handle('update:install', async () => {
|
ipcMain.handle('update:install', async () => {
|
||||||
try {
|
try {
|
||||||
|
// Nie während Minecraft läuft: Der Launcher beendet sich für das Update
|
||||||
|
if (spielLaeuft()) { updateWartetAufSpielende = true; return { ok: false, spielLaeuft: true, message: SPIEL_LAEUFT_TEXT }; }
|
||||||
const asset = pendingUpdateInfo && pendingUpdateInfo.available ? pendingUpdateInfo.asset : null;
|
const asset = pendingUpdateInfo && pendingUpdateInfo.available ? pendingUpdateInfo.asset : null;
|
||||||
if (!asset) throw new Error('Kein geprüftes Update vorhanden – bitte erneut nach Updates suchen.');
|
if (!asset) throw new Error('Kein geprüftes Update vorhanden – bitte erneut nach Updates suchen.');
|
||||||
const file = await updater.downloadAndInstall(asset, (p) => {
|
const file = await updater.downloadAndInstall(asset, (p) => {
|
||||||
broadcast('update:progress', p);
|
broadcast('update:progress', p);
|
||||||
});
|
});
|
||||||
|
// Während des Downloads kann ein Spiel gestartet worden sein – die Datei bleibt liegen
|
||||||
|
if (spielLaeuft()) { updateWartetAufSpielende = true; return { ok: false, spielLaeuft: true, message: SPIEL_LAEUFT_TEXT }; }
|
||||||
const res = await updater.applyUpdate(file);
|
const res = await updater.applyUpdate(file);
|
||||||
// Portable: der Tausch klappt erst, wenn der Launcher die EXE freigibt
|
// Portable: der Tausch klappt erst, wenn der Launcher die EXE freigibt
|
||||||
setTimeout(() => app.quit(), 1200);
|
setTimeout(() => app.quit(), 1200);
|
||||||
|
|||||||
@@ -1711,7 +1711,24 @@ function showUpdateDialog(info) {
|
|||||||
: (channel
|
: (channel
|
||||||
? `Für den Kanal ${channel} liegt in diesem Release keine passende Datei bereit. Bitte im Release nachsehen und von Hand aktualisieren.`
|
? `Für den Kanal ${channel} liegt in diesem Release keine passende Datei bereit. Bitte im Release nachsehen und von Hand aktualisieren.`
|
||||||
: 'Die Paketart dieses Launchers lässt sich nicht sicher bestimmen. Bitte das Update von Hand aus dem Release laden.');
|
: 'Die Paketart dieses Launchers lässt sich nicht sicher bestimmen. Bitte das Update von Hand aus dem Release laden.');
|
||||||
|
updHintNormal = el('upd-hint').textContent;
|
||||||
show('modal-update');
|
show('modal-update');
|
||||||
|
aktualisiereUpdateKnopf();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solange Minecraft läuft, wird nicht installiert: Der Launcher beendet sich für das Update
|
||||||
|
let updHintNormal = '';
|
||||||
|
let updInstalliertGerade = false;
|
||||||
|
async function aktualisiereUpdateKnopf() {
|
||||||
|
if (!pendingUpdate || !pendingUpdate.asset || updInstalliertGerade) return;
|
||||||
|
let laeuft = false;
|
||||||
|
try { laeuft = ((await window.api.laufendeInstanzen()) || []).length > 0; } catch { /* dann nicht sperren */ }
|
||||||
|
const btn = el('upd-install');
|
||||||
|
btn.disabled = laeuft;
|
||||||
|
btn.textContent = laeuft ? 'Minecraft läuft noch' : 'Installieren';
|
||||||
|
el('upd-hint').textContent = laeuft
|
||||||
|
? 'Das Update wird erst installiert, wenn kein Minecraft mehr läuft. Beende das Spiel – danach kannst du hier auf „Installieren“ klicken.'
|
||||||
|
: updHintNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Links in den Update-Hinweisen im Browser öffnen, nie im Launcher-Fenster
|
// Links in den Update-Hinweisen im Browser öffnen, nie im Launcher-Fenster
|
||||||
@@ -1731,10 +1748,19 @@ async function startUpdate() {
|
|||||||
const btn = el('upd-install');
|
const btn = el('upd-install');
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
btn.textContent = 'Wird installiert …';
|
btn.textContent = 'Wird installiert …';
|
||||||
|
updInstalliertGerade = true;
|
||||||
el('upd-progress').classList.remove('hidden');
|
el('upd-progress').classList.remove('hidden');
|
||||||
el('upd-status').textContent = 'Wird heruntergeladen …';
|
el('upd-status').textContent = 'Wird heruntergeladen …';
|
||||||
|
|
||||||
const res = await window.api.updateInstall();
|
const res = await window.api.updateInstall();
|
||||||
|
if (!res.ok) updInstalliertGerade = false;
|
||||||
|
if (!res.ok && res.spielLaeuft) {
|
||||||
|
// Spiel lief schon oder ist während des Downloads gestartet worden
|
||||||
|
el('upd-progress').classList.add('hidden');
|
||||||
|
el('upd-status').textContent = '';
|
||||||
|
aktualisiereUpdateKnopf();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
el('upd-status').textContent = res.kind === 'portable'
|
el('upd-status').textContent = res.kind === 'portable'
|
||||||
? 'Launcher schließt sich, wird ersetzt und startet automatisch neu.'
|
? 'Launcher schließt sich, wird ersetzt und startet automatisch neu.'
|
||||||
@@ -7849,6 +7875,8 @@ window.addEventListener('DOMContentLoaded', async () => {
|
|||||||
}
|
}
|
||||||
el('upd-notes').addEventListener('click', updateLinkKlick);
|
el('upd-notes').addEventListener('click', updateLinkKlick);
|
||||||
window.api.onLaufendeInstanzen(setzeLaufende);
|
window.api.onLaufendeInstanzen(setzeLaufende);
|
||||||
|
// Update-Dialog offen: Knopf freigeben, sobald das letzte Spiel beendet ist (bzw. sperren, wenn eins startet)
|
||||||
|
window.api.onLaufendeInstanzen(() => { if (!el('modal-update').classList.contains('hidden')) aktualisiereUpdateKnopf(); });
|
||||||
window.api.laufendeInstanzen().then(setzeLaufende).catch(() => {});
|
window.api.laufendeInstanzen().then(setzeLaufende).catch(() => {});
|
||||||
el('grid').addEventListener('mousemove', kippeZurMaus);
|
el('grid').addEventListener('mousemove', kippeZurMaus);
|
||||||
baueLichtpunkte();
|
baueLichtpunkte();
|
||||||
|
|||||||
Reference in New Issue
Block a user