#!/bin/sh -ex # # 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" GLOBALS_FILE="$PWD/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 # =================================================== # # # Local server file hierarchy: # # c:/DAYZ # ^--/servers # ^--/cache # export ORIGINAL_DIR="$PWD" export LOCAL_DAYZ_FILES="/mnt/c/DAYZ" export CACHE="$LOCAL_DAYZ_FILES/cache" export STOCK_SERVER_CACHE="$CACHE/stock_server" export MOD_CACHE="$CACHE/mods" export SERVERS="$LOCAL_DAYZ_FILES/servers" # (4 hours, in seconds) ################################# export RESTART_INTERVAL=$((60 * 60 * 4)) # (10 minutes) # export RESTART_INTERVAL=$((10 * 60)) export RESTART_INTERVAL=$((1 * 60)) # =================================================== # 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. init and checks # =================================================== check() { if [ ! -d "$LOCAL_DAYZ_FILES" ] ; then die "dir: $LOCAL_DAYZ_FILES does not exist" fi if [ ! -d "$SERVER_HOME" ] ; then die "dir: $SERVER_HOME does not exist" fi msg "Health checks completed successfully." } init_server() { mkdir -p "$SERVER_HOME" "$CACHE" "$MOD_CACHE" "$STOCK_SERVER_CACHE" "$LOCAL_DAYZ_FILES/stock/maps/$MAP_FOLDER_NAME" :>"$SERVER_HOME/.modstring" check || die "Failed check()" msg "Completed intialization. Using server restart time of $RESTART_INTERVAL seconds." } # =================================================== # 05. Load stock files # =================================================== load_stock_map_data() { mkdir -p "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME" do_sync --exclude='*storage_1*' \ "$LOCAL_DAYZ_FILES/stock/maps/$MAP_FOLDER_NAME"/ \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME" || \ die "Failed to copy remote stock map data to local cache" } refresh_local_cache() { msg "Refreshing local stock server cache" wait_until_remote_server_unlocked do_sync "$REMOTE_STOCK_SERVER"/ "$STOCK_SERVER_CACHE" || \ die "Failed to copy remote stock server data to local cache" msg "Sucessfully copied stock server data into local cache" # ------------------------------------- msg "Refreshing local map data cache for: $MAP_FOLDER_NAME" wait_until_remote_server_unlocked do_sync "$REMOTE_MAPS/$MAP_FOLDER_NAME"/ "$LOCAL_DAYZ_FILES/stock/maps/$MAP_FOLDER_NAME" || \ die "Failed to copy remote stock map data for: $MAP_FOLDER_NAME" msg "Successfully copied stock map data for: $MAP_FOLDER_NAME" # ------------------------------------- msg "Refreshing local mods cache" wait_until_remote_server_unlocked do_sync "$REMOTE_MODS"/ "$MOD_CACHE" || \ die "Failed to copy remote mods to local cache" msg "Successfully copied remote mods into local cache" } setup_environment() { msg "Setting up environment" msg "Copying stock server data from local cache into $SERVER_HOME" # list of all stock server folders for folder in addons battleye bliss docs dta keys ; do do_sync "$STOCK_SERVER_CACHE/$folder"/ "$SERVER_HOME/$folder" || die "Failed to copy stock: $folder" done # list of all stock server files for file in dayz.gproj dayzsetting.xml whitelist.txt \ DayZServer_x64.exe steam_api64.dll steamclient64.dll \ tier0_s64.dll vstdlib_s64.dll ; do cp -fv "$STOCK_SERVER_CACHE/$file" "$SERVER_HOME/$file" || die "Failed to copy stock: $file" done msg "Copying into $SERVER_HOME stock map data for: $MAP_FOLDER_NAME" load_stock_map_data msg "Copying mod files from local cache into $SERVER_HOME" do_sync "$MOD_CACHE/$MAP_FOLDER_NAME"/ "$SERVER_HOME/mods" || die "Failed to copy mods to $SERVER_HOME" msg "Copying DZSA executable" wait_until_remote_server_unlocked do_sync "$REMOTE_DIR/res/software/DZSALModServer.exe" "$SERVER_HOME"/ || \ die "Failed to copy DZSALModServer.exe" } # finds list of mods to load and stores them in .modstring file # to be used as parameters to the server load_mods() { msg "Loading mods" if [ ! -f "$MOD_CACHE/$MAP_FOLDER_NAME/mods.txt" ] ; then die "mods.txt list for $MAP_FOLDER_NAME is missing" fi mkdir -p "$SERVER_HOME/mods" _modstring="" while read -r mod ; do case $mod in '@'*) msg "- Found mod: $mod" _modstring="$_modstring;mods/$mod" # common spelling differences, check for all for addon_folder in addons Addons addon Addon add_ons add_on Add_on Add_ons ; do if [ -d "$SERVER_HOME/mods/$mod/$addon_folder" ] ; then for addon in "$SERVER_HOME/mods/$mod/$addon_folder"/* ; do if [ ! -f "$SERVER_HOME/addons/${addon##*/}" ] ; then cp -f "$addon" "$SERVER_HOME/addons/" fi done fi done for key_folder in keys Keys key Key ; do if [ -d "$SERVER_HOME/mods/$mod/$key_folder" ] ; then for key in "$SERVER_HOME/mods/$mod/$key_folder"/* ; do if [ ! -f "$SERVER_HOME/keys/${key##*/}" ] ; then cp -f "$key" "$SERVER_HOME/keys/" fi done fi done esac done < "$MOD_CACHE/$MAP_FOLDER_NAME/mods.txt" # trim the initial leading ';' _modstring=${_modstring#;} printf '%s\n' "$_modstring" > modstring msg "Mods successfully loaded." } # =================================================== # 06. Start function # =================================================== start_server() { check || die "Failed check()" cd "$SERVER_HOME" || die "Could not cd to '$SERVER_HOME'" wait_until_remote_server_unlocked setup_environment || die "Could not set up environment." load_mods || die "Could not load mods" # ===================================================================================== # creating temp.bat here to avoid the arg max char limit of windows cmd.exe PROCESS_NAME="SERVER: $SERVER_NAME" cat > temp.bat </dev/null ||: msg '%s - Server started.\n' "$(date)" count=0 while [ "$count" -lt "$RESTART_INTERVAL" ] ; do sleep 60 count=$((count + 60)) msg "TIME LEFT BEFORE RESTART: $(( (RESTART_INTERVAL - count) / 60 )) minutes" done msg "Time up - Killing server" cmd.exe /C taskkill /FI "WINDOWTITLE eq $PROCESS_NAME" msg "Sleeping 10 seconds to settle" sleep 10 msg "SERVER IS RESTARTING" } # =================================================== # 07. Main loop # =================================================== main() { cd "$ORIGINAL_DIR" || die "Can no longer cd to $ORIGINAL_DIR" if [ -e ./SERVER.ENV ] ; then . ./SERVER.ENV else die "Could not source ./SERVER.ENV" fi # this must be here and not up top as we must load it from the SERVER.ENV export SERVER_HOME="$SERVERS/$SERVER_NAME" # create directories in $SERVER_HOME # blank the modstring init_server if [ -e ./serverDZ.cfg ] ; then cp -f ./serverDZ.cfg "$SERVER_HOME"/ || die "Failed to copy ./serverDZ into $SERVER_HOME" else die "Could not find ./serverDZ.cfg" fi # sync remote server stock and mod files into local cache refresh_local_cache || die "Failed to refresh local cache." # load stock server, map, mod files into $SERVER_HOME setup_environment || die "Failed to setup environment." # START THE SERVER - RUN ServerDZ.EXE start_server "$@" } main "$@" || exit 1