#!/bin/bash ############################################# ### THIS IS WORK IN PROGRESS! ### DayZ Standalone linuxserver script ### maintained by thelastnoc, fork of linuxgsm ### contribute as you like ############################################# version=26 appid=1042420 dayz_id=221100 #stable=223350 #exp_branch=1042420 if [ "${ansi}" != "off" ]; then # echo colors default="\e[0m" red="\e[31m" green="\e[32m" yellow="\e[33m" lightyellow="\e[93m" blue="\e[34m" lightblue="\e[94m" magenta="\e[35m" cyan="\e[36m" # carriage return & erase to end of line creeol="\r\033[K" fi fn_checkroot_dayz(){ if [ "$(whoami)" == "root" ]; then printf "[ ${red}FAIL${default} ] ${yellow}Do NOT run this script as root!\n" printf "\tSwitch to the dayz user!${default}\n" exit 1 fi } fn_loadconfig_dayz(){ source /files/default.cfg # Handle adding the server name from the environment to the serverFZ.cfg file. if [ ! -f ${HOME}/serverfiles/serverDZ.cfg ] then cp /files/serverDZ.cfg "${HOME}/serverfiles/serverDZ.cfg" sed -i "${HOME}/serverfiles/serverDZ.cfg" -e "s/SERVER_NAME/${SERVER_NAME}/" fi # Set a random RCON password, unless one's set in the environment if [ ! -f "${HOME}/serverfiles/battleye/beserver_x64.cfg" ] then echo -n "Creating Battle Eye RCON file " cp /files/beserver_x64.cfg "${HOME}/serverfiles/battleye/beserver_x64.cfg" if [[ ${RCON_PASSWORD} != "" ]] then echo "using the RCON_PASSWORD in the environment." else RCON_PASSWORD=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10) echo -e "using random RCON password ${yellow}${RCON_PASSWORD}" fi sed -i "${HOME}/serverfiles/battleye/beserver_x64.cfg" -e "s/RCON_PASSWORD/${RCON_PASSWORD}/" fi # # default config # if [ ! -f "${HOME}/.default.cfg" ]; then # wget -P ${HOME}/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/.default.cfg # fi # source ${HOME}/.default.cfg # # script config # if [ ! -f "${HOME}/.dayzserver.cfg" ] || [ "$(grep dayzparameter ${HOME}/.dayzserver.cfg)" == "" ]; then # cp ${HOME}/.default.cfg ${HOME}/.dayzserver.cfg # fi # source ${HOME}/.dayzserver.cfg # hostname/servername # if [ ! -f "${HOME}/serverfiles/serverDZ.cfg" ]; then # wget -P ${HOME}/serverfiles/ -q https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/serverDZ.cfg # fi # defaultservername=$(grep -rwi ${HOME}/serverfiles/serverDZ.cfg -e 'EXAMPLE NAME') # if [ "${defaultservername}" != "" ]; then # printf "[ ${magenta}SERVER${default} ] Servername is set on default! 'EXAMPLE NAME'\n\n" # read -p "Enter a new Servername: " servername # sed -i "/hostname/ s/EXAMPLE NAME/${servername}/" "${HOME}/serverfiles/serverDZ.cfg" # fi # # battleye config and rconpassword setup # if [ ! -f "${HOME}/serverfiles/battleye/beserver_x64.cfg" ]; then # wget -P ${HOME}/serverfiles/battleye/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/beserver_x64.cfg # passwd=$(openssl rand -base64 8 | tr -dc 'A-Za-z0-9') # if [ "${passwd}" == "" ]; then # passwd=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c10) # fi # if [ "${passwd}" == "" ]; then # printf "[ ${red}FAIL${default} ] Could not generate a passwort for RCON!\nOpen the Battleye config with './dayzserver cfg' and enter '3' to open it." # exit 1 # else # sed -i "/RConPassword/ s/CHANGEME/${passwd}/" "${HOME}/serverfiles/battleye/beserver_x64.cfg" # printf "[ ${cyan}INFO${default} ] ${yellow}New " # grep RConPassword ${HOME}/serverfiles/battleye/beserver_x64.cfg # printf "${default}" # fi # fi # # workshop # if [ ! -f "${HOME}/.workshop.cfg" ]; then # wget -P ${HOME}/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/.workshop.cfg # fi } fn_status_dayz(){ dayzstatus=$(tmux list-sessions -F $(whoami)-tmux 2> /dev/null | grep -Ecx $(whoami)-tmux) } fn_start_dayz(){ # fn_status_dayz # if [ "${dayzstatus}" == "1" ]; then # printf "[ ${yellow}DayZ${default} ] Server already running.\n" # exit 1 # else printf "[ ${green}DayZ${default} ] Starting server...\n" # sleep 0.5 fn_loadconfig_dayz # sleep 0.5 cd ${HOME}/serverfiles ./DayZServer $dayzparameter "$workshop" || ( echo echo -e "${yellow}========================================== error.log ==========================================" find /home/user -name error.log -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== script*.log ========================================" find /home/user -name "script*.log" -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== *.RPT ==============================================" find /home/user -name "*.RPT" -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== End crash log ======================================" ) # tmux new-session -d -x 23 -y 80 -s $(whoami)-tmux ./DayZServer $dayzparameter "$workshop" # sleep 1 # cd ${HOME} # date > ${HOME}/.dayzlockfile # fi } fn_stop_dayz(){ fn_status_dayz if [ "${dayzstatus}" == "1" ]; then printf "[ ${magenta}...${default} ] Stopping Server graceful." # waits up to 60 seconds giving the server time to shutdown gracefuly for seconds in {1..60}; do fn_status_dayz if [ "${dayzstatus}" == "0" ]; then printf "\r[ ${green}OK${default} ] Stopping Server graceful.\n" rm -f ${HOME}/.dayzlockfile break fi printf "\r[ ${magenta}...${default} ] Stopping Server graceful: ${seconds} seconds" tmux send-keys C-c -t $(whoami)-tmux > /dev/null 2>&1 sleep 1 done fn_status_dayz if [ "${dayzstatus}" != "0" ]; then printf "\n[ ${red}FAIL${default} ] Stopping Server graceful failed. Stop Signal.\n" sleep 2 rm -f ${HOME}/.dayzlockfile tmux kill-session -t $(whoami)-tmux #killall -u $(whoami) fi else printf "[ ${yellow}DayZ${default} ] Server not running.\n" fi } fn_restart_dayz(){ fn_stop_dayz sleep 1 fn_start_dayz } fn_monitor_dayz(){ if [ ! -f ".dayzlockupdate" ]; then fn_status_dayz if [ "${dayzstatus}" == "0" ] && [ -f "${HOME}/.dayzlockfile" ]; then fn_restart_dayz elif [ "${dayzstatus}" != "0" ] && [ -f "${HOME}/.dayzlockfile" ]; then printf "[ ${lightblue}INFO${default} ] Server should be online!\n" else printf "[ ${yellow}INFO${default} ] Don't use monitor to start the server. Use the start command.\n" fi else printf "[ ${yellow}INFO${default} ] Serverfiles being updated\n." fi } fn_console_dayz(){ printf "[${yellow} Warning ${default}] Press \"CTRL+b\" then \"d\" to exit console.\n Do NOT press CTRL+c to exit.\n\n" sleep 0.1 while true; do read -e -i "Y" -p "Continue? [Y/n] " -r answer case "${answer}" in [Yy]|[Yy][Ee][Ss]) tmux a -t $(whoami)-tmux return 0;; [Nn]|[Nn][Oo]) return 1 ;; *) echo "Please answer yes or no." ;; esac done } fn_steamlogin_dayz(){ if [ ! -f "${HOME}/.steamlogin" ]; then wget -P ${HOME}/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/.steamlogin fi source ${HOME}/.steamlogin if [ "${steamlogin}" == "" ]; then printf "\n[ ${magenta}STEAM${default} ] " read -p "Please type in your Steamlogin (username): " steamname sleep 0.5 sed -i "/steamlogin/ s/=/=$steamname/" ${HOME}/.steamlogin sleep 0.5 source ${HOME}/.steamlogin fi } fn_install_dayz(){ if [ ! -f "${HOME}/steamcmd/steamcmd.sh" ]; then mkdir ${HOME}/steamcmd &> /dev/null curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxf - -C steamcmd printf "[ ${yellow}STEAM${default} ] Steamcmd installed\n" else printf "[ ${lightblue}STEAM${default} ] Steamcmd already installed\n" fi if [ ! -f "${HOME}/serverfiles/DayZServer" ]; then mkdir ${HOME}/serverfiles &> /dev/null mkdir ${HOME}/serverprofile &> /dev/null printf "[ ${yellow}DayZ${default} ] Downloading DayZ Server-Files!\n" fn_steamlogin_dayz fn_runvalidate_dayz else printf "[ ${lightblue}DayZ${default} ] The Server is already installed.\n" fn_opt_usage fi } fn_runupdate_dayz(){ fn_loadconfig_dayz ${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" +quit } fn_update_dayz(){ fn_steamlogin_dayz fn_loadconfig_dayz appmanifestfile=${HOME}/serverfiles/steamapps/appmanifest_"${appid}".acf printf "[ ... ] Checking for update: SteamCMD" # gets currentbuild currentbuild=$(grep buildid "${appmanifestfile}" | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d \ -f3) # Removes appinfo.vdf as a fix for not always getting up to date version info from SteamCMD if [ -f "${HOME}/Steam/appcache/appinfo.vdf" ]; then rm -f "${HOME}/Steam/appcache/appinfo.vdf" sleep 1 fi # check for new build availablebuild=$(${HOME}/steamcmd/steamcmd.sh +login "${steamlogin}" +app_info_update 1 +app_info_print "${appid}" +app_info_print "${appid}" +quit | sed -n '/branch/,$p' | grep -m 1 buildid | tr -cd '[:digit:]') if [ -z "${availablebuild}" ]; then printf "\r[ ${red}FAIL${default} ] Checking for update: SteamCMD\n" sleep 0.5 printf "\r[ ${red}FAIL${default} ] Checking for update: SteamCMD: Not returning version info\n" exit else printf "\r[ ${green}OK${default} ] Checking for update: SteamCMD" sleep 0.5 fi # compare builds if [ "${currentbuild}" != "${availablebuild}" ]; then printf "\r[ ${green}OK${default} ] Checking for update: SteamCMD: Update available\n" printf "Update available:\n" sleep 0.5 printf "\tCurrent build: ${red}${currentbuild}${default}\n" printf "\tAvailable build: ${green}${availablebuild}${default}\n" printf "\thttps://steamdb.info/app/${appid}/\n" sleep 0.5 date > ${HOME}/.dayzlockupdate printf "\nApplying update" for seconds in {1..3}; do printf "." sleep 1 done printf "\n" # run update fn_status_dayz if [ "${dayzstatus}" == "0" ]; then fn_runupdate_dayz fn_workshop_mods rm -f ${HOME}/.dayzlockupdate else fn_stop_dayz fn_runupdate_dayz fn_workshop_mods fn_start_dayz rm -f ${HOME}/.dayzlockupdate fi else printf "\r[ ${green}OK${default} ] Checking for update: SteamCMD: No update available\n" printf "\nNo update available:\n" printf "\tCurrent version: ${green}${currentbuild}${default}\n" printf "\tAvailable version: ${green}${availablebuild}${default}\n" printf "\thttps://steamdb.info/app/${appid}/\n\n" fi } fn_runvalidate_dayz(){ fn_loadconfig_dayz ${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" +app_update "${appid}" validate +quit } fn_validate_dayz(){ fn_status_dayz fn_steamlogin_dayz if [ "${dayzstatus}" == "0" ]; then fn_runvalidate_dayz else date > ${HOME}/.dayzlockupdate fn_stop_dayz fn_runvalidate_dayz fn_workshop_mods rm -f ${HOME}/.dayzlockupdate fn_start_dayz fi } fn_workshop_mods(){ fn_steamlogin_dayz fn_loadconfig_dayz declare -a workshopID workshopfolder="${HOME}/serverfiles/steamapps/workshop/content/221100" workshoplist="" if [ ! -f "${HOME}/.workshop.cfg" ]; then wget -P ${HOME}/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/.workshop.cfg fi mapfile -t -s 4 workshopID < "${HOME}/.workshop.cfg" # gather mods for i in "${workshopID[@]}" do if [[ $i =~ ^[0-9] ]] && [ $(expr length $i) -gt 7 ]; then workshoplist+=" +workshop_download_item "${dayz_id}" "$i"" fi done # download mods ${HOME}/steamcmd/steamcmd.sh +force_install_dir ${HOME}/serverfiles +login "${steamlogin}" ${workshoplist} +quit # link mods for i in "${workshopID[@]}" do if [[ $i =~ ^[0-9] ]] && [ $(expr length $i) -gt 7 ] && [ -d "${workshopfolder}/$i" ]; then modname=$(cut -d '"' -f 2 <<< $(grep name ${workshopfolder}/$i/meta.cpp)) if [ ! -d "${HOME}/serverfiles/@${modname}" ]; then ln -s ${workshopfolder}/$i "${HOME}/serverfiles/@${modname}" &> /dev/null fi find "${workshopfolder}/$i" -depth -exec rename -f 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \; fi done if ls ${HOME}/serverfiles/@* 1> /dev/null 2>&1; then printf "\n[ ${green}DayZ${default} ] Copy Key Files from Mods...\n" cp -vu ${HOME}/serverfiles/@*/keys/* "${HOME}/serverfiles/keys/" > /dev/null 2>&1 fi } fn_backup_dayz(){ fn_status_dayz if [ ! -d "${HOME}/backup" ]; then mkdir ${HOME}/backup &> /dev/null fi missionfolder=$(grep template ${HOME}/serverfiles/serverDZ.cfg | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d \ -f3) if [ "${dayzstatus}" == "0" ]; then printf "[ ${green}DayZ${default} ] Creating backup of Missionfolder: ${cyan}${missionfolder}${default}\n" tar -cf ${HOME}/backup/${missionfolder}-$(date +%Y-%m-%d).tar ${HOME}/serverfiles/mpmissions/${missionfolder} else fn_stop_dayz printf "[ ${green}DayZ${default} ] Creating backup of Missionfolder: ${cyan}${missionfolder}${default}\n" tar -cf ${HOME}/backup/${missionfolder}-$(date +%Y-%m-%d).tar ${HOME}/serverfiles/mpmissions/${missionfolder} sleep 0.5 fn_start_dayz fi } fn_wipe_dayz(){ missionfolder=$(grep template ${HOME}/serverfiles/serverDZ.cfg | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d \ -f3) printf "[ ${red}WARNING${default} ] Wiping Players and reset Central Economy state from...\n" for seconds in {9..0}; do printf "\r\t Selected Mission: ${cyan}${missionfolder}${default} in ${red}"${seconds}"${default} seconds." sleep 1 done printf "\n" if [ "${dayzstatus}" == "0" ]; then rm -f ${HOME}/serverfiles/mpmissions/${missionfolder}/storage_1/players.db rm -f ${HOME}/serverfiles/mpmissions/${missionfolder}/storage_1/data/* printf "[ ${yellow}DayZ${default} ] Player.db and Storage-data wiped!\n" else fn_stop_dayz rm -f ${HOME}/serverfiles/mpmissions/${missionfolder}/storage_1/players.db rm -f ${HOME}/serverfiles/mpmissions/${missionfolder}/storage_1/data/* printf "[ ${yellow}DayZ${default} ] Player.db and Storage-data wiped!\n" sleep 0.5 fn_start_dayz fi } fn_updatescript_dayz(){ checkversion=$(curl -s https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/version) if [ ${checkversion} -gt ${version} ]; then wget -P ${HOME}/ -qN https://raw.githubusercontent.com/thelastnoc/dayz-sa_linuxserver/master/script/dayzserver --show-progress chmod u+x dayzserver else printf "No update\n" fi } fn_config_dayz(){ fn_loadconfig_dayz printf "\nFollowing config Files available!\n\\n\t[${yellow}1${default}] - script\t(.dayzserver.cfg)\n\t[${yellow}2${default}] - serverDZ\t(serverDZ.cfg)\n\t[${yellow}3${default}] - workshop\t(.workshop.cfg)\n\t[${yellow}4${default}] - battleye\t(beserver_x64.cfg)\n\t[${yellow}5${default}] - steamlogin\n\t[${yellow}0${default}] - script-default (read only!)\n\t[${yellow}x${default}] - exit\n\n" read -p "Select the config File: " configfile case "$configfile" in 1|script) nano -c ${HOME}/.dayzserver.cfg;; 2|server|serverDZ) nano -c ${HOME}/serverfiles/serverDZ.cfg;; 3|workshop) nano -c ${HOME}/.workshop.cfg && ./dayzserver ws;; 4|battleye) nano -c $(ls ${HOME}/serverfiles/battleye/beserver_x64.cfg);; 5|steamlogin) nano -c ${HOME}/.steamlogin;; 0|default) nano -cv ${HOME}/.default.cfg;; *) exit 1 esac } cmd_start=( "st;start" "fn_start_dayz" "Start the server." ) cmd_stop=( "sp;stop" "fn_stop_dayz" "Stop the server." ) cmd_restart=( "r;restart" "fn_restart_dayz" "Restart the server.") cmd_monitor=( "m;monitor" "fn_monitor_dayz" "Check server status and restart if crashed." ) cmd_config=( "cfg;config" "fn_config_dayz" "Edit any Config File." ) cmd_console=( "c;console" "fn_console_dayz" "Access server console." ) cmd_install=( "i;install" "fn_install_dayz" "Install steamcmd and DayZ Server-Files." ) cmd_update=( "u;update" "fn_update_dayz" "Check and apply any server updates." ) cmd_validate=( "v;validate" "fn_validate_dayz" "Validate server files with SteamCMD." ) cmd_workshop=( "ws;workshop" "fn_workshop_mods" "Download Mods from Steam Workshop." ) cmd_backup=( "b;backup" "fn_backup_dayz" "Create backup archives of the server (mpmission)." ) cmd_wipe=( "wi;wipe" "fn_wipe_dayz" "Wipe your server data (Player and Storage)." ) cmd_updatescript=( "us;update-script" "fn_updatescript_dayz" "Update the script." ) ### Set specific opt here ### currentopt=( "${cmd_start[@]}" "${cmd_stop[@]}" "${cmd_restart[@]}" "${cmd_monitor[@]}" "${cmd_config[@]}" "${cmd_console[@]}" "${cmd_install[@]}" "${cmd_update[@]}" "${cmd_validate[@]}" "${cmd_workshop[@]}" "${cmd_backup[@]}" "${cmd_wipe[@]}" "${cmd_updatescript[@]}" ) ### Build list of available commands optcommands=() index="0" for ((index="0"; index < ${#currentopt[@]}; index+=3)); do cmdamount="$(echo "${currentopt[index]}" | awk -F ';' '{ print NF }')" for ((cmdindex=1; cmdindex <= ${cmdamount}; cmdindex++)); do optcommands+=( "$(echo "${currentopt[index]}" | awk -F ';' -v x=${cmdindex} '{ print $x }')" ) done done # Shows LinuxGSM usage fn_opt_usage(){ printf "\nDayZ 1.15 Exp - Linux Game Server - Version: "${version}"" printf "\nhttps://steamcommunity.com/sharedfiles/filedetails/?id=1517338673" printf "\nUsage:${lightblue} $0 [command]${default}\n\n" printf "${lightyellow}Commands${default}\n" # Display available commands index="0" { for ((index="0"; index < ${#currentopt[@]}; index+=3)); do # Hide developer commands if [ "${currentopt[index+2]}" != "DEVCOMMAND" ]; then echo -e "${cyan}$(echo "${currentopt[index]}" | awk -F ';' '{ print $2 }')\t${default}$(echo "${currentopt[index]}" | awk -F ';' '{ print $1 }')\t|${currentopt[index+2]}" fi done } | column -s $'\t' -t exit 1 } # Make sure we don't start collecting core files ulimit -c 0 # start functions fn_checkroot_dayz #fn_checktmux #fn_checkscreen # Use an anonymous login for the server files if [ ! -f ${HOME}/.steamlogin ] then echo "steamlogin=anonymous" > ${HOME}/.steamlogin fi getopt=$1 if [ ! -f "${HOME}/steamcmd/steamcmd.sh" ] || [ ! -f "${HOME}/serverfiles/DayZServer" ] && [ "${getopt}" != "cfg" ]; then printf "[ ${yellow}INFO${default} ] No installed steamcmd and/or serverfiles found!\n" # chmod u+x ${HOME}/dayzserver fn_install_dayz if [ -f "${HOME}/steamcmd/steamcmd.sh" ] && [ -f "${HOME}/serverfiles/DayZServer" ]; then exec fn_start_dayz fi echo "Something failed? Shouldn't make it here..." exit else ### Check if user commands exist and run corresponding scripts, or display script usage if [ -z "${getopt}" ]; then fn_opt_usage fi fi # Command exists for i in "${optcommands[@]}"; do if [ "${i}" == "${getopt}" ] ; then # Seek and run command index="0" for ((index="0"; index < ${#currentopt[@]}; index+=3)); do currcmdamount="$(echo "${currentopt[index]}" | awk -F ';' '{ print NF }')" for ((currcmdindex=1; currcmdindex <= ${currcmdamount}; currcmdindex++)); do if [ "$(echo "${currentopt[index]}" | awk -F ';' -v x=${currcmdindex} '{ print $x }')" == "${getopt}" ]; then # Run command eval "${currentopt[index+1]}" exit 1 break fi done done fi done # If we're executing this, it means command was not found echo -e "${red}Unknown command${default}: $0 ${getopt}" fn_opt_usage