This commit is contained in:
Frank Harris 2026-06-09 10:18:46 -05:00
parent ce75f055fe
commit c00f584109

View file

@ -0,0 +1,125 @@
#!/usr/bin/env bash
set -u
MANIFEST="${1:-}"
if [ -z "$MANIFEST" ] || [ ! -f "$MANIFEST" ]; then
echo "ERROR: Workshop manifest missing: $MANIFEST"
exit 2
fi
MANIFEST_DIR="$(dirname "$MANIFEST")"
LOG="$MANIFEST_DIR/workshop_install.log"
touch "$LOG"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"
}
json_value() {
local key="$1"
KEY="$key" MANIFEST_FILE="$MANIFEST" perl -0777 -e '
my $k = $ENV{"KEY"};
my $f = $ENV{"MANIFEST_FILE"};
open my $fh, "<", $f or exit 1;
local $/;
my $json = <$fh>;
if ($json =~ /"\Q$k\E"\s*:\s*"([^"]*)"/s) {
my $v = $1;
$v =~ s/\\\//\//g;
print $v;
exit 0;
}
if ($json =~ /"\Q$k\E"\s*:\s*([0-9]+)/s) {
print $1;
exit 0;
}
exit 0;
'
}
json_items() {
perl -0777 -ne '
if (/"items"\s*:\s*\[(.*?)\]/s) {
my $x = $1;
while ($x =~ /"([0-9]{3,20})"/g) { print "$1\n"; }
while ($x =~ /(?<![0-9])([0-9]{3,20})(?![0-9])/g) { print "$1\n"; }
}
' "$MANIFEST" | awk '!seen[$0]++'
}
ACTION="$(json_value action)"
APPID="$(json_value workshop_app_id)"
STEAM_APPID="$(json_value steam_app_id)"
SERVER_PATH="$(json_value server_path)"
[ -z "$ACTION" ] && ACTION="install"
[ -z "$APPID" ] && APPID="$STEAM_APPID"
[ -z "$SERVER_PATH" ] && SERVER_PATH="$(pwd)"
if [ -z "$APPID" ]; then
log "ERROR: workshop_app_id missing from manifest."
echo "Manifest debug:"
sed -n '1,80p' "$MANIFEST"
exit 3
fi
ITEMS="$(json_items)"
if [ -z "$ITEMS" ]; then
log "ERROR: no Workshop item IDs found in manifest."
echo "Manifest debug:"
sed -n '1,80p' "$MANIFEST"
exit 4
fi
find_steamcmd() {
for c in "${STEAMCMD_PATH:-}" steamcmd steamcmd.sh steamcmd.exe \
/OGP/steamcmd/steamcmd.exe /OGP/steamcmd/steamcmd.sh \
"$SERVER_PATH/steamcmd/steamcmd.exe" "$SERVER_PATH/steamcmd/steamcmd.sh" \
/home/gameserver/steamcmd/steamcmd.sh "$HOME/steamcmd/steamcmd.sh" "$HOME/steamcmd/steamcmd.exe"
do
[ -z "$c" ] && continue
if command -v "$c" >/dev/null 2>&1; then command -v "$c"; return 0; fi
if [ -f "$c" ]; then echo "$c"; return 0; fi
done
return 1
}
log "GSP Workshop job starting. action=$ACTION appid=$APPID server_path=$SERVER_PATH"
if [ "$ACTION" = "remove" ]; then
for id in $ITEMS; do
log "Removing Workshop item files for $id if present."
rm -rf "$SERVER_PATH/@$id" "$SERVER_PATH/workshop/@$id" "$SERVER_PATH/steamapps/workshop/content/$APPID/$id"
done
log "Remove job complete."
exit 0
fi
STEAMCMD="$(find_steamcmd)" || {
log "ERROR: steamcmd was not found. Install SteamCMD on the agent host or set STEAMCMD_PATH."
exit 127
}
RUNSCRIPT="$MANIFEST_DIR/steamcmd_workshop_$$.txt"
{
echo "@ShutdownOnFailedCommand 0"
echo "@NoPromptForPassword 1"
echo "login anonymous"
echo "force_install_dir $SERVER_PATH"
for id in $ITEMS; do
echo "workshop_download_item $APPID $id validate"
done
echo "quit"
} > "$RUNSCRIPT"
log "Using SteamCMD: $STEAMCMD"
log "Running SteamCMD runscript: $RUNSCRIPT"
"$STEAMCMD" +runscript "$RUNSCRIPT" 2>&1 | tee -a "$LOG"
rc=${PIPESTATUS[0]}
if [ "$rc" -ne 0 ]; then
log "ERROR: SteamCMD failed with exit $rc"
exit "$rc"
fi
for id in $ITEMS; do
SRC="$SERVER_PATH/steamapps/workshop/content/$APPID/$id"
DST="$SERVER_PATH/@$id"
if [ ! -d "$SRC" ]; then
log "ERROR: downloaded Workshop source not found: $SRC"
exit 5
fi
log "Installing Workshop item $id to $DST"
rm -rf "$DST"
cp -a "$SRC" "$DST"
if [ -d "$DST/keys" ]; then
mkdir -p "$SERVER_PATH/keys"
find "$DST/keys" -type f -iname '*.bikey' -exec cp -f {} "$SERVER_PATH/keys/" \;
fi
done
log "Workshop job complete."
exit 0