Files
dbledeez 295eb22826 panel public release
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 01:26:41 -07:00

110 lines
4.4 KiB
Bash

#!/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}"