#!/bin/bash
# panel-native RuneScape: Dragonwilds entrypoint.
#
# Contract:
#   /game       — SteamCMD-installed Linux build of Dragonwilds Dedicated
#                 Server (app 4019830). Populated by the panel's SteamCMD
#                 updater sidecar.
#   /game-saves — RSDragonwilds/Saved/ config + save tree + logs.

set -euo pipefail

log() { printf '[panel-dragonwilds] %s\n' "$*"; }

# ----- stage 1: root-only bootstrap -----
if [[ "$(id -u)" = "0" ]]; then
  chown -R panel:panel /game /game-saves /home/panel 2>/dev/null || true
  log "dropping privileges to panel (UID 1000)"
  exec setpriv --reuid=panel --regid=panel --clear-groups \
       --inh-caps=-all --bounding-set=-all \
       env \
         HOME=/home/panel \
         SERVER_NAME="${SERVER_NAME:-panel Dragonwilds}" \
         SERVER_PORT="${SERVER_PORT:-7777}" \
         OWNER_ID="${OWNER_ID:-}" \
         ADMIN_PASSWORD="${ADMIN_PASSWORD:-}" \
         DEFAULT_WORLD_NAME="${DEFAULT_WORLD_NAME:-Gielinor}" \
         PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
       /entrypoint.sh "$@"
fi

GAME_DIR=/game
SAVE_DIR=/game-saves

# --- locate the launcher wrapper ---
# Jagex ships RSDragonwildsServer.sh at the install root; it execs the
# UE5 shipping binary under RSDragonwilds/Binaries/Linux/.
LAUNCHER="${GAME_DIR}/RSDragonwildsServer.sh"
FALLBACK="${GAME_DIR}/RSDragonwilds/Binaries/Linux/RSDragonwildsServer-Linux-Shipping"
if [[ ! -x "${LAUNCHER}" && ! -x "${FALLBACK}" ]]; then
  log "ERROR: ${LAUNCHER} not found or not executable."
  log "       Run 'Update' on this server in the panel — that launches a"
  log "       SteamCMD sidecar which installs Dragonwilds (app 4019830)"
  log "       for Linux into this volume via +@sSteamCmdForcePlatformType linux."
  exit 78   # EX_CONFIG
fi

# --- persist RSDragonwilds/Saved into /game-saves ---
# UE5 writes config + save data under <game>/RSDragonwilds/Saved/. Move
# it into the save volume on first discovery and symlink back so SteamCMD
# validate can't wipe world data. Idempotent on re-boot.
mkdir -p "${SAVE_DIR}/RSDragonwilds" "${GAME_DIR}/RSDragonwilds"
if [[ -d "${GAME_DIR}/RSDragonwilds/Saved" && ! -L "${GAME_DIR}/RSDragonwilds/Saved" ]]; then
  if [[ ! -d "${SAVE_DIR}/RSDragonwilds/Saved" ]]; then
    mv "${GAME_DIR}/RSDragonwilds/Saved" "${SAVE_DIR}/RSDragonwilds/Saved"
  else
    rm -rf "${GAME_DIR}/RSDragonwilds/Saved"
  fi
fi
mkdir -p "${SAVE_DIR}/RSDragonwilds/Saved/Config/LinuxServer"
ln -sfn "${SAVE_DIR}/RSDragonwilds/Saved" "${GAME_DIR}/RSDragonwilds/Saved"

# --- seed DedicatedServer.ini from env on first boot ---
# Jagex requires OwnerId + Server Name + Default World Name + Admin Password
# to be set. Observed behavior on 0.11: Dragonwilds overwrites an absent
# DedicatedServer.ini on first boot with its OWN random-generated values
# under the `[/Script/Dominion.DedicatedServerSettings]` section ("Dominion"
# is the internal UE5 project name). So the best we can do for first-boot
# seeding is to pre-write the file — if it exists the server reads it and
# leaves it. We only touch the file when it doesn't already exist.
INI="${SAVE_DIR}/RSDragonwilds/Saved/Config/LinuxServer/DedicatedServer.ini"
if [[ ! -s "${INI}" ]]; then
  log "seeding DedicatedServer.ini (first boot)"
  cat > "${INI}" <<EOF
;METADATA=(Diff=true, UseCommands=true)
[SectionsToSave]
bCanSaveAllSections=true

[/Script/Dominion.DedicatedServerSettings]
ServerName=${SERVER_NAME}
DefaultWorldName=${DEFAULT_WORLD_NAME}
OwnerId=${OWNER_ID}
AdminPassword=${ADMIN_PASSWORD}
WorldPassword=
EOF
fi

# Mirror logs to the bind-mounted logs dir for external access.
mkdir -p "${SAVE_DIR}/logs"

cd "${GAME_DIR}"
log "starting RuneScape: Dragonwilds dedicated server"
log "  name:        ${SERVER_NAME}"
log "  default world: ${DEFAULT_WORLD_NAME}"
log "  owner id:    ${OWNER_ID:-(unset — server will refuse logins)}"
log "  admin pw:    ${ADMIN_PASSWORD:+<set>}"
log "  port:        ${SERVER_PORT}/udp"

trap 'log "SIGTERM received; stopping server"; kill -TERM "${SRV_PID:-0}" 2>/dev/null || true; wait "${SRV_PID:-0}" 2>/dev/null || true; exit 0' TERM INT

# Use the Jagex-shipped launcher when present; otherwise exec the shipping
# binary directly. `-log` routes UE5 output to stdout. Drop `-NewConsole`
# (Windows-only; harmless but noisy on Linux).
if [[ -x "${LAUNCHER}" ]]; then
  exec stdbuf -oL -eL "${LAUNCHER}" -log "-Port=${SERVER_PORT}" &
else
  exec stdbuf -oL -eL "${FALLBACK}" -log "-Port=${SERVER_PORT}" &
fi
SRV_PID=$!
wait "${SRV_PID}"
