Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de4db5130c | ||
|
|
4a608d5849 | ||
|
|
70730d2492 | ||
|
|
72f4812a23 | ||
|
|
645bf4d2a0 | ||
|
|
2d7ff95c4d | ||
|
|
b5dd76614e | ||
|
|
beaf865c5f | ||
|
|
cd85f9d0ac | ||
|
|
27c5fbb856 | ||
|
|
67337c5b1e | ||
|
|
1e5d8b5b95 | ||
|
|
ceb37566c6 | ||
|
|
c56b41de34 | ||
|
|
4a7a619f35 | ||
|
|
e7f8371b5f | ||
|
|
15d868519e | ||
|
|
5d6117f8b5 |
@@ -2,6 +2,41 @@
|
||||
|
||||
Alle nennenswerten Änderungen an AeroMC werden hier festgehalten.
|
||||
|
||||
## [1.2.4] - 2026-10-11
|
||||
|
||||
### Neu
|
||||
- Beta-Kanal: Unter Optionen → Allgemein gibt es den Schalter „An der Beta teilnehmen“. Wer ihn einschaltet, bekommt Vorabfassungen (Beta, RC) als Update; wer ihn ausschaltet, bekommt ab der nächsten fertigen Version wieder nur fertige Versionen. Wer eine Beta von Hand installiert, nimmt automatisch teil
|
||||
- Vorabfassungen sind oben in der Titelleiste gekennzeichnet (z. B. „Beta 1“)
|
||||
|
||||
### Behoben
|
||||
- Beta-Nutzern wurde die fertige Version derselben Nummer nicht als Update angeboten (z. B. von 1.3.0-beta.2 auf 1.3.0)
|
||||
- Bei vielen Vorabfassungen hintereinander konnte die neueste fertige Version aus der Update-Suche fallen
|
||||
|
||||
## [1.2.3] - 2026-10-07
|
||||
|
||||
### Behoben
|
||||
- Nach der Installation hing das Setup beim Klick auf „Fertigstellen“ einige Sekunden, bevor AeroMC startete – AeroMC öffnet sich jetzt sofort
|
||||
|
||||
## [1.2.2] - 2026-10-05
|
||||
|
||||
### Neu
|
||||
- AeroMC-Look im Spiel (Minecraft 1.14 bis 26.x, Vanilla und mit Loadern – ohne Mod):
|
||||
- Ladebildschirm im Vollbild mit Landschaftsbild, großem AeroMC-Logo samt Pyramide, „DEIN MINECRAFT ERLEBNIS“, hellblauem Fortschrittsbalken und „Wird geladen …“ statt des roten Mojang-Bildschirms (bei 1.14/1.15 AeroMC-Logo auf Nachtblau)
|
||||
- Hauptmenü mit großem AeroMC-Logo, Landschaft als drehendem Hintergrund, eigenen Sprüchen („Mehr als nur Minecraft!“) und Knöpfen im AeroMC-Stil – dunkles Schiefer, beim Darüberfahren leuchtend blau, mit Symbolen vor „Einzelspieler“, „Mehrspieler“, „Minecraft Realms“, „Optionen …“ und „Spiel beenden“
|
||||
- Fenstertitel „AeroMC - Minecraft …“ und AeroMC-Fenstersymbol
|
||||
- Abschaltbar unter Optionen → Spiel → AeroMC-Look; eigene Ressourcenpakete des Spielers haben immer Vorrang
|
||||
- Mods im Spiel verwalten (Instanzen mit Fabric, Quilt, Forge oder NeoForge, Minecraft 1.14 bis 26.x): Im Pausemenü wird „Feedback geben“ zu „Mods verwalten“ (ab 1.21 unter „Mods & Feedback“, in 26.x als Puzzle-Symbol). Es öffnet sich ein AeroMC-Fenster über dem Spiel mit zwei Listen wie bei den Ressourcenpaketen – „Aktive Mods“ und „Deaktivierte Mods“, ein Klick verschiebt eine Mod in die andere Liste, mit Suche und Warnung, wenn andere Mods sie brauchen
|
||||
- Das Spiel läuft dabei weiter: Geladene Mods lassen sich nicht im laufenden Spiel entladen, die Änderung wird vorgemerkt und beim Beenden übernommen
|
||||
- „Übernehmen & neu starten“: Minecraft speichert, startet mit den neuen Mods neu und verbindet automatisch wieder mit demselben Server (ab 1.20 auch zurück in dieselbe Einzelspieler-Welt) – mit demselben Konto wie vorher; im Mod-Fenster steht, wohin der Neustart führt
|
||||
- Neustart-Bildschirm: Während des Neustarts liegt der AeroMC-Ladebildschirm über dem Spielfenster und zeigt, was gerade passiert („Mods werden übernommen …“, „Minecraft startet …“, „Verbinde mit … “) – bis man wieder auf dem Server bzw. in der Welt ist
|
||||
- Nach dem Neustart hat das Spielfenster wieder dieselbe Größe und Lage wie vorher – war es maximiert, ist es wieder maximiert
|
||||
- Auch im Mod-Dialog des Launchers lassen sich Mods jetzt umschalten, während das Spiel läuft („ab nächstem Start“) – vorher kam eine Fehlermeldung, weil Windows die Dateien sperrt
|
||||
- Abschaltbar unter Optionen → Spiel → Mods im Spiel verwalten
|
||||
|
||||
### Behoben
|
||||
- Mod-Dateien, die aus dem Explorer auf eine Gruppe in der Instanzliste gezogen wurden, wurden stillschweigend ignoriert
|
||||
- Ingame-Meldungen und Fenster über dem Spiel fanden in manchen Fällen das versteckte Java-Konsolenfenster statt des Spielfensters
|
||||
|
||||
## [1.2.1] - 2026-10-05
|
||||
|
||||
### Neu
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
DATENSCHUTZERKLÄRUNG FÜR AEROMC
|
||||
Stand: 7. Oktober 2026
|
||||
|
||||
Diese Datenschutzerklärung gilt für den Minecraft-Launcher AeroMC und die zugehörigen Online-Dienste. AeroMC ist ein inoffizielles Programm und steht in keiner Verbindung zu Mojang Studios oder Microsoft.
|
||||
|
||||
|
||||
1. VERANTWORTLICHER
|
||||
|
||||
[Vor- und Nachname]
|
||||
[Straße und Hausnummer]
|
||||
[PLZ und Ort]
|
||||
[Land]
|
||||
E-Mail: [E-Mail-Adresse]
|
||||
|
||||
|
||||
2. GRUNDSATZ
|
||||
|
||||
AeroMC läuft auf deinem Computer. Instanzen, Mods, Welten, Screenshots, Aufnahmen, Einstellungen und Sicherungen werden nur lokal gespeichert. Diese Daten erhalten wir nicht.
|
||||
|
||||
Personenbezogene Daten werden nur übertragen, wenn du eine Funktion nutzt, die das erfordert, zum Beispiel die Anmeldung mit deinem Microsoft-Konto oder das Freundesystem. Es gibt keine Werbung, kein Tracking und keine Analyse-Dienste.
|
||||
|
||||
|
||||
3. ANMELDUNG MIT MICROSOFT / MINECRAFT
|
||||
|
||||
Um Minecraft: Java Edition zu starten, meldest du dich mit deinem Microsoft-Konto an. Die Anmeldung läuft direkt zwischen deinem Computer und den Diensten von Microsoft, Xbox Live und Mojang.
|
||||
|
||||
- Dein Passwort gibst du nur auf der Seite von Microsoft ein. AeroMC sieht es nicht.
|
||||
- Die erhaltenen Zugangsschlüssel, dein Minecraft-Name und deine Spieler-ID (UUID) werden verschlüsselt auf deinem Computer gespeichert.
|
||||
- Änderst du Skin oder Umhang über AeroMC, wird das an Mojang übertragen.
|
||||
|
||||
Es gelten die Datenschutzbestimmungen von Microsoft: https://privacy.microsoft.com/de-de/privacystatement
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO.
|
||||
|
||||
|
||||
4. FREUNDESYSTEM UND AEROMC-DIENSTE
|
||||
|
||||
Das Freundesystem ist optional und lässt sich unter Optionen → Freunde & Umhänge jederzeit abschalten. Es läuft auf unserem Server viper-network.de.
|
||||
|
||||
Die Anmeldung erfolgt wie bei einem Minecraft-Server über die Sitzungsprüfung von Mojang. Ein eigenes Passwort gibt es nicht. Deine Microsoft-Zugangsdaten erhalten wir nicht.
|
||||
|
||||
Wir speichern:
|
||||
- Minecraft-Spieler-ID und Minecraft-Name – um dich im Freundesystem zu erkennen und auffindbar zu machen; bis zur Löschung auf Anfrage.
|
||||
- Sitzungsschlüssel (nur als Prüfwert) – um angemeldet zu bleiben; 30 Tage nach letzter Nutzung gelöscht.
|
||||
- Online-Status: Zeitpunkt, Instanzname, Minecraft-Version und – sofern nicht abgeschaltet – die Server-Adresse, auf der du spielst; wird bei jeder Nutzung überschrieben.
|
||||
- Freundschaften und Freundschaftsanfragen – bis du sie entfernst.
|
||||
- Einladungen auf einen Server – 10 Minuten.
|
||||
- Kurznachrichten und mitgeschickte Screenshots – 7 Tage.
|
||||
- Eigene Umhänge (Bilddatei) – bis du sie entfernst.
|
||||
- Geteilte Instanzen (Liste von Version, Loader und Mods, keine Dateien) – 30 Tage.
|
||||
|
||||
Diese Daten sehen nur deine Freunde bzw. die Personen, denen du etwas schickst oder einen Code gibst. Eigene Umhänge sind für alle AeroMC-Spieler sichtbar, die dir im Spiel begegnen.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO.
|
||||
|
||||
|
||||
5. FEHLERBERICHTE (FREIWILLIG)
|
||||
|
||||
Stürzt Minecraft ab, kann der Absturz-Assistent auf deinen ausdrücklichen Wunsch einen Fehlerbericht senden. Er enthält Launcher-, Minecraft- und Loader-Version, Windows-Version, Arbeitsspeicher, die Mod-Liste der Instanz, das Ende von Absturzbericht, Spielprotokoll und Konsolenausgabe sowie deinen optionalen Kommentar.
|
||||
|
||||
Dein Minecraft-Name und deine Spieler-ID werden vor dem Senden entfernt, außer du wählst ausdrücklich, den Bericht mit Namen zu senden. Fehlerberichte nutzen wir nur zur Fehlerbehebung und löschen sie, sobald sie nicht mehr benötigt werden.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. a DSGVO (Einwilligung durch das Absenden).
|
||||
|
||||
|
||||
6. DOWNLOADS VON SPIELDATEIEN UND INHALTEN
|
||||
|
||||
Für Minecraft, Java und die von dir gewählten Inhalte lädt AeroMC Dateien direkt bei den jeweiligen Anbietern herunter. Diese erhalten technisch bedingt deine IP-Adresse und übliche Verbindungsdaten, aber keine weiteren personenbezogenen Daten:
|
||||
- Mojang / Microsoft – Minecraft-Dateien, Skins und Umhänge
|
||||
- Eclipse Adoptium – Java-Laufzeit
|
||||
- Modrinth – Mods, Ressourcenpakete, Shader, Modpacks
|
||||
- CurseForge – Mods und Modpacks (die Suche läuft über unseren Weiterleitungs-Server)
|
||||
- Fabric, Quilt, Forge, NeoForge – Mod-Loader
|
||||
- Technic – Technic-Modpacks
|
||||
|
||||
Es gelten die Datenschutzbestimmungen des jeweiligen Anbieters.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO.
|
||||
|
||||
|
||||
7. ANZEIGE VON SKINS
|
||||
|
||||
Zur Darstellung von Spielerfiguren ruft AeroMC Bilder anhand der Spieler-ID bei crafthead.net, visage.surgeplay.com und nmsr.nickac.dev ab. Diese erhalten die Spieler-ID und deine IP-Adresse.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
|
||||
|
||||
|
||||
8. UPDATES
|
||||
|
||||
Die Fassung aus dem Microsoft Store wird ausschließlich über den Microsoft Store aktualisiert. Die Fassung von unserer Webseite prüft beim Start auf unseren Servern, ob es eine neue Version gibt. Dabei wird außer der IP-Adresse nichts übertragen.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
|
||||
|
||||
|
||||
9. DISCORD
|
||||
|
||||
Läuft auf deinem Computer Discord, kann AeroMC dort anzeigen, welche Instanz du spielst. Diese Information geht nur an das Discord-Programm auf deinem Computer und von dort nach den Bestimmungen von Discord an deine Discord-Kontakte.
|
||||
|
||||
|
||||
10. SERVER-PROTOKOLLE
|
||||
|
||||
Beim Zugriff auf unsere Server werden technisch bedingt IP-Adresse, Zeitpunkt und angefragte Adresse kurzzeitig protokolliert, um Betrieb und Sicherheit zu gewährleisten.
|
||||
Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO.
|
||||
|
||||
|
||||
11. DEINE RECHTE
|
||||
|
||||
Du hast das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung, Datenübertragbarkeit und Widerspruch. Eine Einwilligung kannst du jederzeit für die Zukunft widerrufen. Wende dich dafür an die oben genannte E-Mail-Adresse und gib deinen Minecraft-Namen an. Du kannst dich außerdem bei einer Datenschutz-Aufsichtsbehörde beschweren.
|
||||
|
||||
|
||||
12. KINDER
|
||||
|
||||
AeroMC richtet sich nicht an Kinder unter 16 Jahren. Jüngere sollten das Freundesystem nur mit Zustimmung der Eltern nutzen.
|
||||
|
||||
|
||||
13. ÄNDERUNGEN
|
||||
|
||||
Wir passen diese Datenschutzerklärung an, wenn sich AeroMC oder die Rechtslage ändert. Es gilt die jeweils aktuelle Fassung.
|
||||
@@ -0,0 +1,192 @@
|
||||
# Datenschutzerklärung für AeroMC
|
||||
|
||||
Stand: 7. Oktober 2026
|
||||
|
||||
Diese Datenschutzerklärung gilt für den Minecraft-Launcher **AeroMC** (Windows-Programm, auch
|
||||
aus dem Microsoft Store) und die zugehörigen Online-Dienste. AeroMC ist ein inoffizielles
|
||||
Programm und steht in keiner Verbindung zu Mojang Studios oder Microsoft.
|
||||
|
||||
---
|
||||
|
||||
## 1. Verantwortlicher
|
||||
|
||||
**[Vor- und Nachname]**
|
||||
[Straße und Hausnummer]
|
||||
[PLZ und Ort]
|
||||
[Land]
|
||||
E-Mail: **[E-Mail-Adresse]**
|
||||
|
||||
---
|
||||
|
||||
## 2. Grundsatz
|
||||
|
||||
AeroMC läuft auf deinem Computer. Instanzen, Mods, Welten, Screenshots, Aufnahmen,
|
||||
Einstellungen und Sicherungen werden **nur lokal** gespeichert, im Ordner
|
||||
`%APPDATA%\AeroMC` bzw. `Dokumente\AeroMC Launcher`. Diese Daten erhalten wir nicht.
|
||||
|
||||
Personenbezogene Daten werden nur übertragen, wenn du eine Funktion nutzt, die das
|
||||
erfordert – zum Beispiel die Anmeldung mit deinem Microsoft-Konto oder das Freundesystem.
|
||||
Es gibt **keine Werbung, kein Tracking und keine Analyse-Dienste**.
|
||||
|
||||
---
|
||||
|
||||
## 3. Anmeldung mit Microsoft / Minecraft
|
||||
|
||||
Um Minecraft: Java Edition zu starten, meldest du dich mit deinem Microsoft-Konto an.
|
||||
Die Anmeldung läuft direkt zwischen deinem Computer und den Diensten von Microsoft, Xbox Live
|
||||
und Mojang (`login.microsoftonline.com`, `user.auth.xboxlive.com`, `xsts.auth.xboxlive.com`,
|
||||
`api.minecraftservices.com`, `sessionserver.mojang.com`).
|
||||
|
||||
- Dein Passwort gibst du nur auf der Seite von Microsoft ein. AeroMC sieht es nicht.
|
||||
- Die erhaltenen Zugangsschlüssel (Tokens), dein Minecraft-Name und deine Spieler-ID (UUID)
|
||||
werden **verschlüsselt auf deinem Computer** gespeichert (Windows-Datenschutz-API).
|
||||
- Änderst du Skin oder Umhang über AeroMC, wird das an Mojang übertragen.
|
||||
|
||||
Für diese Datenverarbeitung gelten die Datenschutzbestimmungen von Microsoft:
|
||||
https://privacy.microsoft.com/de-de/privacystatement
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. b DSGVO (Bereitstellung der von dir gewünschten
|
||||
Funktion).
|
||||
|
||||
---
|
||||
|
||||
## 4. Freundesystem und AeroMC-Dienste
|
||||
|
||||
Das Freundesystem ist optional und lässt sich in den Einstellungen
|
||||
(Optionen → Freunde & Umhänge) jederzeit abschalten. Es läuft auf unserem Server
|
||||
`viper-network.de`.
|
||||
|
||||
### Anmeldung am Freundesystem
|
||||
AeroMC meldet dich wie ein Minecraft-Server über die Sitzungsprüfung von Mojang an. Dabei
|
||||
wird bestätigt, dass du der Besitzer deines Minecraft-Kontos bist. Ein eigenes Passwort gibt
|
||||
es nicht. Wir erhalten **nicht** deine Microsoft-Zugangsdaten.
|
||||
|
||||
### Welche Daten wir speichern
|
||||
|
||||
| Daten | Zweck | Speicherdauer |
|
||||
|---|---|---|
|
||||
| Minecraft-Spieler-ID (UUID) und Minecraft-Name | dich im Freundesystem erkennen und auffindbar machen | bis zur Löschung auf Anfrage |
|
||||
| Sitzungsschlüssel (nur als Prüfwert) | angemeldet bleiben | 30 Tage nach letzter Nutzung |
|
||||
| Online-Status: Zeitpunkt, Instanzname, Minecraft-Version und – falls du es nicht abgeschaltet hast – die Server-Adresse, auf der du spielst | Freunden zeigen, dass und wo du spielst | wird bei jeder Nutzung überschrieben |
|
||||
| Freundschaften und Freundschaftsanfragen | Freundesliste | bis du sie entfernst |
|
||||
| Einladungen auf einen Server | „Komm auf meinen Server“ | 10 Minuten |
|
||||
| Kurznachrichten und mitgeschickte Screenshots | Nachrichten zwischen Freunden | 7 Tage |
|
||||
| Eigene Umhänge (Bilddatei) | deinen Umhang anderen AeroMC-Spielern anzeigen | bis du ihn entfernst |
|
||||
| Geteilte Instanzen (Liste von Version, Loader und Mods, keine Dateien) | Instanz per Code mit Freunden teilen | 30 Tage |
|
||||
|
||||
Diese Daten sehen nur deine Freunde bzw. die Personen, denen du etwas schickst oder einen
|
||||
Code gibst. Eigene Umhänge sind für alle AeroMC-Spieler sichtbar, die dir im Spiel begegnen.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. b DSGVO.
|
||||
|
||||
---
|
||||
|
||||
## 5. Fehlerberichte (freiwillig)
|
||||
|
||||
Stürzt Minecraft ab, kann der Absturz-Assistent auf **deinen ausdrücklichen Wunsch** einen
|
||||
Fehlerbericht an uns senden. Er enthält:
|
||||
|
||||
- Launcher-, Minecraft- und Loader-Version
|
||||
- Windows-Version, Größe des Arbeitsspeichers und den eingestellten Speicher der Instanz
|
||||
- die Liste der Mods der Instanz
|
||||
- das Ende von Absturzbericht, Spielprotokoll und Konsolenausgabe
|
||||
- deinen optionalen Kommentar
|
||||
|
||||
Dein Minecraft-Name und deine Spieler-ID werden vor dem Senden aus dem Bericht entfernt,
|
||||
außer du wählst ausdrücklich, den Bericht mit deinem Namen zu senden.
|
||||
|
||||
Fehlerberichte nutzen wir nur, um Fehler in AeroMC zu finden und zu beheben. Sie werden
|
||||
gelöscht, sobald sie nicht mehr benötigt werden.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. a DSGVO (Einwilligung durch das Absenden).
|
||||
|
||||
---
|
||||
|
||||
## 6. Downloads von Spieldateien und Inhalten
|
||||
|
||||
Für Minecraft, Java und die Inhalte, die du auswählst, lädt AeroMC Dateien direkt bei den
|
||||
jeweiligen Anbietern herunter. Dabei erhält der Anbieter technisch bedingt deine
|
||||
**IP-Adresse** und übliche Verbindungsdaten. Weitere personenbezogene Daten werden dabei
|
||||
nicht übertragen.
|
||||
|
||||
| Anbieter | Wofür |
|
||||
|---|---|
|
||||
| Mojang / Microsoft (`piston-meta.mojang.com`, `libraries.minecraft.net`, `resources.download.minecraft.net`, `textures.minecraft.net`) | Minecraft-Dateien, Skins und Umhänge |
|
||||
| Eclipse Adoptium (`api.adoptium.net`) | Java-Laufzeit |
|
||||
| Modrinth (`api.modrinth.com`) | Mods, Ressourcenpakete, Shader, Modpacks |
|
||||
| CurseForge (`api.curseforge.com`, `edge.forgecdn.net`) | Mods und Modpacks – die Suche läuft über unseren Weiterleitungs-Server `curse.viper.ipv64.net` |
|
||||
| Fabric, Quilt, Forge, NeoForge (`meta.fabricmc.net`, `meta.quiltmc.org`, `maven.minecraftforge.net`, `maven.neoforged.net`) | Mod-Loader |
|
||||
| Technic (`api.technicpack.net`) | Technic-Modpacks |
|
||||
|
||||
Es gelten die Datenschutzbestimmungen des jeweiligen Anbieters.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. b DSGVO.
|
||||
|
||||
---
|
||||
|
||||
## 7. Anzeige von Skins
|
||||
|
||||
Für die Darstellung von Spielerfiguren und Köpfen im Launcher ruft AeroMC Bilder anhand der
|
||||
Spieler-ID (UUID) bei folgenden Diensten ab: `crafthead.net`, `visage.surgeplay.com` und
|
||||
`nmsr.nickac.dev`. Diese erhalten dabei die Spieler-ID und deine IP-Adresse.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Darstellung
|
||||
der Spielfiguren).
|
||||
|
||||
---
|
||||
|
||||
## 8. Updates
|
||||
|
||||
Die Fassung von unserer Webseite prüft beim Start, ob es eine neue Version gibt
|
||||
(`git.viper.ipv64.net` und `viper-network.de`). Die Fassung aus dem Microsoft Store wird
|
||||
ausschließlich über den Microsoft Store aktualisiert. Dabei werden keine personenbezogenen
|
||||
Daten außer deiner IP-Adresse übertragen.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. f DSGVO (Sicherheit und Aktualität des Programms).
|
||||
|
||||
---
|
||||
|
||||
## 9. Discord
|
||||
|
||||
Läuft auf deinem Computer Discord, kann AeroMC dort anzeigen, dass und welche Instanz du
|
||||
spielst („Rich Presence“). Diese Information geht nur an das Discord-Programm auf deinem
|
||||
Computer und von dort nach den Bestimmungen von Discord an deine Discord-Kontakte.
|
||||
|
||||
---
|
||||
|
||||
## 10. Server-Protokolle
|
||||
|
||||
Beim Zugriff auf unsere Server (`viper-network.de`, `git.viper.ipv64.net`,
|
||||
`curse.viper.ipv64.net`, `aeromc.viper.ipv64.net`) werden technisch bedingt IP-Adresse,
|
||||
Zeitpunkt und angefragte Adresse kurzzeitig protokolliert, um den Betrieb und die Sicherheit
|
||||
der Server zu gewährleisten.
|
||||
|
||||
**Rechtsgrundlage:** Art. 6 Abs. 1 lit. f DSGVO.
|
||||
|
||||
---
|
||||
|
||||
## 11. Deine Rechte
|
||||
|
||||
Du hast das Recht auf **Auskunft** über deine gespeicherten Daten, auf **Berichtigung**,
|
||||
**Löschung**, **Einschränkung der Verarbeitung**, **Datenübertragbarkeit** sowie auf
|
||||
**Widerspruch** gegen die Verarbeitung. Eine erteilte Einwilligung kannst du jederzeit für
|
||||
die Zukunft widerrufen.
|
||||
|
||||
Wende dich dafür an die oben genannte E-Mail-Adresse. Gib dabei bitte deinen Minecraft-Namen
|
||||
an, damit wir deine Daten finden.
|
||||
|
||||
Du kannst dich außerdem bei einer Datenschutz-Aufsichtsbehörde beschweren.
|
||||
|
||||
---
|
||||
|
||||
## 12. Kinder
|
||||
|
||||
AeroMC richtet sich nicht an Kinder unter 16 Jahren. Wer jünger ist, sollte das Freundesystem
|
||||
nur mit Zustimmung der Eltern nutzen.
|
||||
|
||||
---
|
||||
|
||||
## 13. Änderungen
|
||||
|
||||
Wir passen diese Datenschutzerklärung an, wenn sich AeroMC oder die Rechtslage ändert. Es
|
||||
gilt die jeweils auf dieser Seite veröffentlichte Fassung.
|
||||
@@ -0,0 +1,86 @@
|
||||
# AeroMC – Sicherheit
|
||||
|
||||
Überblick über die Sicherheitsmaßnahmen im AeroMC Launcher (Stand: Version 1.2.3).
|
||||
|
||||
---
|
||||
|
||||
## 1. Sichere Updates
|
||||
|
||||
- **Digitale Signatur:** Jedes Update ist mit dem Release-Schlüssel des Entwicklers
|
||||
unterschrieben (Ed25519). Der Launcher installiert nur Dateien mit gültiger Signatur.
|
||||
Selbst wer den Update-Server übernimmt, kann so keine manipulierte EXE verteilen.
|
||||
- **Mehr als nur der Inhalt:** Unterschrieben werden Inhalt (SHA-256), Dateiname und Version.
|
||||
Eine alte Version kann nicht als neue ausgegeben werden, Setup und Portable lassen sich
|
||||
nicht vertauschen.
|
||||
- **Doppelte Prüfung:** einmal nach dem Download und noch einmal direkt vor dem Start.
|
||||
- **Getrennte Server:** Die Programmdatei und ihre Signatur liegen auf zwei verschiedenen
|
||||
Servern. Ein Update ohne gültige Signatur wird nicht automatisch installiert.
|
||||
- **Feste Quelle:** Updates werden nur vom offiziellen AeroMC-Server geladen.
|
||||
|
||||
## 2. Geschützte Programmdatei
|
||||
|
||||
- **Aktuelle Technik:** AeroMC basiert auf Electron 44 mit aktuellem Chromium und Node.js
|
||||
und erhält damit laufende Sicherheitsupdates.
|
||||
- **Keine Fernsteuerung:** Debug-Schnittstellen und der Node-Modus sind fest in der EXE
|
||||
gesperrt. Der Launcher lässt sich weder von außen steuern noch für fremde Skripte
|
||||
missbrauchen.
|
||||
- **Integritätsprüfung:** Beim Start prüft AeroMC, ob sein Programmpaket verändert wurde.
|
||||
Ist das der Fall, startet es nicht.
|
||||
- **Keine fremden Webseiten:** Launcher-Fenster laden nie fremde Seiten, Links öffnen sich
|
||||
immer im Browser.
|
||||
- **Geprüfte Abhängigkeiten:** Alle eingesetzten Programmbibliotheken sind ohne bekannte
|
||||
Sicherheitslücken.
|
||||
|
||||
## 3. Schutz der Instanzen
|
||||
|
||||
- **Manipulationsschutz:** AeroMC merkt sich für jede Instanz einen Fingerabdruck aller
|
||||
Mod-Dateien und der Starteinstellungen (Java, JVM-Argumente, Startbefehle).
|
||||
- **Automatische Sperre:** Wird eine Mod-Datei verändert (so arbeitet Schadsoftware, die
|
||||
Mods infiziert) oder werden Starteinstellungen außerhalb des Launchers geändert, wird die
|
||||
Instanz gesperrt und mit einem Verbotszeichen markiert.
|
||||
- **Gesperrte Instanzen** lassen sich nicht mehr starten, bearbeiten, kopieren, exportieren
|
||||
oder teilen. Sie bleiben erhalten, bis man sie selbst löscht.
|
||||
- **Wiederherstellen:** Mit einem Klick wird die Instanz aus der neuesten sauberen
|
||||
Sicherung als neue Instanz angelegt. Sicherungen, die bereits die veränderte Datei
|
||||
enthalten, werden übersprungen.
|
||||
- **Normales Arbeiten bleibt möglich:** Neue, gelöschte, aktivierte oder deaktivierte Mods
|
||||
gelten nicht als Manipulation. Änderungen über den Launcher werden automatisch übernommen.
|
||||
|
||||
## 4. Geprüfte Downloads
|
||||
|
||||
Jede heruntergeladene Datei wird mit der Prüfsumme der Quelle verglichen, bevor sie
|
||||
gespeichert wird. Eine veränderte oder beschädigte Datei wird verworfen.
|
||||
|
||||
| Quelle | Prüfung |
|
||||
|---|---|
|
||||
| Minecraft, Bibliotheken und Assets (Mojang) | SHA-1 |
|
||||
| Java-Laufzeiten (Eclipse Temurin) | SHA-256 |
|
||||
| Mods, Ressourcenpakete, Shader (Modrinth) | SHA-512 / SHA-1 |
|
||||
| Mods, Ressourcenpakete, Shader (CurseForge) | SHA-1 |
|
||||
| Modpacks und ihre Dateien | Prüfsumme der Quelle, nur HTTPS |
|
||||
|
||||
## 5. Sichere Importe
|
||||
|
||||
- Beim Import von Instanzen aus ZIP-Archiven werden keine Java-Pfade und keine
|
||||
JVM-Argumente aus dem Archiv übernommen – so kann ein präpariertes Archiv beim nächsten
|
||||
Start keinen fremden Code ausführen.
|
||||
- Dateinamen aus Archiven werden geprüft, damit nichts außerhalb des Instanzordners landet.
|
||||
|
||||
## 6. Geschützte Daten
|
||||
|
||||
- **Konten:** Anmeldedaten von Microsoft und Minecraft werden mit der Windows-Verschlüsselung
|
||||
(DPAPI) gespeichert – nur das eigene Windows-Konto kann sie lesen.
|
||||
- **Weitere Zugangsdaten:** Proxy-Passwort und CurseForge-Schlüssel werden ebenso
|
||||
verschlüsselt gespeichert.
|
||||
- **Spielerweiterung:** Die Datei, die AeroMC für Umhänge und den AeroMC-Look ins Spiel
|
||||
einbindet, wird vor jedem Spielstart mit dem Original verglichen und bei Abweichung
|
||||
ersetzt.
|
||||
|
||||
## 7. Freundesystem
|
||||
|
||||
- **Anmeldung über Mojang:** Der Launcher meldet sich wie ein Minecraft-Server über Mojangs
|
||||
Sitzungsprüfung an. Ein eigenes Passwort ist nicht nötig.
|
||||
- **Keine Identitätsfälschung:** Jede Anfrage im Namen eines Spielers muss angemeldet sein.
|
||||
Niemand kann sich als ein anderer Spieler ausgeben.
|
||||
- **Privatsphäre:** Der eigene Server kann verborgen oder das Freundesystem ganz
|
||||
abgeschaltet werden.
|
||||
@@ -5,7 +5,7 @@
|
||||
},
|
||||
"projects": {
|
||||
"C:\\Users\\Viper\\Desktop\\AeroMC-Launcher\\installer\\AeroMCSetup.csproj": {
|
||||
"version": "1.2.3",
|
||||
"version": "0.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Users\\Viper\\Desktop\\AeroMC-Launcher\\installer\\AeroMCSetup.csproj",
|
||||
"projectName": "AeroMC-Setup",
|
||||
|
||||
Binary file not shown.
@@ -14,11 +14,11 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyCopyrightAttribute("Copyright (c) M_Viper. Alle Rechte vorbehalten.")]
|
||||
[assembly: System.Reflection.AssemblyDescriptionAttribute("Installiert AeroMC")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.2.3.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2.3")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.2.4.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2.4")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("AeroMC Setup")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("AeroMC Setup")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.2.3.0")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.2.4.0")]
|
||||
[assembly: System.Resources.NeutralResourcesLanguageAttribute("de-DE")]
|
||||
|
||||
// Von der MSBuild WriteCodeFragment-Klasse generiert.
|
||||
|
||||
@@ -1 +1 @@
|
||||
111db8ee3dc7193961107c73afd8913fff02b92fd4e49b8b7e4bf051181600bd
|
||||
c285113a921613345252c7c4e9c903f219339ded7e116f59ea5c382b3fb91383
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
"C:\\Users\\Viper\\.nuget\\packages\\": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.2.3",
|
||||
"version": "0.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Users\\Viper\\Desktop\\AeroMC-Launcher\\installer\\AeroMCSetup.csproj",
|
||||
"projectName": "AeroMC-Setup",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "5nf4o8NXPS0=",
|
||||
"dgSpecHash": "FnRoda2hVew=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Users\\Viper\\Desktop\\AeroMC-Launcher\\installer\\AeroMCSetup.csproj",
|
||||
"expectedPackageFiles": [
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "aeromc",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "aeromc",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"dependencies": {
|
||||
"@xhayper/discord-rpc": "^1.3.4",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "aeromc",
|
||||
"productName": "AeroMC",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"description": "AeroMC – Instanz-basierter Minecraft-Launcher (à la MultiMC/Prism)",
|
||||
"homepage": "https://m-viper.de",
|
||||
"launcherWebsite": "https://aeromc.viper.ipv64.net",
|
||||
|
||||
+25
-10
@@ -8,6 +8,15 @@
|
||||
* mit neuer Signatur – die bereits veröffentlichten EXEs würden dann nicht mehr
|
||||
* dazu passen und kein Launcher nähme das Update an.
|
||||
*
|
||||
* Außerdem sagt es, wie das Release in Gitea heißen muss:
|
||||
*
|
||||
* fertige Version 1.2.4 Tag 1.2.4
|
||||
* Vorabfassung 1.2.4-beta.1 Tag 0.0.0-1.2.4-beta.1 + Haken "Pre-Release"
|
||||
*
|
||||
* Der Vorsatz "0.0.0-" bei Vorabfassungen ist Pflicht: Launcher bis 1.2.3 kennen
|
||||
* das Pre-Release-Feld nicht und würden "1.2.4-beta.1" als normales Update an
|
||||
* ALLE Nutzer verteilen (siehe src/updater.js).
|
||||
*
|
||||
* Ausnahme (z. B. Testbuild, der nie hochgeladen wird): AEROMC_GLEICHE_VERSION=1
|
||||
*/
|
||||
|
||||
@@ -15,25 +24,31 @@ const path = require('path');
|
||||
|
||||
const API = 'https://git.viper.ipv64.net/api/v1/repos/M_Viper/AeroMc-Launcher/releases?limit=50';
|
||||
const version = require(path.join(__dirname, '..', 'package.json')).version;
|
||||
const vorab = /^\d+(?:\.\d+){0,2}-/.test(version);
|
||||
const tag = vorab ? `0.0.0-${version}` : version;
|
||||
|
||||
(async () => {
|
||||
if (process.env.AEROMC_GLEICHE_VERSION === '1') return;
|
||||
let releases;
|
||||
if (process.env.AEROMC_GLEICHE_VERSION !== '1') {
|
||||
try {
|
||||
const res = await fetch(API, { headers: { 'User-Agent': 'AeroMC-Release', Accept: 'application/json' } });
|
||||
if (!res.ok) throw new Error('HTTP ' + res.status);
|
||||
releases = await res.json();
|
||||
} catch (err) {
|
||||
console.warn(`\n! Gitea nicht erreichbar (${err.message}) – Versionsprüfung übersprungen.`);
|
||||
return;
|
||||
}
|
||||
const norm = (v) => String(v || '').trim().replace(/^v/i, '');
|
||||
const treffer = (releases || []).find((r) => !r.draft && norm(r.tag_name) === version);
|
||||
const norm = (v) => String(v || '').trim().replace(/^v/i, '').replace(/^0\.0\.0-(?=\d)/, '');
|
||||
const treffer = (await res.json() || []).find((r) => !r.draft && norm(r.tag_name) === version);
|
||||
if (treffer) {
|
||||
console.error(`\n✖ Version ${version} ist bereits in Gitea veröffentlicht (${treffer.published_at}).`);
|
||||
console.error(`\n✖ Version ${version} ist bereits in Gitea veröffentlicht (Tag ${treffer.tag_name}, ${treffer.published_at}).`);
|
||||
console.error(' Bitte zuerst die Versionsnummer in package.json erhöhen – sonst passen die');
|
||||
console.error(' veröffentlichten Dateien nicht mehr zur Signatur.');
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`\n! Gitea nicht erreichbar (${err.message}) – Versionsprüfung übersprungen.`);
|
||||
}
|
||||
}
|
||||
console.log(`» Version ${version} ist noch nicht veröffentlicht – Build läuft.`);
|
||||
if (vorab) {
|
||||
console.log(` VORABFASSUNG – in Gitea so veröffentlichen: Tag ${tag} und Haken bei "Als Pre-Release kennzeichnen".`);
|
||||
console.log(' Niemals mit dem Tag der reinen Versionsnummer: Ältere Launcher würden die Beta sonst an alle verteilen.');
|
||||
} else {
|
||||
console.log(` In Gitea veröffentlichen mit dem Tag ${tag} (ohne Pre-Release-Haken).`);
|
||||
}
|
||||
})();
|
||||
|
||||
+24
-3
@@ -64,6 +64,27 @@ function ladeZugang() {
|
||||
return { seite: z.seite, benutzer: z.benutzer, passwort: entschluesseln(z.passwort) };
|
||||
}
|
||||
|
||||
/*
|
||||
* Anfrage MIT Zugangsdaten an die WordPress-Seite.
|
||||
* Weiterleitungen werden nie verfolgt: Sonst gingen die Kopfzeilen – vor allem
|
||||
* der eigene X-AeroMC-Auth, den fetch bei einem Wechsel der Domain nicht von
|
||||
* selbst entfernt – samt Anwendungspasswort an das Ziel der Weiterleitung.
|
||||
* Gesendet wird außerdem nur über HTTPS und nur an die hinterlegte Seite.
|
||||
*/
|
||||
async function wordpressAnfrage(zugang, pfad, optionen) {
|
||||
let ziel;
|
||||
try { ziel = new URL(zugang.seite + pfad); } catch { throw new Error('Die hinterlegte WordPress-Adresse ist ungültig.'); }
|
||||
if (ziel.protocol !== 'https:') throw new Error('Zugangsdaten werden nur über HTTPS gesendet – WordPress-Adresse prüfen.');
|
||||
const res = await fetch(ziel, Object.assign({}, optionen, { headers: kopfzeilen(zugang), redirect: 'manual' }));
|
||||
if (res.status >= 300 && res.status < 400) {
|
||||
const wohin = res.headers.get('location') || 'unbekannt';
|
||||
throw new Error(`Die Seite leitet weiter (HTTP ${res.status} → ${wohin}). Die Zugangsdaten wurden NICHT dorthin gesendet.
|
||||
`
|
||||
+ ' Bitte die genaue Adresse eintragen: node scripts/sign-release.js wordpress');
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function kopfzeilen(zugang) {
|
||||
const daten = Buffer.from(`${zugang.benutzer}:${zugang.passwort}`).toString('base64');
|
||||
return {
|
||||
@@ -101,7 +122,7 @@ function zugangsFehler(d, benutzer) {
|
||||
}
|
||||
|
||||
async function pruefeZugang(zugang) {
|
||||
const res = await fetch(`${zugang.seite}/wp-json/aeromc/v1/update-signatur/zugang`, { headers: kopfzeilen(zugang) });
|
||||
const res = await wordpressAnfrage(zugang, '/wp-json/aeromc/v1/update-signatur/zugang', {});
|
||||
if (res.status === 404) throw new Error('Die Seite kennt die Signatur-Schnittstelle nicht – ist das Plugin "AeroMC Freunde" (ab 1.5.4) installiert und aktiviert?');
|
||||
let d = null;
|
||||
try { d = await res.json(); } catch { /* keine JSON-Antwort */ }
|
||||
@@ -189,8 +210,8 @@ async function hochladen(sig) {
|
||||
console.log('» Signatur liegt bereits unverändert auf WordPress.');
|
||||
return;
|
||||
}
|
||||
const res = await fetch(`${zugang.seite}/wp-json/aeromc/v1/update-signatur`, {
|
||||
method: 'POST', headers: kopfzeilen(zugang), body: JSON.stringify(sig),
|
||||
const res = await wordpressAnfrage(zugang, '/wp-json/aeromc/v1/update-signatur', {
|
||||
method: 'POST', body: JSON.stringify(sig),
|
||||
});
|
||||
let antwort = {};
|
||||
try { antwort = await res.json(); } catch { /* leer */ }
|
||||
|
||||
@@ -19,9 +19,14 @@ HOST=0.0.0.0
|
||||
# weiterlaufen, bis alle das Update haben – danach das alte streichen.
|
||||
# CF_PROXY_TOKEN=neues-token,altes-token
|
||||
#
|
||||
# Leer lassen = keine Tokenprüfung.
|
||||
# Pflicht: Ohne Token startet der Dienst nicht – sonst könnte jeder, der die
|
||||
# Adresse kennt, deinen API-Key und dein Download-Kontingent benutzen.
|
||||
# Ein langes Zufalls-Token erzeugen, z. B.: openssl rand -hex 32
|
||||
CF_PROXY_TOKEN=
|
||||
|
||||
# Nur für ein abgeschottetes Netz: Dienst bewusst OHNE Token betreiben.
|
||||
# CF_PROXY_OFFEN=1
|
||||
|
||||
# Anfragen je Minute und Absender. 0 = keine Begrenzung.
|
||||
RATE_LIMIT_PER_MIN=60
|
||||
|
||||
|
||||
@@ -101,7 +101,8 @@ Der Dienst steht offen im Netz. Eingebaut ist:
|
||||
die Host-Liste geprüft, höchstens vier Sprünge.
|
||||
- **Ratenbegrenzung** je Absender, einstellbar über `RATE_LIMIT_PER_MIN`.
|
||||
- **Größengrenze** für durchgereichte Dateien über `MAX_DOWNLOAD_MB`.
|
||||
- **Optionales Token** über `CF_PROXY_TOKEN`.
|
||||
- **Token** über `CF_PROXY_TOKEN` – Pflicht: ohne Token startet der Dienst nicht
|
||||
(bewusst offen nur mit `CF_PROXY_OFFEN=1`, z. B. im abgeschotteten Netz).
|
||||
|
||||
Zum Token eine ehrliche Einordnung: Es steckt dann auch im Launcher und ist
|
||||
dort auslesbar. Es hält Gelegenheitsnutzer ab, keine entschlossenen. Die
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const http = require('http');
|
||||
const crypto = require('crypto');
|
||||
const { Readable } = require('stream');
|
||||
|
||||
const KEY = (process.env.CF_API_KEY || '').trim();
|
||||
@@ -35,6 +36,17 @@ if (!KEY) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Ohne Token wäre der Dienst für jeden offen, der die Adresse kennt – und damit
|
||||
// auch der API-Key und das Download-Kontingent dahinter. Deshalb startet er
|
||||
// ohne CF_PROXY_TOKEN gar nicht erst. Wer ihn bewusst offen betreiben will
|
||||
// (z. B. nur im eigenen Netz), muss das ausdrücklich sagen: CF_PROXY_OFFEN=1.
|
||||
const OFFEN_ERLAUBT = process.env.CF_PROXY_OFFEN === '1';
|
||||
if (!TOKENS.size && !OFFEN_ERLAUBT) {
|
||||
console.error('CF_PROXY_TOKEN fehlt. Ohne Token könnte jeder den Dienst (und deinen API-Key) benutzen.');
|
||||
console.error('Token setzen (siehe .env.example) – oder, nur für ein abgeschottetes Netz, CF_PROXY_OFFEN=1.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Ratenbegrenzung: einfaches Zeitfenster je Absender
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -88,9 +100,21 @@ function sendeJson(res, code, daten) {
|
||||
res.end(koerper);
|
||||
}
|
||||
|
||||
// Vergleich in gleichbleibender Zeit, damit sich ein Token nicht Zeichen für
|
||||
// Zeichen über die Antwortdauer erraten lässt
|
||||
function gleich(a, b) {
|
||||
const x = crypto.createHash('sha256').update(a).digest();
|
||||
const y = crypto.createHash('sha256').update(b).digest();
|
||||
return crypto.timingSafeEqual(x, y);
|
||||
}
|
||||
|
||||
function tokenOk(req) {
|
||||
if (!TOKENS.size) return true;
|
||||
return TOKENS.has(String(req.headers['x-aeromc-token'] || '').trim());
|
||||
if (!TOKENS.size) return OFFEN_ERLAUBT; // ohne Token nur mit ausdrücklicher Freigabe
|
||||
const erhalten = String(req.headers['x-aeromc-token'] || '').trim();
|
||||
if (!erhalten) return false;
|
||||
let ok = false;
|
||||
for (const t of TOKENS) if (gleich(t, erhalten)) ok = true;
|
||||
return ok;
|
||||
}
|
||||
|
||||
function leseKoerper(req, maxBytes = 1_000_000) {
|
||||
@@ -308,7 +332,7 @@ server.listen(PORT, HOST, () => {
|
||||
console.log(`AeroMC CurseForge-Weiterleitung läuft auf ${HOST}:${PORT}`);
|
||||
console.log(` Ratenbegrenzung: ${LIMIT_PRO_MIN > 0 ? LIMIT_PRO_MIN + '/Minute je Absender' : 'aus'}`);
|
||||
// niemals die Token selbst ausgeben – Protokolle wandern schnell woanders hin
|
||||
console.log(` Token verlangt : ${TOKENS.size ? 'ja (' + TOKENS.size + ' gültige)' : 'nein'}`);
|
||||
console.log(` Token verlangt : ${TOKENS.size ? 'ja (' + TOKENS.size + ' gültige)' : 'NEIN – offen für jeden (CF_PROXY_OFFEN=1)'}`);
|
||||
console.log(` Proxy-Stufen : ${PROXY_STUFEN} (${PROXY_STUFEN ? 'Absender aus X-Forwarded-For' : 'Absender aus der Verbindung'})`);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"version": 1,
|
||||
"skills": {
|
||||
"cavecrew": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/cavecrew/SKILL.md",
|
||||
"computedHash": "2e122d819a812bef0e4958706f306e4346e78ecb5a4893997b99cbc19866f514"
|
||||
},
|
||||
"caveman": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman/SKILL.md",
|
||||
"computedHash": "71b600c88c8d1d36f18c4875db23b53c5d6cb9ba3195e19451d6b1bb67db07c4"
|
||||
},
|
||||
"caveman-commit": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-commit/SKILL.md",
|
||||
"computedHash": "b416cf134b0f33ddadeca7977aebdbb2d3db79a166d0fce2e1aabeec98132766"
|
||||
},
|
||||
"caveman-compress": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-compress/SKILL.md",
|
||||
"computedHash": "810b9f31c05c3ef5d195eac4f76cd26674ba13f542d6ad5a0b16d5362b021614"
|
||||
},
|
||||
"caveman-discover": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-discover/SKILL.md",
|
||||
"computedHash": "6850e0ca7bd7a35a1f447cbd342f91b76ece1fb2e3473ad894e51e69746df8a2"
|
||||
},
|
||||
"caveman-evidence-review": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-evidence-review/SKILL.md",
|
||||
"computedHash": "6a2db0191082500739416c87ff896a7894f98aa867f15c70fe932e4d72edd327"
|
||||
},
|
||||
"caveman-explore": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-explore/SKILL.md",
|
||||
"computedHash": "6e89d5fef24957b921cf021d5bb392c47185ed65233db783acef64a9228dbb1b"
|
||||
},
|
||||
"caveman-help": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-help/SKILL.md",
|
||||
"computedHash": "c7a73a8c6afb6f871690666449209106aba847b4a9b0698686648960ece80012"
|
||||
},
|
||||
"caveman-learn": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-learn/SKILL.md",
|
||||
"computedHash": "7af5a39ccea7b778581938662422ffce01df4271fb5403a63953794748210e93"
|
||||
},
|
||||
"caveman-manage": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-manage/SKILL.md",
|
||||
"computedHash": "fdd3834941a8a576cae0ac96a38dfec6ac4bd26ef209ba9997468ca11aaf19f4"
|
||||
},
|
||||
"caveman-optimize": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-optimize/SKILL.md",
|
||||
"computedHash": "5e859a3a8305b5559b2f528616f634324449a426054704d43ef0b6ec8c1d9807"
|
||||
},
|
||||
"caveman-review": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-review/SKILL.md",
|
||||
"computedHash": "36a4007c5c0c6b90b5accfee1cd769a86e4963b651dece2ce5f17a223a0abb4b"
|
||||
},
|
||||
"caveman-setup": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-setup/SKILL.md",
|
||||
"computedHash": "b12b9f8f3fe6b499334a4b319ae1a16aa2da5c2d11e5bc85efd3236eac5213aa"
|
||||
},
|
||||
"caveman-stats": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/caveman-stats/SKILL.md",
|
||||
"computedHash": "cc9fcd21f2a30cff5596b3cbb197fe0f4b1b30b58084a864350853c217ad301a"
|
||||
},
|
||||
"investigate-first": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/investigate-first/SKILL.md",
|
||||
"computedHash": "59b581b5abfc0e19b7dd5a7c3bb2b16621ab5e94e085065c7b724a9c86cc3d4d"
|
||||
},
|
||||
"lean-build": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/lean-build/SKILL.md",
|
||||
"computedHash": "6074721f1653e6e9d6381595b094284807b8d5d001d7d3977ec534679b16a63c"
|
||||
},
|
||||
"megacave": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/megacave/SKILL.md",
|
||||
"computedHash": "60da384ce09cedf553e2b6dfe4669ffb4e53f34c3df8ce2c8012a32e06f8e187"
|
||||
},
|
||||
"migration": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/migration/SKILL.md",
|
||||
"computedHash": "7348b2d21ca05bdecc1e4ec2c8b63515ccb1700c8a261fdbd458b04b7383945b"
|
||||
},
|
||||
"safe-refactor": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/safe-refactor/SKILL.md",
|
||||
"computedHash": "9df34a21a7a2c18ce13dbbe4a3f66b4e91df9e4bc33c1c9da8a80261583367ec"
|
||||
},
|
||||
"surgical-patch": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/surgical-patch/SKILL.md",
|
||||
"computedHash": "028b9c3574142d19639d9f8eb11fbb01c58479f8f441e957d598a7215e79f95d"
|
||||
},
|
||||
"ultracave": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/ultracave/SKILL.md",
|
||||
"computedHash": "d2e5de7e5e664e95c0c93ea0fb84c6b78a4bb2351c71964c453a8a35c63869eb"
|
||||
},
|
||||
"verify-and-stop": {
|
||||
"source": "JuliusBrussee/caveman",
|
||||
"sourceType": "github",
|
||||
"skillPath": "skills/verify-and-stop/SKILL.md",
|
||||
"computedHash": "3d67de16a2b3c48b643bc511ebc4cb86e6c7105215d8428b6140cbcb73aba4e6"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 164 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 183 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
@@ -13,6 +13,7 @@
|
||||
<div class="titelleiste">
|
||||
<img src="assets/logo.png" alt="" class="titel-logo" />
|
||||
<span class="titel-text">AeroMC</span>
|
||||
<span id="titel-beta" class="titel-beta hidden"></span>
|
||||
</div>
|
||||
|
||||
<!-- Obere Werkzeugleiste (MultiMC-Stil: Icon + Text) -->
|
||||
@@ -283,6 +284,10 @@
|
||||
<div class="s-text"><b>Bedrock-Bereich anzeigen</b><small id="s-bedrock-hint">Wird automatisch ausgeblendet, wenn Bedrock nicht installiert ist.</small></div>
|
||||
<label class="schalter"><input id="s-bedrock" type="checkbox" /><i></i></label>
|
||||
</div>
|
||||
<div class="s-zeile">
|
||||
<div class="s-text"><b>An der Beta teilnehmen</b><small>Du bekommst neue Versionen früher zum Ausprobieren. Betas können noch Fehler enthalten. Wieder ausgeschaltet, bekommst du ab der nächsten fertigen Version nur noch fertige Versionen.</small></div>
|
||||
<label class="schalter"><input id="s-beta" type="checkbox" /><i></i></label>
|
||||
</div>
|
||||
</section>
|
||||
<section class="settings-card">
|
||||
<h5>Instanzen</h5>
|
||||
|
||||
+19
-1
@@ -212,6 +212,7 @@ const POPOUT_SPEC = {
|
||||
stats: { title: 'AeroMC – Spielzeit-Statistik', width: 640, height: 560, minWidth: 520, minHeight: 420 },
|
||||
};
|
||||
const POPOUT_DEFAULT = { title: 'AeroMC', width: 860, height: 680, minWidth: 640, minHeight: 480 };
|
||||
let betaStand = false; // zuletzt bekannter Stand von "An der Beta teilnehmen"
|
||||
let pendingUpdateInfo = null; // letztes Ergebnis von update:check/checkForUpdate, für Update-Popup
|
||||
// Ergebnis der letzten Update-Suche (auch "läuft gerade" oder Fehler) – Fenster, die
|
||||
// erst später aufgehen (z. B. Einstellungen → Info), holen es sich hierüber ab
|
||||
@@ -223,7 +224,7 @@ async function pruefeAufUpdates() {
|
||||
letzterUpdateCheck = { checking: true };
|
||||
broadcast('update:checked', letzterUpdateCheck);
|
||||
try {
|
||||
const info = await updater.checkForUpdate(app.getVersion());
|
||||
const info = await updater.checkForUpdate(app.getVersion(), { beta: store.getSettings().betaTeilnahme === true });
|
||||
pendingUpdateInfo = info;
|
||||
letzterUpdateCheck = info;
|
||||
} catch (err) {
|
||||
@@ -1073,6 +1074,18 @@ app.whenReady().then(() => {
|
||||
decrypt: (b) => safeStorage.decryptString(Buffer.from(b, 'base64')),
|
||||
};
|
||||
auth.init(app.getPath('userData'), tresor);
|
||||
// Beta-Teilnahme: Wer eine Vorabfassung von Hand installiert, nimmt ab da teil
|
||||
// (einmalig beim Wechsel von einer fertigen auf eine Vorabfassung – danach
|
||||
// gilt allein der Schalter in den Optionen, auch wenn er wieder aus ist).
|
||||
{
|
||||
const vorab = updater.istVorabVersion(app.getVersion());
|
||||
const e = store.getSettings();
|
||||
const neu = {};
|
||||
if (vorab && !e.letzteVersionVorab && e.betaTeilnahme !== true) neu.betaTeilnahme = true;
|
||||
if (!!e.letzteVersionVorab !== vorab) neu.letzteVersionVorab = vorab;
|
||||
if (Object.keys(neu).length) store.saveSettings(neu);
|
||||
betaStand = store.getSettings().betaTeilnahme === true;
|
||||
}
|
||||
try { integritaet.init(app.getPath('userData'), tresor, store); } catch (err) { console.warn('Manipulationsschutz:', err.message); }
|
||||
setTimeout(() => { pruefeAlleInstanzen().catch(() => {}); }, 8000);
|
||||
// Proxy-Passwort und API-Schlüssel ebenso (siehe store.setzeTresor)
|
||||
@@ -1195,6 +1208,11 @@ ipcMain.handle('settings:save', (_e, patch) => {
|
||||
applyProxy(s);
|
||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'autostart')) applyAutostart(s.autostart);
|
||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'discordClientId')) discordpresence.configure(s);
|
||||
// Beta-Teilnahme umgeschaltet -> gleich neu nach Updates suchen
|
||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'betaTeilnahme') && !!patch.betaTeilnahme !== betaStand) {
|
||||
betaStand = !!patch.betaTeilnahme;
|
||||
pruefeAufUpdates().then((info) => { if (info.available) broadcast('update:available', info); }).catch(() => {});
|
||||
}
|
||||
if (patch && Object.prototype.hasOwnProperty.call(patch, 'friendsEnabled')) {
|
||||
aktualisiereFreundeTastenkuerzel();
|
||||
aktualisiereAnfragenZahl().catch(() => {});
|
||||
|
||||
@@ -6134,6 +6134,7 @@ async function openSettings(pane) {
|
||||
el('s-start-animation').checked = s.startAnimation !== false;
|
||||
el('s-ui-animationen').checked = s.uiAnimationen !== false;
|
||||
el('s-bedrock').checked = s.bedrockEnabled !== false;
|
||||
el('s-beta').checked = s.betaTeilnahme === true;
|
||||
el('s-notify').checked = s.desktopNotifications !== false;
|
||||
el('s-friends').checked = s.friendsEnabled !== false;
|
||||
el('s-friends-server').checked = s.friendsShareServer !== false;
|
||||
@@ -6272,6 +6273,7 @@ async function saveSettings() {
|
||||
startAnimation: el('s-start-animation').checked,
|
||||
uiAnimationen: el('s-ui-animationen').checked,
|
||||
bedrockEnabled: el('s-bedrock').checked,
|
||||
betaTeilnahme: el('s-beta').checked,
|
||||
desktopNotifications: el('s-notify').checked,
|
||||
friendsEnabled: el('s-friends').checked,
|
||||
friendsShareServer: el('s-friends-server').checked,
|
||||
@@ -7879,3 +7881,18 @@ window.addEventListener('DOMContentLoaded', async () => {
|
||||
popoutBoot(Object.fromEntries(new URLSearchParams(location.search)));
|
||||
}
|
||||
});
|
||||
|
||||
// Vorabfassung in der Titelleiste kenntlich machen: aus "1.2.4-beta.1" wird
|
||||
// "Beta 1", aus "1.3.0-rc.2" wird "RC 2". Fertige Versionen zeigen nichts.
|
||||
(async () => {
|
||||
try {
|
||||
const info = await window.api.appInfo();
|
||||
const m = String((info && info.version) || '').match(/^\d+(?:\.\d+){0,2}-([a-z]+)[.-]?(\d+)?/i);
|
||||
const marke = document.getElementById('titel-beta');
|
||||
if (!m || !marke) return;
|
||||
const art = /^rc$/i.test(m[1]) ? 'RC' : m[1].charAt(0).toUpperCase() + m[1].slice(1).toLowerCase();
|
||||
marke.textContent = art + (m[2] ? ' ' + m[2] : '');
|
||||
marke.title = `Vorabfassung ${info.version} – zum Testen, kann noch Fehler enthalten`;
|
||||
marke.classList.remove('hidden');
|
||||
} catch { /* nur Anzeige */ }
|
||||
})();
|
||||
|
||||
@@ -75,6 +75,8 @@ const DEFAULT_SETTINGS = {
|
||||
sortBy: 'lastPlayed', // lastPlayed | name
|
||||
iso3dIcons: true, // Block-Symbole räumlich darstellen
|
||||
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
|
||||
friendsEnabled: true,
|
||||
friendsShareServer: true, // Freunde sehen, auf welchem Server man spielt (für "Beitreten")
|
||||
|
||||
@@ -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}
|
||||
.titel-logo{width:16px;height:16px;flex:none}
|
||||
.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.is-popout>.titelleiste{display:none}
|
||||
|
||||
|
||||
+60
-14
@@ -15,6 +15,32 @@ const crypto = require('crypto');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
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';
|
||||
// Downloads nur von hier – eine Release-Datei mit fremder Adresse wird abgelehnt
|
||||
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
|
||||
* nicht, die die App selbst meldet (Tag "1.0.1" gegen App "1.0.1-beta"),
|
||||
* würde "1.0.1" als neuer gelten – der Launcher böte dasselbe Update nach
|
||||
* jeder Installation erneut an, eine Endlosschleife. Deshalb zählt eine
|
||||
* Vorabkennung nur, wenn sie auf beiden Seiten vorhanden ist (beta.1 -> beta.2).
|
||||
* Früher zählte eine Vorabkennung nur, wenn beide Seiten eine hatten – als
|
||||
* Schutz vor einer Endlosschleife, falls ein Release unter dem Tag "1.0.1"
|
||||
* steht, die App darin sich aber weiter als "1.0.1-beta" meldet. Das kann nicht
|
||||
* mehr passieren: Die Signatur bindet die Version (siehe pruefeSignatur), und
|
||||
* 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) {
|
||||
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++) {
|
||||
const x = a[i]; const y = b[i];
|
||||
if (x === undefined) return -1;
|
||||
@@ -250,20 +283,31 @@ function pickAsset(release, installKind) {
|
||||
* Prüft auf Updates.
|
||||
* -> { available, currentVersion, latestVersion, notes, asset, url, noReleases }
|
||||
*/
|
||||
async function checkForUpdate(currentVersion) {
|
||||
async function checkForUpdate(currentVersion, opts) {
|
||||
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);
|
||||
const list = await res.json();
|
||||
const releases = (Array.isArray(list) ? list : []).filter((r) => !r.draft);
|
||||
if (!releases.length) {
|
||||
const alle = (Array.isArray(list) ? list : []).filter((r) => !r.draft);
|
||||
|
||||
if (!alle.length) {
|
||||
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)
|
||||
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 available = compareVersions(latest.tag_name, currentVersion) > 0;
|
||||
const latestVersion = normVersion(latest.tag_name);
|
||||
const latestVersion = tagVersion(latest.tag_name);
|
||||
const available = compareVersions(latestVersion, currentVersion) > 0;
|
||||
let asset = pickAsset(latest, installKind);
|
||||
// ohne Signatur oder von fremder Adresse wird nichts automatisch installiert
|
||||
let unsigniert = false;
|
||||
@@ -485,6 +529,8 @@ module.exports = {
|
||||
pruefeSignatur,
|
||||
signaturText,
|
||||
holeSignatur,
|
||||
tagVersion,
|
||||
istVorabVersion: (v) => !!parsePreRelease(v),
|
||||
SIGNATUR_API,
|
||||
cleanupUpdateCache,
|
||||
compareVersions,
|
||||
|
||||
Reference in New Issue
Block a user