From 644b8601455f4ed19abd265e42836eb17db9deec Mon Sep 17 00:00:00 2001 From: anima Date: Wed, 4 Nov 2026 22:25:34 +0100 Subject: [PATCH] update README.md --- README.md | 161 +++++++++++++++++------------ source-repos/adventureland_mongodb | 2 +- 2 files changed, 98 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index a4215ad..2527dc2 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,18 @@ docker compose up -d --build Danach im Browser öffnen: **http://localhost:8090** Der erste Start dauert ein paar Minuten (Image-Build inkl. `npm install`). Beim -ersten Start laufen zwei Hilfs-Container: `mongo-init` initialisiert das -Replica-Set, `seed` importiert die 49 Kartendaten. Erst danach starten Backend +ersten Start laufen zwei Hilfs-Container: `al-mongo-init` initialisiert das +Replica-Set, `al-seed` importiert die 49 Kartendaten. Erst danach starten Backend und Game-Server. Bei späteren Starts überspringt sich der Seed selbst. **Konto anlegen:** Auf der Startseite unter „Steam“ auf **„Registrieren [Zum Entwickeln]“** klicken, E-Mail + Passwort eingeben. Danach Charakter erstellen und auf den Charakter klicken – man landet direkt im Spiel. -**Charakter Limits anheben** Folgendes Kommando setzt für alle existierenden Spieler das Charakter Limit auf 18. +**Charakterplätze anheben:** Folgendes Kommando setzt für alle bestehenden +Konten die Zahl der Charakterplätze (`info.slots`) auf das Maximum von 18. Neue +Konten starten weiterhin mit 5 Plätzen (mit verknüpfter Steam-ID `pid`: 8): + ```sh docker compose exec al-mongo mongosh adventureland --eval \ 'db.user.updateMany({}, { $set: { "info.slots": 18 } })' @@ -42,9 +45,10 @@ docker compose exec al-mongo mongosh adventureland --eval \ 'db.user.updateOne({"info.email": "du@example.com"}, { $set: { admin: true } })' ``` -Alternativ in `config/options.js` `unsecure_admin: true` setzen – dann gilt -**jeder** Besucher als Admin (`/admin/executor` erlaubt Code-Ausführung), daher -nur bei rein lokalem Zugriff sinnvoll. +Alternativ in `files/config/options.js` `unsecure_admin: true` setzen – dann +gilt **jeder** Besucher als Admin, solange `Local: true` ist +(`/admin/executor` erlaubt Code-Ausführung). Daher nur bei rein lokalem Zugriff +sinnvoll. **GM werden (Game):** Der Web-Admin ist **kein** Game-GM. Die GM-Rolle hängt am Charakter, nicht am Benutzerkonto: Der Game-Server prüft `player.role` bzw. @@ -79,46 +83,49 @@ docker compose exec al-mongo mongosh adventureland --eval \ ## Aufbau -| Service | Image | Aufgabe | -| ------------ | ------------------- | ------------------------------------------------------------- | -| `mongo` | `mongo:8.0` | Datenbank, läuft als Single-Node-Replica-Set `rs0` (Transaktionen) | -| `mongo-init` | `mongo:8.0` | Einmalig: `rs.initiate()` falls noch nicht geschehen | -| `seed` | `adventureland:local` | Einmalig: importiert die Kartengeometrie, überspringt sich selbst | -| `backend` | `adventureland:local` | Express-Backend, Web-Client, API – Port 8090 | -| `game` | `adventureland:local` | Socket.IO-Game-Server – Port 7192 | +| Service | Image | Aufgabe | +| -------------- | --------------------------------------------- | ------------------------------------------------------------- | +| `al-mongo` | `mongo:8.0` | Datenbank, läuft als Single-Node-Replica-Set `rs0` (Transaktionen) | +| `al-mongo-init` | `mongo:8.0` | Einmalig: `rs.initiate()` falls noch nicht geschehen | +| `al-seed` | `git.ao-it.net/gaming/adventureland:latest` | Einmalig: importiert die Kartengeometrie, überspringt sich selbst | +| `al-backend` | `git.ao-it.net/gaming/adventureland:latest` | Express-Backend, Web-Client, API – Port 8090 | +| `al-game` | `git.ao-it.net/gaming/adventureland:latest` | Socket.IO-Game-Server – Port 7192 | -Die Spieldaten (Image) werden beim Build aus drei Repositories geklont und -liegen im Container unter `/app` – es wird nichts in diesen Ordner geklont. +Das Image klont beim Build die drei Upstream-Repositories nach `/app`. Die +Submodule unter `source-repos/` sind lokale Arbeitskopien zur Kontrolle und +werden nicht ins Image kopiert; die Build-Patches liegen unter `docker/`. ## Konfiguration -`config/` wird als `/app/secretsandconfig` in die Container gemountet und +`files/config/` wird als `/app/secretsandconfig` in die Container gemountet und ersetzt das Template aus dem Upstream-Repo: -- `config/keys.js` – MongoDB-URI, Master-Keys, Stripe/Steam/SES (alles leer bzw. - feste Entwicklungs-Defaults). Die Werte sind absichtlich stabil, damit - Sitzungen und Serverdatensätze Neustarts überleben. -- `config/options.js` – `base_url`, Ports, Serverdefinition `local`, +- `files/config/keys.js` – MongoDB-Verbindung, Master-Keys, Stripe/Steam/SES, + Discord und Apple. Externe Dienste sind leer, die Master-Keys haben lokale + Entwicklungs-Defaults. Die Werte sollten stabil bleiben: Login-Sitzungen + liegen in MongoDB und hängen nicht an den Keys, aber `SERVER_MASTER` + verschlüsselt die gespeicherten MCP-Token-Geheimnisse. +- `files/config/options.js` – `base_url`, Ports, Serverdefinition `local`, Multi-Account-Limits. Beide Dateien sind normale Node-Module; nach Änderungen Container neu starten: ```sh -docker compose restart backend game +docker compose restart al-backend al-game ``` -> Wenn du die Ports änderst, passe sie an **drei** Stellen an: -> `docker-compose.yml` (`ports`), `config/options.js` (`port`, `local_port`, -> `address`) und `base_url` (inkl. Port). +> Wenn du die Ports änderst, passe sie in `docker-compose.yml` (`ports`) und +> `files/config/options.js` (`port`, `local_port`, `address`; `local_ip` nur bei +> Bedarf) sowie `base_url` (inkl. Port) an. ### Multi-Account-Limits -`config/options.js` steuert, wie viele Charaktere gleichzeitig online sein +`files/config/options.js` steuert, wie viele Charaktere gleichzeitig online sein dürfen: | Option | Bedeutung | aktuell | | --- | --- | --- | -| `ip_limit` | Nicht-Händler pro IP (mal `ipx` einer IP-Ausnahme) | `9` | +| `ip_limit` | Nicht-Händler pro IP (multipliziert mit dem `info.limit` einer `IP_`-Ausnahme) | `9` | | `character_limit` | Nicht-Händler pro Konto | `3` | | `merchant_ip_limit` | Händler pro IP | `3` | | `merchant_owner_limit` | Händler pro Konto | `1` | @@ -128,7 +135,7 @@ Die Werte gelten beim Login (`is_player_allowed`) und im Backend-Cron `docker/patch-multi-account-limits.js` ersetzt dabei die früher fest codierten Grenzen (3 Nicht-Händler, 1 Händler). Mit den aktuellen Werten können z. B. drei Konten von derselben IP jeweils drei Nicht-Händler-Charaktere online haben -(9 insgesamt); ein zehntes Nicht-Händler-Charakter bzw. ein vierter Händler wird +(9 insgesamt); ein zehnter Nicht-Händler-Charakter bzw. ein vierter Händler wird abgewiesen. `character_limit` ist die Zahl der **gleichzeitig online** erlaubten Charaktere, nicht die Zahl der Charakterplätze (`info.slots`); `ip_limit` ist ebenfalls keine Slotzahl. Eine `IP_`-Ausnahme mit @@ -156,31 +163,42 @@ docker compose exec al-mongo mongosh adventureland --eval 'db.getCollectionNames ```sh docker compose ps -docker compose logs -f backend game +docker compose logs -f al-backend al-game ``` ## Stoppen, Zurücksetzen, Sichern ```sh -docker compose stop # anhalten -docker compose down # Container entfernen, Daten behalten -docker compose down -v # ALLES löschen, inkl. Konten, Charakteren, Karten +docker compose stop # Container anhalten, Daten bleiben +docker compose down # Container entfernen, Daten in ./files/db bleiben +docker compose down -v # zusätzlich benannte/anonyme Volumes; ./files/db bleibt ``` -Nach `down -v` importiert der `seed`-Container die Karten beim nächsten Start -wieder. Backup/Restore des Datenbank-Volumes: +`./files/db` ist ein Bind-Mount, kein Docker-Volume. `down -v` löscht es +deshalb **nicht**. Für einen vollständigen Reset: ```sh -docker compose stop backend game -docker run --rm -v adventureland_mongo-data:/data -v "$PWD":/backup alpine \ - tar czf /backup/mongo-data-$(date +%F).tar.gz -C /data . -docker compose start backend game +docker compose down +sudo find files/db -mindepth 1 -delete +docker compose up -d ``` -Restore: `docker compose down`, das Volume leeren und das Archiv -(`tar xzf mongo-data-….tar.gz -C `) zurückkopieren, dann -`docker compose up -d` – `seed` erkennt die vorhandenen Collections und -überspringt den Import. +Beim nächsten Start ist die Datenbank leer; `al-mongo-init` initialisiert das +Replica-Set und `al-seed` importiert die Karten neu. + +Backup/Restore über `mongodump`/`mongorestore` (beide sind im MongoDB-Image): + +```sh +mkdir -p backups +docker compose exec -T al-mongo mongodump --db adventureland --archive --gzip \ + > backups/adventureland-$(date +%F-%H%M).dump.gz + +# Restore (vorher Backend und Game stoppen): +docker compose stop al-backend al-game +docker compose exec -T al-mongo mongorestore --archive --gzip --drop \ + < backups/adventureland-….dump.gz +docker compose start al-backend al-game +``` ## Aktualisieren @@ -227,7 +245,7 @@ bricht der Build ab. Limits konfigurierbar. Upstream prüft beim Login `options.ip_limit` und `options.character_limit`, würgt im Backend-Cron aber pauschal nach 3 Nicht-Händlern bzw. 1 Händler ab. Der Patch liest beide Stellen aus -`config/options.js` (`ip_limit`, `character_limit`, `merchant_ip_limit`, +`files/config/options.js` (`ip_limit`, `character_limit`, `merchant_ip_limit`, `merchant_owner_limit`). Fehlt ein Anker in `node/server_functions.js` oder `adventure_functions.js`, bricht der Build ab. @@ -247,8 +265,10 @@ Aufbau (alle Angaben optional): - `items`, `monsters`, `npcs`, `maps`, `sets`, `craft`, `skills`, `conditions`, `classes`, `levels`, `upgrades`, `compounds`, `multipliers`, `titles`, `tokens`, `dismantle`: Objekte werden tief zusammengeführt, Arrays ersetzt. - Neue IDs sind erlaubt, wenn sie eine vorhandene Grafik aus - `design/dimensions.js` nutzen (Items und Monster brauchen ein `skin`). + Neue IDs sind erlaubt, wenn sie vorhandene Grafiken wiederverwenden: Monster + aus `design/dimensions.js`, Items und Condition-Icons aus dem Sprite-Atlas + (`design/positions.js`). Items brauchen ein `skin`; bei Monstern dient die ID + als Fallback, Conditions dürfen ohne `skin` bleiben. Neue Karten gehen nicht: ihre Geometrie liegt in MongoDB (`MP_*`). - `drops`: `{ main: [[0.001, "item_id"]] }` hängt Zeilen an die Tabelle an. - `gold`: überschreibt `drops.gold`, z. B. `{ base: 0.8 }`. @@ -259,17 +279,19 @@ Aufbau (alle Angaben optional): Beim Start loggen beide Container `custom-game: loaded ...`; neue IDs stehen als `(new: ...)` dabei. Unbekannte Top-Level-Schlüssel, unbekannte Drop-Tabellen, -fehlende Items und fehlende Grafiken brechen den Start mit einer klaren Meldung -ab, statt das Spiel halb gepatcht zu starten. +fehlende Items und bei neuen IDs fehlende Grafiken brechen den Start mit einer +klaren Meldung ab, statt das Spiel halb gepatcht zu starten. Enthaltenes Beispiel: Der Buff „Lone Wolf“ gibt 10× XP statt 3×. Die Multiplikatoren liest der Game-Server aus der Condition-Definition (Patch in `docker/patch-custom-game.js`), der Tooltip-Text kommt aus `phrases`. Die Datei ist versioniert (`files/custom/`), `files/db` bleibt von Git ausgenommen. -Grenzen: Alles, was in `design/*.js` als Datum steht, ist überschreibbar. -Konstanten, die im Code stehen (z. B. andere Encouragement-Raten), brauchen -weiterhin einen Patch wie den für Lone Wolf. Endet ein Season-Event zur +Grenzen: Überschreibbar sind genau die oben gelisteten Design-Globals sowie +`drops`, `gold` und `phrases`. Andere `design/*.js`-Dateien (z. B. +`positions.js`, `dimensions.js`, `animations.js`) lassen sich darüber nicht +ersetzen. Konstanten, die im Code stehen (z. B. andere Encouragement-Raten), +brauchen weiterhin einen Patch wie den für Lone Wolf. Endet ein Season-Event zur Laufzeit, können eventmodifizierte Monsterfelder auf den Stand vor der Custom-Datei zurückgesetzt werden; dann den Game-Server neu starten. @@ -280,7 +302,8 @@ Custom-Datei zurückgesetzt werden; dann den Game-Server neu starten. nächsten Login auf „verifiziert“; die Verifikationsmail wird übersprungen. Der „Not Verified“-Debuff (Gold/Glück −25 %) tritt damit nicht mehr auf. Auf `false` gestellt, gilt wieder der Upstream-Ablauf: Im Backend-Log erscheint - `send_email error InvalidClientTokenId`, und der Verifizierungslink muss + ein SES-Fehler (bei leeren Credentials typischerweise + `send_email error InvalidClientTokenId`), und der Verifizierungslink muss manuell geöffnet werden: ```sh @@ -289,9 +312,16 @@ Custom-Datei zurückgesetzt werden; dann den Game-Server neu starten. print("http://localhost:8090/ev/" + u._id + "/" + u.info.everification))' ``` - Link im Browser öffnen, danach neu einloggen. Alternativ `info.verified` direkt - auf `true` setzen (siehe Admin-Befehl oben). Die `/ev`-Route bleibt in beiden - Fällen funktionsfähig. + Die URL ggf. an `base_url` aus `files/config/options.js` anpassen. Link im + Browser öffnen, danach neu einloggen. Alternativ `info.verified` direkt auf + `true` setzen: + + ```sh + docker compose exec al-mongo mongosh adventureland --eval \ + 'db.user.updateOne({"info.email": "du@example.com"}, { $set: { "info.verified": true } })' + ``` + + Die `/ev`-Route bleibt in beiden Fällen funktionsfähig. - **Tutorial-Belohnung (`c0`):** Jedes verifizierte Konto kann nach abgeschlossenem Tutorial einmal `c0` abholen. Die Belohnung ist ein zufälliger @@ -317,22 +347,25 @@ Custom-Datei zurückgesetzt werden; dann den Game-Server neu starten. - **Der Relay in `docker/entrypoint.sh`:** Das Backend spricht Game-Server über die Adresse an, die auch der Browser benutzt (`localhost:7192`). Innerhalb des - Backend-Containers wäre das es selbst, deshalb leitet ein kleines - `socat`-Relay `127.0.0.1:7192` an den `game`-Container weiter. Ohne das - schlagen Admin-/Server-Funktionen (`server_eval`) fehl. + Backend-Containers wäre das der Backend-Container selbst, deshalb leitet ein + kleines `socat`-Relay `127.0.0.1:7192` an den `al-game`-Container weiter. Ohne + das schlagen Admin-/Server-Funktionen (`server_eval`) fehl. - **Lizenz/Attribution:** Die AdventureLandOnlyUse-Lizenz verlangt einen - crawlable Link auf https://adventure.land. Der ersetzt deshalb die + crawlable Link auf https://adventure.land. Der Link ersetzt deshalb die „E-Mail, für alles“-Zeile im Login (siehe `docker/patch-attribution.js`). Zusätzlich ist einmalig eine kurze Mail an hello@adventure.land fällig, wenn die Instanz öffentlich erreichbar geht – das ist keine Code-Änderung. -- **Nur lokal erreichbar:** Die Ports sind standardmäßig an `127.0.0.1` des - Hosts gebunden. Für Zugriff aus dem LAN in `docker-compose.yml` die - `127.0.0.1:`-Präfixe entfernen und `base_url` (sowie ggf. - `servers.local.address`) in `config/options.js` auf die Host-IP bzw. den - Hostnamen umstellen. Der Browser verbindet sich direkt mit - `servers.local.address`. -- **Passwort-/Key-Änderungen:** `config/keys.js` enthält +- **Netzwerk/Ports:** Die Ports sind in `docker-compose.yml` derzeit an alle + Host-Interfaces gebunden (`8090:8090`, `7192:7192`). Für rein lokalen Betrieb + in `docker-compose.yml` `127.0.0.1:` voranstellen. Für Caddy auf einem anderen + Host müssen die Ports erreichbar bleiben; dann per Firewall auf die + Caddy-/LAN-Adresse beschränken. `base_url` und ggf. `servers.local.address` + in `files/config/options.js` auf die öffentliche URL bzw. den Hostnamen + umstellen. Der Browser verbindet sich direkt mit `servers.local.address`. +- **Passwort-/Key-Änderungen:** `files/config/keys.js` enthält Entwicklungs-Platzhalter. Vor einem öffentlich erreichbaren Betrieb ersetzen. + Die Datei wird read-only gemountet; nach einer Änderung genügt ein Neustart + von `al-backend` und `al-game`, kein Rebuild. Echte Secrets nicht committen. - **Quellcode anpassen:** Der Code liegt im Image, nicht im Host-Ordner. Für eigene Änderungen im `Dockerfile` über die Build-Args `AL_REPO`, `AL_REF`, `COMMON_REPO`/`COMMON_REF` bzw. `CONFIG_REPO`/`CONFIG_REF` einen Fork oder diff --git a/source-repos/adventureland_mongodb b/source-repos/adventureland_mongodb index 93bb1c7..a5c133d 160000 --- a/source-repos/adventureland_mongodb +++ b/source-repos/adventureland_mongodb @@ -1 +1 @@ -Subproject commit 93bb1c76f81c52493d90f505a2cd1d2359939eb5 +Subproject commit a5c133dcc31f97edab987119517b4a60581248f6