Upload via GUI (146 Dateien)
This commit is contained in:
@@ -155,6 +155,15 @@ function analysiere(text, ctx = {}) {
|
|||||||
{ typ: 'java-auto' });
|
{ typ: 'java-auto' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Alte Forge-Version verträgt aktuelles Java 8 nicht ---
|
||||||
|
// Forge 1.16.5 vor 36.2.26 (und ähnlich alte Fassungen) nutzt eine interne
|
||||||
|
// Java-Klasse, die es seit Java 8u321 so nicht mehr gibt.
|
||||||
|
if (/sun\.security\.util\.ManifestEntryVerifier\.<init>/i.test(t) && /forge/i.test(String(ctx.loader || ''))) {
|
||||||
|
fund('forge-alt', 'Diese Forge-Version ist zu alt für das aktuelle Java',
|
||||||
|
'Ältere Forge-Versionen laufen mit aktuellem Java 8 nicht mehr (Fehler „ManifestEntryVerifier“). Eine neuere Forge-Version für dieselbe Minecraft-Version behebt das – Mods und Welten bleiben erhalten.',
|
||||||
|
{ typ: 'forge-aktualisieren' });
|
||||||
|
}
|
||||||
|
|
||||||
// --- Zu wenig Arbeitsspeicher ---
|
// --- Zu wenig Arbeitsspeicher ---
|
||||||
if (/java\.lang\.OutOfMemoryError|There is insufficient memory for the Java Runtime/i.test(t)) {
|
if (/java\.lang\.OutOfMemoryError|There is insufficient memory for the Java Runtime/i.test(t)) {
|
||||||
const jetzt = Number(ctx.maxMemMb) || 2048;
|
const jetzt = Number(ctx.maxMemMb) || 2048;
|
||||||
|
|||||||
+39
-4
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
/* ===================== Design-Auswahl in den Optionen ===================== */
|
/* ===================== Design-Auswahl in den Optionen ===================== */
|
||||||
.design-raster{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
|
.design-raster{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
|
||||||
.settings-card-wide .design-raster{grid-template-columns:repeat(5,minmax(0,1fr))}
|
.settings-card .design-raster{grid-template-columns:repeat(5,minmax(0,1fr))}
|
||||||
@media (max-width:900px){.settings-card-wide .design-raster{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
@media (max-width:900px){.settings-card .design-raster{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
||||||
.design-wahl{display:flex;flex-direction:column;gap:5px;padding:6px;border:1px solid var(--border);border-radius:8px;background:none;color:var(--text);font-family:inherit;font-size:12px;cursor:pointer;text-align:left}
|
.design-wahl{display:flex;flex-direction:column;gap:5px;padding:6px;border:1px solid var(--border);border-radius:8px;background:none;color:var(--text);font-family:inherit;font-size:12px;cursor:pointer;text-align:left}
|
||||||
.design-wahl:hover{border-color:var(--sel-br)}
|
.design-wahl:hover{border-color:var(--sel-br)}
|
||||||
.design-wahl.on{border-color:var(--sel-br);box-shadow:0 0 0 1px var(--sel-br);background:var(--sel)}
|
.design-wahl.on{border-color:var(--sel-br);box-shadow:0 0 0 1px var(--sel-br);background:var(--sel)}
|
||||||
@@ -94,6 +94,10 @@
|
|||||||
:root:is([data-design="aero"],[data-design="lila"]) .card.sel{background:linear-gradient(180deg,rgba(var(--p-akzent),.24),rgba(var(--p-tief),.14));border-color:rgba(var(--p-akzent2),.55);box-shadow:0 10px 28px -14px rgba(var(--p-akzent),.95),0 0 0 1px rgba(var(--p-hell),.08) inset}
|
:root:is([data-design="aero"],[data-design="lila"]) .card.sel{background:linear-gradient(180deg,rgba(var(--p-akzent),.24),rgba(var(--p-tief),.14));border-color:rgba(var(--p-akzent2),.55);box-shadow:0 10px 28px -14px rgba(var(--p-akzent),.95),0 0 0 1px rgba(var(--p-hell),.08) inset}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .card.sel .card-name{background:linear-gradient(120deg,rgb(var(--p-akzent2)),rgb(var(--p-akzent)) 60%,rgb(var(--p-tief)));color:#fff;border-radius:999px}
|
:root:is([data-design="aero"],[data-design="lila"]) .card.sel .card-name{background:linear-gradient(120deg,rgb(var(--p-akzent2)),rgb(var(--p-akzent)) 60%,rgb(var(--p-tief)));color:#fff;border-radius:999px}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .card-icon-img{border-radius:10px}
|
:root:is([data-design="aero"],[data-design="lila"]) .card-icon-img{border-radius:10px}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .card.laeuft::after{border-color:rgb(var(--p-akzent2));--accent:rgb(var(--p-akzent2))}
|
||||||
|
:root.ui-animiert:is([data-design="aero"],[data-design="lila"]) .lichtpunkte{display:block}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .lichtpunkte i{background:rgb(var(--p-hell));box-shadow:0 0 calc(var(--g) * 3) 1px rgba(var(--p-akzent2),.85)}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .erfolg .funke{box-shadow:0 0 5px 2px rgb(var(--p-hell)),0 0 14px 4px rgba(var(--p-akzent2),.8)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .card-taste{border-radius:999px;background:linear-gradient(120deg,rgb(var(--p-akzent2)),rgb(var(--p-akzent)))}
|
:root:is([data-design="aero"],[data-design="lila"]) .card-taste{border-radius:999px;background:linear-gradient(120deg,rgb(var(--p-akzent2)),rgb(var(--p-akzent)))}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .empty h2{background:linear-gradient(120deg,rgb(var(--p-hell)),rgb(var(--p-akzent)) 60%,rgb(var(--p-tief)));-webkit-background-clip:text;background-clip:text;color:transparent;font-size:26px}
|
:root:is([data-design="aero"],[data-design="lila"]) .empty h2{background:linear-gradient(120deg,rgb(var(--p-hell)),rgb(var(--p-akzent)) 60%,rgb(var(--p-tief)));-webkit-background-clip:text;background-clip:text;color:transparent;font-size:26px}
|
||||||
|
|
||||||
@@ -132,7 +136,7 @@
|
|||||||
:root:is([data-design="aero"],[data-design="lila"]) .mods-filters select,
|
:root:is([data-design="aero"],[data-design="lila"]) .mods-filters select,
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .mmc-bar select,
|
:root:is([data-design="aero"],[data-design="lila"]) .mmc-bar select,
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .clip-length select,
|
:root:is([data-design="aero"],[data-design="lila"]) .clip-length select,
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .path-row input,
|
:root:is([data-design="aero"],[data-design="lila"]) .path-row input,:root:is([data-design="aero"],[data-design="lila"]) .path-row select,:root:is([data-design="aero"],[data-design="lila"]) select.s-wert,:root:is([data-design="aero"],[data-design="lila"]) input.s-wert,:root:is([data-design="aero"],[data-design="lila"]) .s-paar input,:root:is([data-design="aero"],[data-design="lila"]) .s-einheit input,
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .se-farbzeile input[type=text],
|
:root:is([data-design="aero"],[data-design="lila"]) .se-farbzeile input[type=text],
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .se-feld select{background:var(--input);color:var(--text);border-color:var(--border);border-radius:10px}
|
:root:is([data-design="aero"],[data-design="lila"]) .se-feld select{background:var(--input);color:var(--text);border-color:var(--border);border-radius:10px}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .search-wrap input{border-radius:999px}
|
:root:is([data-design="aero"],[data-design="lila"]) .search-wrap input{border-radius:999px}
|
||||||
@@ -145,6 +149,9 @@
|
|||||||
:root:is([data-design="aero"],[data-design="lila"]) input[type=checkbox],:root:is([data-design="aero"],[data-design="lila"]) input[type=radio],:root:is([data-design="aero"],[data-design="lila"]) input[type=range]{accent-color:rgb(var(--p-akzent))}
|
:root:is([data-design="aero"],[data-design="lila"]) input[type=checkbox],:root:is([data-design="aero"],[data-design="lila"]) input[type=radio],:root:is([data-design="aero"],[data-design="lila"]) input[type=range]{accent-color:rgb(var(--p-akzent))}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .login-usercode{background:var(--input);color:var(--text);border-color:var(--border);border-radius:12px}
|
:root:is([data-design="aero"],[data-design="lila"]) .login-usercode{background:var(--input);color:var(--text);border-color:var(--border);border-radius:12px}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .upd-notes{background:var(--input);border-radius:10px}
|
:root:is([data-design="aero"],[data-design="lila"]) .upd-notes{background:var(--input);border-radius:10px}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .upd-notes h5{color:rgb(var(--p-hell))}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .upd-notes li::marker{color:rgb(var(--p-akzent2))}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .upd-notes a{color:rgb(var(--p-hell))}
|
||||||
|
|
||||||
/* Knöpfe – rund wie auf der Webseite */
|
/* Knöpfe – rund wie auf der Webseite */
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .btn{border-radius:999px;padding:7px 15px;background:var(--surface);border-color:var(--border);color:var(--text);transition:background .15s,border-color .15s,transform .15s}
|
:root:is([data-design="aero"],[data-design="lila"]) .btn{border-radius:999px;padding:7px 15px;background:var(--surface);border-color:var(--border);color:var(--text);transition:background .15s,border-color .15s,transform .15s}
|
||||||
@@ -190,6 +197,7 @@
|
|||||||
:root:is([data-design="aero"],[data-design="lila"]) .snav:hover{background:var(--surface)}
|
:root:is([data-design="aero"],[data-design="lila"]) .snav:hover{background:var(--surface)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .snav.on{background:linear-gradient(120deg,rgba(var(--p-akzent),.30),rgba(var(--p-tief),.18));border-color:rgba(var(--p-akzent2),.40);box-shadow:none}
|
:root:is([data-design="aero"],[data-design="lila"]) .snav.on{background:linear-gradient(120deg,rgba(var(--p-akzent),.30),rgba(var(--p-tief),.18));border-color:rgba(var(--p-akzent2),.40);box-shadow:none}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .settings-card{background:var(--surface);border-color:var(--border);border-radius:16px}
|
:root:is([data-design="aero"],[data-design="lila"]) .settings-card{background:var(--surface);border-color:var(--border);border-radius:16px}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .schalter input:checked+i{background:linear-gradient(120deg,rgb(var(--p-akzent)),rgb(var(--p-akzent2)));box-shadow:0 0 10px -2px rgba(var(--p-akzent),.8)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .settings-kv-row,
|
:root:is([data-design="aero"],[data-design="lila"]) .settings-kv-row,
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .about-brand{border-bottom-color:var(--border2)}
|
:root:is([data-design="aero"],[data-design="lila"]) .about-brand{border-bottom-color:var(--border2)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .appinfo-item{background:rgba(var(--p-linie),.04);border-color:var(--border2);border-radius:12px}
|
:root:is([data-design="aero"],[data-design="lila"]) .appinfo-item{background:rgba(var(--p-linie),.04);border-color:var(--border2);border-radius:12px}
|
||||||
@@ -197,6 +205,12 @@
|
|||||||
:root:is([data-design="aero"],[data-design="lila"]) .settings-hero h4{background:linear-gradient(120deg,rgb(var(--p-hell)),rgb(var(--p-akzent)) 70%);-webkit-background-clip:text;background-clip:text;color:transparent}
|
:root:is([data-design="aero"],[data-design="lila"]) .settings-hero h4{background:linear-gradient(120deg,rgb(var(--p-hell)),rgb(var(--p-akzent)) 70%);-webkit-background-clip:text;background-clip:text;color:transparent}
|
||||||
|
|
||||||
/* Kontextmenü, Hinweis, Bildlaufleisten */
|
/* Kontextmenü, Hinweis, Bildlaufleisten */
|
||||||
|
/* Erfolg-Meldung: Glas-Karte mit Leuchtrand wie die Webseite */
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .erfolg{background:linear-gradient(135deg,rgba(var(--p-akzent),.22),var(--surface) 55%);border:1px solid rgba(var(--p-akzent),.45);border-radius:14px;
|
||||||
|
box-shadow:0 0 0 1px rgba(255,255,255,.04) inset,0 18px 40px -12px rgba(0,0,0,.8),0 0 24px -8px rgba(var(--p-akzent),.7)}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .erfolg-symbol{border-radius:10px;background:rgba(var(--p-akzent),.18)}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .erfolg-kopf{color:rgb(var(--p-hell))}
|
||||||
|
:root:is([data-design="aero"],[data-design="lila"]) .erfolg-karte{border-radius:12px;background:var(--surface)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .ctx{background:var(--surface);border-color:var(--border);border-radius:12px;box-shadow:0 18px 40px -12px rgba(0,0,0,.8)}
|
:root:is([data-design="aero"],[data-design="lila"]) .ctx{background:var(--surface);border-color:var(--border);border-radius:12px;box-shadow:0 18px 40px -12px rgba(0,0,0,.8)}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .ctx-item{border-radius:8px}
|
:root:is([data-design="aero"],[data-design="lila"]) .ctx-item{border-radius:8px}
|
||||||
:root:is([data-design="aero"],[data-design="lila"]) .ctx-item:hover{background:rgba(var(--p-akzent),.22)}
|
:root:is([data-design="aero"],[data-design="lila"]) .ctx-item:hover{background:rgba(var(--p-akzent),.22)}
|
||||||
@@ -267,6 +281,10 @@
|
|||||||
:root[data-design="minecraft"] .toolbar{
|
:root[data-design="minecraft"] .toolbar{
|
||||||
background:url(assets/design/gras.png) 0 0/32px 8px repeat-x,url(assets/design/schiefer.png) 0 0/64px 64px;
|
background:url(assets/design/gras.png) 0 0/32px 8px repeat-x,url(assets/design/schiefer.png) 0 0/64px 64px;
|
||||||
image-rendering:pixelated;border-bottom:2px solid #000;padding:11px 8px 6px}
|
image-rendering:pixelated;border-bottom:2px solid #000;padding:11px 8px 6px}
|
||||||
|
:root[data-design="minecraft"] .toolbar{position:relative;isolation:isolate}
|
||||||
|
:root.ui-animiert[data-design="minecraft"] .toolbar::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.18;
|
||||||
|
background:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='512' height='48' shape-rendering='crispEdges' fill='white'><rect x='20' y='8' width='56' height='8'/><rect x='8' y='16' width='96' height='8'/><rect x='170' y='22' width='40' height='6'/><rect x='158' y='28' width='80' height='8'/><rect x='184' y='36' width='36' height='4'/><rect x='300' y='4' width='72' height='8'/><rect x='288' y='12' width='120' height='8'/><rect x='312' y='20' width='64' height='6'/><rect x='438' y='26' width='48' height='8'/><rect x='426' y='34' width='70' height='6'/></svg>") 0 0/512px 100% repeat-x;animation:wolken-ziehen 70s steps(512) infinite}
|
||||||
|
@keyframes wolken-ziehen{to{background-position:512px 0}}
|
||||||
:root[data-design="minecraft"] .tbtn{color:#fff;border-radius:0;text-shadow:1px 1px 0 #1a1a1a;image-rendering:auto}
|
:root[data-design="minecraft"] .tbtn{color:#fff;border-radius:0;text-shadow:1px 1px 0 #1a1a1a;image-rendering:auto}
|
||||||
:root[data-design="minecraft"] .tbtn:hover{background:rgba(0,0,0,.35);border-color:#fff}
|
:root[data-design="minecraft"] .tbtn:hover{background:rgba(0,0,0,.35);border-color:#fff}
|
||||||
:root[data-design="minecraft"] .tbtn:active{background:rgba(0,0,0,.5)}
|
:root[data-design="minecraft"] .tbtn:active{background:rgba(0,0,0,.5)}
|
||||||
@@ -288,7 +306,7 @@
|
|||||||
:root[data-design="minecraft"] .mods-filters select,
|
:root[data-design="minecraft"] .mods-filters select,
|
||||||
:root[data-design="minecraft"] .mmc-bar select,
|
:root[data-design="minecraft"] .mmc-bar select,
|
||||||
:root[data-design="minecraft"] .clip-length select,
|
:root[data-design="minecraft"] .clip-length select,
|
||||||
:root[data-design="minecraft"] .path-row input,
|
:root[data-design="minecraft"] .path-row input,:root[data-design="minecraft"] .path-row select,:root[data-design="minecraft"] select.s-wert,:root[data-design="minecraft"] input.s-wert,:root[data-design="minecraft"] .s-paar input,:root[data-design="minecraft"] .s-einheit input,
|
||||||
:root[data-design="minecraft"] .login-usercode,
|
:root[data-design="minecraft"] .login-usercode,
|
||||||
:root[data-design="minecraft"] .upd-notes,
|
:root[data-design="minecraft"] .upd-notes,
|
||||||
:root[data-design="minecraft"] .se-farbzeile input[type=text],
|
:root[data-design="minecraft"] .se-farbzeile input[type=text],
|
||||||
@@ -319,6 +337,11 @@
|
|||||||
:root[data-design="minecraft"] .card.sel .card-name{background:none;color:#ffff7f;border-radius:0}
|
:root[data-design="minecraft"] .card.sel .card-name{background:none;color:#ffff7f;border-radius:0}
|
||||||
:root[data-design="minecraft"] .card-taste{border-radius:0;background:#3c8527;box-shadow:inset -1px -1px 0 #1d4d13}
|
:root[data-design="minecraft"] .card-taste{border-radius:0;background:#3c8527;box-shadow:inset -1px -1px 0 #1d4d13}
|
||||||
:root[data-design="minecraft"] .card-icon-img{border-radius:0}
|
:root[data-design="minecraft"] .card-icon-img{border-radius:0}
|
||||||
|
:root[data-design="minecraft"] .card.laeuft::after{border-color:#7fd858;--accent:#7fd858;border-radius:0}
|
||||||
|
/* Abbau-Risse: Download-Fortschritt auf dem Block, beim Fertigwerden springt er kurz */
|
||||||
|
:root[data-design="minecraft"] .card.abbau .card-riss{display:block}
|
||||||
|
:root.ui-animiert[data-design="minecraft"] .card.abgebaut .card-icon,:root.ui-animiert[data-design="minecraft"] .card.abgebaut .card-icon-img{animation:block-bricht .45s cubic-bezier(.3,.7,.4,1)}
|
||||||
|
@keyframes block-bricht{0%{transform:scale(.8)}45%{transform:scale(1.14)}100%{transform:none}}
|
||||||
:root[data-design="minecraft"] .empty h2{font-family:var(--pixel);font-weight:400;font-size:24px;color:#fff;text-shadow:3px 3px 0 #3f3f3f}
|
:root[data-design="minecraft"] .empty h2{font-family:var(--pixel);font-weight:400;font-size:24px;color:#fff;text-shadow:3px 3px 0 #3f3f3f}
|
||||||
:root[data-design="minecraft"] .empty p{color:#d0d0d0}
|
:root[data-design="minecraft"] .empty p{color:#d0d0d0}
|
||||||
|
|
||||||
@@ -332,6 +355,8 @@
|
|||||||
:root[data-design="minecraft"] .hr{background:#000;height:2px;margin:6px 0}
|
:root[data-design="minecraft"] .hr{background:#000;height:2px;margin:6px 0}
|
||||||
:root[data-design="minecraft"] .sbtn{margin-bottom:3px;padding:5px 2px}
|
:root[data-design="minecraft"] .sbtn{margin-bottom:3px;padding:5px 2px}
|
||||||
:root[data-design="minecraft"] .sbtn.play{font-family:var(--pixel);font-size:16px;font-weight:400;padding:6px 4px 7px;text-shadow:var(--mc-schatten)}
|
:root[data-design="minecraft"] .sbtn.play{font-family:var(--pixel);font-size:16px;font-weight:400;padding:6px 4px 7px;text-shadow:var(--mc-schatten)}
|
||||||
|
:root[data-design="minecraft"] .sbtn.play::before,:root:is([data-design="aero"],[data-design="lila"]) .sbtn.play::before{background:#fff;opacity:.28}
|
||||||
|
:root[data-design="minecraft"] .sbtn.play.laedt .play-text{font-size:13px}
|
||||||
|
|
||||||
/* Statusleiste */
|
/* Statusleiste */
|
||||||
:root[data-design="minecraft"] .statusbar{background:url(assets/design/schiefer.png) 0 0/64px 64px;image-rendering:pixelated;border-top:2px solid #000}
|
:root[data-design="minecraft"] .statusbar{background:url(assets/design/schiefer.png) 0 0/64px 64px;image-rendering:pixelated;border-top:2px solid #000}
|
||||||
@@ -391,6 +416,10 @@
|
|||||||
:root[data-design="minecraft"] .settings-hero h4{font-family:var(--pixel);font-size:24px;font-weight:400;text-shadow:3px 3px 0 #3f3f3f}
|
:root[data-design="minecraft"] .settings-hero h4{font-family:var(--pixel);font-size:24px;font-weight:400;text-shadow:3px 3px 0 #3f3f3f}
|
||||||
:root[data-design="minecraft"] .settings-hero p{color:#d0d0d0}
|
:root[data-design="minecraft"] .settings-hero p{color:#d0d0d0}
|
||||||
:root[data-design="minecraft"] .settings-card{background:#313233;border:2px solid #000;border-radius:0;box-shadow:inset 2px 2px 0 #5a5b5d,inset -2px -2px 0 #1e1e1f}
|
:root[data-design="minecraft"] .settings-card{background:#313233;border:2px solid #000;border-radius:0;box-shadow:inset 2px 2px 0 #5a5b5d,inset -2px -2px 0 #1e1e1f}
|
||||||
|
:root[data-design="minecraft"] .schalter i{border-radius:0;background:#1e1e1f;box-shadow:inset 2px 2px 0 #000}
|
||||||
|
:root[data-design="minecraft"] .schalter i::after{border-radius:0;background:#c6c6c6;box-shadow:inset -2px -2px 0 #555,inset 2px 2px 0 #fff}
|
||||||
|
:root[data-design="minecraft"] .schalter input:checked+i{background:#3c8527}
|
||||||
|
:root[data-design="minecraft"] .s-zeile{border-top-color:rgba(0,0,0,.55)}
|
||||||
:root[data-design="minecraft"] .settings-card h5{font-family:var(--pixel);font-size:16px;font-weight:400;text-shadow:var(--mc-schatten)}
|
:root[data-design="minecraft"] .settings-card h5{font-family:var(--pixel);font-size:16px;font-weight:400;text-shadow:var(--mc-schatten)}
|
||||||
:root[data-design="minecraft"] .settings-kv-row,
|
:root[data-design="minecraft"] .settings-kv-row,
|
||||||
:root[data-design="minecraft"] .about-brand{border-bottom-color:#1a1a1b}
|
:root[data-design="minecraft"] .about-brand{border-bottom-color:#1a1a1b}
|
||||||
@@ -399,6 +428,12 @@
|
|||||||
:root[data-design="minecraft"] .spane h4{font-family:var(--pixel);font-size:16px;font-weight:400;text-shadow:var(--mc-schatten)}
|
:root[data-design="minecraft"] .spane h4{font-family:var(--pixel);font-size:16px;font-weight:400;text-shadow:var(--mc-schatten)}
|
||||||
|
|
||||||
/* Kontextmenü, Hinweis, Bildlaufleisten */
|
/* Kontextmenü, Hinweis, Bildlaufleisten */
|
||||||
|
/* Erfolg-Meldung wie im Spiel („Erfolg erzielt!“) */
|
||||||
|
:root[data-design="minecraft"] .erfolg{background:#212121;border:2px solid #555;border-radius:0;box-shadow:inset 2px 2px 0 #373737,inset -2px -2px 0 #141414,0 10px 24px rgba(0,0,0,.45);color:#fff;font-family:"AeroPixel","Segoe UI",sans-serif}
|
||||||
|
:root[data-design="minecraft"] .erfolg-symbol{border-radius:0;background:#8b8b8b;box-shadow:inset 2px 2px 0 #373737,inset -2px -2px 0 #fff}
|
||||||
|
:root[data-design="minecraft"] .erfolg-kopf{color:#ffff55;font-size:14px;font-weight:400;letter-spacing:0;text-transform:none}
|
||||||
|
:root[data-design="minecraft"] .erfolg-name{font-size:14px;font-weight:400}
|
||||||
|
:root[data-design="minecraft"] .erfolg-karte{border-radius:0;border:2px solid #000;background:rgba(0,0,0,.35)}
|
||||||
:root[data-design="minecraft"] .ctx{background:#1e1e1f;border:2px solid #000;border-radius:0;box-shadow:inset 1px 1px 0 #48494a,0 8px 24px rgba(0,0,0,.5)}
|
:root[data-design="minecraft"] .ctx{background:#1e1e1f;border:2px solid #000;border-radius:0;box-shadow:inset 1px 1px 0 #48494a,0 8px 24px rgba(0,0,0,.5)}
|
||||||
:root[data-design="minecraft"] .ctx-item{border-radius:0;text-shadow:1px 1px 0 #000}
|
:root[data-design="minecraft"] .ctx-item{border-radius:0;text-shadow:1px 1px 0 #000}
|
||||||
:root[data-design="minecraft"] .ctx-item:hover{background:#3c8527}
|
:root[data-design="minecraft"] .ctx-item:hover{background:#3c8527}
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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 };
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Garderobe: gespeicherte Skins und Umhänge zum schnellen Wechseln.
|
||||||
|
*
|
||||||
|
* Mojang merkt sich keine früheren Skins – wer einen neuen hochlädt, verliert
|
||||||
|
* den alten. Die Garderobe hält Skins (samt Armform) und eigene AeroMC-Umhänge
|
||||||
|
* als PNG-Dateien im Launcher-Datenordner fest; vor jedem Skinwechsel im
|
||||||
|
* Launcher wird der bisherige Skin automatisch gesichert. Gleiche Dateien
|
||||||
|
* (gleiche Prüfsumme) werden nicht doppelt abgelegt.
|
||||||
|
*/
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const MAX_AUTOMATISCH = 20; // ältere automatische Sicherungen fliegen raus
|
||||||
|
let ordner = null;
|
||||||
|
|
||||||
|
function init(userDataDir) {
|
||||||
|
ordner = path.join(userDataDir, 'garderobe');
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexDatei = () => path.join(ordner, 'garderobe.json');
|
||||||
|
function lies() {
|
||||||
|
try { return JSON.parse(fs.readFileSync(indexDatei(), 'utf8')); } catch { return []; }
|
||||||
|
}
|
||||||
|
function schreibe(liste) {
|
||||||
|
fs.mkdirSync(ordner, { recursive: true });
|
||||||
|
fs.writeFileSync(indexDatei(), JSON.stringify(liste, null, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Alle Einträge, neueste zuerst, jeweils mit Bild als data:-Adresse. */
|
||||||
|
function liste() {
|
||||||
|
return lies()
|
||||||
|
.filter((e) => fs.existsSync(path.join(ordner, e.datei)))
|
||||||
|
.sort((a, b) => String(b.erstellt).localeCompare(String(a.erstellt)))
|
||||||
|
.map((e) => Object.assign({}, e, {
|
||||||
|
dataUri: 'data:image/png;base64,' + fs.readFileSync(path.join(ordner, e.datei)).toString('base64'),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legt einen Skin/Umhang ab. art: 'skin' | 'umhang', daten: PNG-Buffer.
|
||||||
|
* Gibt es dieselbe Datei schon, wird nur ggf. aus "automatisch" ein fester Eintrag.
|
||||||
|
*/
|
||||||
|
function hinzufuegen({ art, daten, name, variante, automatisch }) {
|
||||||
|
const hash = crypto.createHash('sha1').update(daten).digest('hex');
|
||||||
|
const eintraege = lies();
|
||||||
|
const vorhanden = eintraege.find((e) => e.art === art && e.hash === hash);
|
||||||
|
if (vorhanden) {
|
||||||
|
if (!automatisch && vorhanden.automatisch) {
|
||||||
|
vorhanden.automatisch = false;
|
||||||
|
if (name) vorhanden.name = name;
|
||||||
|
schreibe(eintraege);
|
||||||
|
}
|
||||||
|
return { eintrag: vorhanden, neu: false };
|
||||||
|
}
|
||||||
|
fs.mkdirSync(ordner, { recursive: true });
|
||||||
|
const id = Date.now().toString(36) + crypto.randomBytes(3).toString('hex');
|
||||||
|
const datei = `${art}-${id}.png`;
|
||||||
|
fs.writeFileSync(path.join(ordner, datei), daten);
|
||||||
|
const eintrag = {
|
||||||
|
id, art, hash, datei,
|
||||||
|
name: String(name || '').trim().slice(0, 40) || (art === 'skin' ? 'Skin' : 'Umhang'),
|
||||||
|
variante: art === 'skin' ? (variante === 'slim' ? 'slim' : 'classic') : undefined,
|
||||||
|
automatisch: !!automatisch,
|
||||||
|
erstellt: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
eintraege.push(eintrag);
|
||||||
|
// automatische Sicherungen begrenzen (feste Einträge bleiben immer)
|
||||||
|
const auto = eintraege.filter((e) => e.automatisch).sort((a, b) => String(b.erstellt).localeCompare(String(a.erstellt)));
|
||||||
|
for (const alt of auto.slice(MAX_AUTOMATISCH)) loescheIntern(eintraege, alt.id);
|
||||||
|
schreibe(eintraege);
|
||||||
|
return { eintrag, neu: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
function loescheIntern(eintraege, id) {
|
||||||
|
const i = eintraege.findIndex((e) => e.id === id);
|
||||||
|
if (i < 0) return false;
|
||||||
|
try { fs.unlinkSync(path.join(ordner, eintraege[i].datei)); } catch { /* schon weg */ }
|
||||||
|
eintraege.splice(i, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loeschen(id) {
|
||||||
|
const eintraege = lies();
|
||||||
|
const ok = loescheIntern(eintraege, id);
|
||||||
|
if (ok) schreibe(eintraege);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
function umbenennen(id, name) {
|
||||||
|
const eintraege = lies();
|
||||||
|
const e = eintraege.find((x) => x.id === id);
|
||||||
|
if (!e) return false;
|
||||||
|
e.name = String(name || '').trim().slice(0, 40) || e.name;
|
||||||
|
e.automatisch = false; // umbenannt = bewusst behalten
|
||||||
|
schreibe(eintraege);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Eintrag samt Dateipfad (zum Anziehen). */
|
||||||
|
function holen(id) {
|
||||||
|
const e = lies().find((x) => x.id === id);
|
||||||
|
return e ? Object.assign({}, e, { pfad: path.join(ordner, e.datei) }) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { init, liste, hinzufuegen, loeschen, umbenennen, holen };
|
||||||
Reference in New Issue
Block a user