Files
dayz-servers/modserver_update.sh
2023-11-29 07:11:56 -06:00

306 lines
8.8 KiB
Bash

#!/bin/sh -e
#
# 01. "should check code directly not $?"
# shellcheck disable=2181
#
# 02. "can't follow . import"
# shellcheck disable=1090,1091
#
# 03. "possible misspelling"
# shellcheck disable=2153
#
# 04. "use find .. over ls"
# shellcheck disable=2011
# -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# ===================================================
# 01. Attempt to load global DayZ values
# ===================================================
echo "Starting, attempting to load globals.sh"
# if we are called externally by one of the servers,
# the command will be "~/dayz-servers/modserver_update.sh"
# we need to change from $PWD to accomodate for that
export WORKING_DIR=$PWD
if [ ! -d "$WORKING_DIR"/lib ] ; then
export WORKING_DIR="$HOME/dayz-servers"
if [ ! -d "$WORKING_DIR"/lib ] ; then
>&2 echo "Could not find lib. Exiting"
exit 1
fi
fi
# grab fresh copy of all helper scripts / libraries
if [ -d "$WORKING_DIR/lib" ] ; then
cp -f "$WORKING_DIR/lib"/* .
fi
GLOBALS_FILE="$WORKING_DIR/globals.sh"
if [ -e "$GLOBALS_FILE" ] ; then
chmod +x "$GLOBALS_FILE"
. "$GLOBALS_FILE"
else
>&2 echo "Could not load: $GLOBALS_FILE"
exit 1
fi
# ===================================================
# 02. Local script variables
# ===================================================
export STEAMCMD_USER=steam
export MODLISTS="$WORKING_DIR/modlists"
export LOCAL_STOCK="$HOME/stock"
export LOCAL_STOCK_GAME="$LOCAL_STOCK/DayZ"
export LOCAL_STOCK_SERVER="$LOCAL_STOCK/DayZServer"
export LOCAL_MODS="$HOME/mods"
# ===================================================
# 03. Mount network drive
# ===================================================
if ! is_network_drive_mounted ; then
mount_dayz_network_drive
if ! is_network_drive_mounted ; then
die "Could not mount network drive"
fi
fi
# ===================================================
# 04. Checks
# ===================================================
check() {
mkdir -p "$LOCAL_STOCK_GAME" "$LOCAL_STOCK_SERVER" "$LOCAL_MODS"
if [ "$USER" != "$STEAMCMD_USER" ] ; then
die "Current user: '$USER' does not match '$STEAMCMD_USER'"
fi
if [ ! -d "$MODLISTS" ] ; then
die "Could not find modlists at: $MODLISTS"
fi
if [ ! -d "$REMOTE_MODS" ] ; then
die "Could not find remote mods at: $REMOTE_MODS"
fi
if [ ! -d "$REMOTE_MAPS" ] ; then
die "Could not find remote maps at: $REMOTE_MAPS"
fi
if islocked_remote_server ; then
die "Remote server already locked?"
fi
msg "(MODSERVER): Health checks passed successfully."
}
# ===================================================
# 05. Begin functions
# ===================================================
update_server() {
msg "(MODSERVER): STARTING UPDATING DAYZ SERVER"
steamcmd -tcp \
+force_install_dir "$LOCAL_STOCK_SERVER" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
+app_update "$DAYZ_SERVER_ID" \
+quit
is_network_drive_mounted &&
do_sync "$LOCAL_STOCK_SERVER"/ "$REMOTE_STOCK_SERVER"
msg "(MODSERVER): FINISHED UPDATING DAYZ SERVER"
}
update_game() {
msg "(MODSERVER): STARTING UPDATING DAYZ GAME"
steamcmd -tcp \
+force_install_dir "$LOCAL_STOCK_GAME" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
+app_update "$DAYZ_GAME_ID" \
+quit
is_network_drive_mounted &&
do_sync "$LOCAL_STOCK_GAME"/ "$REMOTE_STOCK_GAME"
msg "(MODSERVER): FINISHED UPDATING DAYZ GAME"
}
# args: $1 = server_modlist.txt to update
update_mods_for_server() {
msg "(MODSERVER): UPDATING MODS FOR MAP: $1"
mods_file="$MODLISTS/$1"
map_name=${1%.txt}
remote_map_mod_dir="$REMOTE_MODS/$map_name"
mkdir -p "$remote_map_mod_dir"
# Create temporary file to list all the mod_id's we are
# going to download. This speeds up steamcmd and avoids rate limits.
tempfile="/tmp/$map_name-mods_to_download.txt"
:> "$tempfile"
# load the server_modlist.txt, copying the mod id's we need to update
# to the temp file, while skipping comments and blank lines
#
# format should be: "mod_id^nickname"
#
# # Dabs Framework
# # https://steamcommunity.com/sharedfiles/filedetails/?id=2545327648
# 2545327648^dabsframework
#
while read -r mod ; do
case "$mod" in
\#*|''|' ')
;;
*)
mod=${mod%%^*}
# check validity of syntax
if [ -z "$mod" ] ; then
die "mod for $map_name appears to be empty - syntax error"
fi
printf "+workshop_download_item $DAYZ_GAME_ID %s\n" "$mod" >> "$tempfile"
esac
done <"$mods_file"
unset mod
# shellcheck disable=2046
steamcmd \
-tcp \
+force_install_dir "$LOCAL_MODS" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
$(xargs < "$tempfile") \
+quit
if [ $? -ne 0 ] ; then
die "Problem downloading mods for $map_name"
fi
msg "(MODSERVER): RENAMING MODS"
# blank map's mods.txt
:> "$remote_map_mod_dir/mods.txt"
while read -r mod ; do
# skip comments, blank lines
case "$mod" in
\#*|''|' ')
;;
*)
mod_id=${mod%%^*}
mod_name=${mod##*^}
if [ ! -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id" ] ; then
die "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id does not exist"
fi
do_sync "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$mod_id"/ "$remote_map_mod_dir/@${mod_name}"
printf '@%s\n' "$mod_name" >> "$remote_map_mod_dir/mods.txt"
msg "(MODSERVER): Finished syncing: $mod_name"
esac
done < "$mods_file"
rm -f "$tempfile" 2>/dev/null ||:
unset tempfile mod map_name mods_file mod_name mod_id remote_map_mod_dir
msg "(MODSERVER): FINISHED UPDATING MODS FOR MAP: $1"
}
update_stock_maps() {
msg "(MODSERVER): UPDATING MAPS"
msg "(MODSERVER): Copying Stock Chernarus"
do_sync \
"$LOCAL_STOCK_SERVER/mpmissions/$CHERNARUS_MAP_NAME"/ \
"$REMOTE_MAPS/$CHERNARUS_MAP_NAME"
msg "(MODSERVER): Updating Namalsk Survival"
steamcmd \
-tcp \
+force_install_dir "$LOCAL_MODS" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
+workshop_download_item \
"$DAYZ_GAME_ID" \
"$NAMALSK_SURVIVAL_MOD_ID" \
+quit
if [ $? -ne 0 ] ; then
die "Failed to update Namalsk Survival"
fi
if [ -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$NAMALSK_SURVIVAL_MOD_ID/Extras/Regular/$NAMALSK_MAP_NAME" ] ; then
do_sync "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$NAMALSK_SURVIVAL_MOD_ID/Extras/Regular/$NAMALSK_MAP_NAME"/ \
"$REMOTE_MAPS/$NAMALSK_MAP_NAME" || \
die "failed to copy Namalsk map files"
fi
msg "(MODSERVER): Updating Namalsk Island"
steamcmd \
-tcp \
+force_install_dir "$LOCAL_MODS" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
+workshop_download_item \
"$DAYZ_GAME_ID" \
"$NAMALSK_ISLAND_MOD_ID" \
+quit
if [ $? -ne 0 ] ; then
die "Failed to update Namalsk Island"
fi
####################TODO: # msg "Updating Optimized Namalsk Server PBOs"
msg "(MODSERVER): Updating TakistanPlus"
steamcmd \
-tcp \
+force_install_dir "$LOCAL_MODS" \
+@sSteamCmdForcePlatformType windows \
+@ShutdownOnFailedCommand 1 \
+login "$STEAM_USER" \
+workshop_download_item \
"$DAYZ_GAME_ID" \
"$TAKISTAN_MOD_ID" \
+quit
if [ $? -ne 0 ] ; then
die "Failed to update TakistanPlus"
fi
if [ -d "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$TAKISTAN_MOD_ID/Mission/$TAKISTAN_MAP_NAME" ] ; then
do_sync "$LOCAL_MODS/steamapps/workshop/content/$DAYZ_GAME_ID/$TAKISTAN_MOD_ID/Mission/$TAKISTAN_MAP_NAME"/ \
"$REMOTE_MAPS/$TAKISTAN_MAP_NAME" || \
die "failed to copy Takistan map files"
fi
}
main() {
check || die "Failed to pass health checks"
lock_remote_server
update_server
update_game
update_stock_maps
for server in $(ls "$MODLISTS" | xargs) ; do
if [ ! -f "$MODLISTS/$server" ] ; then
msg "(MODSERVER): Could not find modlist for: $MODLISTS/$server"
continue
fi
update_mods_for_server "$server"
unset server
done
unlock_remote_server
}
main "$@" || exit 1