From e204704a5602b9c7b942dab35565cf126660b910 Mon Sep 17 00:00:00 2001 From: Daniel Ceregatti Date: Fri, 25 Mar 2022 16:24:50 -0700 Subject: [PATCH] Initial import. --- Dockerfile | 41 +++++ dayzserver | 494 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 535 insertions(+) create mode 100644 Dockerfile create mode 100755 dayzserver diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f57e81f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +FROM debian:bookworm + +# Replace shell with bash so we can source files +RUN rm /bin/sh && ln -s /bin/bash /bin/sh + +# Set debconf to run non-interactively +RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections + +# Add contrib and backports +RUN sed -i /etc/apt/sources.list -e 's/main/main contrib/' + +RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list + +# Add 32 bit arch for steam crap +RUN dpkg --add-architecture i386 + +# Install necessary packages +RUN apt-get update && apt-get -y upgrade && apt-get -y install \ + tmux \ + nano \ + htop \ + curl \ + lib32gcc-s1 \ + lib32stdc++6 \ + psmisc \ + wget \ + rename + +# Setup a non-privileged user +RUN groupadd -g 1000 user && \ + useradd -l -u ${USER_ID} -m -g user user + +RUN chown user:user /home/user -R + +USER ${USER_ID} + +WORKDIR /work + +COPY . /home/user + +CMD ["server.sh"] diff --git a/dayzserver b/dayzserver new file mode 100755 index 0000000..800cb39 --- /dev/null +++ b/dayzserver @@ -0,0 +1,494 @@ +#!/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_checktmux(){ + if [ -n "${TMUX}" ]; then + printf "[ ${red}FAIL${default} ] The Script creates a tmux session when starting the server.\n" + printf "\tIt is not possible to run a tmux session inside another tmux session\n" + exit 1 + fi +} + +fn_checkscreen(){ + if [ -n "${STY}" ]; then + printf "[ ${red}FAIL${default} ] The Script creates a tmux session when starting the server.\n" + printf "\tIt is not possible to run a tmux session inside screen session\n" + exit 1 + fi +} + +fn_loadconfig_dayz(){ + # 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 + 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 +} + +# start functions +fn_checkroot_dayz +fn_checktmux +fn_checkscreen + +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 + fn_opt_usage + fi + 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