Upload via GUI (202 Dateien)

This commit is contained in:
2026-10-11 07:05:48 +00:00
parent 67337c5b1e
commit 27c5fbb856
3 changed files with 81 additions and 31 deletions
+2
View File
@@ -75,6 +75,8 @@ const DEFAULT_SETTINGS = {
sortBy: 'lastPlayed', // lastPlayed | name sortBy: 'lastPlayed', // lastPlayed | name
iso3dIcons: true, // Block-Symbole räumlich darstellen iso3dIcons: true, // Block-Symbole räumlich darstellen
bedrockEnabled: true, // Bedrock-Bereich anzeigen (nur wenn auch installiert) bedrockEnabled: true, // Bedrock-Bereich anzeigen (nur wenn auch installiert)
betaTeilnahme: false, // Vorabfassungen (Beta, RC) als Update bekommen
letzteVersionVorab: false, // lief zuletzt eine Vorabfassung? (siehe main.js: Beta-Teilnahme)
desktopNotifications: true, // Windows-Meldung bei fertigem Hintergrund-Download/-Backup desktopNotifications: true, // Windows-Meldung bei fertigem Hintergrund-Download/-Backup
friendsEnabled: true, friendsEnabled: true,
friendsShareServer: true, // Freunde sehen, auf welchem Server man spielt (für "Beitreten") friendsShareServer: true, // Freunde sehen, auf welchem Server man spielt (für "Beitreten")
+2
View File
@@ -82,6 +82,8 @@ body{display:grid;grid-template-rows:auto auto 1fr auto;grid-template-columns:mi
.titelleiste{display:flex;align-items:center;gap:8px;height:32px;padding:0 150px 0 10px;background:var(--titel-bg);color:var(--titel-fg);-webkit-app-region:drag;user-select:none;font-size:12px} .titelleiste{display:flex;align-items:center;gap:8px;height:32px;padding:0 150px 0 10px;background:var(--titel-bg);color:var(--titel-fg);-webkit-app-region:drag;user-select:none;font-size:12px}
.titel-logo{width:16px;height:16px;flex:none} .titel-logo{width:16px;height:16px;flex:none}
.titel-text{white-space:nowrap} .titel-text{white-space:nowrap}
/* Kennzeichnung einer Vorabfassung ("Beta 1", "RC 2") neben dem Namen */
.titel-beta{padding:1px 8px;border-radius:99px;background:#e9a800;color:#1b1400;font-size:10.5px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;line-height:16px;white-space:nowrap}
body.fenster-inaktiv .titelleiste>*{opacity:.55} body.fenster-inaktiv .titelleiste>*{opacity:.55}
body.is-popout>.titelleiste{display:none} body.is-popout>.titelleiste{display:none}
+60 -14
View File
@@ -15,6 +15,32 @@ const crypto = require('crypto');
const { spawn } = require('child_process'); const { spawn } = require('child_process');
const API = 'https://git.viper.ipv64.net/api/v1/repos/M_Viper/AeroMc-Launcher/releases'; const API = 'https://git.viper.ipv64.net/api/v1/repos/M_Viper/AeroMc-Launcher/releases';
/*
* Beta-Kanal: Vorabfassungen (Beta, RC) liegen im selben Repository wie die
* fertigen Versionen, in Gitea als "Pre-Release" markiert – und mit einem Tag,
* dem "0.0.0-" vorangestellt ist:
*
* App-Version 1.2.4-beta.1 -> Tag 0.0.0-1.2.4-beta.1
*
* Der Vorsatz ist nötig, weil Launcher bis 1.2.3 das Pre-Release-Feld nicht
* kennen und nur die Zahlen am Anfang des Tags lesen: "1.2.4-beta.1" wäre für
* sie ein normales Update auf 1.2.4, das ALLE Nutzer bekämen. "0.0.0-…" lesen
* sie als uralte Version 0.0.0 und ignorieren sie; fertige Versionen finden sie
* weiterhin. (Ein Tag ohne Zahl vorn, etwa "beta-…", taugt nicht: Er bringt bei
* alten Launchern die Sortierung durcheinander, sie fänden dann gar kein Update
* mehr – mit dem echten 1.2.3 geprüft.)
*/
const BETA_VORSATZ = /^0\.0\.0-(?=\d)/;
// Version, die ein Release wirklich enthält: Tag ohne "v" und ohne Beta-Vorsatz
function tagVersion(tag) {
return normVersion(tag).replace(BETA_VORSATZ, '');
}
// Vorabfassung? In Gitea so markiert, mit Beta-Vorsatz oder mit Kennung im Tag
function istVorab(release) {
return !!release.prerelease || BETA_VORSATZ.test(normVersion(release.tag_name)) || !!parsePreRelease(tagVersion(release.tag_name));
}
const UA = 'AeroMC-Launcher'; const UA = 'AeroMC-Launcher';
// Downloads nur von hier – eine Release-Datei mit fremder Adresse wird abgelehnt // Downloads nur von hier – eine Release-Datei mit fremder Adresse wird abgelehnt
const ERLAUBTER_HOST = 'git.viper.ipv64.net'; const ERLAUBTER_HOST = 'git.viper.ipv64.net';
@@ -188,16 +214,23 @@ function parsePreRelease(v) {
} }
/* /*
* Vergleicht die Vorabkennungen zweier gleicher Versionsnummern. * Vergleicht die Vorabkennungen zweier gleicher Versionsnummern – wie SemVer:
* Die fertige Fassung ist neuer als jede Vorabfassung derselben Nummer
* ("1.3.0" > "1.3.0-beta.2"), sonst könnten Beta-Nutzer nie auf die fertige
* Version wechseln.
* *
* Bewusst nicht streng nach SemVer: trägt ein Release-Tag die Vorabkennung * Früher zählte eine Vorabkennung nur, wenn beide Seiten eine hatten – als
* nicht, die die App selbst meldet (Tag "1.0.1" gegen App "1.0.1-beta"), * Schutz vor einer Endlosschleife, falls ein Release unter dem Tag "1.0.1"
* würde "1.0.1" als neuer gelten – der Launcher böte dasselbe Update nach * steht, die App darin sich aber weiter als "1.0.1-beta" meldet. Das kann nicht
* jeder Installation erneut an, eine Endlosschleife. Deshalb zählt eine * mehr passieren: Die Signatur bindet die Version (siehe pruefeSignatur), und
* Vorabkennung nur, wenn sie auf beiden Seiten vorhanden ist (beta.1 -> beta.2). * sign-release.js nimmt sie aus derselben package.json wie die App. Ein Release,
* bei dem Tag und App-Version nicht übereinstimmen, lässt sich gar nicht
* installieren.
*/ */
function comparePreRelease(a, b) { function comparePreRelease(a, b) {
if (!a || !b) return 0; if (!a && !b) return 0;
if (!a) return 1; // a ist die fertige Fassung, b eine Vorabfassung
if (!b) return -1;
for (let i = 0; i < Math.max(a.length, b.length); i++) { for (let i = 0; i < Math.max(a.length, b.length); i++) {
const x = a[i]; const y = b[i]; const x = a[i]; const y = b[i];
if (x === undefined) return -1; if (x === undefined) return -1;
@@ -250,20 +283,31 @@ function pickAsset(release, installKind) {
* Prüft auf Updates. * Prüft auf Updates.
* -> { available, currentVersion, latestVersion, notes, asset, url, noReleases } * -> { available, currentVersion, latestVersion, notes, asset, url, noReleases }
*/ */
async function checkForUpdate(currentVersion) { async function checkForUpdate(currentVersion, opts) {
const installKind = detectInstallKind(); const installKind = detectInstallKind();
const res = await fetch(API + '?limit=10', { headers: { 'User-Agent': UA, Accept: 'application/json' } }); const kopf = { headers: { 'User-Agent': UA, Accept: 'application/json' } };
const res = await fetch(API + '?limit=30', kopf);
if (!res.ok) throw new Error('Update-Server antwortet mit HTTP ' + res.status); if (!res.ok) throw new Error('Update-Server antwortet mit HTTP ' + res.status);
const list = await res.json(); const list = await res.json();
const releases = (Array.isArray(list) ? list : []).filter((r) => !r.draft); const alle = (Array.isArray(list) ? list : []).filter((r) => !r.draft);
if (!releases.length) {
if (!alle.length) {
return { available: false, noReleases: true, currentVersion }; return { available: false, noReleases: true, currentVersion };
} }
// Vorabfassungen (Beta, RC …) bekommt nur, wer selbst eine Vorabfassung nutzt.
// Wer die fertige Fassung installiert hat, bleibt auf fertigen Versionen.
// Ob jemand teilnimmt, entscheidet der Schalter "An der Beta teilnehmen"
// (opts.beta). Ohne Angabe zählt die installierte Version.
const nutztVorab = opts && typeof opts.beta === 'boolean' ? opts.beta : !!parsePreRelease(currentVersion);
const releases = nutztVorab ? alle : alle.filter((r) => !istVorab(r));
if (!releases.length) {
return { available: false, currentVersion, installKind };
}
// neueste anhand der Versionsnummer (nicht nach Datum, damit Nachträge nicht stören) // neueste anhand der Versionsnummer (nicht nach Datum, damit Nachträge nicht stören)
releases.sort((a, b) => compareVersions(b.tag_name, a.tag_name)); releases.sort((a, b) => compareVersions(tagVersion(b.tag_name), tagVersion(a.tag_name)));
const latest = releases[0]; const latest = releases[0];
const available = compareVersions(latest.tag_name, currentVersion) > 0; const latestVersion = tagVersion(latest.tag_name);
const latestVersion = normVersion(latest.tag_name); const available = compareVersions(latestVersion, currentVersion) > 0;
let asset = pickAsset(latest, installKind); let asset = pickAsset(latest, installKind);
// ohne Signatur oder von fremder Adresse wird nichts automatisch installiert // ohne Signatur oder von fremder Adresse wird nichts automatisch installiert
let unsigniert = false; let unsigniert = false;
@@ -485,6 +529,8 @@ module.exports = {
pruefeSignatur, pruefeSignatur,
signaturText, signaturText,
holeSignatur, holeSignatur,
tagVersion,
istVorabVersion: (v) => !!parsePreRelease(v),
SIGNATUR_API, SIGNATUR_API,
cleanupUpdateCache, cleanupUpdateCache,
compareVersions, compareVersions,