Files
dayz-servers/start.sh
2022-12-07 23:28:22 -06:00

315 lines
10 KiB
Bash
Executable File

#!/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' "$*"
}
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
}
# -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
# 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
die "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 <<EOF
:start
start "DayZ Server" /min DZSALModServer.exe -config="$SERVER_CONFIG_FILE" -port="$SERVER_PORT" -profiles=Profilesfolder -mod="$mod_string" -cpuCount="$SERVER_CPU" -dologs -adminlog -netlog -freezecheck
EOF
cmd.exe /C temp.bat
printf '\n**** Sleeping for: %s *****\n\n' "$RESTART_INTERVAL"
count=0
while [ "$count" -lt "$RESTART_INTERVAL" ] ; do
sleep 60
count=$((count + 60))
msg "TIME LEFT BEFORE RESTART: $(( (RESTART_INTERVAL - count) / 60 )) minutes"
done
echo "==========================="
msg "Time up"
msg "Killing server"
cmd.exe /C taskkill /im DayZServer_x64.exe /F
rm -f temp.bat 2>/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