AMP und feste Host-Namen aus Doku und Tests entfernen
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. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
413df03237
commit
726974fe82
4 files changed
+16
-16
No files matched your search
@@ -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.
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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\<Name>\.ssh\config`) und die Anmeldung per Schlüssel einrichten:
|
||||
2. Auf dem Rechner mit CS2 Mapveto einen SSH-Eintrag anlegen (Windows: `C:\Users\<Name>\.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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user