mirror of
https://github.com/Ayymoss/Plutainer
synced 2026-08-24 14:32:06 -04:00
The iw4x-launcher was rewritten (Rust -> C++/build2) and dropped --path.
It now canonicalises /proc/self/exe and treats its own directory as the
installation root, ignoring cwd, so the current invocation fails outright
and the cache marker we probe for never appears.
Run a copy of the binary from inside the volume so the install root is
runtime/gamefiles/. This has to be a real cp, not a symlink: canonical()
would resolve a symlink back to .plutainer/ (an image layer) and the
~800MB of game data would be re-downloaded on every container recreate.
Verified against launcher source rather than observed behaviour:
- launcher.cli no --path in the option list
- launcher.cxx:1064-67 install root == cwd == binary dir
- cache-database.hxx:34-35 cache/iw4x.db, not launcher/cache.json
- cache-reconciler.cxx:888 clean() only prunes its own DB-tracked
files, so our symlinks are safe
Also:
- userraw/ and zone/ become real dirs with host contents symlinked in.
userraw/ is ENGINE_CONFIG_DIR, so a directory symlink to the read-only
mount made link_configs fail under set -e; zone/ has to be writable
for the launcher's zone/patch/*.ff.
- usermaps/ linked so custom maps in playlists resolve.
- Launcher failure is now only fatal on first run, so a GitHub or CDN
outage can't take a working server down.
- PLUTAINER_MAP_ROTATE=false drops the map-rotate arg, which otherwise
overrides playlist-driven map selection. Applied family-wide rather
than iw4x-only, since Plutonium takes the same arg.
Add link_dir_contents() for the real-dir-plus-symlinked-contents pattern;
alterentry.sh's inlined zone/ handling now uses it too.
144 lines
5 KiB
Bash
144 lines
5 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Validate environment, prepare the game-files tree and configs/ symlinks,
|
|
# update Plutonium binaries, then launch the requested Plutonium server.
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
source "$SCRIPT_DIR/game-config.sh"
|
|
|
|
detect_game_type || hold_indefinitely "detect_game_type failed."
|
|
check_volume_version || hold_indefinitely "check_volume_version failed."
|
|
resolve_engine_config_dir
|
|
resolve_mod_config_dir
|
|
resolve_config_layout
|
|
|
|
SOURCE_DIR="$PLUTAINER_SOURCE_DIR"
|
|
DEST_DIR="$PLUTAINER_GAMEFILES_DIR"
|
|
mkdir -p "$DEST_DIR"
|
|
|
|
# --- Step 1: Link Game Files ---
|
|
case "$BASE_GAME" in
|
|
iw5)
|
|
echo "Linking files for iw5 (Modern Warfare 3)..."
|
|
link_files "$SOURCE_DIR" "$DEST_DIR" main miles zone binkw32.dll localization.txt mss32.dll
|
|
;;
|
|
t4)
|
|
echo "Linking files for t4 (World at War)..."
|
|
link_files "$SOURCE_DIR" "$DEST_DIR" zone binkw32.dll localization.txt cod.bmp codlogo.bmp
|
|
mkdir -p "$DEST_DIR/main"
|
|
link_files "$SOURCE_DIR/main" "$DEST_DIR/main" \
|
|
iw_00.iwd iw_14.iwd iw_21.iwd iw_22.iwd iw_24.iwd iw_26.iwd \
|
|
localized_english_iw00.iwd localized_english_iw04.iwd
|
|
;;
|
|
t5)
|
|
echo "Linking files for t5 (Black Ops)..."
|
|
link_files "$SOURCE_DIR" "$DEST_DIR" main zone binkw32.dll localization.txt
|
|
;;
|
|
t6)
|
|
echo "Linking files for t6 (Black Ops II)..."
|
|
link_files "$SOURCE_DIR" "$DEST_DIR" zone binkw32.dll codlogo.bmp
|
|
;;
|
|
*)
|
|
hold_indefinitely "Unknown BASE_GAME value '$BASE_GAME'."
|
|
;;
|
|
esac
|
|
|
|
# --- Step 2: Update Plutonium ---
|
|
mkdir -p "$PLUTAINER_PLUTONIUM_DIR"
|
|
PLUTO_CDN_INFO_LOC="$PLUTAINER_PLUTONIUM_DIR/cdn_info.json"
|
|
if [[ -f "$PLUTO_CDN_INFO_LOC" && "${PLUTAINER_AUTO_UPDATE:-}" == "false" ]]; then
|
|
echo "Skipping Plutonium update because PLUTAINER_AUTO_UPDATE is set to 'false'."
|
|
else
|
|
if [[ -f "$PLUTO_CDN_INFO_LOC" ]]; then
|
|
echo "Checking for Plutonium updates..."
|
|
else
|
|
echo "First container run detected. Downloading Plutonium initial files..."
|
|
fi
|
|
/home/plutainer/.plutainer/plutonium-updater --directory "$PLUTAINER_PLUTONIUM_DIR"
|
|
fi
|
|
|
|
cd "$PLUTAINER_PLUTONIUM_DIR"
|
|
|
|
# --- Step 3a: Auto-lift any user-placed real cfg from engine path ---
|
|
auto_lift_user_config
|
|
|
|
# --- Step 3b: Seed default configs from bundled community repos ---
|
|
if [[ "${PLUTAINER_SKIP_SEED:-}" != "true" ]]; then
|
|
case "$BASE_GAME" in
|
|
t4) seed_configs t4 "$PLUTAINER_GAMEFILES_DIR/main" "" ;;
|
|
iw5) seed_configs iw5 "$PLUTAINER_GAMEFILES_DIR/admin" "" ;;
|
|
t5|t6) seed_configs "$BASE_GAME" "$PLUTAINER_PLUTONIUM_DIR/storage/$BASE_GAME" "" ;;
|
|
esac
|
|
fi
|
|
|
|
# --- Step 4: Fan-out configs/ → engine + mod config dirs ---
|
|
link_configs "$ENGINE_CONFIG_DIR" "$MOD_CONFIG_DIR"
|
|
|
|
# --- Step 5: Validate environment + ensure config file exists ---
|
|
PLUTAINER_SERVER_NAME="${PLUTAINER_SERVER_NAME:-Plutonium Docker Server}"
|
|
VALID_GAMES="iw5mp t4mp t4sp t5mp t5sp t6mp t6zm"
|
|
|
|
if [[ ! " ${VALID_GAMES} " =~ " ${PLUTAINER_GAME} " ]]; then
|
|
hold_indefinitely "Invalid PLUTAINER_GAME for Plutonium: \"${PLUTAINER_GAME}\". Valid: ${VALID_GAMES}"
|
|
fi
|
|
if [[ -z "${PLUTO_SERVER_KEY:-}" ]]; then
|
|
hold_indefinitely "PLUTO_SERVER_KEY is not set. Get a server key from https://platform.plutonium.pw/serverkeys"
|
|
fi
|
|
if [[ -z "${PLUTAINER_CONFIG_FILE:-}" ]]; then
|
|
hold_indefinitely "PLUTAINER_CONFIG_FILE is not set. Specify the filename of your server config (e.g. 'dedicated.cfg')."
|
|
fi
|
|
if ! ensure_config_present; then
|
|
hold_indefinitely "Config file not found. See [ERROR] above."
|
|
fi
|
|
|
|
# --- Step 6: Resolve port ---
|
|
if [[ -z "${PLUTAINER_PORT:-}" ]]; then
|
|
echo "PLUTAINER_PORT not set, using default for ${BASE_GAME}..."
|
|
resolve_default_port "${BASE_GAME}" || hold_indefinitely "Could not resolve default port."
|
|
PLUTAINER_PORT="${DEFAULT_PORT}"
|
|
echo "Default port set to ${PLUTAINER_PORT}"
|
|
fi
|
|
|
|
# --- Step 7: Build Server Command Arguments ---
|
|
declare -a CMD_ARGS=(
|
|
"${PLUTAINER_GAME}"
|
|
"$PLUTAINER_GAMEFILES_DIR"
|
|
-dedicated
|
|
+set key "${PLUTO_SERVER_KEY}"
|
|
+set net_port "${PLUTAINER_PORT}"
|
|
)
|
|
|
|
if [[ "${BASE_GAME}" == "iw5" ]]; then
|
|
CMD_ARGS+=(+set sv_config "${PLUTAINER_CONFIG_FILE}")
|
|
else
|
|
CMD_ARGS+=(+exec "${PLUTAINER_CONFIG_FILE}")
|
|
fi
|
|
|
|
if [[ -n "${PLUTAINER_MOD:-}" ]]; then
|
|
CMD_ARGS+=(+set fs_game "${PLUTAINER_MOD}")
|
|
fi
|
|
if [[ -n "${PLUTO_MAX_CLIENTS:-}" ]]; then
|
|
CMD_ARGS+=(+set sv_maxclients "${PLUTO_MAX_CLIENTS}")
|
|
fi
|
|
if [[ -n "${PLUTAINER_EXTRA_ARGS:-}" ]]; then
|
|
CMD_ARGS+=(${PLUTAINER_EXTRA_ARGS})
|
|
fi
|
|
|
|
# Opt-out: an unconditional map-rotate arg overrides playlist- or cfg-driven
|
|
# map selection. iw5 spells it differently to the rest of the family.
|
|
if [[ "${PLUTAINER_MAP_ROTATE:-true}" != "false" ]]; then
|
|
if [[ "${BASE_GAME}" == "iw5" ]]; then
|
|
CMD_ARGS+=(+start_map_rotate)
|
|
else
|
|
CMD_ARGS+=(+map_rotate)
|
|
fi
|
|
fi
|
|
|
|
# --- Step 8: Launch (with 30s crash throttle) ---
|
|
/home/plutainer/.plutainer/log-watcher.sh &
|
|
|
|
echo "Starting Plutonium ${PLUTAINER_GAME} Server: ${PLUTAINER_SERVER_NAME}"
|
|
echo "EXECUTING: wine bin/plutonium-bootstrapper-win32.exe ${CMD_ARGS[*]}"
|
|
launch_game wine bin/plutonium-bootstrapper-win32.exe "${CMD_ARGS[@]}"
|