#!/usr/bin/env bash # # shellcheck disable=2043 # # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # General Settings # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* export DAYZ_FILES=/mnt/dayz export STOCK_SERVER_DATA="$DAYZ_FILES/stock/DayZServer" export MAIN="/mnt/c/DAYZ" export SERVERS="$MAIN/servers" export CACHE="$MAIN/cache" export MOD_CACHE="$CACHE/mods" export RESTART_INTERVAL=$((60 * 60 * 4 + 3)) # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Helper functions # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* if [ ! "$DEBUG" ] ; then alias do_sync='rsync -rltDhu --delete --partial' alias do_secure_sync='rsync -crltDhu --delete --partial' else alias do_sync='rsync -vrltDhu --delete --partial --progress' alias do_secure_sync='rsync -cvrltDhu --delete --partial --progress' fi msg() { >&2 printf '[*] %s ...\n' "$*" } warn() { >&2 printf '\n\n<<<< WARNING: %s >>>>>\n\n' "$*" } die() { msg "$*" exit 1 } debug() { if [ "$DEBUG" ] ; then >&2 printf ' DEBUG: %s\n' "$*" fi } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Checks # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* check() { mkdir -p "$DAYZ_FILES" if ! mount | grep -i "$DAYZ_FILES" >/dev/null ; then msg "$DAYZ_FILES is not mounted!" echo "hint: mount -t drvfs //truenas.home.weaver/dayz $DAYZ_FILES" exit 1 fi if [ ! -d "$MAIN" ] ; then die "$MAIN does not exist" fi if [ ! -d "$STOCK_SERVER_DATA" ] ; then die "$STOCK_SERVER_DATA does not exist" fi } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Environment Setup # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* init() { mkdir -p "$SERVER_HOME" "$MOD_CACHE/$MAP_FOLDER_NAME" :>"$SERVER_HOME/.modstring" } setup_environment() { msg "Copying stock server data" # list of all stock folders for folder in addons battleye bliss docs dta keys ; do do_sync "$STOCK_SERVER_DATA/$folder"/ "$SERVER_HOME/$folder" || die "Failed to copy stock: $folder" done # list of all stock files for file in ban.txt dayz.gproj dayzsetting.xml serverDZ.cfg whitelist.txt \ DayZServer_x64.exe steam_api64.dll steamclient64.dll tier0_s64.dll vstdlib_s64.dll ; do do_sync "$STOCK_SERVER_DATA/$file" "$SERVER_HOME/$file" || die "Failed to copy stock: $file" done msg "Copying mod files" do_sync "$DAYZ_FILES/mods/$MAP_FOLDER_NAME"/ "$MOD_CACHE/$MAP_FOLDER_NAME" || die "Failed to copy mod files" msg "Copying DZSA executable" do_sync "$DAYZ_FILES/software/DZSALModServer.exe" "$SERVER_HOME/DZSALModServer.exe" } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Load Mods # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* load_mods() { if [ ! -f "$MOD_CACHE/$MAP_FOLDER_NAME/mods.txt" ] ; then die "mods.txt list missing" fi mkdir -p "$SERVER_HOME/mods" _modstring="" while read -r mod ; do case $mod in '@'*) msg "- Found mod: $mod" _modstring="$_modstring;mods/$mod" do_sync "$MOD_CACHE/$MAP_FOLDER_NAME/$mod"/ "$SERVER_HOME/mods/$mod" for addon_folder in addons Addons addon Addon ; 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 do_sync "$addon" "$SERVER_HOME/addons/${addon##*/}" 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 do_sync "$key" "$SERVER_HOME/keys/${key##*/}" fi done fi done esac done < "$MOD_CACHE/$MAP_FOLDER_NAME/mods.txt" # trim the initial leading ';' _modstring=${_modstring#;} printf '%s\n' "$_modstring" > .modstring } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Load Map # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* load_stock_map_data() { msg "Loading stock map data" do_sync --exclude="*storage_1*" \ "$DAYZ_FILES/stock/maps/$MAP_FOLDER_NAME"/ \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME" } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Types Patching # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* patch_types() { if [ ! -f "$DAYZ_FILES/server_configs/types/default_types_to_delete.txt" ] ; then die "CANNOT REACH FILE: default_types_to_delete.txt" fi # deletes while read -r line ; do case "$line" in '#'*|' '*|'') ;; *) debug "TYPES -- deleting object: $line" xmlstarlet ed -L -P -d "//types/type[@name=\"$line\"]" \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/db/types.xml" esac done < "$DAYZ_FILES/server_configs/types/default_types_to_delete.txt" # copy types edit tool if [ -f "$DAYZ_FILES/scripts/adjust_type.sh" ] ; then cp -f "$DAYZ_FILES/scripts/adjust_type.sh" "$SERVER_HOME"/ else die "Could not find adjust_type.sh" fi if [ -f "$DAYZ_FILES/server_configs/types/$MAP_FOLDER_NAME.sh" ] ; then cp -f "$DAYZ_FILES/server_configs/types/$MAP_FOLDER_NAME.sh" \ "$SERVER_HOME"/ cd "$SERVER_HOME" || die "could not cd to $SERVER_HOME" sh "$SERVER_HOME/$MAP_FOLDER_NAME.sh" \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/db/types.xml" || \ die "Failed while running maps types edit script" else warn "Could not find $DAYZ_FILES/server_configs/types/$MAP_FOLDER_NAME.sh" fi } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Configs # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* load_configs() { msg "Loading server configs" if [ -d "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME" ] ; then for xml in "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME"/*.xml ; do if [ -f "$xml" ] ; then debug "Found: $xml -- Copying." do_sync "$xml" "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/${xml##*/}" || \ die "Failed to copy: ${xml##*/}" fi done for json in "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME"/*.json ; do if [ -f "$json" ] ; then debug "Found: $json -- Copying." do_sync "$json" "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/${json##*/}" || \ die "Failed to copy: ${json##*/}" fi done if [ -f "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/init.c" ] ; then debug "Found: init.c -- Copying." do_secure_sync \ "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/init.c" \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/init.c" || \ die "failed to copy init.c" fi if [ -f "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/areaflags.map" ] ; then debug "Found: areaflags.map -- Copying." do_sync \ "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/areaflags.map" \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/areaflags.map" || \ die "failed to copy areaflags.map" fi fi if [ -d "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/db" ] ; then for xml in "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/db"/*.xml ; do if [ -f "$xml" ] ; then debug "Found: $xml -- Copying." do_sync "$xml" "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/db/${xml##*/}" || \ die "Failed to copy: ${xml##*/}" fi done fi if [ -d "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/env" ] ; then for xml in "$DAYZ_FILES/server_configs/mpmissions/$MAP_FOLDER_NAME/env"/*.xml ; do if [ -f "$xml" ] ; then debug "Found: $xml -- Copying." do_sync "$xml" "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/env/${xml##*/}" || \ die "Failed to copy: ${xml##*/}" fi done fi } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Main # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* main() { init cd "$SERVER_HOME" || die "Could not cd to '$SERVER_HOME'" check || die "Failed check" msg "Setting up environment" setup_environment || die "Could not set up environment." msg "Loading mods" load_mods || die "Could not load mods" mod_string=$(cat .modstring) msg "Loading stock map data" load_stock_map_data || die "Could not load map" msg "Patching types.xml" patch_types || die "Failed to patch types" msg "Copying server configs" load_configs || die "Failed to load configs" # msg "Creating custom types list" ############################# echo '====================================' printf '%s - Server started.\n' "$(date)" echo '====================================' # creating temp.bat here to avoid the arg max char limit of windows cmd.exe cat > temp.bat </dev/null ||: msg "Sleeping 10 seconds to settle" sleep 10 msg "SERVER IS RESTARTING" } while msg 'Starting loop' ; do if [ -f ./SERVER.ENV ] ; then . ./SERVER.ENV else die "Could not source ./SERVER.ENV" fi main "$@" done