Files
AeroMc-Launcher/src/erfolge.js
T
2026-10-05 17:20:30 +00:00

74 lines
4.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Erfolge im Minecraft-Stil („Erfolg erzielt!“).
*
* Bewertet wird aus dem, was der Launcher ohnehin weiß (Instanzen, Spielzeit,
* Starts, Mods), plus ein paar Merkern für einzelne Aktionen (Umhang
* hochgeladen, Skin im Editor übernommen, Leistungs-Paket …). Freigeschaltete
* Erfolge landen mit Datum in userData/erfolge.json.
*/
const fs = require('fs');
const path = require('path');
const STUNDE = 3600;
const LISTE = [
{ id: 'erster-start', symbol: 'grass', titel: 'Los geht’s!', text: 'Starte zum ersten Mal ein Spiel mit AeroMC.', pruefe: (w) => w.starts >= 1 },
{ id: 'starts-10', symbol: 'pickaxe', titel: 'Stammgast', text: 'Starte 10-mal ein Spiel.', pruefe: (w) => w.starts >= 10 },
{ id: 'starts-100', symbol: 'gold', titel: 'Ohne mich geht nichts', text: 'Starte 100-mal ein Spiel.', pruefe: (w) => w.starts >= 100 },
{ id: 'zeit-1', symbol: 'map', titel: 'Erste Stunde', text: 'Spiele insgesamt eine Stunde.', pruefe: (w) => w.sekunden >= STUNDE },
{ id: 'zeit-10', symbol: 'sword', titel: 'Zeit vergeht wie im Flug', text: 'Spiele insgesamt 10 Stunden.', pruefe: (w) => w.sekunden >= 10 * STUNDE },
{ id: 'zeit-50', symbol: 'diamond', titel: 'Abenteurer', text: 'Spiele insgesamt 50 Stunden.', pruefe: (w) => w.sekunden >= 50 * STUNDE },
{ id: 'zeit-100', symbol: 'star', titel: 'Lebt in Minecraft', text: 'Spiele insgesamt 100 Stunden.', pruefe: (w) => w.sekunden >= 100 * STUNDE },
{ id: 'instanzen-5', symbol: 'chest', titel: 'Sammler', text: 'Lege 5 Instanzen an.', pruefe: (w) => w.instanzen >= 5 },
{ id: 'instanzen-10', symbol: 'book', titel: 'Archivar', text: 'Lege 10 Instanzen an.', pruefe: (w) => w.instanzen >= 10 },
{ id: 'versionen-3', symbol: 'end', titel: 'Zeitreisender', text: 'Spiele 3 verschiedene Minecraft-Versionen.', pruefe: (w) => w.versionen >= 3 },
{ id: 'erste-mod', symbol: 'redstone', titel: 'Bastler', text: 'Habe die erste Mod in einer Instanz.', pruefe: (w) => w.mods >= 1 },
{ id: 'mods-50', symbol: 'potion', titel: 'Mod-Meister', text: 'Habe 50 Mods in deinen Instanzen.', pruefe: (w) => w.mods >= 50 },
{ id: 'modpack', symbol: 'nether', titel: 'Das volle Paket', text: 'Installiere ein Modpack.', pruefe: (w) => w.modpacks >= 1 },
{ id: 'freund', symbol: 'creeper', titel: 'Gemeinsam statt einsam', text: 'Füge deinen ersten Freund hinzu.', pruefe: (w) => w.freunde >= 1 },
{ id: 'umhang', symbol: 'star', titel: 'Modeschöpfer', text: 'Lade einen eigenen AeroMC-Umhang hoch.', pruefe: (w) => w.merker.umhang },
{ id: 'skin-editor', symbol: 'map', titel: 'Pixelkünstler', text: 'Übernimm einen im Skin-Editor gemalten Skin.', pruefe: (w) => w.merker['skin-editor'] },
{ id: 'leistung', symbol: 'tnt', titel: 'Turbo', text: 'Installiere das Leistungs-Paket.', pruefe: (w) => w.merker.leistung },
];
let datei = null;
function init(userDataDir) { datei = path.join(userDataDir, 'erfolge.json'); }
function lies() {
try { return JSON.parse(fs.readFileSync(datei, 'utf8')); } catch { return null; }
}
function schreibe(stand) {
try { fs.writeFileSync(datei, JSON.stringify(stand, null, 1)); } catch { /* nicht schlimm */ }
}
/**
* werte: { starts, sekunden, instanzen, versionen, mods, modpacks, freunde }
* merker: zusätzliche Einzel-Aktionen ({ umhang: true } …)
* -> { neu: [Erfolge], ersteAuswertung }
*/
function pruefe(werte, merker = {}) {
const vorher = lies();
const stand = vorher || { freigeschaltet: {}, merker: {} };
Object.assign(stand.merker, merker);
const w = Object.assign({ starts: 0, sekunden: 0, instanzen: 0, versionen: 0, mods: 0, modpacks: 0, freunde: 0 }, werte, { merker: stand.merker });
const neu = [];
const jetzt = new Date().toISOString();
for (const e of LISTE) {
if (stand.freigeschaltet[e.id]) continue;
let erreicht = false;
try { erreicht = !!e.pruefe(w); } catch { /* Wert fehlt */ }
if (erreicht) { stand.freigeschaltet[e.id] = jetzt; neu.push(oeffentlich(e, jetzt)); }
}
if (neu.length || !vorher || Object.keys(merker).length) schreibe(stand);
return { neu, ersteAuswertung: !vorher };
}
const oeffentlich = (e, am) => ({ id: e.id, symbol: e.symbol, titel: e.titel, text: e.text, am: am || null });
/** Alle Erfolge mit Datum (null = noch offen). */
function liste() {
const stand = lies() || { freigeschaltet: {} };
return LISTE.map((e) => oeffentlich(e, stand.freigeschaltet[e.id] || null));
}
module.exports = { init, pruefe, liste };