From 9fd5e3810cb08dbef6bc6971ab7ed0979ade2098 Mon Sep 17 00:00:00 2001 From: denshooter <44590296+denshooter@users.noreply.github.com> Date: Fri, 29 Aug 2025 18:05:57 +0200 Subject: [PATCH] Update index.html --- loading/index.html | 250 +++++++++++++++++++++------------------------ 1 file changed, 115 insertions(+), 135 deletions(-) diff --git a/loading/index.html b/loading/index.html index 13dec8a..882a5c1 100644 --- a/loading/index.html +++ b/loading/index.html @@ -4,110 +4,105 @@ - Verbinde … - -
-
Server: Map: Modus: Du:
+

Willkommen auf deinem Server 👋

- - + +
+
Workshop
+
+
Server-Content
+
+
Initialisierung
+
-
Fortschritt
+
-
Workshop0%
-
-
Warte auf Daten …
+
Workshop-Downloadslädt …
+
+
Warte auf Workshop …
+
-
Server-Content0%
-
-
Warte auf Daten …
+
Server-Contentlädt …
+
+
Warte auf Server-Dateien …
+
-
Initialisierung
-
+
Initialisierungwartet …
+
Warte auf Client-Info …
Datei:
-
Tipps
    @@ -116,7 +111,7 @@ Dieses Overlay benötigt JavaScript, um Server/Map/Modus und Fortschritt zu zeig
  • Tab zeigt die Rollen-Übersicht.
@@ -127,103 +122,88 @@ Dieses Overlay benötigt JavaScript, um Server/Map/Modus und Fortschritt zu zeig (() => { const $ = id => document.getElementById(id); - // Elemente - const ph = { work:$('ph-work'), srv:$('ph-srv'), init:$('ph-init') }; - const work = { fill:$('w-fill'), pct:$('w-pct'), sub:$('w-sub'), total:0, need:0, last:0, done:false }; - const srv = { fill:$('s-fill'), pct:$('s-pct'), sub:$('s-sub'), total:0, need:0, last:0, done:false }; - const init = { pct:$('i-pct'), sub:$('i-sub') }; - let phase = 'work'; + // Spielername aus Query (bevorzugt), sonst SteamID + const qp = new URLSearchParams(location.search); + const qpName = decodeURIComponent((qp.get('name')||qp.get('nick')||qp.get('player')||qp.get('n')||'').replace(/\+/g,' ')).trim(); - function setPhase(next){ - phase = next; - // Chips visuell updaten - [ph.work, ph.srv, ph.init].forEach(el => el.classList.remove('on')); - if (next === 'work') ph.work.classList.add('on'); - if (next === 'srv') ph.srv.classList.add('on'); - if (next === 'init') ph.init.classList.add('on'); + // Grunddaten aus URL für sofortige Anzeige + $('map').textContent = qp.get('map') || 'Unbekannt'; + $('me').textContent = qpName || qp.get('sid') || '—'; + + // Step/Phase-Helpers + const steps = { + work: { stepEl: $('st-work'), bar: $('w-bar'), right: $('w-right'), sub: $('w-sub') }, + srv: { stepEl: $('st-srv'), bar: $('s-bar'), right: $('s-right'), sub: $('s-sub') }, + init: { stepEl: $('st-init'), bar: $('i-bar'), right: $('i-right'), sub: $('i-sub') } + }; + let active = 'work'; + + function setActive(key){ + ['work','srv','init'].forEach(k=>{ + const c = steps[k].stepEl.classList; + c.remove('active'); + }); + steps[key].stepEl.classList.add('active'); + active = key; } - function setPct(obj, v){ - v = Math.max(obj.last || 0, Math.min(100, Math.round(v))); - obj.last = v; - obj.fill.style.width = v + '%'; - obj.pct.textContent = v + '%'; + function markDone(key, text){ + steps[key].stepEl.classList.add('done'); + steps[key].bar.classList.remove('indet'); + steps[key].bar.classList.add('done'); + steps[key].right.textContent = text || 'fertig'; } - function updateBars(){ - // Workshop - if (work.total > 0){ - const done = Math.max(0, work.total - (work.need||0)); - setPct(work, (done / work.total) * 100); - work.sub.textContent = `${done} / ${work.total} Dateien`; - if (!work.done && done >= work.total){ work.done = true; setPhase('srv'); } - } - // Server - if (srv.total > 0){ - const done = Math.max(0, srv.total - (srv.need||0)); - setPct(srv, (done / srv.total) * 100); - srv.sub.textContent = `${done} / ${srv.total} Dateien`; - if (!srv.done && done >= srv.total){ srv.done = true; setPhase('init'); } - } - } - - // ===== von GMod aufgerufene Funktionen ===== - window.GameDetails = function(serverName, serverURL, mapName, maxPlayers, steamID, gamemode){ - $('sv').textContent = serverName || 'Unbekannt'; + // ===== GMod Callbacks ===== + window.GameDetails = function(serverName, serverUrl, mapName, maxPlayers, steamID, gamemode){ + $('sv').textContent = serverName || 'Unbekannt'; $('sv2').textContent = serverName || 'deinem Server'; - $('map').textContent = mapName || 'Unbekannt'; - $('gm').textContent = gamemode || 'TTT2'; - $('me').textContent = steamID || '—'; + $('gm').textContent = gamemode || 'TTT2'; + if (mapName) $('map').textContent = mapName; + + // Name bevorzugen, sonst SteamID + $('me').textContent = qpName || steamID || '—'; }; - // GMod ruft diese zweimal in „Wellen“ auf: erst Workshop, dann Server-DLs. - window.SetFilesTotal = function(total){ - total = Number(total) || 0; - // Heuristik: Wenn im Workshop die Gesamtzahl plötzlich kleiner wird, dann startet Server-Content - if (phase === 'work' && work.total && total && total < work.total && (work.last >= 95 || work.done)){ - work.done = true; setPhase('srv'); - } - if (phase === 'work'){ work.total = total; } - else if (phase === 'srv'){ srv.total = total; } - updateBars(); - }; - - window.SetFilesNeeded = function(need){ - need = Number(need) || 0; - if (phase === 'work'){ work.need = need; } - else if (phase === 'srv'){ srv.need = need; } - updateBars(); - }; + // Wir ignorieren die Prozent-Callbacks absichtlich (falsch/inkonsistent). + window.SetFilesTotal = function(){ /* noop (indeterminierte Balken) */ }; + window.SetFilesNeeded = function(){ /* noop (indeterminierte Balken) */ }; window.DownloadingFile = function(path){ $('file').textContent = (path||'').split('/').slice(-3).join('/'); + // Kleiner UX-Touch: zeige Datei unter der aktuell aktiven Phase + if (active === 'work') steps.work.sub.textContent = 'Lade: ' + $('file').textContent; + else if (active === 'srv') steps.srv.sub.textContent = 'Lade: ' + $('file').textContent; }; window.SetStatusChanged = function(status){ - const s = (status || '').toLowerCase(); + const s = (status||'').toLowerCase(); - // Phasenwechsel anhand Status - if (s.includes('workshop')) setPhase('work'); - if (s.includes('download') || s.includes('materials') || s.includes('models') || s.includes('.bsp')) setPhase('srv'); - if (s.includes('sending client info') || s.includes('precaching') || s.includes('client info') || s.includes('spawn')) - setPhase('init'); + // rudimentäres Phasen-Mapping nur für Optik + if (s.includes('workshop')) { setActive('work'); steps.work.sub.textContent = status; } + else if (s.includes('download') || s.includes('materials') || s.includes('models') || s.includes('.bsp') || s.includes('file')) { + steps.work.stepEl.classList.add('done'); setActive('srv'); steps.srv.sub.textContent = status; + } + else if (s.includes('sending client info') || s.includes('precaching') || s.includes('client info') || s.includes('parsing')) { + steps.work.stepEl.classList.add('done'); steps.srv.stepEl.classList.add('done'); + setActive('init'); steps.init.sub.textContent = status; + // wenn wir hier sind, frieren wir die Balken hübsch ein + markDone('work'); markDone('srv'); markDone('init','bereit'); + } - // Untertitel je nach Phase - if (phase === 'work') work.sub.textContent = status || ''; - if (phase === 'srv') srv.sub.textContent = status || ''; - if (phase === 'init'){ init.sub.textContent = status || 'Initialisiere …'; init.pct.textContent = '…'; } + // falls ein „complete“ kommt, markiere die aktuelle Phase als done + if (s.includes('complete')) { + if (active === 'work') { markDone('work'); setActive('srv'); } + else if (active === 'srv') { markDone('srv'); setActive('init'); } + } }; - // Kleiner Fallback fürs Testen im normalen Browser (kein Muss) - if (!('GameDetails' in window)) { - // Dummy-Werte - window.GameDetails('Gaming Mäuse - TTT', '', 'ttt_lego', 16, 'STEAM_0:1:123456', 'terrortown'); - // Fake-Progress - let a=0,b=0; const fake = setInterval(()=>{ - if (a < 100){ work.total=100; work.need=100-a; a+=7; updateBars(); } - else if (b < 100){ setPhase('srv'); srv.total=100; srv.need=100-b; b+=12; updateBars(); } - else { setPhase('init'); clearInterval(fake); } - }, 500); + // Fallback, falls GMod gar nichts ruft (nur für Browser-Preview) + if (document.visibilityState !== 'hidden') { + // steppt automatisch durch, rein für Demo/Preview + setTimeout(()=>{ setActive('srv'); }, 2000); + setTimeout(()=>{ setActive('init'); }, 4000); + setTimeout(()=>{ markDone('work'); markDone('srv'); markDone('init','bereit'); }, 6000); } })();