From 8aad9cd42eb6ea98e6de0db626305f5037895f4b Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Mon, 27 Jun 2016 19:16:57 +1000 Subject: [PATCH 01/24] Don't print the warning message twice --- tools/arkmanager | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index afd72cb..ac73ec7 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -991,7 +991,6 @@ printWarnMessage(){ reason="${reason//\{time\}/${msgtime}}" reason="${reason//\{modnamesupdated\}/${modnamesupdated}}" msg="${msg//\{reason\}/${reason}}" - printf "%s\n" "$msg" else if [ "$1" == "update" ]; then if [ "$3" == "minutes" ]; then From c7053d8a9341032b411d49da95a607746610f0e0 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Tue, 28 Jun 2016 19:58:26 +1000 Subject: [PATCH 02/24] Fix --stagingdir= parameter --- tools/arkmanager | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index ac73ec7..72795ae 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1185,7 +1185,7 @@ doUpdate() { modupdate=1 elif [ "$arg" == "--backup" ]; then arkBackupPreUpdate=true - elif [[ "$arg" =~ "^--stagingdir=" ]]; then + elif [[ "$arg" =~ ^--stagingdir= ]]; then arkStagingDir="${ark#--stagingdir=}" elif [ "$arg" == "--downloadonly" ]; then downloadonly=1 From e1b2cdb8c89d8221250fc41d1b988d23212435a7 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 1 Jul 2016 23:11:28 +1000 Subject: [PATCH 03/24] Add option to allow players to cancel restart --- tools/arkmanager | 30 ++++++++++++++++++++++++++++++ tools/arkmanager.cfg | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/tools/arkmanager b/tools/arkmanager index 72795ae..4c06104 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1040,6 +1040,28 @@ printWarnMessage(){ doBroadcastWithEcho "$msg" } +# +# Checks if a player has requested an update cancel in the last 5 minutes +# +isUpdateCancelRequested(){ + if [ -n "$chatCommandRestartCancel" ]; then + local canceltime="$( + find ~/ARK/server1/ShooterGame/Saved/Logs -name 'ServerGame.*.log' -mmin -5 -print0 | + xargs -0 grep -F -e "${chatCommandRestartCancel}" | + sed 's@^[[]\(....\)\.\(..\)\.\(..\)-\(..\)\.\(..\)\.\(..\):.*@\1-\2-\3 \4:\5:\6 UTC@' | + head -n1)" + if [ -n canceltime ]; then + canceltime="$(date +%s --date="${canceltime}")" + local timenow="$(date +%s --date="now - 5 minutes")" + if (( canceltime > timenow )); then + return 0 + fi + fi + fi + + return 1 +} + # # Waits for a configurable number of minutes before updating the server # @@ -1107,6 +1129,10 @@ doWarn(){ rm -f "${arkserverroot}/.ark-warn.lock" return 0 fi + if isUpdateCancelRequested; then + doBroadcastWithEcho "Restart cancelled by player request" + return 1 + fi wait $sleeppid if (( $min > $warninterval )); then sleep 1m & @@ -1136,6 +1162,10 @@ doWarn(){ rm -f "${arkserverroot}/.ark-warn.lock" return 0 fi + if isUpdateCancelRequested; then + doBroadcastWithEcho "Restart cancelled by player request" + return 1 + fi fi wait $sleeppid warnseconds=$warninterval diff --git a/tools/arkmanager.cfg b/tools/arkmanager.cfg index b563ff2..750f866 100644 --- a/tools/arkmanager.cfg +++ b/tools/arkmanager.cfg @@ -32,6 +32,10 @@ msgWarnRestartMinutes="This ARK server will shutdown for a restart in %d minutes msgWarnRestartSeconds="This ARK server will shutdown for a restart in %d seconds" msgWarnShutdownMinutes="This ARK server will shutdown in %d minutes" msgWarnShutdownSeconds="This ARK server will shutdown in %d seconds" +msgWarnCancelled="Restart cancelled by player request" + +# Restart cancel chat command +#chatCommandRestartCancel="/cancelupdate" # ARK server common options - use ark_= # comment out these values if you want to define them From 3fe29777e6694b6100f26bda48bdb8b202b940d9 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 8 Jul 2016 09:29:55 +1000 Subject: [PATCH 04/24] Add support for -automanagedmods --- tools/arkmanager | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index 4c06104..76cfa12 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -607,7 +607,7 @@ function numPlayersConnected(){ # run function # doRun() { - cd "$arkserverroot" + cd "${arkserverroot}/${arkserverexec%/*}" arkserveropts="$serverMap" @@ -703,6 +703,14 @@ doRun() { fi done + if [[ " ${arkextraopts[*]} " =~ " -automanagedmods " ]]; then + if [ ! -f "${arkserverroot}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd.sh" ]; then + mkdir -p "${arkserverroot}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + curl -s "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" -o "${arkserverroot}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd_linux.tar.gz" + tar -xzf "${arkserverroot}/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamcmd_linux.tar.gz" -C "${arkserverroot}/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fi + fi + arkserveropts="${arkserveropts}?listen" # run the server in background echo "`timestamp`: start" From 4c8d9d53da88a36407f443245f00e4559880889a Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 8 Jul 2016 09:43:26 +1000 Subject: [PATCH 05/24] Add -automanagedmods support to update --- tools/arkmanager | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index 76cfa12..d12903c 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1284,6 +1284,7 @@ doUpdate() { fi rm -rf "$arkStagingDir/ShooterGame/Content/Mods/"* rm -rf "$arkStagingDir/ShooterGame/Saved/"* + rm -rf "$arkStagingDir/Engine/Binaries/ThirdParty/SteamCMD/Linux/steamapps" fi if [ -z "$nodownload" ]; then @@ -1384,7 +1385,7 @@ doUpdate() { echo "`timestamp`: update to $instver complete" >> "$logdir/update.log" fi - if [ -n "$modupdate" ]; then + if [ -n "$modupdate" ] && [ -z "$arkflag_automanagedmods" ]; then for modid in $(getModIds); do if isModUpdateNeeded $modid; then echo "Updating mod $modid" @@ -1423,6 +1424,10 @@ getModIds(){ # doDownloadMod(){ local modid=$1 + local steamcmdroot="$steamcmdroot" + if [ -n "$arkflag_automanagedmods" ]; then + steamcmdroot="$arkserverroot/Engine/Binaries/ThirdParty/SteamCMD/Linux" + fi local modsrcdir="$steamcmdroot/steamapps/workshop/content/$mod_appid/$modid" local moddldir="$steamcmdroot/steamapps/workshop/downloads/$mod_appid" cd "$steamcmdroot" From 55f9a80dddd6ccf49ce02314393ccdcb5fd179e5 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 9 Jul 2016 14:26:43 +1000 Subject: [PATCH 06/24] Change systemd service type to forking --- tools/systemd/arkmanager.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/systemd/arkmanager.service b/tools/systemd/arkmanager.service index c2d4053..97ec6bd 100644 --- a/tools/systemd/arkmanager.service +++ b/tools/systemd/arkmanager.service @@ -5,7 +5,7 @@ After=network.target [Service] ExecStart=/usr/libexec/arkmanager/arkmanager.init start ExecStop=/usr/libexec/arkmanager/arkmanager.init stop -Type=oneshot +Type=forking [Install] WantedBy=multi-user.target From 794171e7e457d90e4dc002b55862af4102de2309 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 9 Jul 2016 15:50:25 +1000 Subject: [PATCH 07/24] Add option to always auto-restart --- tools/arkmanager | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/arkmanager b/tools/arkmanager index d12903c..ffa3dc0 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -742,6 +742,9 @@ doRun() { # Disable auto-restart so we don't get caught in a restart loop rm -f "$arkserverroot/$arkautorestartfile" restartserver=0 + if [ -n "$arkAlwaysRestartOnCrash" ]; then + restartserver=1 + fi sleep 5 @@ -762,6 +765,8 @@ doRun() { echo "`timestamp`: Bad PID '$pid'; expected '$serverpid'" if [ "$pid" != "" ]; then # Another instance must be running - disable autorestart + echo "Error: another server instance is running from the same directory" + echo "Aborting - two servers MUST NOT run from the same directory" restartserver=0 fi break @@ -797,6 +802,10 @@ doStart() { doUpdate --update-mods fi fi + + if [[ " $* " =~ " --alwaysrestart " ]]; then + arkAlwaysRestartOnCrash=true + fi tput sc echo "The server is starting..." From f6a770c624e3837a9d2dd83ed9073a61a12cfe0b Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 9 Jul 2016 15:59:38 +1000 Subject: [PATCH 08/24] Add arkAlwaysRestartOnCrash to readme --- README.asciidoc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.asciidoc b/README.asciidoc index 21c43a7..d295e60 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -149,6 +149,11 @@ instances. `--noautoupdate`;; Disables automatic updating on startup if it is enabled + `--alwaysrestart`;; + Enable automatically restarting the server even if it crashes + without becoming ready for player connections. + + `stop`:: Stops the server if it is running @@ -343,6 +348,12 @@ The following options can be overridden on a per-instance basis: The relative path within an ARK server install to place the autorestart lock file +`arkAlwaysRestartOnCrash`:: + Set to `true` to enable automatically restarting even when the + server has not become ready for player connections. + Be aware that this may cause the server to enter an endless + crash-restart loop if the cause of the crash is not resolved. + `arkAutoUpdateOnStart`:: Set to `true` to enable updating before server startup From 12198f8f3c6c77f5923d57e8f8c0fc00938af747 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 9 Jul 2016 16:34:43 +1000 Subject: [PATCH 09/24] Add RemainAfterExit=yes to arkmanager.service --- tools/systemd/arkmanager.service | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/systemd/arkmanager.service b/tools/systemd/arkmanager.service index 97ec6bd..55ab37d 100644 --- a/tools/systemd/arkmanager.service +++ b/tools/systemd/arkmanager.service @@ -6,6 +6,7 @@ After=network.target ExecStart=/usr/libexec/arkmanager/arkmanager.init start ExecStop=/usr/libexec/arkmanager/arkmanager.init stop Type=forking +RemainAfterExit=yes [Install] WantedBy=multi-user.target From b22b16b41db4176d1826f9342589d988bca69b7a Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sun, 10 Jul 2016 18:44:49 +1000 Subject: [PATCH 10/24] Create the saved arks directory if it doesn't exist --- tools/arkmanager | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/arkmanager b/tools/arkmanager index ffa3dc0..14f557c 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -202,6 +202,7 @@ checkConfig() { # SavedArks directory if [ -n "$arkserverroot" ]; then local savedarksdir="${arkserverroot}/ShooterGame/Saved/${ark_AltSaveDirectoryName:-SavedArks}" + mkdir -p "${savedarksdir}" if [ ! -w "${savedarksdir}" ]; then echo -e "[" "$RED" "ERROR" "$NORMAL" "]" "\tThe ARK SavedArks directory is not writable, and saveworld will fail" fi From 6d207952b5fdefd84462bb535d4a5d1f537cc620 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Mon, 11 Jul 2016 10:03:44 +1000 Subject: [PATCH 11/24] Fix arkAlwaysRestartOnCrash --- tools/arkmanager | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/arkmanager b/tools/arkmanager index 14f557c..5c0e97b 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -745,6 +745,7 @@ doRun() { restartserver=0 if [ -n "$arkAlwaysRestartOnCrash" ]; then restartserver=1 + touch "$arkserverroot/$arkautorestartfile" fi sleep 5 @@ -782,6 +783,7 @@ doRun() { # doStop will remove the autorestart file if [ ! -f "$arkserverroot/$arkautorestartfile" ]; then restartserver=0 + fi if [ "$restartserver" -ne 0 ]; then From 7f8aa05e80102dc03719b2b79b4f594b97c5a1a8 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Mon, 11 Jul 2016 13:23:54 +1000 Subject: [PATCH 12/24] Add printconfig command This new command will print the file that each config option is taken from. --- tools/arkmanager | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/arkmanager b/tools/arkmanager index 5c0e97b..3197a44 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -2088,6 +2088,23 @@ doListAllInstances(){ fi } +doPrintConfig(){ + declare -A vars + declare -A vals + for v in $(eval echo \$\{\!{a..z}\*\} \$\{\!{A..Z}\*\} \$\{\!_\*\}); do + vals["$v"]="${!v}" + done + for cfgfile in "$configfile" "$HOME/.arkmanager.cfg" "/etc/arkmanager/arkmanager.cfg"; do + while read v; do + val="$(source "$cfgfile"; echo "${!v}")" + if [[ "$val" = "${vals[$v]}" && -z "${vars[$v]}" ]]; then + vars["$v"]="$cfgfile" + echo "${cfgfile} => ${v}" + fi + done < <(sed -n 's/^[[:space:]]*\([A-Za-z_][A-Za-z0-9_]*\)=.*/\1/p' <"$cfgfile") + done +} + useConfig() { configfile= if [ -f "/etc/arkmanager/instances/${1}.cfg" ]; then @@ -2377,6 +2394,9 @@ main(){ rconcmd) rconcmd "${args[@]}" ;; + printconfig) + doPrintConfig + ;; status) printStatus ;; From 23757124c92d863ded13a21c8e3edcf2a45cd5cc Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Mon, 11 Jul 2016 11:17:45 +1000 Subject: [PATCH 13/24] Change config migration Write new example global config to `arkmanager.cfg.example` Write migrated global config to `arkmanager.cfg.NEW` Write migrated main instance config to `instances/main.cfg.NEW` --- tools/install.sh | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/tools/install.sh b/tools/install.sh index cf801ed..eac2d60 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -3,6 +3,7 @@ userinstall=no steamcmd_user= showusage=no +migrateconfig=no while [ -n "$1" ]; do case "$1" in @@ -63,6 +64,9 @@ while [ -n "$1" ]; do DATADIR="$2" shift ;; + --migrate-config) + migrateconfig=yes + ;; -*) echo "Invalid option '$1'" showusage=yes @@ -169,7 +173,7 @@ if [ "$userinstall" == "yes" ]; then "${INSTALL_ROOT}${INSTANCEDIR}/instance.cfg.example" # Copy arkmanager.cfg to ~/.arkmanager.cfg.NEW - cp arkmanager.cfg "${INSTALL_ROOT}${CONFIGFILE}.NEW" + cp arkmanager.cfg "${INSTALL_ROOT}${CONFIGFILE}.example" # Change the defaults in the new config file sed -i -e "s|^steamcmd_user=\"steam\"|steamcmd_user=\"--me\"|" \ -e "s|\"/home/steam|\"${PREFIX}|" \ @@ -177,18 +181,24 @@ if [ "$userinstall" == "yes" ]; then -e "s|^install_bindir=.*|install_bindir=\"${BINDIR}\"|" \ -e "s|^install_libexecdir=.*|install_libexecdir=\"${LIBEXECDIR}\"|" \ -e "s|^install_datadir=.*|install_datadir=\"${DATADIR}\"|" \ - "${INSTALL_ROOT}${CONFIGFILE}.NEW" + "${INSTALL_ROOT}${CONFIGFILE}.example" # Copy arkmanager.cfg to ~/.arkmanager.cfg if it doesn't already exist if [ -f "${INSTALL_ROOT}${CONFIGFILE}" ]; then - bash ./migrate-config.sh "${INSTALL_ROOT}${CONFIGFILE}" - bash ./migrate-main-instance.sh "${INSTALL_ROOT}${CONFIGFILE}" "${INSTALL_ROOT}${INSTANCEDIR}/main.cfg" + SUFFIX= + if [ "$migrateconfig" = "no" ]; then + SUFFIX=".NEW" + cp "${INSTALL_ROOT}${CONFIGFILE}" "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" + fi + + bash ./migrate-config.sh "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" + bash ./migrate-main-instance.sh "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" "${INSTALL_ROOT}${INSTANCEDIR}/main.cfg${SUFFIX}" echo "A previous version of ARK Server Tools was detected in your system, your old configuration was not overwritten. You may need to manually update it." echo "A copy of the new configuration file was included in '${CONFIGFILE}.NEW'. Make sure to review any changes and update your config accordingly!" exit 2 else - mv -n "${INSTALL_ROOT}${CONFIGFILE}.NEW" "${INSTALL_ROOT}${CONFIGFILE}" + cp -n "${INSTALL_ROOT}${CONFIGFILE}.example" "${INSTALL_ROOT}${CONFIGFILE}" cp -n "${INSTALL_ROOT}/${INSTANCEDIR}/instance.cfg.example" "${INSTALL_ROOT}/${INSTANCEDIR}/main.cfg" fi else @@ -301,24 +311,30 @@ else # Copy arkmanager.cfg inside linux configuation folder if it doesn't already exists mkdir -p "${INSTALL_ROOT}/etc/arkmanager" chown "$steamcmd_user" "${INSTALL_ROOT}/etc/arkmanager" - cp arkmanager.cfg "${INSTALL_ROOT}${CONFIGFILE}.NEW" - chown "$steamcmd_user" "${INSTALL_ROOT}${CONFIGFILE}.NEW" + cp arkmanager.cfg "${INSTALL_ROOT}${CONFIGFILE}.example" + chown "$steamcmd_user" "${INSTALL_ROOT}${CONFIGFILE}.example" sed -i -e "s|^steamcmd_user=\"steam\"|steamcmd_user=\"$steamcmd_user\"|" \ -e "s|\"/home/steam|\"/home/$steamcmd_user|" \ -e "s|^install_bindir=.*|install_bindir=\"${BINDIR}\"|" \ -e "s|^install_libexecdir=.*|install_libexecdir=\"${LIBEXECDIR}\"|" \ -e "s|^install_datadir=.*|install_datadir=\"${DATADIR}\"|" \ - "${INSTALL_ROOT}${CONFIGFILE}.NEW" + "${INSTALL_ROOT}${CONFIGFILE}.example" if [ -f "${INSTALL_ROOT}${CONFIGFILE}" ]; then - bash ./migrate-config.sh "${INSTALL_ROOT}${CONFIGFILE}" - bash ./migrate-main-instance.sh "${INSTALL_ROOT}${CONFIGFILE}" "${INSTALL_ROOT}${INSTANCEDIR}/main.cfg" + SUFFIX= + if [ "$migrateconfig" = "no" ]; then + SUFFIX=".NEW" + cp "${INSTALL_ROOT}${CONFIGFILE}" "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" + fi + + bash ./migrate-config.sh "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" + bash ./migrate-main-instance.sh "${INSTALL_ROOT}${CONFIGFILE}${SUFFIX}" "${INSTALL_ROOT}${INSTANCEDIR}/main.cfg${SUFFIX}" echo "A previous version of ARK Server Tools was detected in your system, your old configuration was not overwritten. You may need to manually update it." echo "A copy of the new configuration file was included in /etc/arkmanager. Make sure to review any changes and update your config accordingly!" exit 2 else - mv -n "${INSTALL_ROOT}${CONFIGFILE}.NEW" "${INSTALL_ROOT}${CONFIGFILE}" + cp -n "${INSTALL_ROOT}${CONFIGFILE}.example" "${INSTALL_ROOT}${CONFIGFILE}" cp -n "${INSTALL_ROOT}/${INSTANCEDIR}/instance.cfg.example" "${INSTALL_ROOT}/${INSTANCEDIR}/main.cfg" fi fi From 4d4f4888638d3d4899c566eed46b0d18db242f7b Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Wed, 13 Jul 2016 23:08:19 +1000 Subject: [PATCH 14/24] Improve restart behaviour using pid files --- tools/arkmanager | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index 3197a44..bf672e3 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -151,6 +151,8 @@ arkserverLog="arkserver.log" # here is logged the output of ShooterGameServer appid="${appid:-376030}" mod_appid="${mod_appid:-346110}" arkautorestartfile="${arkautorestartfile:-ShooterGame/Saved/.autorestart}" +arkserverpidfile="${arkserverpidfile:-ShooterGame/Saved/.arkserver.pid}" +arkmanagerpidfile="${arkmanagerpidfile:-ShooterGame/Saved/.arkmanager.pid}" install_bindir="${install_bindir:-${0%/*}}" install_libexecdir="${install_libexecdir:-${install_bindir%/*}/libexec/arkmanager}" @@ -507,6 +509,13 @@ function getAvailableVersion(){ # Get the PID of the server process # function getServerPID(){ + if [ -f "${arkserverroot}/${arkserverpidfile}" ]; then + serverpid="$(<"${arkserverroot}/${arkserverpidfile}")" + if kill -0 "$serverpid" >/dev/null 2>&1; then + echo $serverpid + return + fi + fi ps -ef | grep "$arkserverroot/$arkserverexec" | grep -v grep | awk '{print $2}' } @@ -610,6 +619,14 @@ function numPlayersConnected(){ doRun() { cd "${arkserverroot}/${arkserverexec%/*}" + if isTheServerRunning; then + echo "Error: another server instance is running from the same directory" + echo "Aborting - two servers MUST NOT run from the same directory" + exit 1 + fi + + echo "$$" >"${arkserverroot}/${arkmanagerpidfile}" + arkserveropts="$serverMap" if [ -n "$serverMapModId" ]; then @@ -722,10 +739,11 @@ doRun() { # Shutdown the server when we are terminated shutdown_server(){ restartserver=0 - rm "$arkserverroot/$arkautorestartfile" + rm -f "$arkserverroot/$arkautorestartfile" if [ "$serverpid" -ne 0 ]; then - kill -INT $serverpid + kill -INT $serverpid >/dev/null 2>&1 fi + exit 0 } trap shutdown_server INT TERM @@ -739,6 +757,7 @@ doRun() { "$arkserverroot/$arkserverexec" "$arkserveropts" "${arkextraopts[@]}" & # Grab the server PID serverpid=$! + echo "$serverpid" >"${arkserverroot}/${arkserverpidfile}" echo "`timestamp`: Server PID: $serverpid" # Disable auto-restart so we don't get caught in a restart loop rm -f "$arkserverroot/$arkautorestartfile" @@ -767,8 +786,6 @@ doRun() { echo "`timestamp`: Bad PID '$pid'; expected '$serverpid'" if [ "$pid" != "" ]; then # Another instance must be running - disable autorestart - echo "Error: another server instance is running from the same directory" - echo "Aborting - two servers MUST NOT run from the same directory" restartserver=0 fi break @@ -882,6 +899,13 @@ doStop() { kill -KILL $PID fi + if [ -f "${arkserverroot}/${arkmanagerpidfile}" ]; then + PID="$(<"${arkserverroot}/${arkmanagerpidfile}")" + if [ -n "$PID" ]; then + kill $PID + fi + fi + tput rc; tput ed; echo "The server has been stopped" echo "`timestamp`: stopped" >> "$logdir/$arkmanagerLog" From 4786e5e9253bee0693726be1fbca686adf01649d Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 15 Jul 2016 16:35:30 +1000 Subject: [PATCH 15/24] Fix --arg bug in install-cronjob --- tools/arkmanager | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index bf672e3..d28afda 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -2002,7 +2002,7 @@ doInstallCronJob(){ output= ;; --arg=*) - cmdargs="${cmdargs} $(printf "%q" "${opt#--opt=}")" + cmdargs="${cmdargs} $(printf "%q" "${opt#--arg=}")" ;; --*) cmdopts="${cmdopts} $(printf "%q" "${opt}")" From dea6befbe65fb03934670b87033e1b8c1485437e Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 15 Jul 2016 16:40:15 +1000 Subject: [PATCH 16/24] Use full arkmanager path --- tools/arkmanager | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index d28afda..7a2fd3c 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1982,6 +1982,7 @@ doInstallCronJob(){ cmdopts="${arkCronExtraOpts}" cmdargs="" output=">/dev/null 2>&1" + arkmanagerpath="${0}" command="$1" shift @@ -2013,10 +2014,10 @@ doInstallCronJob(){ esac done - cronjob="${minute} ${hour} * * * arkmanager --cronjob ${command} @${instance} ${cmdopts} --args ${cmdargs} -- ${output}" + cronjob="${minute} ${hour} * * * ${arkmanagerpath} --cronjob ${command} @${instance} ${cmdopts} --args ${cmdargs} -- ${output}" (crontab -l | \ - sed -e "/ [*] [*] [*] arkmanager --cronjob ${command} @${instance} /d"; + sed -e "/ [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} /d"; echo "${cronjob}" ) | \ crontab - } @@ -2025,10 +2026,11 @@ doInstallCronJob(){ # Removes an installed cron job # doRemoveCronJob(){ + arkmanagerpath="${0}" command="$1" crontab -l | \ - sed -e "/ [*] [*] [*] arkmanager --cronjob ${command} @${instance} /d" | \ + sed -e "/ [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} /d" | \ crontab - } From 421c2c4c0b2ef59c71085330685f6205c4ae1de8 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 15 Jul 2016 20:03:31 +1000 Subject: [PATCH 17/24] Fix sed command in install-cronjob --- tools/arkmanager | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index 7a2fd3c..da12cf7 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -2017,7 +2017,7 @@ doInstallCronJob(){ cronjob="${minute} ${hour} * * * ${arkmanagerpath} --cronjob ${command} @${instance} ${cmdopts} --args ${cmdargs} -- ${output}" (crontab -l | \ - sed -e "/ [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} /d"; + sed -e "\\# [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} #d"; echo "${cronjob}" ) | \ crontab - } @@ -2030,7 +2030,7 @@ doRemoveCronJob(){ command="$1" crontab -l | \ - sed -e "/ [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} /d" | \ + sed -e "\\# [*] [*] [*] ${arkmanagerpath} --cronjob ${command} @${instance} #d" | \ crontab - } From bab7832fc9a58cb4009de23e3caaa7bd2aabc609 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 15 Jul 2016 20:53:02 +1000 Subject: [PATCH 18/24] Elaborate on install-cronjob --minute and --hour --- README.asciidoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.asciidoc b/README.asciidoc index d295e60..89edc23 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -272,10 +272,16 @@ instances. `--hour=`;; Specifies one or more hours when the command should execute. This is the hour field of the cron job. + If you want to have the command execute every n hours, then + use `--hour='*/n'` + Default: `*` (i.e. all hours) `--minute=`;; Specifies one or more minutes of the hour when the command should execute. This is the minute field of the cron job. + If you want to have the command execute every n minutes, + then use `--minute='*/n'` + Default: `0` (i.e. the first minute of the hour) `--enable-output`;; Enables the output from the command - the cron daemon usually From 915b5ace415686fef6d6f3f1ab2e985570f7005d Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Fri, 15 Jul 2016 21:26:35 +1000 Subject: [PATCH 19/24] Point user to crontab(5) man page --- README.asciidoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.asciidoc b/README.asciidoc index 89edc23..eb6b78a 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -262,6 +262,9 @@ instances. as well as the following options. In order to specify an argument to the command (e.g. to the `broadcast` command), use the `--arg=` option. + Please read your `man 5 crontab` manpage to determine what + minute and hour values are valid, as some implementations + may not accept e.g. the `*/n` minute / hour specification. `--daily`;; The command should be executed daily From 9a76dd8e1671d76b2d2e1be14f0a0b007f856a78 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 16 Jul 2016 13:11:27 +1000 Subject: [PATCH 20/24] Add --warnreason --- tools/arkmanager | 54 ++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index da12cf7..29f602a 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -865,7 +865,7 @@ doStop() { for arg in "$@"; do case "$arg" in --warn) dowarn=1; ;; - --warnreason=*) warnreason="${arg#*=}"; ;; + --warnreason=*) warnreason="${arg#--warnreason=}"; ;; --saveworld) dosave=1; ;; esac done @@ -995,6 +995,12 @@ printWarnMessage(){ fi fi msg="${msgWarnReason//\{time\}/$msgtime}" + if [ -n "$warnreason" ]; then + local v="warnreason_$warnreason" + reason="${!v}" + if [ -z "$reason" ]; then + reason="$warnreason" + fi if [ "$1" == "update" ]; then if [ -n "$appupdate" ]; then if [ -n "$modupdate" ]; then @@ -1242,34 +1248,24 @@ doUpdate() { local nodownload= for arg in "$@"; do - if [ "$arg" == "--force" ]; then - appupdate=1 - elif [ "$arg" == "--safe" ]; then - updatetype=safe - elif [ "$arg" == "--warn" ]; then - updatetype=warn - elif [ "$arg" == "--ifempty" ]; then - updatetype=ifempty - elif [ "$arg" == "--validate" ]; then - validate=validate - appupdate=1 - elif [ "$arg" == "--saveworld" ]; then - saveworld=1 - elif [ "$arg" == "--update-mods" ]; then - modupdate=1 - elif [ "$arg" == "--backup" ]; then - arkBackupPreUpdate=true - elif [[ "$arg" =~ ^--stagingdir= ]]; then - arkStagingDir="${ark#--stagingdir=}" - elif [ "$arg" == "--downloadonly" ]; then - downloadonly=1 - elif [ "$arg" == "--no-download" ]; then - nodownload=1 - else - echo "Unrecognized option $arg" - echo "Try 'arkmanager -h' or 'arkmanager --help' for more information." - exit 1 - fi + case "$arg" in + --force) appupdate=1; ;; + --safe) updatetype=safe; ;; + --warn) updatetype=warn; ;; + --ifempty) updatetype=ifempty; ;; + --warnreason=*) warnreason="${arg#--warnreason=}"; ;; + --validate) validate=validate; appupdate=1; ;; + --saveworld) saveworld=1; ;; + --update-mods) modupdate=1; ;; + --backup) arkBackupPreUpdate=true; ;; + --stagingdir=*) arkStagingDir="${arg#--stagingdir=}"; ;; + --downloadonly) downloadonly=1; ;; + --no-download) nodownload=1; ;; + *) + echo "Unrecognized option $arg" + echo "Try 'arkmanager -h' or 'arkmanager --help' for more information." + exit 1 + esac done echo "$$" >"${arkserverroot}/.ark-update.lock.$$" 2>/dev/null From ca9ea08ebe46b4c5be5a339a19ebbb9736accf69 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 16 Jul 2016 13:17:20 +1000 Subject: [PATCH 21/24] Fix error in last commit --- tools/arkmanager | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/arkmanager b/tools/arkmanager index 29f602a..63d3743 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1001,7 +1001,7 @@ printWarnMessage(){ if [ -z "$reason" ]; then reason="$warnreason" fi - if [ "$1" == "update" ]; then + elif [ "$1" == "update" ]; then if [ -n "$appupdate" ]; then if [ -n "$modupdate" ]; then if [ -n "$msgReasonUpdateAppMod" ]; then From 94f3e9566d6bc19620845c458ad31eb68d02478a Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 16 Jul 2016 13:21:25 +1000 Subject: [PATCH 22/24] Stop warning if server is offline --- tools/arkmanager | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index 63d3743..bf6bd69 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -1174,7 +1174,10 @@ doWarn(){ for (( min = warnminutes; min >= warninterval; min-- )); do numplayers=$(numPlayersConnected) echo "There are ${numplayers} players connected" - if (( (numplayers + 0) == 0 )); then + if [[ "numplayers" == "-1" ]]; then + echo "Server is not running. Shutting down immediately" + return 0 + elif (( (numplayers + 0) == 0 )); then doBroadcastWithEcho "Nobody is connected. Shutting down immediately" rm -f "${arkserverroot}/.ark-warn.lock" return 0 @@ -1207,7 +1210,10 @@ doWarn(){ if (( warnseconds >= 20 )); then numplayers=$(numPlayersConnected) echo "There are ${numplayers} players connected" - if (( (numplayers + 0) == 0 )); then + if [[ "numplayers" == "-1" ]]; then + echo "Server is not running. Shutting down immediately" + return 0 + elif (( (numplayers + 0) == 0 )); then doBroadcastWithEcho "Nobody is connected. Shutting down immediately" rm -f "${arkserverroot}/.ark-warn.lock" return 0 From 4b98f92ff8a158075922f462a143f50b1de581e9 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 23 Jul 2016 02:18:51 +1000 Subject: [PATCH 23/24] Use the A2S_PLAYER query to get active players --- tools/arkmanager | 57 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index bf6bd69..788ed96 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -599,18 +599,39 @@ function isTheServerOnline(){ # Check if anybody is connected to the server # function numPlayersConnected(){ - perl -MSocket -e ' - my $port = int($ARGV[0]); - socket(my $socket, PF_INET, SOCK_DGRAM, 0); - setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack("i4", 1, 0, 0, 0)); - my $sockaddr = pack_sockaddr_in($port, inet_aton($ARGV[1])); - send($socket, "\xff\xff\xff\xffTSource Engine Query\x00", 0, $sockaddr); - my $data = ""; - recv($socket, $data, 1400, 0) or (print "-1" and exit(1)); - my ($servername, $mapname, $game, $fullname, $rest) = split(/\x00/, substr($data, 6), 5); - my $players = ord(substr($rest, 2, 1)); - print "$players\n"; - ' "$(getQueryPort)" "${ark_MultiHome:-127.0.0.1}" + if [ -n "$arkUsePlayerList" ]; then + perl -MSocket -e ' + my $port = int($ARGV[0]); + socket(my $socket, PF_INET, SOCK_DGRAM, 0); + setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack("i4", 1, 0, 0, 0)); + my $sockaddr = pack_sockaddr_in($port, inet_aton($ARGV[1])); + send($socket, "\xff\xff\xff\xff\x55\xff\xff\xff\xff", 0, $sockaddr); + my $data = ""; + recv($socket, $data, 1400, 0) or (print "-1" and exit(1)); + if (ord(substr($data, 4, 1)) == 0x41) { + my $chal = substr($data, 5); + send($socket, "\xff\xff\xff\xff\x55" . $chal, 0, $sockaddr); + $data = ""; + recv($socket, $data, 1400, 0) or (print "-1" and exit(1)); + } + ord(substr($data, 4, 1)) != 0x44 and (print "-1" and exit(1)); + my $players = ord(substr($data, 5, 1)); + print "$players\n"; + ' "$(getQueryPort)" "${ark_MultiHome:-127.0.0.1}" + else + perl -MSocket -e ' + my $port = int($ARGV[0]); + socket(my $socket, PF_INET, SOCK_DGRAM, 0); + setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack("i4", 1, 0, 0, 0)); + my $sockaddr = pack_sockaddr_in($port, inet_aton($ARGV[1])); + send($socket, "\xff\xff\xff\xffTSource Engine Query\x00", 0, $sockaddr); + my $data = ""; + recv($socket, $data, 1400, 0) or (print "-1" and exit(1)); + my ($servername, $mapname, $game, $fullname, $rest) = split(/\x00/, substr($data, 6), 5); + my $players = ord(substr($rest, 2, 1)); + print "$players\n"; + ' "$(getQueryPort)" "${ark_MultiHome:-127.0.0.1}" + fi } # @@ -2063,6 +2084,18 @@ printStatus(){ my $maxplayers = ord(substr($rest, 3, 1)); print "Server Name: $servername\n"; print "Players: $players / $maxplayers\n"; + send($socket, "\xff\xff\xff\xff\x55\xff\xff\xff\xff", 0, $sockaddr); + $data = ""; + recv($socket, $data, 1400, 0) or (print "Challenge request failed" and exit(1)); + if (ord(substr($data, 4, 1)) == 0x41) { + my $chal = substr($data, 5); + send($socket, "\xff\xff\xff\xff\x55" . $chal, 0, $sockaddr); + $data = ""; + recv($socket, $data, 1400, 0) or (print "A2S_PLAYERS request failed" and exit(1)); + } + ord(substr($data, 4, 1)) != 0x44 and (print ("A2S_PLAYERS Response: : " . unpack("H*", $data)) and exit(1)); + my $players = ord(substr($data, 5, 1)); + print "Active Players: $players\n"; ' "$(getQueryPort)" "${ark_MultiHome:-127.0.0.1}" if isTheServerOnline; then From 2d76c199e6054707023c4f88c5f00c37db828b50 Mon Sep 17 00:00:00 2001 From: Ben Peddell Date: Sat, 23 Jul 2016 02:46:22 +1000 Subject: [PATCH 24/24] --warnreason now implies --warn --- tools/arkmanager | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/arkmanager b/tools/arkmanager index 788ed96..90a4f23 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -886,7 +886,7 @@ doStop() { for arg in "$@"; do case "$arg" in --warn) dowarn=1; ;; - --warnreason=*) warnreason="${arg#--warnreason=}"; ;; + --warnreason=*) warnreason="${arg#--warnreason=}"; dowarn=1; ;; --saveworld) dosave=1; ;; esac done @@ -1280,7 +1280,7 @@ doUpdate() { --safe) updatetype=safe; ;; --warn) updatetype=warn; ;; --ifempty) updatetype=ifempty; ;; - --warnreason=*) warnreason="${arg#--warnreason=}"; ;; + --warnreason=*) warnreason="${arg#--warnreason=}"; updatetype=warn; ;; --validate) validate=validate; appupdate=1; ;; --saveworld) saveworld=1; ;; --update-mods) modupdate=1; ;;