#!/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 # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # alias do_sync='rsync -rltDh --delete --partial' # 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 whitelist.txt \ DayZServer_x64.exe steam_api64.dll steamclient64.dll tier0_s64.dll vstdlib_s64.dll ; do cp -f "$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" cp -f "$DAYZ_FILES/software/DZSALModServer.exe" "$SERVER_HOME/" } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # 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 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 } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # Load Map # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* load_stock_map_data() { mkdir -p "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME" do_sync --exclude='*storage_1*' \ "$DAYZ_FILES/stock/maps/$MAP_FOLDER_NAME"/ \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME" || \ die "Failed to copy stock map data" } # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* # 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 die "Could not find $DAYZ_FILES/server_configs/types/$MAP_FOLDER_NAME.sh" fi # if we're on namalsk, we will have a types_dzn.xml as well # this file contains the frozen food etc unique namalsk items case $MAP_FOLDER_NAME in *namalsk*) DZN_FILE=namalsk_dzn.sh msg "Patching $DZN_FILE" if [ -f "$DAYZ_FILES/server_configs/types/$DZN_FILE" ] ; then cp -f "$DAYZ_FILES/server_configs/types/$DZN_FILE" \ "$SERVER_HOME"/ cd "$SERVER_HOME" || die "could not cd to $SERVER_HOME" sh "$SERVER_HOME/$DZN_FILE" \ "$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/db/types_dzn.xml" || \ die "Failed while running maps types edit script on types_dzn.xml" else die "Could not find $DAYZ_FILES/server_configs/types/$DZN_FILE" fi ;; esac } load_customtypes() { if [ -d "$DAYZ_FILES/server_configs/types/custom.$MAP_FOLDER_NAME" ] ; then CUSTOM_TYPES="$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/customtypes" CFG_ECORE="$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/cfgeconomycore.xml" mkdir -p "$CUSTOM_TYPES" do_sync "$DAYZ_FILES/server_configs/types/custom.$MAP_FOLDER_NAME"/ \ "$CUSTOM_TYPES" for xml in "$CUSTOM_TYPES"/*.xml ; do debug " - Found custom type: ${xml##*/}" if [ -f "$xml" ] ; then sed -E -i '/<\/economycore>/d' "$CFG_ECORE" printf '\n\n\n\n\n' "${xml##*/}" \ >> "$CFG_ECORE" printf '%s\n' '' >> "$CFG_ECORE" fi done fi # ============== custom SPAWNABLE types =================== if [ -d "$DAYZ_FILES/server_configs/types/spawnabletypes.$MAP_FOLDER_NAME" ] ; then msg "Copying custom spawnable types" CUSTOM_SPAWNABLE_TYPES="$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/spawnabletypes" CFG_SPAWNABLE_TYPES="$SERVER_HOME/mpmissions/$MAP_FOLDER_NAME/cfgspawnabletypes.xml" mkdir -p "$CUSTOM_SPAWNABLE_TYPES" do_sync "$DAYZ_FILES/server_configs/types/spawnabletypes.$MAP_FOLDER_NAME"/ \ "$CUSTOM_SPAWNABLE_TYPES" for xml in "$CUSTOM_SPAWNABLE_TYPES"/*.xml ; do debug " - Found custom spawnabletype: ${xml##*/}" if [ -f "$xml" ] ; then sed -E -i '/<\/spawnabletypes>/d' "$CFG_SPAWNABLE_TYPES" cat "$xml" >> "$CFG_SPAWNABLE_TYPES" printf '%s\n' '' >> "$CFG_SPAWNABLE_TYPES" fi done 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_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 msg "Copying generic Profilesfolder configs" if [ -d "$DAYZ_FILES/server_configs/Profilesfolder/sUDE/config" ] ; then mkdir -p "$SERVER_HOME/Profilesfolder/sUDE/config" cp -f "$DAYZ_FILES/server_configs/Profilesfolder/sUDE/config"/* "$SERVER_HOME/Profilesfolder/sUDE/config"/ else die "missing: $DAYZ_FILES/server_configs/Profilesfolder/sUDE/config" 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" load_customtypes || die "Failed to load custom types" 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" } ORIGINAL_DIR="$PWD" while msg 'Starting loop' ; do 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 if [ -f ./serverDZ.cfg ] ; then cp -f ./serverDZ.cfg "$SERVER_HOME"/ else die "Could not find ./serverDZ.cfg" fi main "$@" done