#!/usr/bin/env bash # Make sure we don't start collecting core files # FIXME Set this in Docker somewhere ulimit -c 0 # DayZ SteamID appid=1042420 dayz_id=221100 config=serverDZ.cfg port=2302 profile="-profiles=${HOME}/serverprofile/" # To log or not to log #logs="-dologs -adminlog -netlog" logs="-nologs" # mods="@CF;@community-Online-Tools;@Banov;@SimpleAutorun" mods="" # modify carefully! server won't start if syntax is corrupt! dayzparameter=" -config=${config} -port=${port} -mod='${mods}' -freezecheck ${profile} ${logs}" # Colors default="\e[0m" red="\e[31m" green="\e[32m" yellow="\e[93m" lightblue="\e[94m" blue="\e[34m" magenta="\e[35m" cyan="\e[36m" # Base directories CFG_SRC_FILES="/files" SERVER_FILES="${HOME}/serverfiles" SERVER_PROFILE="${HOME}/serverprofile" # Server configuration file SERVER_CFG_FILE="serverDZ.cfg" SERVER_CFG_DST="${SERVER_FILES}/${SERVER_CFG_FILE}" SERVER_CFG_SRC="${CFG_SRC_FILES}/${SERVER_CFG_FILE}" # Used to check if dayZ is installed SERVER_INSTALL_FILE="${SERVER_FILES}/DayZServer" # Steam files STEAM_LOGIN="${HOME}/steamlogin" STEAMCMD=steamcmd # Workshop WORKSHOP_CFG="${HOME}/workshop.cfg" # Other stuff YES="${green}yes${default}" NO="${red}no${default}" fn_usage(){ echo -e " ${red}Bad option or arguments! ${yellow}${*}${default} Usage: ${green}$(basename $0)${yellow} option [ arg1 [ arg2 ] ] Options and arguments: install - Install the DayZ server files login - Login to Steam rcon - RCON Features say - Send a message to players on the server status - Shows the server's status as well as the state of the server files and mods (Needs install, update, etc.) stop - Stop the server update - Update the DayZ server files workshop - Workshop Features activate id [id...] - Activate one or many installed DayZ Workshop item by id add id [id...] - Add one or many DayZ Workshop items by id deactivate id [id...] - Deactivate one or many installed DayZ Workshop items by id - Keeps the addon files but excludes from -mod= list - List Workshop items and their states (Active vs. Non) remove id [id...] - Remove one or many Workshop items by id ${default}" exit 1 } fn_prompt_yn(){ echo -n "${1} (y|N) " >&2 read -s -n 1 a a=$(echo ${a} | tr A-Z a-z) if [[ "${a}" = "y" ]] then echo return 0 else echo return 1 fi } fn_loadconfig_dayz(){ if [ ! -f "${SERVER_INSTALL_FILE}" ] then echo echo -e "The DayZ server files are not installed yet. Run '${green}dayzserver install${default}'" echo exit 1 fi # Handle the server configuration file if [ ! -f ${SERVER_CFG_DST} ] then echo "Creating initial server configuration file" cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" elif ! diff -q "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" then echo "=========================================================================" diff -Nau --color "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" echo "=========================================================================" if fn_prompt_yn "The new server configuration file differs from what's installed. Use it?" then echo "Updating the server configuration file" cp "${SERVER_CFG_SRC}" "${SERVER_CFG_DST}" else echo "NOT updating the server configuration file" fi fi } fn_start_dayz(){ # Check for interactive shell if [ -t 0 ] then echo echo -e "Not starting the server in an interactive shell. Start the server using '${green}docker-compose up -d${default}'" echo exit fi fn_loadconfig_dayz fn_workshop_mods printf "[ ${green}DayZ${default} ] Starting server...\n" cd ${SERVER_FILES} ./DayZServer $dayzparameter "$workshop" || ( echo echo -e "${yellow}========================================== error.log ==========================================" find "${HOME}" -name error.log -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== script*.log ========================================" find "${HOME}" -name "script*.log" -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== *.RPT ==============================================" find "${HOME}" -name "*.RPT" -exec cat {} \; -exec rm -f {} \; echo echo -e "${yellow}========================================== End crash log ======================================" ) } fn_stop_dayz(){ echo "Stopping DayZ server..." } fn_steam_login(){ if [ -f "${STEAM_LOGIN}" ] then if fn_prompt_yn "The steam login is already set. Reset it?" then rm -f "${STEAM_LOGIN}" else echo "Not reset." exit 0 fi fi if [ ! -f "${STEAM_LOGIN}" ] then echo "Setting up Steam credentials" echo -n "Steam Username (anonymous): " read steamlogin if [[ "${steamlogin}" = "" ]] then echo "Steam login set to 'anonymous'" steamlogin="anonymous" fi echo "steamlogin=${steamlogin}" > "${STEAM_LOGIN}" ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" +quit fi } fn_steamlogin_dayz(){ if [ -f "${STEAM_LOGIN}" ] then source "${STEAM_LOGIN}" else echo "No cached Steam credentials. Please configure this now: " fn_steam_login fi } fn_runvalidate_dayz(){ fn_loadconfig_dayz ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" +app_update "${appid}" validate +quit } fn_install_dayz(){ if [ ! -f "${SERVER_INSTALL_FILE}" ]; then mkdir -p "${SERVER_FILES}" mkdir -p "${SERVER_PROFILE}" 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" fi } fn_runupdate_dayz(){ fn_loadconfig_dayz ${STEAMCMD} +force_install_dir ${SERVER_FILES} +login "${steamlogin}" +app_update "${appid}" +quit } fn_update_dayz(){ fn_steamlogin_dayz fn_loadconfig_dayz appmanifestfile=${SERVER_FILES}/steamapps/appmanifest_"${appid}".acf printf "[ ... ] Checking for update:" # 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" fi # check for new build availablebuild=$(${STEAMCMD} +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:\n" printf "\r[ ${red}FAIL${default} ] Checking for update:: Not returning version info\n" exit else printf "\r[ ${green}OK${default} ] Checking for update:" fi # compare builds if [ "${currentbuild}" != "${availablebuild}" ]; then printf "\r[ ${green}OK${default} ] Checking for update:: Update available\n" printf "Update available:\n" printf "\tCurrent build: ${red}${currentbuild}${default}\n" printf "\tAvailable build: ${green}${availablebuild}${default}\n" printf "\thttps://steamdb.info/app/${appid}/\n" printf "\nApplying update" # run update fn_runupdate_dayz fn_workshop_mods else printf "\r[ ${green}OK${default} ] Checking for update:: 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_workshop_mods(){ fn_steamlogin_dayz fn_loadconfig_dayz declare -a workshopID workshopfolder="${SERVER_FILES}/steamapps/workshop/content/${dayz_id}" workshoplist="" if [ ! -f "${WORKSHOP_CFG}" ] then echo "No workshop mods..." return else echo "Syncing workshop mods..." fi mapfile -t workshopID < "${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 ${STEAMCMD} +force_install_dir ${SERVER_FILES} +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 "${SERVER_FILES}/@${modname}" ]; then ln -s ${workshopfolder}/$i "${SERVER_FILES}/@${modname}" &> /dev/null fi find "${workshopfolder}/$i" -depth -exec rename -f 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \; fi done if ls ${SERVER_FILES}/@* 1> /dev/null 2>&1; then printf "\n[ ${green}DayZ${default} ] Copy Key Files from Mods...\n" cp -vu ${SERVER_FILES}/@*/keys/* "${SERVER_FILES}/keys/" > /dev/null 2>&1 fi } fn_rcon(){ case "${1}" in say) echo "Sending message to server: '${1}'" ;; **) fn_usage rcon "${1}" ;; esac } fn_status(){ INSTALLED="${NO}" LOGGED_IN="${NO}" RUNNING="${NO}" MOD_INSTALLED="${yellow}0${default}" MOD_LIST="" # DayZ Server files installation if [ -f "${SERVER_INSTALL_FILE}" ] then INSTALLED="${YES}" fi # Logged into Steam if [ -f "${STEAM_LOGIN}" ] then LOGGED_IN="${YES}" fi # Running or not if pidof DayZServer then RUNNING="${YES}" fi # Number of mods plus the list denoting on or off echo -e " Status: Logged in to Steam: ${LOGGED_IN} Server files installed: ${INSTALLED} Mods installed: ${MOD_INSTALLED}${MOD_LIST} Server running: ${RUNNING} " } case "${1}" in install) fn_install_dayz ;; login) fn_steam_login ;; rcon) fn_rcon "${2}" ;; start) fn_start_dayz ;; status) fn_status ;; stop) fn_stop_dayz ;; update) fn_update_dayz ;; workshop) fn_workshop_mods "${2}" ;; **) fn_usage "$*" ;; esac