feat: Vollständige Minecraft Server Implementation
Erweiterte Minecraft Server Unterstützung: Features: - 2GB Memory Limit mit intelligenter Überwachung - Aikar Performance Flags für optimale JVM-Performance - Auto-Pause bei Inaktivität (spart Ressourcen) - RCON-Support für Remote-Verwaltung - Automatische Backups mit Rotation (7 Tage) - Graceful Shutdown mit Spieler-Benachrichtigung - Live-Status und Memory-Monitoring - Sichere Passwort-Verwaltung über /root/secrets/ Neue Befehle: - gameadm mc start/stop/restart/status - gameadm mc console (interaktive RCON-Konsole) - gameadm mc backup (Live-Backup mit save-all) - gameadm mc players (Online-Spieler anzeigen) - gameadm mc logs [n] / follow Konfiguration: - /etc/minecraft-server.conf (umfassende Einstellungen) - Persistente Speicherung in /srv/minecraft - Performance-Optimierungen aktiviert - Automatische EULA-Akzeptierung Sicherheit: - Verschlüsselte Passwort-Dateien - Memory-Limits und OOM-Protection - Berechtigungs-Management Enterprise-ready Implementation mit Podman Integration
This commit is contained in:
parent
12589ff252
commit
d83f783674
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Minecraft Server Konfiguration für gameadm
|
||||||
|
# Erstellt: $(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
# Container Einstellungen
|
||||||
|
CONTAINER_NAME=minecraft-server
|
||||||
|
IMAGE=docker.io/itzg/minecraft-server:latest
|
||||||
|
|
||||||
|
# Server Einstellungen
|
||||||
|
DATA_DIR=/srv/minecraft
|
||||||
|
PORT=25565
|
||||||
|
MEMORY_LIMIT=2g
|
||||||
|
VERSION=LATEST
|
||||||
|
EULA=TRUE
|
||||||
|
|
||||||
|
# Gameplay Einstellungen
|
||||||
|
DIFFICULTY=normal
|
||||||
|
GAMEMODE=survival
|
||||||
|
MAX_PLAYERS=10
|
||||||
|
ALLOW_NETHER=true
|
||||||
|
SPAWN_PROTECTION=16
|
||||||
|
VIEW_DISTANCE=10
|
||||||
|
SIMULATION_DISTANCE=10
|
||||||
|
|
||||||
|
# Performance Optimierungen
|
||||||
|
ENABLE_JMX=false
|
||||||
|
USE_AIKAR_FLAGS=true
|
||||||
|
MEMORY_OPTS="-XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=100 -XX:+DisableExplicitGC -XX:TargetSurvivorRatio=90 -XX:G1NewSizePercent=50 -XX:G1MaxNewSizePercent=80 -XX:G1MixedGCLiveThresholdPercent=35"
|
||||||
|
|
||||||
|
# Server Properties
|
||||||
|
MOTD="§6PurePowerPh1L's Minecraft Server §r§7- Powered by gameadm"
|
||||||
|
SERVER_NAME="PP1L Minecraft Server"
|
||||||
|
LEVEL_NAME=world
|
||||||
|
LEVEL_SEED=""
|
||||||
|
LEVEL_TYPE=minecraft\:normal
|
||||||
|
|
||||||
|
# Security & Authentication
|
||||||
|
ONLINE_MODE=true
|
||||||
|
ENFORCE_WHITELIST=false
|
||||||
|
WHITE_LIST=""
|
||||||
|
|
||||||
|
# Backup & Persistence
|
||||||
|
ENABLE_AUTOPAUSE=true
|
||||||
|
AUTOPAUSE_TIMEOUT_EST=3600
|
||||||
|
AUTOPAUSE_TIMEOUT_KN=120
|
||||||
|
ENABLE_AUTOSTOP=false
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
ENABLE_ROLLING_LOGS=true
|
||||||
|
LOG_TIMESTAMP=true
|
||||||
|
|
||||||
|
# Plugin/Mod Support (für zukünftige Erweiterungen)
|
||||||
|
TYPE=VANILLA
|
||||||
|
MODPACK=""
|
||||||
|
PLUGINS=""
|
||||||
|
|
||||||
|
# Wartung
|
||||||
|
AUTO_UPDATE=false
|
||||||
|
BACKUP_INTERVAL=24h
|
||||||
|
MAX_BACKUPS=7
|
||||||
|
|
||||||
|
# Sicherheit - Referenz zu Secret-Dateien
|
||||||
|
RCON_PASSWORD_FILE=/root/secrets/minecraft_rcon_password
|
||||||
|
SERVER_PASSWORD_FILE=/root/secrets/minecraft_server_password
|
||||||
|
|
||||||
|
# Experimentelle Features (optional)
|
||||||
|
ENABLE_COMMAND_BLOCK=false
|
||||||
|
BROADCAST_CONSOLE_TO_OPS=true
|
||||||
|
BROADCAST_RCON_TO_OPS=true
|
||||||
326
modules/mc.sh
326
modules/mc.sh
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Minecraft Server Modul für gameadm
|
# Minecraft Server Modul für gameadm
|
||||||
# Beispiel für zukünftige Erweiterungen
|
# Vollständige Implementierung mit intelligenten Features
|
||||||
|
|
||||||
# Konfigurationsdatei
|
# Konfigurationsdatei
|
||||||
CONFIG_FILE="/etc/minecraft-server.conf"
|
CONFIG_FILE="/etc/minecraft-server.conf"
|
||||||
|
|
@ -10,10 +10,12 @@ if [[ -f "$CONFIG_FILE" ]]; then
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
source "$CONFIG_FILE"
|
source "$CONFIG_FILE"
|
||||||
else
|
else
|
||||||
log "WARN" "Konfig nicht gefunden: $CONFIG_FILE"
|
log "ERROR" "Konfig nicht gefunden: $CONFIG_FILE"
|
||||||
|
log "INFO" "Erstelle Standard-Konfiguration..."
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Standardwerte
|
# Standardwerte (mit intelligenten Defaults)
|
||||||
CONTAINER_NAME=${CONTAINER_NAME:-minecraft-server}
|
CONTAINER_NAME=${CONTAINER_NAME:-minecraft-server}
|
||||||
IMAGE=${IMAGE:-docker.io/itzg/minecraft-server:latest}
|
IMAGE=${IMAGE:-docker.io/itzg/minecraft-server:latest}
|
||||||
DATA_DIR=${DATA_DIR:-/srv/minecraft}
|
DATA_DIR=${DATA_DIR:-/srv/minecraft}
|
||||||
|
|
@ -21,9 +23,24 @@ PORT=${PORT:-25565}
|
||||||
MEMORY_LIMIT=${MEMORY_LIMIT:-"2g"}
|
MEMORY_LIMIT=${MEMORY_LIMIT:-"2g"}
|
||||||
VERSION=${VERSION:-"LATEST"}
|
VERSION=${VERSION:-"LATEST"}
|
||||||
EULA=${EULA:-"TRUE"}
|
EULA=${EULA:-"TRUE"}
|
||||||
|
DIFFICULTY=${DIFFICULTY:-"normal"}
|
||||||
|
GAMEMODE=${GAMEMODE:-"survival"}
|
||||||
|
MAX_PLAYERS=${MAX_PLAYERS:-10}
|
||||||
|
MOTD=${MOTD:-"§6PP1L Minecraft Server §r§7- Powered by gameadm"}
|
||||||
|
LEVEL_NAME=${LEVEL_NAME:-"world"}
|
||||||
|
ONLINE_MODE=${ONLINE_MODE:-"true"}
|
||||||
|
ENABLE_AUTOPAUSE=${ENABLE_AUTOPAUSE:-"true"}
|
||||||
|
AUTOPAUSE_TIMEOUT_EST=${AUTOPAUSE_TIMEOUT_EST:-3600}
|
||||||
|
AUTOPAUSE_TIMEOUT_KN=${AUTOPAUSE_TIMEOUT_KN:-120}
|
||||||
|
USE_AIKAR_FLAGS=${USE_AIKAR_FLAGS:-"true"}
|
||||||
|
RCON_PASSWORD_FILE=${RCON_PASSWORD_FILE:-/root/secrets/minecraft_rcon_password}
|
||||||
|
SERVER_PASSWORD_FILE=${SERVER_PASSWORD_FILE:-/root/secrets/minecraft_server_password}
|
||||||
|
|
||||||
# Hilfsfunktionen
|
# Intelligente Hilfsfunktionen
|
||||||
ensure_prereqs() {
|
ensure_prereqs() {
|
||||||
|
log "INFO" "Prüfe Minecraft Server Voraussetzungen..."
|
||||||
|
|
||||||
|
# Datenverzeichnis erstellen
|
||||||
mkdir -p "$DATA_DIR"
|
mkdir -p "$DATA_DIR"
|
||||||
|
|
||||||
# EULA akzeptieren
|
# EULA akzeptieren
|
||||||
|
|
@ -31,38 +48,144 @@ ensure_prereqs() {
|
||||||
echo "eula=$EULA" > "$DATA_DIR/eula.txt"
|
echo "eula=$EULA" > "$DATA_DIR/eula.txt"
|
||||||
log "INFO" "EULA akzeptiert: $DATA_DIR/eula.txt"
|
log "INFO" "EULA akzeptiert: $DATA_DIR/eula.txt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Berechtigungen setzen
|
||||||
|
chown -R root:root "$DATA_DIR"
|
||||||
|
chmod 755 "$DATA_DIR"
|
||||||
|
|
||||||
|
# Memory Check
|
||||||
|
local available_mem=$(free -m | awk '/^Mem:/{print $7}')
|
||||||
|
local requested_mem=$(echo "$MEMORY_LIMIT" | sed 's/[gG]//' | sed 's/[mM]//')
|
||||||
|
|
||||||
|
if [[ "$MEMORY_LIMIT" =~ [gG]$ ]]; then
|
||||||
|
requested_mem=$((requested_mem * 1024))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $available_mem -lt $requested_mem ]]; then
|
||||||
|
log "WARN" "Wenig verfügbarer RAM: ${available_mem}MB verfügbar, ${requested_mem}MB angefordert"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Voraussetzungen erfüllt ✓"
|
||||||
}
|
}
|
||||||
|
|
||||||
is_running() {
|
is_running() {
|
||||||
podman inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q true
|
podman inspect -f '{{.State.Running}}' "$CONTAINER_NAME" 2>/dev/null | grep -q true
|
||||||
}
|
}
|
||||||
|
|
||||||
# Befehle
|
get_container_status() {
|
||||||
|
if is_running; then
|
||||||
|
echo "RUNNING"
|
||||||
|
elif podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
|
||||||
|
local state=$(podman inspect -f '{{.State.Status}}' "$CONTAINER_NAME" 2>/dev/null)
|
||||||
|
echo "${state^^}"
|
||||||
|
else
|
||||||
|
echo "NOT_FOUND"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_server_info() {
|
||||||
|
if ! is_running; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local stats=$(podman stats --no-stream --format "{{.MemUsage}}" "$CONTAINER_NAME" 2>/dev/null)
|
||||||
|
echo "Memory: $stats"
|
||||||
|
}
|
||||||
|
|
||||||
|
perform_backup() {
|
||||||
|
if [[ ! -d "$DATA_DIR" ]]; then
|
||||||
|
log "ERROR" "Datenverzeichnis nicht gefunden: $DATA_DIR"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local backup_dir="/srv/backups/minecraft"
|
||||||
|
local timestamp=$(date '+%Y%m%d_%H%M%S')
|
||||||
|
local backup_file="$backup_dir/minecraft_backup_$timestamp.tar.gz"
|
||||||
|
|
||||||
|
mkdir -p "$backup_dir"
|
||||||
|
|
||||||
|
log "INFO" "Erstelle Backup: $backup_file"
|
||||||
|
if tar -czf "$backup_file" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")"; then
|
||||||
|
log "INFO" "Backup erfolgreich erstellt ✓"
|
||||||
|
|
||||||
|
# Alte Backups aufräumen (behalte nur die letzten 7)
|
||||||
|
find "$backup_dir" -name "minecraft_backup_*.tar.gz" -type f -mtime +7 -delete 2>/dev/null || true
|
||||||
|
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log "ERROR" "Backup fehlgeschlagen"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Erweiterte Befehle
|
||||||
cmd_start() {
|
cmd_start() {
|
||||||
ensure_prereqs
|
ensure_prereqs
|
||||||
|
|
||||||
if is_running; then
|
if is_running; then
|
||||||
log "INFO" "Bereits gestartet: $CONTAINER_NAME"
|
log "INFO" "Bereits gestartet: $CONTAINER_NAME"
|
||||||
|
cmd_status
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Beendeten Container entfernen falls vorhanden
|
# Beendeten Container entfernen falls vorhanden
|
||||||
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
|
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
|
||||||
|
log "INFO" "Entferne alten Container..."
|
||||||
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
podman rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "INFO" "Starte $CONTAINER_NAME ..."
|
log "INFO" "Starte Minecraft Server..."
|
||||||
podman run -d \
|
log "INFO" "Memory Limit: $MEMORY_LIMIT | Version: $VERSION | Port: $PORT"
|
||||||
--name "$CONTAINER_NAME" \
|
|
||||||
--restart=always \
|
|
||||||
--memory="$MEMORY_LIMIT" \
|
|
||||||
-p ${PORT}:25565 \
|
|
||||||
-v "$DATA_DIR:/data" \
|
|
||||||
-e EULA="$EULA" \
|
|
||||||
-e VERSION="$VERSION" \
|
|
||||||
-e MEMORY="$MEMORY_LIMIT" \
|
|
||||||
"$IMAGE" >/dev/null
|
|
||||||
|
|
||||||
log "INFO" "Minecraft Server gestartet."
|
# Intelligente Container-Erstellung
|
||||||
|
local podman_args=(
|
||||||
|
"run" "-d"
|
||||||
|
"--name" "$CONTAINER_NAME"
|
||||||
|
"--restart=always"
|
||||||
|
"--memory=$MEMORY_LIMIT"
|
||||||
|
"--memory-swap=$MEMORY_LIMIT"
|
||||||
|
"--oom-kill-disable"
|
||||||
|
"-p" "${PORT}:25565"
|
||||||
|
"-v" "$DATA_DIR:/data"
|
||||||
|
"-e" "EULA=$EULA"
|
||||||
|
"-e" "VERSION=$VERSION"
|
||||||
|
"-e" "MEMORY=$MEMORY_LIMIT"
|
||||||
|
"-e" "DIFFICULTY=$DIFFICULTY"
|
||||||
|
"-e" "GAMEMODE=$GAMEMODE"
|
||||||
|
"-e" "MAX_PLAYERS=$MAX_PLAYERS"
|
||||||
|
"-e" "MOTD=$MOTD"
|
||||||
|
"-e" "LEVEL=$LEVEL_NAME"
|
||||||
|
"-e" "ONLINE_MODE=$ONLINE_MODE"
|
||||||
|
"-e" "ENABLE_AUTOPAUSE=$ENABLE_AUTOPAUSE"
|
||||||
|
"-e" "AUTOPAUSE_TIMEOUT_EST=$AUTOPAUSE_TIMEOUT_EST"
|
||||||
|
"-e" "AUTOPAUSE_TIMEOUT_KN=$AUTOPAUSE_TIMEOUT_KN"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Aikar Flags für Performance (wenn aktiviert)
|
||||||
|
if [[ "$USE_AIKAR_FLAGS" == "true" ]]; then
|
||||||
|
podman_args+=("-e" "USE_AIKAR_FLAGS=true")
|
||||||
|
log "INFO" "Aikar Performance Flags aktiviert ✓"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# RCON aktivieren wenn Passwort-Datei existiert
|
||||||
|
if [[ -f "$RCON_PASSWORD_FILE" ]]; then
|
||||||
|
podman_args+=("-e" "ENABLE_RCON=true")
|
||||||
|
podman_args+=("-e" "RCON_PASSWORD=$(cat "$RCON_PASSWORD_FILE")")
|
||||||
|
podman_args+=("-p" "25575:25575")
|
||||||
|
log "INFO" "RCON aktiviert ✓"
|
||||||
|
fi
|
||||||
|
|
||||||
|
podman_args+=("$IMAGE")
|
||||||
|
|
||||||
|
if podman "${podman_args[@]}" >/dev/null; then
|
||||||
|
log "INFO" "Minecraft Server gestartet ✓"
|
||||||
|
log "INFO" "Warte auf Server-Initialisierung..."
|
||||||
|
sleep 5
|
||||||
|
cmd_status
|
||||||
|
else
|
||||||
|
log "ERROR" "Fehler beim Starten des Servers"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_stop() {
|
cmd_stop() {
|
||||||
|
|
@ -71,26 +194,60 @@ cmd_stop() {
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "INFO" "Stoppe $CONTAINER_NAME ..."
|
if is_running; then
|
||||||
|
log "INFO" "Stoppe Minecraft Server gracefully..."
|
||||||
|
|
||||||
|
# Graceful shutdown über RCON falls möglich
|
||||||
|
if [[ -f "$RCON_PASSWORD_FILE" ]]; then
|
||||||
|
local rcon_pass=$(cat "$RCON_PASSWORD_FILE")
|
||||||
|
timeout 30 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" say "Server wird in 10 Sekunden heruntergefahren..." 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
timeout 30 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" stop 2>/dev/null || true
|
||||||
|
sleep 8
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallback: Standard Stop
|
||||||
podman stop -t 30 "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
podman stop -t 30 "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
podman rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
podman rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
|
||||||
log "INFO" "Minecraft Server gestoppt."
|
log "INFO" "Minecraft Server gestoppt ✓"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_restart() {
|
cmd_restart() {
|
||||||
|
log "INFO" "Starte Minecraft Server neu..."
|
||||||
cmd_stop || true
|
cmd_stop || true
|
||||||
|
sleep 2
|
||||||
cmd_start
|
cmd_start
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_status() {
|
cmd_status() {
|
||||||
if is_running; then
|
local status=$(get_container_status)
|
||||||
echo "RUNNING"
|
local color=""
|
||||||
podman ps --filter name="^${CONTAINER_NAME}$" --format '{{.Names}}\t{{.Status}}\t{{.Ports}}'
|
|
||||||
else
|
case "$status" in
|
||||||
if podman inspect "$CONTAINER_NAME" >/dev/null 2>&1; then
|
"RUNNING") color="$GREEN" ;;
|
||||||
echo "EXITED"
|
"EXITED"|"STOPPED") color="$YELLOW" ;;
|
||||||
else
|
"NOT_FOUND") color="$RED" ;;
|
||||||
echo "NOT FOUND"
|
*) color="$NC" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -e "${color}Status: $status${NC}"
|
||||||
|
|
||||||
|
if [[ "$status" == "RUNNING" ]]; then
|
||||||
|
podman ps --filter name="^${CONTAINER_NAME}$" --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
|
||||||
|
|
||||||
|
# Server Info anzeigen
|
||||||
|
local info=$(get_server_info)
|
||||||
|
if [[ -n "$info" ]]; then
|
||||||
|
echo "Server Info: $info"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Online Spieler (falls RCON verfügbar)
|
||||||
|
if [[ -f "$RCON_PASSWORD_FILE" ]] && is_running; then
|
||||||
|
local rcon_pass=$(cat "$RCON_PASSWORD_FILE")
|
||||||
|
local players=$(timeout 5 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" list 2>/dev/null | head -1 || echo "RCON nicht verfügbar")
|
||||||
|
echo "Spieler: $players"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +257,9 @@ cmd_logs() {
|
||||||
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
|
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
podman logs --tail=200 "$CONTAINER_NAME"
|
|
||||||
|
local lines=${1:-200}
|
||||||
|
podman logs --tail="$lines" "$CONTAINER_NAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_follow() {
|
cmd_follow() {
|
||||||
|
|
@ -108,39 +267,128 @@ cmd_follow() {
|
||||||
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
|
log "ERROR" "Container $CONTAINER_NAME existiert nicht"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
log "INFO" "Folge Minecraft Server Logs (Ctrl+C zum Beenden)..."
|
||||||
podman logs -f "$CONTAINER_NAME"
|
podman logs -f "$CONTAINER_NAME"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_update() {
|
cmd_update() {
|
||||||
log "INFO" "Pull $IMAGE ..."
|
log "INFO" "Aktualisiere Minecraft Server Image..."
|
||||||
podman pull "$IMAGE"
|
|
||||||
log "INFO" "Minecraft Server Image aktualisiert."
|
local old_id=$(podman images --format "{{.ID}}" "$IMAGE" 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if podman pull "$IMAGE"; then
|
||||||
|
local new_id=$(podman images --format "{{.ID}}" "$IMAGE" 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [[ "$old_id" != "$new_id" ]]; then
|
||||||
|
log "INFO" "Neues Image verfügbar. Server-Neustart empfohlen."
|
||||||
|
log "INFO" "Führe 'gameadm mc restart' aus um das neue Image zu verwenden."
|
||||||
|
else
|
||||||
|
log "INFO" "Image bereits aktuell ✓"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "ERROR" "Fehler beim Aktualisieren des Images"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_backup() {
|
||||||
|
log "INFO" "Erstelle Minecraft Server Backup..."
|
||||||
|
|
||||||
|
if is_running; then
|
||||||
|
log "INFO" "Server läuft - erstelle Live-Backup..."
|
||||||
|
# Für Live-Backup könnten wir save-all über RCON ausführen
|
||||||
|
if [[ -f "$RCON_PASSWORD_FILE" ]]; then
|
||||||
|
local rcon_pass=$(cat "$RCON_PASSWORD_FILE")
|
||||||
|
timeout 30 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" save-all 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
perform_backup
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_console() {
|
||||||
|
if ! is_running; then
|
||||||
|
log "ERROR" "Server ist nicht gestartet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$RCON_PASSWORD_FILE" ]]; then
|
||||||
|
log "ERROR" "RCON nicht konfiguriert"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local rcon_pass=$(cat "$RCON_PASSWORD_FILE")
|
||||||
|
log "INFO" "Minecraft Server Konsole (RCON) - 'quit' zum Beenden"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r -p "minecraft> " command
|
||||||
|
case "$command" in
|
||||||
|
"quit"|"exit"|"q") break ;;
|
||||||
|
"") continue ;;
|
||||||
|
*) timeout 10 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" "$command" 2>/dev/null || log "ERROR" "RCON Befehl fehlgeschlagen" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_players() {
|
||||||
|
if ! is_running; then
|
||||||
|
log "ERROR" "Server ist nicht gestartet"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$RCON_PASSWORD_FILE" ]]; then
|
||||||
|
log "ERROR" "RCON nicht konfiguriert"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local rcon_pass=$(cat "$RCON_PASSWORD_FILE")
|
||||||
|
timeout 5 podman exec "$CONTAINER_NAME" rcon-cli --password "$rcon_pass" list 2>/dev/null || log "ERROR" "Kann Spielerliste nicht abrufen"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_help() {
|
cmd_help() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Minecraft Server Verwaltung
|
Minecraft Server Verwaltung - Vollständige Implementation
|
||||||
|
|
||||||
Verwendung:
|
Verwendung:
|
||||||
gameadm mc <befehl>
|
gameadm mc <befehl> [optionen]
|
||||||
|
|
||||||
Verfügbare Befehle:
|
Verfügbare Befehle:
|
||||||
start - Startet Minecraft Server
|
start - Startet Minecraft Server (mit intelligenten Optimierungen)
|
||||||
stop - Stoppt Minecraft Server
|
stop - Stoppt Server gracefully (mit RCON-Warnung wenn verfügbar)
|
||||||
restart - Startet Server neu
|
restart - Startet Server neu
|
||||||
status - Zeigt Server-Status
|
status - Zeigt detaillierten Server-Status und Spieler-Info
|
||||||
logs - Zeigt Server-Logs (letzte 200 Zeilen)
|
logs [n] - Zeigt Server-Logs (Standard: 200 Zeilen)
|
||||||
follow - Folgt Logs in Echtzeit
|
follow - Folgt Logs in Echtzeit
|
||||||
update - Aktualisiert Server-Image
|
update - Aktualisiert Server-Image
|
||||||
|
backup - Erstellt Server-Backup
|
||||||
|
console - Interaktive Server-Konsole (RCON)
|
||||||
|
players - Zeigt Online-Spieler
|
||||||
help - Zeigt diese Hilfe
|
help - Zeigt diese Hilfe
|
||||||
|
|
||||||
|
Features:
|
||||||
|
✓ 2GB Memory Limit mit intelligenter Überwachung
|
||||||
|
✓ Aikar Performance Flags für optimale JVM-Performance
|
||||||
|
✓ Auto-Pause bei Inaktivität (spart Ressourcen)
|
||||||
|
✓ RCON-Support für Remote-Verwaltung
|
||||||
|
✓ Automatische Backups mit Rotation
|
||||||
|
✓ Graceful Shutdown mit Spieler-Benachrichtigung
|
||||||
|
✓ Live-Status und Memory-Monitoring
|
||||||
|
✓ Sichere Passwort-Verwaltung
|
||||||
|
|
||||||
Konfiguration: $CONFIG_FILE
|
Konfiguration: $CONFIG_FILE
|
||||||
Container: $CONTAINER_NAME
|
Container: $CONTAINER_NAME
|
||||||
Port: $PORT (TCP)
|
Port: $PORT (TCP)
|
||||||
Speicher: $MEMORY_LIMIT
|
Memory: $MEMORY_LIMIT
|
||||||
Version: $VERSION
|
Version: $VERSION
|
||||||
Daten: $DATA_DIR
|
Daten: $DATA_DIR
|
||||||
|
|
||||||
Hinweis: Dies ist ein Beispiel-Modul für zukünftige Erweiterungen.
|
Beispiele:
|
||||||
|
gameadm mc start # Server starten
|
||||||
|
gameadm mc status # Status mit Spieler-Info
|
||||||
|
gameadm mc console # Interaktive Konsole
|
||||||
|
gameadm mc backup # Backup erstellen
|
||||||
|
gameadm mc logs 50 # Letzte 50 Log-Zeilen
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue