#!/bin/sh # Puts the mod stack on top of the Valve game files in hlds/. setup.sh runs this inside the # image after every game download/update (a Steam "validate" puts Valve's engine back and # silently removes ReHLDS + Metamod, so this always has to run after it). # Safe to run again. Kept as they are on re-runs: maps, stats, bot navigation graphs, and your # edits to users.ini (admins), amxx.cfg, csdm/config.ini, mapcycle.txt and custom.cfg. # Mounts (see setup.sh): repo at /cs/repo (read-only) with dl/ writable, hlds at /cs/hlds. set -e R=/cs/repo; DL=$R/dl; H=/cs/hlds; C=$H/cstrike; A=$C/addons; CF=$C/addons/amxmodx/configs X=$(mktemp -d) trap 'rm -rf "$X"' EXIT step() { printf ' - %s\n' "$*"; } die() { printf '\033[31merror:\033[0m %s\n' "$*" >&2; exit 1; } sha() { sha256sum < "$1" | cut -c1-64; } [ -x $H/hlds_linux ] || die "no game files in hlds/ (the Steam download didn't finish)" step "downloads (pinned, checked against tools/versions.txt)" mkdir -p $DL/gg $DL/snd $DL/spawns MIRROR=$(sed -n 's/^#mirror //p' $R/tools/versions.txt | tr -d '\r') grep -v '^#' $R/tools/versions.txt | while read -r f sum url; do [ -n "$f" ] || continue [ -f "$DL/$f" ] && [ "$(sha "$DL/$f")" = "$sum" ] && continue # main site first; if that fails, the backup copy on the project's Gitea (same checksum check) curl -fsSL --retry 3 -o "$DL/$f.part" "$url" || { [ -n "$MIRROR" ] && echo " $f: main site failed, trying the backup copy" && curl -fsSL --retry 2 -o "$DL/$f.part" "$MIRROR${f##*/}"; } || die "download failed: $url" got=$(sha "$DL/$f.part") [ "$got" = "$sum" ] || { rm -f "$DL/$f.part"; die "checksum mismatch for $f: expected $sum, got $got"; } mv "$DL/$f.part" "$DL/$f" done ls $DL/rehlds-bin-*.zip >/dev/null # Game mode in use right now (re-run) or from .env (first install) if [ -f $CF/plugins-gungame.ini ]; then MODE=gg elif [ -f $CF/plugins-CSDM_ReAPI.ini ] || [ -f $CF/plugins-CSDM_ReAPI.ini.off ]; then MODE=dm else MODE=${CS_MODE:-dm}; fi case "$MODE" in dm|gg) ;; *) die "CS_MODE must be dm or gg (is: $MODE)" ;; esac # Files people edit: save them now, put them back after the archives are unpacked FIRST=; [ -f $C/.cs16-dm-server ] || FIRST=1 KEEP="addons/amxmodx/configs/users.ini addons/amxmodx/configs/amxx.cfg addons/amxmodx/configs/csdm/config.ini" if [ -z "$FIRST" ]; then for f in $KEEP; do [ -f "$C/$f" ] && mkdir -p "$X/keep/$(dirname "$f")" && cp -p "$C/$f" "$X/keep/$f"; done fi step "ReHLDS (engine)" unzip -qo $DL/rehlds-bin-3.15.0.896.zip 'bin/linux32/*' -d $X/rehlds cp -a $X/rehlds/bin/linux32/. $H/ chmod +x $H/hlds_linux $H/hltv # the zip has no exec bits step "ReGameDLL (game logic)" unzip -qo $DL/regamedll-bin-5.30.0.814.zip 'bin/linux32/cstrike/*' -d $X/regame cp -a $X/regame/bin/linux32/cstrike/. $C/ # game.cfg runs at every map start and would force alltalk off: server.cfg decides that instead sed -i 's|^sv_alltalk "0"|// sv_alltalk "0" // cs16-dm-server: set in server.cfg instead|' $C/game.cfg step "Metamod-R" unzip -qo $DL/metamod-bin-1.3.0.149.zip 'addons/*' -d $X/mm cp -a $X/mm/addons/. $A/ [ -f $C/liblist.gam.orig ] || cp $C/liblist.gam $C/liblist.gam.orig sed -i 's|^gamedll_linux .*|gamedll_linux "addons/metamod/metamod_i386.so"|' $C/liblist.gam step "AMX Mod X + ReAPI" tar xzf $DL/amxmodx-1.10.0-git5486-base-linux.tar.gz -C $C tar xzf $DL/amxmodx-1.10.0-git5486-cstrike-linux.tar.gz -C $C unzip -qo $DL/reapi-bin-5.29.0.358.zip 'addons/*' -d $X/reapi cp -a $X/reapi/addons/. $A/ step "ReUnion (non-Steam clients)" unzip -qo $DL/reunion-0.2.0.25.zip bin/Linux/reunion_mm_i386.so reunion.cfg -d $X/reu mkdir -p $A/reunion cp $X/reu/bin/Linux/reunion_mm_i386.so $A/reunion/ SALT=$(tr -d '\r\n' < /cs/secrets/reunion-salt.txt) [ -n "$SALT" ] || die "secrets/reunion-salt.txt is empty" # IDClientsLimit 0: several non-Steam players with the same placeholder ID can all join ( umask 077; sed -e "s|^SteamIdHashSalt =.*|SteamIdHashSalt = $SALT|" -e 's|^IDClientsLimit = .*|IDClientsLimit = 0|' \ $X/reu/reunion.cfg > $C/reunion.cfg ) step "CSDM-ReAPI (deathmatch) + spawn points" unzip -qo $DL/CSDM-ReAPI-v1.0.8.zip 'cstrike/*' -d $X/csdm cp -a $X/csdm/cstrike/. $C/ mkdir -p $CF/csdm/spawns for f in $DL/spawns/*.spawns.cfg; do b=$(basename "$f") # old 6-field lines (de_prodigy, de_train) -> the 10 fields CSDM-ReAPI reads (others are skipped) awk 'NF==6 {print $0" 0 0 0 0"; next} {print}' "$f" > $CF/csdm/spawns/$b ln -sfn spawns/$b $CF/csdm/$b # GunGame looks for them one folder up done step "YaPB (bots)" tar xJf $DL/yapb-4.4.957-linux.tar.xz -C $C find $A/yapb -type d -exec chmod 775 {} + # the tarball's dirs have no x bit sed -i -e 's/^yb_csdm_mode ".*"/yb_csdm_mode "2"/' -e 's/^yb_quota_mode ".*"/yb_quota_mode "fill"/' \ $A/yapb/conf/yapb.cfg # FFA-aware bots; quota = fill up to CS_BOTS players (start.sh sets it) step "GunGame + announcer sounds" cp $DL/gg/gungame.sma $A/amxmodx/scripting/ cp $DL/gg/gungame.txt $A/amxmodx/data/lang/ mkdir -p $C/sound/gungame $C/sound/misc cp $DL/gg/*.wav $C/sound/gungame/ cp $DL/snd/*.wav $C/sound/misc/ step "configs from the repo" cp -a $R/cstrike/. $C/ if [ -n "$FIRST" ]; then cp $R/defaults/mapcycle.txt $C/mapcycle.txt fi [ -f $C/custom.cfg ] || cp $R/defaults/custom.cfg $C/custom.cfg if [ -z "$FIRST" ] && [ -d $X/keep ]; then cp -a $X/keep/. $C/; fi step "compiling plugins" cp $R/plugins/*.sma $A/amxmodx/scripting/ cd $A/amxmodx/scripting for p in rtv esef_extras esef_mode gungame; do ./amxxpc $p.sma -o../plugins/$p.amxx > $X/$p.log 2>&1 || { cat $X/$p.log; die "compiling $p.sma failed"; } done cd - >/dev/null step "game mode: $MODE" # exactly one of the two plugin lists is active (.ini), the other one is .ini.off for ini in plugins-gungame.ini plugins-CSDM_ReAPI.ini; do [ -f $CF/$ini ] && rm -f $CF/$ini.off # fresh copy from the archive/repo wins [ -f $CF/$ini ] || mv $CF/$ini.off $CF/$ini done if [ "$MODE" = gg ]; then mv $CF/plugins-CSDM_ReAPI.ini $CF/plugins-CSDM_ReAPI.ini.off else mv $CF/plugins-gungame.ini $CF/plugins-gungame.ini.off; fi # hlds looks for steamclient.so here; without it: "Unable to initialize Steam" mkdir -p /cs/steamcmd-home/.steam/sdk32 ln -sfn /cs/hlds/steamclient.so /cs/steamcmd-home/.steam/sdk32/steamclient.so touch $C/.cs16-dm-server echo " mod stack installed"