|
|
|
|
@@ -0,0 +1,219 @@
|
|
|
|
|
# Minecraft Modpack installieren / wechseln (FTB / CurseForge)
|
|
|
|
|
|
|
|
|
|
Diese Anleitung beschreibt, wie auf dem Minecraft-Server (VM 100, `192.168.2.51`,
|
|
|
|
|
`/opt/minecraft`, screen `minecraft`) ein **FTB-Modpack** installiert oder gegen ein
|
|
|
|
|
anderes ausgetauscht wird. Sie ist generisch — am Beispiel **FTB StoneBlock 4** —, gilt
|
|
|
|
|
aber für jedes FTB-Pack. Damit muss das nicht jedes Mal neu recherchiert werden.
|
|
|
|
|
|
|
|
|
|
> **Quelle der Wahrheit für Versionen ist die FTB-API**, nicht CurseForge (CurseForge zeigt
|
|
|
|
|
> oft veraltete „latest"-Stände). Siehe Schritt 1.
|
|
|
|
|
|
|
|
|
|
## Zugang
|
|
|
|
|
|
|
|
|
|
VM ist eine QEMU-VM auf Proxmox. Ist sie aus, erst starten:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
ssh alex@192.168.2.10 "ssh root@192.168.2.20 'qm start 100; qm status 100'"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
SSH zur VM läuft **über den GSM-Monitor (.30)** als Jump-Host (dort liegt der passende Key
|
|
|
|
|
`/root/.ssh/id_ed25519`), nicht direkt über den Pi:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
ssh alex@192.168.2.10 "ssh root@192.168.2.30 'ssh root@192.168.2.51 \"BEFEHL\"'"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
> Tipp: Bei mehrfach verschachteltem SSH + komplexen Befehlen die innerste Befehlskette
|
|
|
|
|
> base64-kodieren und remote mit `echo <b64> | base64 -d | bash` ausführen — spart das
|
|
|
|
|
> Quoting-Chaos über drei Shell-Ebenen.
|
|
|
|
|
|
|
|
|
|
## Voraussetzungen auf der VM (bereits erfüllt)
|
|
|
|
|
|
|
|
|
|
- Debian 13, **OpenJDK 21** installiert (`java -version` → 21.x). FTB-Packs ab MC 1.20.5
|
|
|
|
|
brauchen **Java 21**.
|
|
|
|
|
- `screen`, `curl` vorhanden.
|
|
|
|
|
- GSM startet den Server fest mit `cd /opt/minecraft && screen -dmS minecraft ./run.sh`
|
|
|
|
|
(siehe `gsm-backend/services/ssh.js`). **Es wird kein `nogui` angehängt** → die
|
|
|
|
|
`run.sh` des Packs muss `nogui` enthalten (FTB/NeoForge-`run.sh` tut das standardmäßig).
|
|
|
|
|
|
|
|
|
|
## Schritt 1: Pack-ID und Version-ID über die FTB-API ermitteln
|
|
|
|
|
|
|
|
|
|
FTB-Packs haben eine numerische **Pack-ID** (in der FTB-URL, z. B.
|
|
|
|
|
`feed-the-beast.com/modpacks/130-ftb-stoneblock-4` → ID `130`).
|
|
|
|
|
|
|
|
|
|
Alle Versionen + IDs auflisten:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -s https://api.feed-the-beast.com/v1/modpacks/public/modpack/130 | \
|
|
|
|
|
python3 -c 'import sys,json; d=json.load(sys.stdin); print(d["name"]); [print(v["id"], v["name"], v["type"]) for v in d["versions"]]'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Die höchste `release`-Version nehmen (Beispiel StoneBlock 4: Version `1.15.3` =
|
|
|
|
|
Version-ID `100372`, MC `1.21.1`, NeoForge `21.1.233`).
|
|
|
|
|
|
|
|
|
|
## Schritt 2: FTB-Server-Installer herunterladen
|
|
|
|
|
|
|
|
|
|
FTB liefert ein eigenständiges (statisches Go-)Installer-Binary pro Pack/Version:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
https://api.feed-the-beast.com/v1/modpacks/public/modpack/<PACK_ID>/<VERSION_ID>/server/linux
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In ein **frisches** Verzeichnis installieren (altes `/opt/minecraft` bleibt unangetastet,
|
|
|
|
|
bis das neue Pack verifiziert ist):
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
mkdir -p /opt/sb4_new && cd /opt/sb4_new
|
|
|
|
|
curl -fsSL -o serverinstall \
|
|
|
|
|
"https://api.feed-the-beast.com/v1/modpacks/public/modpack/130/100372/server/linux"
|
|
|
|
|
chmod +x serverinstall
|
|
|
|
|
./serverinstall --help # Flags ansehen
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Wichtige Flags: `-auto` (keine Rückfragen), `-force` (nötig, wenn Zielordner nicht leer ist
|
|
|
|
|
— z. B. weil das Installer-Binary schon drinliegt), `-accept-eula`, `-no-java` (System-Java
|
|
|
|
|
21 nutzen statt ein eigenes JRE mitzuinstallieren), `-dir`, `-pack`, `-version`.
|
|
|
|
|
|
|
|
|
|
## Schritt 3: Installer laufen lassen
|
|
|
|
|
|
|
|
|
|
Lädt NeoForge + alle Mods (StoneBlock 4: ~6900 Dateien / 378 Mods, ~1,2 GB). Wegen der
|
|
|
|
|
Laufzeit per `nohup` im Hintergrund starten und das Log pollen:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cd /opt/sb4_new
|
|
|
|
|
nohup ./serverinstall -auto -force -accept-eula -no-java -no-colours \
|
|
|
|
|
-pack 130 -version 100372 -dir /opt/sb4_new > install.log 2>&1 &
|
|
|
|
|
# Fortschritt:
|
|
|
|
|
tr '\r' '\n' < install.log | tail -5
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Erfolg = Logzeilen `SUCCESS: NeoForge installed successfully` und
|
|
|
|
|
`SUCCESS: Modpack installed successfully`. Danach existieren u. a.: `run.sh` (enthält
|
|
|
|
|
`nogui`), `user_jvm_args.txt` (Heap, Default `-Xmx8192M`), `eula.txt` (=true),
|
|
|
|
|
`libraries/`, `mods/`, `config/`, `defaultconfigs/` und eine **`default-server.properties`**
|
|
|
|
|
(Pack-Empfehlung — siehe Stolperfalle unten).
|
|
|
|
|
|
|
|
|
|
## Schritt 4 (WICHTIG): `default-server.properties` korrekt befüllen
|
|
|
|
|
|
|
|
|
|
> ⚠️ **Stolperfalle / der Grund, warum RCON / Whitelist / MOTD beim ersten Start „verschwinden":**
|
|
|
|
|
> StoneBlock 4 (und viele FTB-Packs) bringen den Mod **`default-server-properties`** mit. Der
|
|
|
|
|
> **erzwingt bei *jedem* Serverstart** die Werte aus `default-server.properties` in die
|
|
|
|
|
> `server.properties` und setzt den Rest auf Vanilla-Defaults zurück. Eine selbst geschriebene
|
|
|
|
|
> `server.properties` allein **überlebt den Start daher nicht** — alles außer den in
|
|
|
|
|
> `default-server.properties` gelisteten Keys wird auf Default zurückgesetzt
|
|
|
|
|
> (z. B. `enable-rcon=false`, `motd=A Minecraft Server`, `white-list=false`).
|
|
|
|
|
|
|
|
|
|
Deshalb alle **erzwungenen Betriebs-Settings in `default-server.properties` eintragen** (das
|
|
|
|
|
ist die vom Pack vorgesehene Quelle). Mindestens nötig für GSM-Betrieb:
|
|
|
|
|
|
|
|
|
|
```properties
|
|
|
|
|
# vom Pack vorgegeben (behalten!)
|
|
|
|
|
allow-flight=true
|
|
|
|
|
allow-nether=false
|
|
|
|
|
difficulty=normal
|
|
|
|
|
enable-command-block=true
|
|
|
|
|
generate-structures=true
|
|
|
|
|
level-type=minecraft\:normal
|
|
|
|
|
spawn-protection=512
|
|
|
|
|
# für GSM / Betrieb ergänzen:
|
|
|
|
|
enable-rcon=true
|
|
|
|
|
rcon.port=25575
|
|
|
|
|
rcon.password=gsm-mc-2026
|
|
|
|
|
broadcast-rcon-to-ops=true
|
|
|
|
|
white-list=true
|
|
|
|
|
enforce-whitelist=true
|
|
|
|
|
motd=FTB StoneBlock 4
|
|
|
|
|
server-port=25565
|
|
|
|
|
query.port=25565
|
|
|
|
|
max-players=20
|
|
|
|
|
online-mode=true
|
|
|
|
|
pvp=true
|
|
|
|
|
view-distance=7
|
|
|
|
|
simulation-distance=10
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- **`enable-command-block=true`** ist bei StoneBlock 4 Pflicht — ohne Command-Blöcke
|
|
|
|
|
funktionieren Strukturen/Quests im Pack nicht korrekt (steht so in der CurseForge-Beschreibung
|
|
|
|
|
und ist bereits in der `default-server.properties` des Packs gesetzt).
|
|
|
|
|
- **`rcon.password=gsm-mc-2026`** + **`rcon.port=25575`** müssen mit
|
|
|
|
|
`gsm-backend/config.json` (Server `minecraft`) übereinstimmen, sonst funktionieren
|
|
|
|
|
GSM-Spielerzählung, Konsole und Whitelist-Verwaltung nicht.
|
|
|
|
|
|
|
|
|
|
Zur Sicherheit zusätzlich eine vollständige `server.properties` mit denselben Werten schreiben
|
|
|
|
|
(vermeidet ein kurzes Fenster falscher Werte beim allerersten Start).
|
|
|
|
|
|
|
|
|
|
## Schritt 5: Spieler/Icon übernehmen + Swap
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# bestehende Spieler & Icon übernehmen (gleicher Zugang wie vorher)
|
|
|
|
|
cp /opt/minecraft/whitelist.json /opt/sb4_new/whitelist.json
|
|
|
|
|
cp /opt/minecraft/ops.json /opt/sb4_new/ops.json
|
|
|
|
|
cp /opt/minecraft/server-icon.png /opt/sb4_new/server-icon.png
|
|
|
|
|
|
|
|
|
|
# Swap (altes Pack als Backup behalten)
|
|
|
|
|
screen -S minecraft -X quit 2>/dev/null || true
|
|
|
|
|
mv /opt/minecraft /opt/minecraft_<altespack>_backup
|
|
|
|
|
rm -f /opt/sb4_new/serverinstall /opt/sb4_new/*.log # Installer-Reste
|
|
|
|
|
mv /opt/sb4_new /opt/minecraft
|
|
|
|
|
chmod +x /opt/minecraft/run.sh
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Schritt 6: Starten + verifizieren
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cd /opt/minecraft && screen -dmS minecraft ./run.sh
|
|
|
|
|
# auf "Done (" warten:
|
|
|
|
|
grep 'Done (' logs/latest.log
|
|
|
|
|
# Pflicht-Checks:
|
|
|
|
|
ss -tlnp | grep -E ':25565|:25575' # beide Ports müssen lauschen (25575 = RCON!)
|
|
|
|
|
grep -E '^(enable-rcon|motd|white-list|enable-command-block)' server.properties
|
|
|
|
|
grep -i 'RCON running' logs/latest.log # "RCON running on 0.0.0.0:25575"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Erststart lädt alle Mods + generiert die Welt (StoneBlock 4: „Done" nach ~75 s). Das alte
|
|
|
|
|
Welt-Save ist mit einem neuen Pack **inkompatibel** — es wird eine neue Welt erzeugt.
|
|
|
|
|
|
|
|
|
|
### Bekannte, harmlose Logmeldungen
|
|
|
|
|
|
|
|
|
|
`DataMapLoader ... Object with ID <mod>:<item> ... doesn't exist` (ERROR) und
|
|
|
|
|
`LootJS: Skipping unexpected loot action` (WARN) sind **nicht fatal** — sie kommen so mit dem
|
|
|
|
|
offiziellen Pack (Datamaps referenzieren Items optionaler/umbenannter Mods). Server erreicht
|
|
|
|
|
trotzdem „Done".
|
|
|
|
|
|
|
|
|
|
### RAM
|
|
|
|
|
|
|
|
|
|
VM hat 12 GB (real ~11 GiB nutzbar). Heap in `user_jvm_args.txt`; **8 GB (`-Xmx8192M`)** ist
|
|
|
|
|
ein sicherer Wert mit Headroom fürs OS + Off-Heap. 10 GB Heap auf 11 GiB ist OOM-gefährdet.
|
|
|
|
|
|
|
|
|
|
## Schritt 7: GSM / Discord auf den neuen Namen anpassen
|
|
|
|
|
|
|
|
|
|
Code-Änderungen **nur über Git** (commit → push → CI/CD deployt automatisch). **Niemals per
|
|
|
|
|
SCP!** Anzupassen sind:
|
|
|
|
|
|
|
|
|
|
| Datei | Änderung |
|
|
|
|
|
|-------|----------|
|
|
|
|
|
| `gsm-backend/config.json` | `servers[minecraft].name` → `"<Pack> | Minecraft"` |
|
|
|
|
|
| `gsm-backend/services/discordBot.js` | `serverDisplay.minecraft.name` (+ ggf. `color`) |
|
|
|
|
|
| `gsm-backend/services/serverUpdates.js` | `updateHandlers.minecraft.gameName` |
|
|
|
|
|
| `gsm-frontend/src/components/ServerCard.jsx` | `serverInfo.minecraft.links` (Label + CurseForge-URL) |
|
|
|
|
|
| `docs/infrastructure.md`, `docs/gsm.md`, `CLAUDE.md` | Modpack-Name/Version |
|
|
|
|
|
|
|
|
|
|
> **Discord-Update-Meldung:** Ein Modpack-Wechsel löst **keine** automatische Discord-Meldung
|
|
|
|
|
> aus — `updateHandlers.minecraft.supportsUpdate` ist `false`, und Meldungen werden nur durch
|
|
|
|
|
> `performUpdate()` (manuelle Update-Aktion) oder den internen Endpoint
|
|
|
|
|
> `POST /api/servers/discord/internal-update` versendet. Den Endpoint bei einem Modpack-Wechsel
|
|
|
|
|
> bewusst **nicht** aufrufen, wenn keine „Update"-Benachrichtigung gewünscht ist. Der
|
|
|
|
|
> Status-Embed des Bots zeigt nach dem Deploy einfach den neuen Namen — das ist normale
|
|
|
|
|
> Statusanzeige, keine Update-Benachrichtigung.
|
|
|
|
|
|
|
|
|
|
## Referenz: konkrete Werte StoneBlock 4 (Stand 2026-06)
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|-|-|
|
|
|
|
|
| FTB Pack-ID | `130` |
|
|
|
|
|
| Version | `1.15.3` (Version-ID `100372`) |
|
|
|
|
|
| Minecraft | `1.21.1` |
|
|
|
|
|
| Modloader | NeoForge `21.1.233` |
|
|
|
|
|
| Java | 21 |
|
|
|
|
|
| Heap | `-Xmx8192M` |
|
|
|
|
|
| Pflicht | `enable-command-block=true` |
|