Files
adventureland/README.md
T
anima 3de09009d6
build container / build (push) Failing after 1m25s
fix mail verify
2026-11-02 02:16:44 +01:00

269 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Adventure Land – Docker-Setup
Lokale Installation des [Adventure Land MongoDB Ports](https://github.com/kaansoral/adventureland_mongodb)
mit Docker Compose: MongoDB, Backend (Web-Client) und Game-Server, inklusive
automatischem Datenbank-Seed.
## Voraussetzungen
- Docker Engine mit Compose v2 (`docker compose version`)
- Ports **8090** (Web) und **7192** (Game-Server) müssen auf dem Host frei sein
- Internetzugang beim ersten Build (die Quellcode-Repos werden geklont, Node-Pakete installiert)
## Start
```sh
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
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.
**Admin werden:** Die Admin-Seiten (`/admin/executor`, `/admin/renderer`) sind
standardmäßig gesperrt. `is_admin` in `common/admin.js` prüft das Feld
`user.admin`; setzen lässt es sich direkt in MongoDB:
```sh
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.
## 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 |
Die Spieldaten (Image) werden beim Build aus drei Repositories geklont und
liegen im Container unter `/app` – es wird nichts in diesen Ordner geklont.
## Konfiguration
`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`.
Beide Dateien sind normale Node-Module; nach Änderungen Container neu starten:
```sh
docker compose restart backend 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).
### MongoDB-Zugriff
Die Datenbank ist nur im Compose-Netz erreichbar. Für einen Blick hinein:
```sh
docker compose exec al-mongo mongosh adventureland --eval 'db.getCollectionNames()'
```
## Logs & Status
```sh
docker compose ps
docker compose logs -f backend 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
```
Nach `down -v` importiert der `seed`-Container die Karten beim nächsten Start
wieder. Backup/Restore des Datenbank-Volumes:
```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
```
Restore: `docker compose down`, das Volume leeren und das Archiv
(`tar xzf mongo-data-….tar.gz -C <volume-mountpoint>`) zurückkopieren, dann
`docker compose up -d` – `seed` erkennt die vorhandenen Collections und
überspringt den Import.
## Aktualisieren
Das Image klont beim Build den jeweils aktuellen `main`-Branch:
```sh
docker compose build --pull --no-cache
docker compose up -d
```
Ein Neu-Seed ist nicht nötig; bestehende Konten, Charaktere und Karten bleiben
erhalten.
Der Build wendet zusätzlich den lokalen Patch aus `docker/patch-drm-check.js` an
(siehe „Gut zu wissen“). Verschiebt Upstream die betroffene Zeile in
`node/server.js`, bricht der Build mit einer klaren Meldung ab – dann das
Suchmuster im Skript anpassen.
Ebenso ersetzt `docker/patch-attribution.js` die Hilfe-Zeile im Login
(„E-Mail, für alles“) durch einen Self-Host-Hinweis mit Link auf
https://adventure.land. Die Texte liegen in `docker/attribution/en.js` und
`docker/attribution/de.json`, alle anderen Sprachen fallen auf Englisch zurück.
Auch dieser Patch bricht den Build ab, wenn die Upstream-Vorlage nicht mehr
passt.
`docker/patch-custom-game.js` hakt den Loader für `files/custom/game.js` in
Backend und Game-Server ein und macht die Lone-Wolf-Raten datengetrieben (siehe
„Spieldaten anpassen“). Fehlt ein Anker, bricht der Build ebenfalls ab.
`docker/patch-auto-verify-email.js` markiert bei aktivem
`options.auto_verify_email` neue Konten beim Signup und bestehende beim nächsten
Login als verifiziert und überspringt die Verifikationsmail. Ohne den Schalter
bleibt das Upstream-Verhalten unverändert. Auch dieser Patch bricht den Build
ab, wenn ein Anker in `api.js` fehlt.
## Spieldaten anpassen (`files/custom/game.js`)
Werte bestehender Elemente und neue Elemente lassen sich ohne Quelltextänderung
über `files/custom/game.js` setzen. Die Datei wird in beide Spielcontainer als
`/app/custom/game.js` gemountet und beim Start gelesen; Änderungen brauchen nur
einen Neustart, keinen Rebuild:
```sh
docker compose restart al-backend al-game
```
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 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 }`.
- `phrases`: überschreibt Anzeigetexte. `"*"` gilt für alle Sprachen, ein
Sprachcode (`de`, `en`, ...) hat Vorrang. Nötig, wenn sich Zahlen in einem
Tooltip ändern.
- `apply(game)`: Funktion für Sonderfälle, läuft nach dem Zusammenführen.
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.
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
Laufzeit, können eventmodifizierte Monsterfelder auf den Stand vor der
Custom-Datei zurückgesetzt werden; dann den Game-Server neu starten.
## Gut zu wissen
- **E-Mail-Verifizierung:** AWS SES ist nicht konfiguriert. Deshalb setzt
`options.auto_verify_email: true` neue Konten beim Signup und bestehende beim
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
manuell geöffnet werden:
```sh
docker compose exec al-mongo mongosh --quiet adventureland --eval \
'db.user.find({}, {"info.email": 1, "info.everification": 1}).forEach((u) =>
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.
- **Tutorial-Belohnung (`c0`):** Jedes Konto mit `auth_id` (Steam/MAS) kann nach
abgeschlossenem Tutorial einmal `c0` abholen. Die Belohnung ist ein zufälliger
kosmetischer Look aus dem `cosmo0`-Pool (über 100 Varianten). Der Game-Server
prüft dafür `player.verified` **und** `player.auth_id`
(`node/server.js:5272`). Bei reinen Web-Accounts ohne Steam/MAS bleibt
`auth_id` leer, deshalb ist die Belohnung trotz Auto-Verifizierung weiterhin
gesperrt. Die alten Klassen-Belohnungen (`creward`) sind in
`design/classes.js` auskommentiert und werden vom Client nicht angefragt;
Hardcore-Rewards gelten nur auf dem Hardcore-Server.
- **„Authorization Failure“ (Gold/Glück −85 %, XP −20 %):** Das ist die
DRM-Prüfung des Game-Servers. Sie verlangt für jedes Konto ab 2019 eine
Steam-/Mac-App-Store-ID, die nur der jeweilige Game-Client ausstellen kann.
Eine selbst gehostete Instanz kann das nicht: Steam-Tickets brauchen den
privaten Publisher-Key, und die Steam-Anmeldung im Browser setzt diese ID
nicht. Deshalb patcht das Image die Prüfung über `docker/patch-drm-check.js`
und Compose setzt `AL_DRM_CHECK: "0"`; nach dem nächsten Login verschwindet die
Bedingung. Mit `AL_DRM_CHECK: "1"` (oder ohne die Variable) gilt wieder das
Upstream-Verhalten.
- **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.
- **Lizenz/Attribution:** Die AdventureLandOnlyUse-Lizenz verlangt einen
crawlable Link auf https://adventure.land. Der 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
Entwicklungs-Platzhalter. Vor einem öffentlich erreichbaren Betrieb ersetzen.
- **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
Branch eintragen und mit `docker compose build` neu bauen. Alternativ in
`docker-compose.override.yml` einen Checkout nach `/app` mounten und dabei
`node_modules` aus dem Image in ein eigenes Volume auslagern.
# docker-builder
## setup
Set Repo / Org vars:
- AOIT_GIT_URL
- NTFY_HOST
- NTFY_USER
- NTFY_CHANNEL
Set Repo / Org Secrets
- TOKEN_SVC_CI (for download repo)
- TOKEN_SVC_DOCKER (for upload container)
- REGISTRY_USER (for upload container)
- NTFY_PASS