# 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 | 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///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__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 : ... 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` → `" | 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` |