From 30ec5359b16e539e730b4313ef33cc82abbcd4d7 Mon Sep 17 00:00:00 2001 From: MrEgosar Date: Sun, 25 Oct 2026 22:54:38 +0100 Subject: [PATCH] AMP und feste Host-Namen aus Doku und Tests entfernen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Docker-Host ist beliebig; Beispiele nutzen jetzt DOCKER-HOST-IP bzw. den SSH-Alias docker-host statt eines Rechnernamens. Testfixture heißt echte-logs-wingman.log. --- README.md | 4 ++-- docs/container.md | 2 +- docs/portainer-cs2.md | 14 +++++++------- server/test/liveScore.test.js | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ae2af15..ecba1cb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Webanwendung zur Organisation von Counter-Strike-2-Matches: Match-Lobbys mit Tea CS2-Server-Container auf demselben Docker-Host startet. Siehe [docs/container.md](docs/container.md): ```powershell -docker -H ssh://cs2docker build -t cs2-mapveto:latest . +docker -H ssh://USER@DOCKER-HOST-IP build -t cs2-mapveto:latest . ``` …dann den Stack aus der Anleitung in Portainer anlegen. @@ -298,7 +298,7 @@ Beim Konfigurieren setzt CS2 Mapveto auf dem Server `log on` und `logaddress_add - Stream-Seite - **Nach dem Spielende:** Ist die Serie noch offen, lädt CS2 Mapveto nach `SERIES_AUTO_ADVANCE_SECONDS` (Standard 30) die nächste Map. Ist sie entschieden (z. B. 2:0 im Best of 3), wird das Match abgeschlossen und der Server freigegeben. Mit `-1` geht beides nur manuell. - **Voraussetzung:** Der CS2-Server muss `LOG_RECEIVER_URL` erreichen, im LAN z. B. `http://192.168.178.31:3000`. Ob Daten ankommen, zeigt das Serverpanel des Organisators. Mit `LOG_DEBUG=true` gibt das Backend alle empfangenen Zeilen aus. -- **Geprüft:** mit einem AMP-Server (Wingman), siehe `server/test/fixtures/amp-wingman-inferno.log`. +- **Geprüft:** mit echten Logzeilen eines CS2-Servers (Wingman), siehe `server/test/fixtures/echte-logs-wingman.log`. Zwei Eigenheiten von CS2 berücksichtigt der Parser: - CS2 sendet `Match_Start` schon beim Laden der Map. Gezählt wird erst, nachdem der Organisator „Aufwärmphase beenden“ geklickt hat. diff --git a/docs/container.md b/docs/container.md index 66864b8..fdadb8d 100644 --- a/docs/container.md +++ b/docs/container.md @@ -2,7 +2,7 @@ CS2 Mapveto läuft als **ein** Container: Webseite, Backend, Datenbank (SQLite) und ein Docker-Client. Er steht auf demselben Docker-Host wie die CS2-Server und startet pro Match über `/var/run/docker.sock` -einen eigenen CS2-Container. Der Host kann jeder Linux-Rechner mit Docker sein, ein AMP-Server ist nicht nötig. +einen eigenen CS2-Container. Der Host kann jeder Linux-Rechner mit Docker sein. ``` Docker-Host (beliebig, Linux, Adresse z. B. 192.168.178.111) diff --git a/docs/portainer-cs2.md b/docs/portainer-cs2.md index d9c7cc4..64a0654 100644 --- a/docs/portainer-cs2.md +++ b/docs/portainer-cs2.md @@ -220,22 +220,22 @@ Läuft CS2 Mapveto auf einem anderen Rechner als Docker (z. B. Windows-PC → Do ```bash sudo usermod -aG docker server ``` -2. Auf dem Rechner mit CS2 Mapveto einen SSH-Eintrag anlegen (Windows: `C:\Users\\.ssh\config`) und die Anmeldung per Schlüssel einrichten: +2. Auf dem Rechner mit CS2 Mapveto einen SSH-Eintrag anlegen (Windows: `C:\Users\\.ssh\config`) und die Anmeldung per Schlüssel einrichten. `DOCKER-HOST-IP` und `USER` durch deine Werte ersetzen: ``` - Host cs2docker - HostName 192.168.178.111 - User server + Host docker-host + HostName DOCKER-HOST-IP + User USER ``` 3. Testen, **auf dem Rechner mit CS2 Mapveto**, nicht auf dem Docker-Host: ```powershell - docker -H ssh://cs2docker ps + docker -H ssh://docker-host ps ``` ### 2. `.env` von CS2 Mapveto ```env SERVER_ADAPTER=docker -DOCKER_HOST=ssh://cs2docker +DOCKER_HOST=ssh://docker-host # leer = LAN-Modus (sv_lan 1), sonst ein Game Server Login Token CS2_GSLT= # Adresse, unter der Spieler den Docker-Host erreichen @@ -257,7 +257,7 @@ Wichtig dabei: - **Starts laufen nacheinander:** Jeder Match-Container prüft beim Start per SteamCMD auf Updates. Damit nie zwei Container gleichzeitig das Volume aktualisieren, startet CS2 Mapveto den nächsten erst, wenn der vorige seinen Update-Check abgeschlossen hat. Nach einem CS2-Patch dauert der erste Start dadurch länger, die übrigen warten kurz. - **Ein GSLT gilt nur für einen laufenden Server.** Ohne Token (LAN-Modus) gibt es diese Grenze nicht. - **Hardware:** Ein CS2-Server braucht etwa 1–2 CPU-Kerne und 2–3 GB RAM. 6 Kerne und 16 GB reichen für etwa 2–3 gleichzeitige Matches. -- **Plätze:** CSTV belegt selbst einen Spielerplatz. Der Adapter startet Container deshalb mit 6 (Wingman) bzw. 12 (5 gegen 5) Plätzen: alle Spieler, CSTV und eine Reserve. Bei festen Servern (AMP, Stack) `maxplayers` genauso hoch setzen, sonst kommt der letzte Spieler nicht drauf. +- **Plätze:** CSTV belegt selbst einen Spielerplatz. Der Adapter startet Container deshalb mit 6 (Wingman) bzw. 12 (5 gegen 5) Plätzen: alle Spieler, CSTV und eine Reserve. Bei festen Servern (Stack) `maxplayers` genauso hoch setzen, sonst kommt der letzte Spieler nicht drauf. - **Serverliste:** Match-Container tauchen im LAN-Tab von CS2 nicht auf. Der Client sucht dort nur auf den Ports 27015–27020, und Broadcasts erreichen Docker-Container kaum. Spieler verbinden sich über den Befehl bzw. den Knopf „In CS2 verbinden“ auf der Match-Seite. Jedes Match hat ohnehin ein eigenes Passwort. - **Bots zum Testen:** Ohne menschliche Spieler entfernt CS2 Bots zum Matchstart wieder (`bot_join_after_player 1`). Für Tests `CS2_EXTRA_COMMANDS=bot_join_after_player 0;bot_quota 4;bot_quota_mode fill` setzen. diff --git a/server/test/liveScore.test.js b/server/test/liveScore.test.js index 7190cd3..7ef54c3 100644 --- a/server/test/liveScore.test.js +++ b/server/test/liveScore.test.js @@ -60,10 +60,10 @@ test('Seitenzuordnung nach dem Rundenende hat Vorrang, veraltete Zeilen zu Runde assert.deepEqual(s.rounds.map((r) => r.winner), ['A', 'B']); }); -test('Echte Logzeilen eines AMP-Servers (Wingman, 4 Runden, Halbzeit nach 2)', () => { - const lines = fs.readFileSync(path.join(here, 'fixtures', 'amp-wingman-inferno.log'), 'utf8').split(/\r?\n/).filter(Boolean); +test('Echte Logzeilen eines CS2-Servers (Wingman, 4 Runden, Halbzeit nach 2)', () => { + const lines = fs.readFileSync(path.join(here, 'fixtures', 'echte-logs-wingman.log'), 'utf8').split(/\r?\n/).filter(Boolean); const warmupEnd = lines.findIndex((l) => l.includes('command "mp_warmup_end"')); - const amp = { teamNames: { A: 'MaxLAN Blau', B: 'MaxLAN Rot' }, maxRounds: 4, overtimeRounds: 6 }; + const ctx = { teamNames: { A: 'MaxLAN Blau', B: 'MaxLAN Rot' }, maxRounds: 4, overtimeRounds: 6 }; const check = (s) => { assert.equal(s.status, 'finished'); @@ -75,15 +75,15 @@ test('Echte Logzeilen eines AMP-Servers (Wingman, 4 Runden, Halbzeit nach 2)', ( // a) wie vom Server in Paketen geschickt let s = initialLiveState({ map: 'de_inferno', ctTeam: 'A' }); - ({ state: s } = applyLogLines(s, lines.slice(0, warmupEnd), amp)); + ({ state: s } = applyLogLines(s, lines.slice(0, warmupEnd), ctx)); assert.equal(s.status, 'warmup'); s.warmupEnded = true; // Organisator hat "Aufwärmphase beenden" geklickt - ({ state: s } = applyLogLines(s, lines.slice(warmupEnd), amp)); + ({ state: s } = applyLogLines(s, lines.slice(warmupEnd), ctx)); check(s); // b) jede Zeile einzeln (ungünstigste Paketgrenzen) let t = initialLiveState({ map: 'de_inferno', ctTeam: 'A', warmupEnded: true }); - for (const line of lines.slice(warmupEnd)) ({ state: t } = applyLogLines(t, [line], amp)); + for (const line of lines.slice(warmupEnd)) ({ state: t } = applyLogLines(t, [line], ctx)); check(t); });