diff --git a/.version b/.version index 7e32cd5..c068b24 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.3 +1.4 diff --git a/README.md b/README.md index 9cafe98..3b22950 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,12 @@ NB: You may want to change the `bash -s` parameter to fit your steam user if dif This will copy the `arkmanager` script and its daemon to the proper directories and will create an empty log directory in `/var/log` for ARK Server Tools. +To instead perform a user-install of ARK Server Tools as an unprivileged user, run this command: + +```sh +curl -sL http://git.io/vtf5N | bash -s -- --me +``` + ## Configuration Stored in `/etc/arkmanager/arkmanager.cfg` you can find the variables needed to start the server, like the port numbers, the system environment variables and so on. @@ -54,6 +60,12 @@ ark_DifficultyOffset=1 Your session name may not contain special characters (eg. `!![EU]!! Aw&some ARK`) as it could break the startup command. In this case you may want to comment out the `ark_SessionName` variable and define it inside your **GameUserSettings.ini** file instead. +To specify an option without an argument (e.g. `bRawSockets`), specify an empty argument (e.g. `ark_bRawSockets=""`). + +To specify a dash-option without an argument (e.g. `-log`), add the option="" prefixed with `arkflag_` (e.g. `arkflag_log=""`). + +To specify a dash-option with an argument (e.g. `-StructureDestructionTag=DestroySwampSnowStructures`), add the option=value prefixed with `arkopt_` (e.g. `arkopt_StructureDestructionTag=DestroySwampSnowStructures`). + You can override or add variables for a specific system user creating a file called `.arkmanager.cfg` in the home directory of the system user. ## Install ARK Server @@ -80,30 +92,46 @@ Stops ARK server Restarts ARK server #### arkmanager update -Manually updates ARK server if a new version is available +Manually updates ARK server if a new version is available. +This accepts zero or more of the below options. -#### arkmanager update --force +##### arkmanager update --force Apply update without check the current version -#### arkmanager update --safe +##### arkmanager update --safe Waits for server to perform world save and then updates. +##### arkmanager update --warn +Warns the players for a configurable amount of time before updating. Should be suitable for adding to a cron job. + +##### arkmanager update --validate +Validates all ARK server files + +##### arkmanager update --update-mods +Updates installed and requested mods + +##### arkmanager update --backup +Takes a backup of the save files before updating. + #### arkmanager status Get the status of the server. Show if the process is running, if the server is up and the current version number #### arkmanager checkupdate Check if a new version of the server is available but not apply it -#### arkmanager upgrade +#### arkmanager upgrade-tools Check for a new ARK Server Tools version and upgrades it if needed +#### arkmanager uninstall-tools +Uninstalls the ARK Server Tools + #### arkmanager backup Saves a backup of your server inside the backup directory #### arkmanager broadcast "message" Broadcast a message to all curently connected players. Example: ``` -arkmanager broadcast "Hi, admin there" +arkmanager broadcast "Hi, admin here" ``` #### arkmanager saveworld diff --git a/netinstall.sh b/netinstall.sh index e1a2a40..867428f 100644 --- a/netinstall.sh +++ b/netinstall.sh @@ -4,7 +4,9 @@ # Net Installer, used with curl # +steamcmd_user="$1" channel=${2:-master} # if defined by 2nd argument install the defined version, otherwise install master +shift 2 # Download and untar installation files cd /tmp @@ -33,7 +35,7 @@ sed -i "s|^arkstCommit='.*'$|arkstCommit='${COMMIT}'|" arkmanager version=`<../.version` sed -i "s|^arkstVersion=\".*\"|arkstVersion='${version}'|" arkmanager chmod +x install.sh -bash install.sh $1 > /dev/null +bash install.sh "$steamcmd_user" "$@" > /dev/null status=$? @@ -42,7 +44,7 @@ rm -rf /tmp/ark-server-tools-${channel} # Print messages case "$status" in "0") - echo "ARK Server Tools were correctly installed in your system inside the home directory of $1!" + echo "ARK Server Tools were correctly installed in your system inside the home directory of $steamcmd_user!" ;; "1") @@ -50,6 +52,6 @@ case "$status" in ;; "2") echo "WARNING: 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 "ARK Server Tools were correctly installed in your system inside the home directory of $1!" + echo "ARK Server Tools were correctly installed in your system inside the home directory of $steamcmd_user!" ;; esac diff --git a/tools/arkmanager b/tools/arkmanager index f8b6b3f..cd9d2f6 100755 --- a/tools/arkmanager +++ b/tools/arkmanager @@ -6,10 +6,111 @@ # Maintainer: FezVrasta # Contributors: Sispheor, Atriusftw, klightspeed, lexat, puseidr +# Script version +arkstVersion="1.4" +arkstCommit='' + +doUpgradeTools() { + local sudo=sudo + if [ "$UID" == 0 -o "$steamcmd_user" == "--me" ]; then + sudo= + fi + echo "arkmanager v${arkstVersion}: Checking for updates..." + arkstLatestVersion=`curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/.version` + arkstLatestCommit=`curl -s https://api.github.com/repos/FezVrasta/ark-server-tools/git/refs/heads/${arkstChannel} | sed -n 's/^ *"sha": "\(.*\)",.*/\1/p'` + + if [ "$arkstLatestVersion" == "Not Found" ]; then + echo "Channel ${arkstChannel} does not exist" + echo + echo "Available channels:" + curl -s https://api.github.com/repos/FezVrasta/ark-server-tools/git/refs/heads | sed -n 's|^ *"ref": "refs/heads/\(.*\)",|\1|p' + echo + return + fi + + reinstall_args=() + if [ -n "$install_bindir" ]; then + reinstall_args=( "${reinstall_args[@]}" "--bindir" "$install_bindir" ) + fi + if [ -n "$install_libexecdir" ]; then + reinstall_args=( "${reinstall_args[@]}" "--libexecdir" "$install_libexecdir" ) + fi + if [ -n "$install_datadir" ]; then + reinstall_args=( "${reinstall_args[@]}" "--datadir" "$install_datadir" ) + fi + if [[ $arkstLatestVersion > $arkstVersion ]]; then + read -p "A new version was found! Do you want to upgrade ARK Server Tools to v${arkstLatestVersion}?" -n 1 -r + echo -en "\n" + if [[ $REPLY =~ ^[Yy]$ ]]; then + curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/netinstall.sh | $sudo bash -s -- ${steamcmd_user} ${arkstChannel} "${reinstall_args[@]}" + exit 0 + fi + elif [[ $arkstLatestVersion == $arkstVersion && "$arkstLatestCommit" != "$arkstCommit" ]]; then + read -p "A hotfix is available for v${arkstLatestVersion}. Do you wish to install it?" -n 1 -r + echo -en "\n" + if [[ $REPLY =~ ^[Yy]$ ]]; then + curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/netinstall.sh | $sudo bash -s -- ${steamcmd_user} ${arkstChannel} "${reinstall_args[@]}" + exit 0 + fi + else + echo "Your ARK server tools are already up to date" + fi +} + +doUninstallTools() { + local sudo=sudo + if [ "$UID" == 0 -o "$steamcmd_user" == "--me" ]; then + sudo= + fi + + read -p "Are you sure you want to uninstall the ARK Server Tools?" -n 1 -r + + if [[ "$REPLY" =~ ^[Yy]$ ]]; then + if [ -n "${install_datadir}" -a -x "${install_datadir}/arkmanager-uninstall.sh" ]; then + $sudo "${install_datadir}/arkmanager-uninstall.sh" + exit 0 + elif [ -n "${install_libexecdir}" -a -x "${install_libexecdir}/arkmanager-uninstall.sh" ]; then + $sudo "${install_libexecdir}/arkmanager-uninstall.sh" + exit 0 + fi + fi +} + +runAsRoot(){ + getConfigVar(){ + val="$(echo -ne "$(sed -n "/^$1=/{s|^[^=]*=||;s|[[:space:]]*\(#.*\)*\$||;s|^\"\\(.*\\)\"\$|\\1|;s|^'\\(.*\\)'\$|\\1|;p}" <"/etc/arkmanager/arkmanager.cfg" | tail -n1)")" + if [ -n "$val" ]; then + echo "$val" + else + echo "$2" + fi + } + + arkstChannel="$(getConfigVar arkstChannel "master")" + install_bindir="$(getConfigVar install_bindir "${0%/*}")" + install_libexecdir="$(getConfigVar install_libexecdir "${install_bindir%/*}/libexec/arkmanager")" + install_datadir="$(getConfigVar install_datadir "${install_bindir%/*}/share/arkmanager")" + steamcmd_user="$(getConfigVar steamcmd_user "steam")" + + if ! getent passwd "$steamcmd_user" >/dev/null 2>&1; then + echo "Invalid steamcmd_user in config file" + exit 1 + fi + + if [ "$1" == "upgrade-tools" ]; then + doUpgrade + elif [ "$1" == "uninstall-tools" ]; then + doUninstallTools + else + su "$steamcmd_user" -c "$(printf "%q" "$0")$(printf " %q" "$@")" + exit 1 + fi +} + # Check the user is not currently running this script as root if [ "$(id -u)" == "0" ]; then - echo "This script must NOT be run as root" 1>&2 - exit 1 + runAsRoot "$@" + exit 0 fi #--------------------- @@ -39,12 +140,23 @@ YELLOW="\\e[0;33m" NORMAL="\\033[0;39m" maxOpenFiles=100000 +# Set TERM to "dumb" if TERM is not set +export TERM=${TERM:-dumb} + arkmanagerLog="arkmanager.log" # here are logged the actions performed by arkmanager arkserverLog="arkserver.log" # here is logged the output of ShooterGameServer -# Script version -arkstVersion="1.3" -arkstCommit='' +appid="${appid:-376030}" +mod_appid="${mod_appid:-346110}" +arkautorestartfile="${arkautorestartfile:-ShooterGame/Saved/.autorestart}" +install_bindir="${install_bindir:-${0%/*}}" +install_libexecdir="${install_libexecdir:-${install_bindir%/*}/libexec/arkmanager}" + +if [ "$steamcmd_user" == "--me" ]; then + install_datadir="${install_datadir:-${HOME}/.share/local/arkmanager}" +else + install_datadir="${install_datadir:-${install_bindir%/*}/share/arkmanager}" +fi #--------------------- # functions @@ -130,17 +242,18 @@ rconcmd() { } my $port = $ARGV[0]; - my $password = $ARGV[1]; - my $command = $ARGV[2]; + my $ipaddr = $ARGV[1]; + my $password = $ARGV[2]; + my $command = $ARGV[3]; socket(my $socket, PF_INET, SOCK_STREAM, 0); setsockopt($socket, SOL_SOCKET, SO_RCVTIMEO, pack("i4", 30, 0, 0, 0)); - my $sockaddr = pack_sockaddr_in($port, inet_aton("127.0.0.1")); + my $sockaddr = pack_sockaddr_in($port, inet_aton($ipaddr)); connect($socket, $sockaddr) or die "Error connecting to server"; auth($socket, $password); sendpkt($socket, 2, 2, $command); my ($resid, $restype, $rcvbody) = recvpkt($socket); print $rcvbody, "\n"; - ' "${ark_RCONPort}" "`getAdminPassword`" "$1" + ' "${ark_RCONPort}" "${ark_MultiHome:-127.0.0.1}" "`getAdminPassword`" "$1" } # @@ -200,12 +313,11 @@ function checkForUpdate(){ function isUpdateNeeded(){ getCurrentVersion getAvailableVersion - if [ "$bnumber" -eq "$instver" ]; then + if [[ "$bnumber" == "Unknown" || "$bnumber" -eq "$instver" ]]; then return 1 # no update needed else return 0 # update needed fi - } # @@ -245,7 +357,6 @@ function getCurrentVersion(){ else instver="" fi - return $instver } # @@ -253,8 +364,10 @@ function getCurrentVersion(){ # function getAvailableVersion(){ rm -f "$steamcmd_appinfocache" - bnumber=`$steamcmdroot/$steamcmdexec +login anonymous +app_info_update 1 +app_info_print "$appid" +quit | while read name val; do if [ "${name}" == "{" ]; then parseSteamACF ".depots.branches.public" "buildid"; break; fi; done` - return $bnumber + bnumber=`$steamcmdroot/$steamcmdexec +@NoPromptForPassword 1 +login ${steamlogin:-anonymous} +app_info_update 1 +app_info_print "$appid" +quit | while read name val; do if [ "${name}" == "{" ]; then parseSteamACF ".depots.branches.public" "buildid"; break; fi; done` + if [ -z "$bnumber" ]; then + bnumber="Unknown" + fi } # @@ -276,12 +389,36 @@ function isTheServerRunning(){ } # -# Check if the server is up and visible in steam server list +# Check if the server is up # # function isTheServerUp(){ - $lsof -i :"$ark_Port" > /dev/null + $lsof -i "${ark_MultiHome:+udp@}${ark_MultiHome}:${ark_Port}" > /dev/null result=$? + if [ $result -ne 0 ]; then + perl -MSocket -MFcntl -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 $flags = fcntl($socket, F_GETFL, 0) or exit(1); + fcntl($socket, F_SETFL, $flags | O_NONBLOCK) or exit(1); + my $data = ""; + my $rin = ""; + vec($rin, fileno($socket), 1) = 1; + if (select($rin, undef, undef, 0.25) >= 0) { + recv($socket, $data, 1400, 0) or exit(1); + my ($servername, $mapname, $game, $fullname, $rest) = split(/\x00/, substr($data, 6), 5); + my $maxplayers = ord(substr($rest, 3, 1)); + if ($maxplayers == 0) { exit(1); } + exit(0); + } else { + exit(1); + } + ' "${ark_QueryPort}" "${ark_MultiHome:-127.0.0.1}" + result=$? + fi # In this case, the result is: # 1 if the command fail. The port is not listenning # 0 if the command succeed. The port is listenning @@ -292,16 +429,44 @@ function isTheServerUp(){ fi } +# +# Check if the server is visible in the steam server list +# +function isTheServerOnline(){ + if [ -n "$ark_MultiHome" ]; then + publicip="$(curl --interface "${ark_MultiHome}" -s https://api.ipify.org/)" + else + publicip="$(curl -s https://api.ipify.org/)" + fi + local serverresp + + if [[ "$publicip" =~ [1-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]* ]]; then + serverresp="$(curl -s "http://api.steampowered.com/ISteamApps/GetServersAtAddress/v0001?addr=${publicip}:${ark_QueryPort}")" + fi + + # If the Steam server response contains "addr": "$ip:$port", + # then the server has registered with the Steam master server + if [[ "$serverresp" =~ \"addr\":\ \"([^\"]*):([0-9]*)\" ]]; then + return 0 + else + return 1 + fi +} + # # run function # doRun() { + cd "$arkserverroot" + arkserveropts="$serverMap" if [ -n "$serverMapModId" ]; then arkserveropts="-MapModID=$serverMapModId" fi + arkextraopts=( ) + # bring in ark_... options for varname in "${!ark_@}"; do name="${varname#ark_}" @@ -321,13 +486,96 @@ doRun() { fi done + # bring in arkflag_... flags + for varname in "${!arkflag_@}"; do + name="${varname#arkflag_}" + + arkextraopts=( "${arkextraopts[@]}" "-${name}" ) + done + + # bring in arkopt_... options + for varname in "${!arkopt_@}"; do + name="${varname#arkopt_}" + val="${!varname}" + + if [ -n "$val" ]; then + arkextraopts=( "${arkextraopts[@]}" "-${name}=${val}" ) + fi + done + arkserveropts="${arkserveropts}?listen" # run the server in background echo "`timestamp`: start" # set max open files limit before we start the server ulimit -n $maxOpenFiles - "$arkserverroot/$arkserverexec" "$arkserveropts" - echo "`timestamp`: exited with status $?" + + serverpid=0 + restartserver=1 + + # Shutdown the server when we are terminated + shutdown_server(){ + restartserver=0 + rm "$arkserverroot/$arkautorestartfile" + if [ "$serverpid" -ne 0 ]; then + kill -INT $serverpid + fi + } + + trap shutdown_server INT TERM + + # Auto-restart loop + while [ $restartserver -ne 0 ]; do + echo -n "`timestamp`: Running" + printf " %q" "$arkserverroot/$arkserverexec" "$arkserveropts" "${arkextraopts[@]}" + echo + # Put the server process into the background so we can monitor it + "$arkserverroot/$arkserverexec" "$arkserveropts" "${arkextraopts[@]}" & + # Grab the server PID + serverpid=$! + echo "`timestamp`: Server PID: $serverpid" + # Disable auto-restart so we don't get caught in a restart loop + rm -f "$arkserverroot/$arkautorestartfile" + restartserver=0 + + sleep 5 + + while true; do + # Grab the current server PID + local pid="`getServerPID`" + if [ "$pid" == "$serverpid" ]; then + if [ "$restartserver" -eq 0 ]; then + # Check if the server has fully started + if ! isTheServerUp; then + # Enable auto-restart if the server is up + echo "`timestamp`: server is up" + touch "$arkserverroot/$arkautorestartfile" + restartserver=1 + fi + fi + else + echo "`timestamp`: Bad PID '$pid'; expected '$serverpid'" + if [ "$pid" != "" ]; then + # Another instance must be running - disable autorestart + restartserver=0 + fi + break + fi + sleep 5 + done + + # Wait on the now-dead process to reap it and get its return status + wait $serverpid + echo "`timestamp`: exited with status $?" + + # doStop will remove the autorestart file + if [ ! -f "$arkserverroot/$arkautorestartfile" ]; then + restartserver=0 + fi + + if [ "$restartserver" -ne 0 ]; then + echo "`timestamp`: restarting server" + fi + done } # @@ -347,6 +595,21 @@ doStart() { fi } +# +# starts all servers specified by configfile_xxxxx in config file +# +doStartAll(){ + doStart + for cfg in "${!configfile_@}"; do + if [ -f "${!cfg}" ]; then + ( + source "${!cfg}" + doStart + ) + fi + done +} + # # stop the ARK server # @@ -355,11 +618,12 @@ doStop() { tput sc echo "Stopping server..." echo "`timestamp`: stopping" >> "$logdir/$arkmanagerLog" + rm -f "$arkserverroot/$arkautorestartfile" # kill the server with the PID PID=`getServerPID` kill -INT $PID - for (( i = 0; i < 10; i++ )); do + for (( i = 0; i < 20; i++ )); do sleep 1 if ! isTheServerRunning; then break @@ -380,6 +644,21 @@ doStop() { fi } +# +# stops all servers specified by configfile_xxxxx in config file +# +doStopAll(){ + doStop + for cfg in "${!configfile_@}"; do + if [ -f "${!cfg}" ]; then + ( + source "${!cfg}" + doStop + ) + fi + done +} + # # install of ARK server # @@ -397,108 +676,382 @@ doInstall() { cd "$steamcmdroot" # install the server - ./$steamcmdexec +login anonymous +force_install_dir "$arkserverroot" +app_update $appid validate +quit + ./$steamcmdexec +@NoPromptForPassword 1 +login ${steamlogin:-anonymous} +force_install_dir "$arkserverroot" +app_update $appid validate +quit # the current version should be the last version. We set our version getCurrentVersion } +# +# Waits for a configurable number of minutes before updating the server +# +doUpdateWarn(){ + cd "$arkserverroot" + + local pid=`getServerPID` + if [ -n "$pid" ]; then + local warnmsg + local warnminutes=$(( arkwarnminutes )) + if (( warnminutes == 0 )); then + warnminutes=60 + fi + + local warnintervals=( 90 60 45 30 20 15 10 5 4 3 2 1 ) + + for warninterval in "${warnintervals[@]}"; do + if [ "`getServerPID`" != "$pid" ]; then + echo "Server has stopped. Aborting update" + return 1 + fi + if (( arkwarnminutes > warninterval )); then + if [ -n "$msgWarnUpdateMinutes" ]; then + warnmsg="$(printf "$msgWarnUpdateMinutes" "$warnminutes")" + else + warnmsg="$(printf "This ARK server will shutdown for an update in %d minutes" "$warnminutes")" + fi + doBroadcastWithEcho "$warnmsg" + sleep $(( warnminutes - warninterval ))m + warnminutes=$warninterval + fi + done + + local warnseconds=90 + warnintervals=( 60 45 30 20 15 10 5 0 ) + for warninterval in "${warnintervals[@]}"; do + if [ "`getServerPID`" != "$pid" ]; then + echo "Server has stopped. Aborting update" + return 1 + fi + if [ -n "$msgWarnUpdateSeconds" ]; then + warnmsg="$(printf "$msgWarnUpdateSeconds" "$warnseconds")" + else + warnmsg="$(printf "This ARK server will shutdown for an update in %d seconds" "$warnseconds")" + fi + doBroadcastWithEcho "$warnmsg" + sleep $(( warnseconds - warninterval ))s + warnseconds=$warninterval + done + fi + + if [ "`getServerPID`" != "$pid" ]; then + echo "Server has stopped. Aborting update" + return 1 + fi + + return 0 +} + # # Stop the server, update it and then start it back. # doUpdate() { + local appupdate= + local updatetype=normal + local validate= + local modupdate= + local saveworld= + + for arg in "$@"; do + if [ "$arg" == "--force" ]; then + appupdate=1 + elif [ "$arg" == "--safe" ]; then + updatetype=safe + elif [ "$arg" == "--warn" ]; then + updatetype=warn + 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 + fi + done + + if [ -n "$modupdate" ]; then + if ! doDownloadAllMods; then + modupdate= + fi + if ! isAnyModUpdateNeeded; then + modupdate= + fi + fi + cd "$arkserverroot" if isUpdateNeeded; then - forceUpdate + appupdate=1 + fi + + if [ -n "$appupdate" -o -n "$modupdate" ]; then + if isTheServerRunning; then + if [ "$updatetype" == "safe" ]; then + while [ ! `find $arkserverroot/ShooterGame/Saved/SavedArks -mmin -1 -name ${serverMap##*/}.ark` ]; do + echo "`timestamp`: Save file older than 1 minute. Delaying update." >> "$logdir/update.log" + sleep 30s + done + echo "`timestamp`: Save file newer than 1 minute. Performing an update." >> "$logdir/update.log" + elif [ "$updatetype" == "warn" ]; then + if ! doUpdateWarn; then + return 1 + fi + fi + fi + + # check if the server was alive before the update so we can launch it back after the update + serverWasAlive=0 + if isTheServerRunning ;then + serverWasAlive=1 + fi + + if [ -n "$saveworld" ]; then + echo "Saving world" + doSaveWorld + fi + + doStop + + # If user wants to back-up, we do it here. + + if [ "$arkBackupPreUpdate" == "true" ]; then + doBackup + fi + + if [ -n "$appupdate" ]; then + cd "$steamcmdroot" + ./$steamcmdexec +@NoPromptForPassword 1 +login ${steamlogin:-anonymous} +force_install_dir "$arkserverroot" +app_update $appid $validate +quit + # the current version should be the last version. We set our version + getCurrentVersion + echo "`timestamp`: update to $instver complete" >> "$logdir/update.log" + fi + + if [ -n "$modupdate" ]; then + for modid in $(getModIds); do + if isModUpdateNeeded $modid; then + doExtractMod $modid + echo "`timestamp`: Mod $modid updated" >> "$logdir/update.log" + fi + done + fi + + # we restart the server only if it was started before the update + if [ $serverWasAlive -eq 1 ]; then + doStart + fi else echo "Your server is already up to date! The most recent version is ${bnumber}." echo "`timestamp`: No update needed." >> "$logdir/update.log" fi; } -forceUpdate(){ - # check if the server was alive before the update so we can launch it back after the update - serverWasAlive=0 - if isTheServerRunning ;then - serverWasAlive=1 - fi - echo "Saving world" - doSaveWorld - doStop +# +# Get the Mod IDs of the installed mods and the requested mods +# +getModIds(){ + ( + echo "${serverMapModId}" + echo "${ark_TotalConversionMod}" + echo "${ark_GameModIds}" | tr ',' '\n' + find "${arkserverroot}/ShooterGame/Content/Mods" -maxdepth 1 -type d -printf "%P\n" + ) | sort | uniq | grep '^[1-9][0-9]*$' +} + +# +# Downloads a mod from the Steam workshop +# +doDownloadMod(){ + local modid=$1 + local modsrcdir="$steamcmdroot/steamapps/workshop/content/$mod_appid/$modid" + local moddldir="$steamcmdroot/steamapps/workshop/downloads/$mod_appid/$modid" + local dlsize=0 cd "$steamcmdroot" - ./$steamcmdexec +login anonymous +force_install_dir "$arkserverroot" +app_update $appid +quit - # the current version should be the last version. We set our version - getCurrentVersion - echo "`timestamp`: update to $instver complete" >> "$logdir/update.log" - # we restart the server only if it was started before the update - if [ $serverWasAlive -eq 1 ]; then - doStart - fi -} + while true; do + ./$steamcmdexec +@NoPromptForPassword 1 +login ${steamlogin:-anonymous} +workshop_download_item $mod_appid $modid +quit + if [ ! -d "$moddldir" ]; then break; fi + local newsize="`du -s "$moddldir" | cut -f1`" + if [ $newsize -eq $dlsize ]; then break; fi + dlsize=$newsize + done -# -# Waits for server to perform save before update (until save file is newer than 1 minute) -# -doSafeUpdate(){ - cd "$arkserverroot" - - if isUpdateNeeded; then - while [ ! `find $arkserverroot/ShooterGame/Saved/SavedArks -mmin -1 -name ${serverMap##*/}.ark` ]; do - echo "`timestamp`: Save file older than 1 minute. Delaying update." >> "$logdir/update.log" - sleep 30s - done - echo "`timestamp`: Save file newer than 1 minute. Performing an update." >> "$logdir/update.log" - forceUpdate + if [ -f "$modsrcdir/mod.info" ]; then + echo "Mod $modid downloaded" + return 0 else - echo "Your server is already up to date! The most recent version is ${bnumber}." - echo "`timestamp`: No update needed." >> "$logdir/update.log" + echo "Mod $modid was not successfully downloaded" + return 1 fi } # -# Waits for a configurable number of minutes before updating the server +# Downloads all installed and requested mods from the Steam workshop # -doWarnUpdate(){ - cd "$arkserverroot" +doDownloadAllMods(){ + for modid in $(getModIds); do + doDownloadMod $modid || return 1 + done +} - if isUpdateNeeded; then - local pid=`getServerPID` - if [ -n "$pid" ]; then - local warnminutes=$(( arkwarnminutes )) - if (( warnminutes == 0 )); then - warnminutes=60 +# +# Checks if the files a mod owns need to be updated +# +isModUpdateNeeded(){ + local modid=$1 + local modsrcdir="$steamcmdroot/steamapps/workshop/content/$mod_appid/$modid" + local moddestdir="$arkserverroot/ShooterGame/Content/Mods/$modid" + local modbranch="${mod_branch:-Linux}" + + for varname in "${!mod_branch_@}"; do + if [ "mod_branch_$modid" == "$varname" ]; then + modbranch="${!varname}" + fi + done + + if [ \( ! -f "$moddestdir/.modbranch" \) ] || [ "$(<"$moddestdir/.modbranch")" != "$modbranch" ]; then + return 0 + fi + + if [ -f "$modsrcdir/mod.info" ]; then + if [ -f "$modsrcdir/${modbranch}NoEditor/mod.info" ]; then + modsrcdir="$modsrcdir/${modbranch}NoEditor" + fi + + find "$modsrcdir" -type f ! -name "*.z.uncompressed_size" -printf "%P\n" | while read f; do + if [ \( ! -f "$moddestdir/${f%.z}" \) -o "$modsrcdir/$f" -nt "$moddestdir/${f%.z}" ]; then + return 0 fi + done + fi - local warnintervals=( 90 60 45 30 20 15 10 5 4 3 2 1 ) + return 1 +} - for warninterval in "${warnintervals[@]}"; do - if [ "`getServerPID`" != "$pid" ]; then - echo "Server has stopped. Aborting update" - fi - if (( arkwarnminutes > warninterval )); then - doBroadcastWithEcho "This ARK server will shutdown for an update in $warnminutes minutes" - sleep $(( warnminutes - warninterval ))m - warnminutes=$warninterval - fi - done +# +# Checks if any installed or requested mods need to be updated +# +isAnyModUpdateNeeded(){ + for modid in $(getModIds); do + if isModUpdateNeeded $modid; then + return 0 + fi + done - local warnseconds=90 - warnintervals=( 60 45 30 20 15 10 5 0 ) - for warninterval in "${warnintervals[@]}"; do - if [ "`getServerPID`" != "$pid" ]; then - echo "Server has stopped. Aborting update" - fi - doBroadcastWithEcho "This ARK server will shutdown for an update in $warnseconds seconds" - sleep $(( warnseconds - warninterval ))s - warnseconds=$warninterval - done + return 1 +} + +# +# Extracts a mod into the ARK Mods directory +# +doExtractMod(){ + local modid=$1 + local modsrcdir="$steamcmdroot/steamapps/workshop/content/$mod_appid/$modid" + local moddestdir="$arkserverroot/ShooterGame/Content/Mods/$modid" + local modbranch="${mod_branch:-Windows}" + + for varname in "${!mod_branch_@}"; do + if [ "mod_branch_$modid" == "$varname" ]; then + modbranch="${!varname}" + fi + done + + if [ \( ! -f "$moddestdir/.modbranch" \) ] || [ "$(<"$moddestdir/.modbranch")" != "$modbranch" ]; then + rm -rf "$moddestdir" + fi + + if [ -f "$modsrcdir/mod.info" ]; then + echo "Copying files to $moddestdir" + + if [ -f "$modsrcdir/${modbranch}NoEditor/mod.info" ]; then + modsrcdir="$modsrcdir/${modbranch}NoEditor" fi - if [ "`getServerPID`" != "$pid" ]; then - echo "Server has stopped. Aborting update" + find "$modsrcdir" -type d -printf "$moddestdir/%P\0" | xargs -0 -r mkdir -p + + find "$modsrcdir" -type f ! \( -name '*.z' -or -name '*.z.uncompressed_size' \) -printf "%P\n" | while read f; do + if [ \( ! -f "$moddestdir/$f" \) -o "$modsrcdir/$f" -nt "$moddestdir/$f" ]; then + printf "%10d %s " "`stat -c '%s' "$modsrcdir/$f"`" "$f" + cp "$modsrcdir/$f" "$moddestdir/$f" + echo -ne "\r\\033[K" + fi + done + + find "$modsrcdir" -type f -name '*.z' -printf "%P\n" | while read f; do + if [ \( ! -f "$moddestdir/${f%.z}" \) -o "$modsrcdir/$f" -nt "$moddestdir/${f%.z}" ]; then + printf "%10d %s " "`stat -c '%s' "$modsrcdir/$f"`" "${f%.z}" + perl -M'Compress::Raw::Zlib' -e ' + my $sig; + read(STDIN, $sig, 8) or die "Unable to read compressed file"; + if ($sig != "\xC1\x83\x2A\x9E\x00\x00\x00\x00"){ + die "Bad file magic"; + } + my $data; + read(STDIN, $data, 24) or die "Unable to read compressed file"; + my ($chunksizelo, $chunksizehi, + $comprtotlo, $comprtothi, + $uncomtotlo, $uncomtothi) = unpack("(LLLLLL)<", $data); + my @chunks = (); + my $comprused = 0; + while ($comprused < $comprtotlo) { + read(STDIN, $data, 16) or die "Unable to read compressed file"; + my ($comprsizelo, $comprsizehi, + $uncomsizelo, $uncomsizehi) = unpack("(LLLL)<", $data); + push @chunks, $comprsizelo; + $comprused += $comprsizelo; + } + foreach my $comprsize (@chunks) { + read(STDIN, $data, $comprsize) or die "File read failed"; + my ($inflate, $status) = new Compress::Raw::Zlib::Inflate(); + my $output; + $status = $inflate->inflate($data, $output, 1); + if ($status != Z_STREAM_END) { + die "Bad compressed stream; status: " . ($status); + } + if (length($data) != 0) { + die "Unconsumed data in input" + } + print $output; + } + ' <"$modsrcdir/$f" >"$moddestdir/${f%.z}" + touch -c -r "$modsrcdir/$f" "$moddestdir/${f%.z}" + echo -ne "\r\\033[K" + fi + done + + perl -e ' + my $data; + { local $/; $data = ; } + my $mapnamelen = unpack("@0 L<", $data); + my $mapname = substr($data, 4, $mapnamelen - 1); + $mapnamelen += 4; + my $mapfilelen = unpack("@" . ($mapnamelen + 4) . " L<", $data); + my $mapfile = substr($data, $mapnamelen + 8, $mapfilelen); + print pack("L< L< L< Z8 L< C L< L<", $ARGV[0], 0, 8, "ModName", 1, 0, 1, $mapfilelen); + print $mapfile; + print "\x33\xFF\x22\xFF\x02\x00\x00\x00\x01"; + ' $modid <"$moddestdir/mod.info" >"$moddestdir/.mod" + + if [ -f "$moddestdir/modmeta.info" ]; then + cat "$moddestdir/modmeta.info" >>"$moddestdir/.mod" + else + echo -ne '\x01\x00\x00\x00\x08\x00\x00\x00ModType\x00\x02\x00\x00\x001\x00' >>"$moddestdir/.mod" fi - doUpdate + fi +} + +# +# Downloads mod and installs it into mods directory +# +doInstallMod(){ + local modid=$1 + + if [ -f "$steamcmdroot/steamapps/workshop/appworkshop_${mod_appid}.acf" ]; then + sed -i "/^\\t\\t\"${modid}\"/,/^\\t\\t}/d" "$steamcmdroot/steamapps/workshop/appworkshop_${mod_appid}.acf" + fi + + if doDownloadMod $modid; then + doExtractMod $modid + echo "Mod $modid installed" fi } @@ -508,6 +1061,7 @@ doWarnUpdate(){ doBackup(){ local datestamp=`date +"%Y-%m-%d_%H.%M.%S"` local backupdir="${arkbackupdir}/${datestamp}" + local savedir="SavedArks" mkdir -p "$backupdir" # extract the map name from the active map mod @@ -524,17 +1078,22 @@ doBackup(){ ' <"${arkserverroot}/ShooterGame/Content/Mods/${serverMapModId}/mod.info")" fi + # Get save directory name + if [ -n "${ark_AltSaveDirectoryName}" ]; then + savedir="${ark_AltSaveDirectoryName}" + fi + # ARK server uses Write-Unlink-Rename echo -ne "${NORMAL} Copying ARK world file " - cp -p "${arkserverroot}/ShooterGame/Saved/SavedArks/${serverMap##*/}.ark" "${backupdir}/${serverMap##*/}.ark" + cp -p "${arkserverroot}/ShooterGame/Saved/${savedir}/${serverMap##*/}.ark" "${backupdir}/${serverMap##*/}.ark" if [ ! -f "${backupdir}/${serverMap##*/}.ark" ]; then sleep 2 - cp -p "${arkserverroot}/ShooterGame/Saved/SavedArks/${serverMap##*/}.ark" "${backupdir}/${serverMap##*/}.ark" + cp -p "${arkserverroot}/ShooterGame/Saved/${savedir}/${serverMap##*/}.ark" "${backupdir}/${serverMap##*/}.ark" fi # If both attempts fail, server may have # crashed between unlink and rename if [ ! -f "${backupdir}/${serverMap##*/}.ark" ]; then - cp -p "${arkserverroot}/ShooterGame/Saved/SavedArks/${serverMap##*/}.tmp" "${backupdir##*/}/${serverMap##*/}.ark" + cp -p "${arkserverroot}/ShooterGame/Saved/${savedir}/${serverMap##*/}.tmp" "${backupdir##*/}/${serverMap##*/}.ark" fi if [ -f "${backupdir}/${serverMap##*/}.ark" ]; then echo -e "${NORMAL}[ ${GREEN}OK${NORMAL} ]" @@ -543,11 +1102,11 @@ doBackup(){ fi # ARK server uses Lock-Truncate-Write-Unlock - # Unfortunately we can't lock the file, as + # Unfortunately we can't lock the file, as # ARK server uses a non-blocking lock and will # fail to update the file if the lock fails. echo -e "${NORMAL} Copying ARK profile files" - for f in "${arkserverroot}/ShooterGame/Saved/SavedArks/"*.arkprofile; do + for f in "${arkserverroot}/ShooterGame/Saved/${savedir}/"*.arkprofile; do echo -ne "${NORMAL} ${f##*/} " cp -p "${f}" "${backupdir}/${f##*/}" if [ ! -s "${backupdir}/${f##*/}" ]; then @@ -568,7 +1127,7 @@ doBackup(){ # ARK server uses Lock-Truncate-Write-Unlock echo -e "${NORMAL} Copying ARK tribe files " - for f in "${arkserverroot}/ShooterGame/Saved/SavedArks/"*.arktribe; do + for f in "${arkserverroot}/ShooterGame/Saved/${savedir}/"*.arktribe; do echo -ne "${NORMAL} ${f##*/} " cp -p "${f}" "${backupdir}/${f##*/}" if [ ! -s "${backupdir}/${f##*/}" ]; then @@ -612,14 +1171,14 @@ printStatus(){ fi if isTheServerUp ;then - echo -e "$NORMAL" "Server online: " "$RED" "No" "$NORMAL" + echo -e "$NORMAL" "Server listening: " "$RED" "No" "$NORMAL" else - echo -e "$NORMAL" "Server online: " "$GREEN" "Yes" "$NORMAL" + echo -e "$NORMAL" "Server listening: " "$GREEN" "Yes" "$NORMAL" 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("127.0.0.1")); + 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 "Unable to query server\n" and exit(1)); @@ -628,42 +1187,24 @@ printStatus(){ my $maxplayers = ord(substr($rest, 3, 1)); print "Server Name: $servername\n"; print "Players: $players / $maxplayers\n"; - ' "${ark_QueryPort}" + ' "${ark_QueryPort}" "${ark_MultiHome:-127.0.0.1}" + + if isTheServerOnline; then + echo -e "$NORMAL" "Server online: " "$GREEN" "Yes" "$NORMAL" + echo -e "$NORMAL" "ARKServers link: " "$GREEN" "http://arkservers.net/server/${publicip}:${ark_QueryPort}" "$NORMAL" + else + echo -e "$NORMAL" "Server online: " "$RED" "No" "$NORMAL" + fi fi + getCurrentVersion echo -e "$NORMAL" "Server version: " "$GREEN" $instver "$NORMAL" } -doUpgrade() { - local sudo=sudo - if [ "$steamcmd_user" == "--me" ]; then - sudo= - fi - echo "arkmanager v${arkstVersion}: Checking for updates..." - arkstLatestVersion=`curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/.version` - arkstLatestCommit=`curl -s https://api.github.com/repos/FezVrasta/ark-server-tools/git/refs/heads/${arkstChannel} | sed -n 's/^ *"sha": "\(.*\)",.*/\1/p'` - if [[ $arkstLatestVersion > $arkstVersion ]]; then - read -p "A new version was found! Do you want to upgrade ARK Server Tools to v${arkstLatestVersion}?" -n 1 -r - echo -en "\n" - if [[ $REPLY =~ ^[Yy]$ ]]; then - curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/netinstall.sh | $sudo bash -s -- ${steamcmd_user} ${arkstChannel} - else - exit 0 - fi - elif [[ "$arkstLatestCommit" != "$arkstCommit" ]]; then - read -p "A hotfix is available for v${arkstLatestVersion}. Do you wish to install it?" -n 1 -r - echo -en "\n" - if [[ $REPLY =~ ^[Yy]$ ]]; then - curl -s https://raw.githubusercontent.com/FezVrasta/ark-server-tools/${arkstChannel}/netinstall.sh | $sudo bash -s -- ${steamcmd_user} ${arkstChannel} - else - exit 0 - fi - else - echo "Your ARK server tools are already up to date" - fi -} - useConfig() { + if [ "$1" == "main" ]; then + return + fi for varname in "${!configfile_@}"; do if [ "configfile_$1" == "$varname" ]; then source "${!varname}" @@ -682,17 +1223,39 @@ checkConfig while true; do case "$1" in + run) + doRun + ;; start) - doStart + if [ "$2" == "--all" ]; then + doStartAll + shift + else + doStart + fi ;; stop) - doStop + if [ "$2" == "--all" ]; then + doStopAll + shift + else + doStop + fi ;; restart) - doStop + if [ "$2" == "--all" ]; then + doStopAll + else + doStop + fi echo "`timestamp`: stop" >> "$logdir/$arkmanagerLog" sleep 1 - doStart + if [ "$2" == "--all" ]; then + doStartAll + shift + else + doStart + fi echo "`timestamp`: start" >> "$logdir/$arkmanagerLog" echo "`timestamp`: restart" >> "$logdir/$arkmanagerLog" ;; @@ -700,22 +1263,22 @@ while true; do doInstall ;; update) - if [ "$2" == "--force" ]; then - forceUpdate + args=() + + while [[ "$2" =~ ^-- ]]; do + args=( "${args[@]}" "$2" ) shift - elif [ "$2" == "--safe" ]; then - doSafeUpdate - shift - elif [ "$2" == "--warn" ]; then - doWarnUpdate - shift - else - doUpdate - fi + done + + doUpdate "${args[@]}" ;; checkupdate) checkForUpdate ;; + installmod) + doInstallMod "$2" + shift + ;; backup) doBackup ;; @@ -733,8 +1296,11 @@ while true; do status) printStatus ;; - upgrade) - doUpgrade + upgrade-tools) + doUpgradeTools + ;; + uninstall-tools) + doUninstallTools ;; useconfig) useConfig "$2" @@ -742,23 +1308,35 @@ while true; do ;; -h|--help) echo -e "Usage: arkmanager [OPTION]\n" - echo "Option Description" - echo "backup Saves a backup of your server inside the backup directory" - echo "broadcast Sends a message to all users connected to server" - echo "saveworld Saves the game world to disk" - echo "rconcmd Execute RCON command on server" - echo "checkupdate Check for a new ARK server version" - echo "install Install the ARK server files from steamcmd" - echo "restart Stops the server and then starts it" - echo "start Starts the server" - echo "stop Stops the server" - echo "status Returns the status of the current ARK server instance" - echo "update Check for a new ARK server version, if needed, stops the server, updates it, and starts it again" - echo "update --force Apply update without check the current version" - echo "update --safe Wait for server to perform world save and update." - echo "update --warn Warn players before updating server" - echo "upgrade Check for a new ARK Server Tools version and upgrades it if needed" - echo "useconfig Use the configuration overrides in the specified config name or file" + echo "Option Description" + echo "backup Saves a backup of your server inside the backup directory" + echo "broadcast Sends a message to all users connected to server" + echo "saveworld Saves the game world to disk" + echo "rconcmd Execute RCON command on server" + echo "checkupdate Check for a new ARK server version" + echo "install Install the ARK server files from steamcmd" + echo "installmod Installs a mod from the Steam workshop" + echo "restart Stops the server and then starts it" + echo "restart --all Restarts all servers specified in configfile_xxxxx" + echo "run Runs the server without daemonizing" + echo "start Starts the server" + echo "start --all Starts all servers specified in configfile_xxxxx" + echo "stop Stops the server" + echo "stop --all Stops all servers specified in configfile_xxxxx" + echo "status Returns the status of the current ARK server instance" + echo "update [OPTION ...] Check for a new ARK server version, if needed, stops the server, updates it, and starts it again" + echo "upgrade-tools Check for a new ARK Server Tools version and upgrades it if needed" + echo "uninstall-tools Uninstall the ARK Server Tools" + echo "useconfig Use the configuration overrides in the specified config name or file" + echo + echo "Update command takes the below options:" + echo " --force Apply update without checking the current version" + echo " --safe Wait for server to perform world save and update." + echo " --warn Warn players before updating server" + echo " --validate Validates all ARK server files" + echo " --saveworld Saves world before update" + echo " --update-mods Updates installed and requested mods" + echo " --backup Takes a backup of the save files before updating" exit 1 ;; *) diff --git a/tools/arkmanager.cfg b/tools/arkmanager.cfg index 4525da0..a5c9f51 100644 --- a/tools/arkmanager.cfg +++ b/tools/arkmanager.cfg @@ -1,22 +1,34 @@ arkstChannel="master" # change it to a different branch to get non-stable versions +install_bindir="/usr/bin" +install_libexecdir="/usr/libexec/arkmanager" +install_datadir="/usr/share/arkmanager" # config SteamCMD steamcmdroot="/home/steam/steamcmd" # path of your steamcmd instance steamcmdexec="steamcmd.sh" # name of steamcmd executable steamcmd_user="steam" # name of the system user who own steamcmd folder steamcmd_appinfocache="/home/steam/Steam/appcache/appinfo.vdf" # cache of the appinfo command +#steamlogin="anonymous" # Uncomment this to specify steam login instead of using anonymous login # config environment arkserverroot="/home/steam/ARK" # path of your ARK server files (default ~/ARK) arkserverexec="ShooterGame/Binaries/Linux/ShooterGameServer" # name of ARK server executable arkbackupdir="/home/steam/ARK-Backups" # path to backup directory arkwarnminutes="60" # number of minutes to warn players when using update --warn +arkautorestartfile="ShooterGame/Saved/.autorestart" # path to autorestart file +arkBackupPreUpdate="false" # set this to true if you want to perform a backup before updating + +# Update warning messages +# Modify as desired, putting the %d replacement operator where the number belongs +msgWarnUpdateMinutes="This ARK server will shutdown for an update in %d minutes" +msgWarnUpdateSeconds="This ARK server will shutdown for an update in %d seconds" # ARK server options - use ark_= # comment out these values if you want to define them # inside your GameUserSettings.ini file serverMap="TheIsland" # server map (default TheIsland) #serverMapModId="469987622" # Uncomment this to specify the Map Mod Id ( in http://steamcommunity.com/sharedfiles/filedetails/?id=) +#ark_TotalConversionMod="496735411" # Uncomment this to specify a total-conversion mod ark_RCONEnabled="True" # Enable RCON Protocol ark_RCONPort="32330" # RCON Port ark_SessionName="ARK Server Tools" # if your session name needs special characters please use the .ini instead @@ -26,6 +38,14 @@ ark_ServerPassword="" # ARK server ark_ServerAdminPassword="keyboardcat" # ARK server admin password, KEEP IT SAFE! ark_MaxPlayers="70" #ark_GameModIds="487516323,487516324,487516325" # Uncomment to specify additional mods by Mod Id separated by commas +#ark_AltSaveDirectoryName="SotF" # Uncomment to specify a different save directory name + +# ARK server flags - use arkflag_=true +#arkflag_OnlyAdminRejoinAsSpectator=true # Uncomment to only allow admins to rejoin as spectator +#arkflag_DisableDeathSpectator=true # Uncomment to disable players from becoming spectators when they die + +# ARK server options - i.e. for -optname=val, use arkopt_optname=val +#arkopt_StructureDestructionTag=DestroySwampSnowStructures # config Service servicename="arkserv" # Name of the service (don't change if you don't know what are you doing) @@ -33,7 +53,13 @@ logdir="/var/log/arktools" # Logs path # steamdb specific appid=376030 # Linux server App ID +mod_appid=346110 # App ID for mods + +# Mod OS Selection +mod_branch=Windows +# Add mod-specific OS selection below: +#mod_branch_496735411=Windows # alternate configs # example for config name "ark1": -#config_ark1="/path/to/config/file" +#configfile_ark1="/path/to/config/file" diff --git a/tools/install.sh b/tools/install.sh index 7084eab..737a32b 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -1,51 +1,224 @@ #!/bin/bash -if [ "$1" == "--me" ]; then - PREFIX="${PREFIX:-${HOME}}" - EXECPREFIX="${EXECPREFIX:-${PREFIX}}" -else - EXECPREFIX="${EXECPREFIX:-/usr/local}" +userinstall=no +steamcmd_user= +showusage=no + +while [ -n "$1" ]; do + case "$1" in + --me) + userinstall=yes + steamcmd_user="--me" + ;; + -h|--help) + showusage=yes + break + ;; + --prefix=*) + PREFIX="${1#--prefix=}" + ;; + --prefix) + PREFIX="$2" + shift + ;; + --exec-prefix=*) + EXECPREFIX="${1#--exec-prefix=}" + ;; + --exec-prefix) + EXECPREFIX="$2" + shift + ;; + --data-prefix=*) + DATAPREFIX="${1#--data-prefix=}" + ;; + --data-prefix) + DATAPREFIX="$2" + shift + ;; + --install-root=*) + INSTALL_ROOT="${1#--install-root=}" + ;; + --install-root) + INSTALL_ROOT="$2" + shift + ;; + --bindir=*) + BINDIR="${1#--bindir=}" + ;; + --bindir) + BINDIR="$2" + shift + ;; + --libexecdir=*) + LIBEXECDIR="${1#--libexecdir=}" + ;; + --libexecdir) + LIBEXECDIR="$2" + shift + ;; + --datadir=*) + DATADIR="${1#--datadir=}" + ;; + --datadir) + DATADIR="$2" + shift + ;; + -*) + echo "Invalid option '$1'" + showusage=yes + break; + ;; + *) + if [ -n "$steamcmd_user" ]; then + echo "Multiple users specified" + showusage=yes + break; + elif getent passwd "$1" >/dev/null 2>&1; then + steamcmd_user="$1" + else + echo "Invalid user '$1'" + showusage=yes + break; + fi + ;; + esac + shift +done + +if [ "$userinstall" == "yes" -a "$UID" -eq 0 ]; then + echo "Refusing to perform user-install as root" + showusage=yes fi -if [ ! -z "$1" ]; then - if [ "$1" == "--me" -a "$UID" -ne 0 ]; then +if [ "$showusage" == "no" -a -z "$steamcmd_user" ]; then + echo "No user specified" + showusage=yes +fi + +if [ "$userinstall" == "yes" ]; then + PREFIX="${PREFIX:-${HOME}}" + EXECPREFIX="${EXECPREFIX:-${PREFIX}}" + DATAPREFIX="${DATAPREFIX:-${PREFIX}/.local/share}" +else + PREFIX="${PREFIX:-/usr/local}" + EXECPREFIX="${EXECPREFIX:-${PREFIX}}" + DATAPREFIX="${DATAPREFIX:-${PREFIX}/share}" +fi + +BINDIR="${BINDIR:-${EXECPREFIX}/bin}" +LIBEXECDIR="${LIBEXECDIR:-${EXECPREFIX}/libexec/arkmanager}" +DATADIR="${DATADIR:-${DATAPREFIX}/arkmanager}" + +if [ "$showusage" == "yes" ]; then + echo "Usage: ./install.sh {|--me} [OPTIONS]" + echo "You must specify your system steam user who own steamcmd directory to install ARK Tools." + echo "Specify the special used '--me' to perform a user-install." + echo + echo " The user arkmanager should be run as" + echo + echo "Option Description" + echo "--help, -h Show this help text" + echo "--me Perform a user-install" + echo "--prefix Specify the prefix under which to install arkmanager" + echo " [PREFIX=${PREFIX}]" + echo "--exec-prefix Specify the prefix under which to install executables" + echo " [EXECPREFIX=${EXECPREFIX}]" + echo "--data-prefix Specify the prefix under which to install suppor files" + echo " [DATAPREFIX=${DATAPREFIX}]" + echo "--install-root Specify the staging directory in which to perform the install" + echo " [INSTALL_ROOT=${INSTALL_ROOT}]" + echo "--bindir Specify the directory under which to install executables" + echo " [BINDIR=${BINDIR}]" + echo "--libexecdir Specify the directory under which to install executable support files" + echo " [LIBEXECDIR=${LIBEXECDIR}]" + echo "--datadir Specify the directory under which to install support files" + echo " [DATADIR=${DATADIR}]" + exit 1 +fi + +if [ "$userinstall" == "yes" ]; then # Copy arkmanager to ~/bin - mkdir -p "${INSTALL_ROOT}${EXECPREFIX}/bin" - cp arkmanager "${INSTALL_ROOT}${EXECPREFIX}/bin/arkmanager" - chmod +x "${INSTALL_ROOT}${EXECPREFIX}/bin/arkmanager" + mkdir -p "${INSTALL_ROOT}${BINDIR}" + cp arkmanager "${INSTALL_ROOT}${BINDIR}/arkmanager" + chmod +x "${INSTALL_ROOT}${BINDIR}/arkmanager" + + # Create a folder in ~/.local/share to store arkmanager support files + mkdir -p "${INSTALL_ROOT}${DATADIR}" + + # Copy the uninstall script to ~/.local/share/arkmanager + cp uninstall-user.sh "${INSTALL_ROOT}${DATADIR}/arkmanager-uninstall.sh" + chmod +x "${INSTALL_ROOT}${DATADIR}/arkmanager-uninstall.sh" + sed -i -e "s|^BINDIR=.*|BINDIR=\"${BINDIR}\"|" \ + -e "s|^DATADIR=.*|DATADIR=\"${DATADIR}\"|" \ + "${INSTALL_ROOT}${DATADIR}/arkmanager-uninstall.sh" # Create a folder in ~/logs to let Ark tools write its own log files mkdir -p "${INSTALL_ROOT}${PREFIX}/logs/arktools" + # Copy arkmanager.cfg to ~/.arkmanager.cfg.NEW + cp arkmanager.cfg "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW" + # Change the defaults in the new config file + sed -i -e "s|^steamcmd_user=\"steam\"|steamcmd_user=\"--me\"|" \ + -e "s|\"/home/steam|\"${PREFIX}|" \ + -e "s|/var/log/arktools|${PREFIX}/logs/arktools|" \ + -e "s|^install_bindir=.*|install_bindir=\"${BINDIR}\"|" \ + -e "s|^install_libexecdir=.*|install_libexecdir=\"${LIBEXECDIR}\"|" \ + -e "s|^install_datadir=.*|install_datadir=\"${DATADIR}\"|" \ + "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW" + # Copy arkmanager.cfg to ~/.arkmanager.cfg if it doesn't already exist if [ -f "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" ]; then - cp -n arkmanager.cfg "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW" - sed -i "s|^steamcmd_user=\"steam\"|steamcmd_user=\"--me\"|;s|\"/home/steam|\"${PREFIX}|;s|/var/log/arktools|${PREFIX}/logs/arktools|" "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW" + newopts=( arkbackupdir arkautorestartfile install_bindir install_libexecdir install_datadir mod_appid ) + newopt_steamcmd_appinfocache="${PREFIX}/Steam/appcache/appinfo.vdf" + newopt_arkbackupdir="${PREFIX}/ARK-Backups" + newopt_arkautorestartfile="ShooterGame/Saved/.autorestart" + newopt_install_bindir="${BINDIR}" + newopt_install_libexecdir="${LIBEXECDIR}" + newopt_install_datadir="${DATADIR}" + newopt_mod_appid=346110 + + if grep '^\(servermail\|arkstVersion\)=' "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" >/dev/null 2>&1; then + sed -i '/^\(servermail\|arkstVersion\)=/d' "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" + fi + + for optname in "${newopts[@]}"; do + if ! grep "^${optname}=" "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" >/dev/null 2>&1; then + noptname="newopt_${optname}" + echo "${optname}='${!noptname}'" >>"${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" + fi + done + 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 '${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW'. Make sure to review any changes and update your config accordingly!" exit 2 else - cp -n arkmanager.cfg "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" - sed -i "s|^steamcmd_user=\"steam\"|steamcmd_user=\"--me\"|;s|\"/home/steam|\"${PREFIX}|;s|/var/log/arktools|${PREFIX}/logs/arktools|" "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" + mv -n "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg.NEW" "${INSTALL_ROOT}${PREFIX}/.arkmanager.cfg" fi - elif [ "$1" == "--me" ]; then - echo "You specified the special '--me' user while running as root. This is not permitted." - exit 1 - else +else # Copy arkmanager to /usr/bin and set permissions - cp arkmanager "${INSTALL_ROOT}${EXECPREFIX}/bin/arkmanager" - chmod +x "${INSTALL_ROOT}${EXECPREFIX}/bin/arkmanager" + cp arkmanager "${INSTALL_ROOT}${BINDIR}/arkmanager" + chmod +x "${INSTALL_ROOT}${BINDIR}/arkmanager" + + # Copy the uninstall script to ~/.local/share/arkmanager + mkdir -p "${INSTALL_ROOT}${LIBEXECDIR}" + cp uninstall.sh "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager-uninstall.sh" + chmod +x "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager-uninstall.sh" + sed -i -e "s|^BINDIR=.*|BINDIR=\"${BINDIR}\"|" \ + -e "s|^LIBEXECDIR=.*|LIBEXECDIR=\"${LIBEXECDIR}\"|" \ + -e "s|^DATADIR=.*|DATADIR=\"${DATADIR}\"|" \ + "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager-uninstall.sh" # Copy arkdaemon to /etc/init.d ,set permissions and add it to boot if [ -f /lib/lsb/init-functions ]; then # on debian 8, sysvinit and systemd are present. If systemd is available we use it instead of sysvinit if [ -f /etc/systemd/system.conf ]; then # used by systemd - mkdir -p "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager" - cp lsb/arkdaemon "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - chmod +x "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - cp systemd/arkdeamon.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s|=/usr/|=${EXECPREFIX}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s@^DAEMON=\"/usr@DAEMON=\"${EXECPREFIX}@" "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" + mkdir -p "${INSTALL_ROOT}${LIBEXECDIR}" + cp systemd/arkmanager.init "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + chmod +x "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + cp systemd/arkmanager.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + sed -i "s|=/usr/libexec/arkmanager/|=${LIBEXECDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + cp systemd/arkmanager@.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager@.service" + sed -i "s|=/usr/bin/|=${BINDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" if [ -z "${INSTALL_ROOT}" ]; then systemctl daemon-reload systemctl enable arkmanager.service @@ -55,7 +228,7 @@ if [ ! -z "$1" ]; then else # systemd not present, so use sysvinit cp lsb/arkdaemon "${INSTALL_ROOT}/etc/init.d/arkmanager" chmod +x "${INSTALL_ROOT}/etc/init.d/arkmanager" - sed -i "s|^DAEMON=\"/usr|DAEMON=\"${EXECPREFIX}|" "${INSTALL_ROOT}/etc/init.d/arkmanager" + sed -i "s|^DAEMON=\"/usr/bin/|DAEMON=\"${BINDIR}/|" "${INSTALL_ROOT}/etc/init.d/arkmanager" # add to startup if the system use sysinit if [ -x /usr/sbin/update-rc.d -a -z "${INSTALL_ROOT}" ]; then update-rc.d arkmanager defaults @@ -66,12 +239,13 @@ if [ ! -z "$1" ]; then elif [ -f /etc/rc.d/init.d/functions ]; then # on RHEL 7, sysvinit and systemd are present. If systemd is available we use it instead of sysvinit if [ -f /etc/systemd/system.conf ]; then # used by systemd - mkdir -p "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager" - cp redhat/arkdaemon "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - chmod +x "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - cp systemd/arkdeamon.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s|=/usr/|=${EXECPREFIX}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s@^DAEMON=\"/usr@DAEMON=\"${EXECPREFIX}@" "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" + mkdir -p "${INSTALL_ROOT}${LIBEXECDIR}" + cp systemd/arkmanager.init "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + chmod +x "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + cp systemd/arkmanager.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + sed -i "s|=/usr/libexec/arkmanager/|=${LIBEXECDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + cp systemd/arkmanager@.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager@.service" + sed -i "s|=/usr/bin/|=${BINDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" if [ -z "${INSTALL_ROOT}" ]; then systemctl daemon-reload systemctl enable arkmanager.service @@ -81,7 +255,7 @@ if [ ! -z "$1" ]; then else # systemd not preset, so use sysvinit cp redhat/arkdaemon "${INSTALL_ROOT}/etc/rc.d/init.d/arkmanager" chmod +x "${INSTALL_ROOT}/etc/rc.d/init.d/arkmanager" - sed -i "s@^DAEMON=\"/usr@DAEMON=\"${EXECPREFIX}@" "${INSTALL_ROOT}/etc/rc.d/init.d/arkmanager" + sed -i "s@^DAEMON=\"/usr/bin/@DAEMON=\"${BINDIR}/@" "${INSTALL_ROOT}/etc/rc.d/init.d/arkmanager" if [ -x /sbin/chkconfig -a -z "${INSTALL_ROOT}" ]; then chkconfig --add arkmanager echo "Ark server will now start on boot, if you want to remove this feature run the following line" @@ -91,20 +265,22 @@ if [ ! -z "$1" ]; then elif [ -f /sbin/runscript ]; then cp openrc/arkdaemon "${INSTALL_ROOT}/etc/init.d/arkmanager" chmod +x "${INSTALL_ROOT}/etc/init.d/arkmanager" - sed -i "s@^DAEMON=\"/usr@DAEMON=\"${EXECPREFIX}@" "${INSTALL_ROOT}/etc/init.d/arkmanager" + sed -i "s@^DAEMON=\"/usr/bin/@DAEMON=\"${BINDIR}/@" "${INSTALL_ROOT}/etc/init.d/arkmanager" if [ -x /sbin/rc-update -a -z "${INSTALL_ROOT}" ]; then rc-update add arkmanager default echo "Ark server will now start on boot, if you want to remove this feature run the following line" echo "rc-update del arkmanager default" fi elif [ -f /etc/systemd/system.conf ]; then # used by systemd - mkdir -p "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager" - cp systemd/arkdaemon.init "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - chmod +x "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" - cp systemd/arkdeamon.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s|=/usr/|=${EXECPREFIX}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" - sed -i "s@^DAEMON=\"/usr@DAEMON=\"${EXECPREFIX}@" "${INSTALL_ROOT}${EXECPREFIX}/libexec/arkmanager/arkmanager.init" + mkdir -p "${INSTALL_ROOT}${LIBEXECDIR}" + cp systemd/arkmanager.init "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + chmod +x "${INSTALL_ROOT}${LIBEXECDIR}/arkmanager.init" + cp systemd/arkmanager.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + sed -i "s|=/usr/libexec/arkmanager/|=${LIBEXECDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager.service" + cp systemd/arkmanager@.service "${INSTALL_ROOT}/etc/systemd/system/arkmanager@.service" + sed -i "s|=/usr/bin/|=${BINDIR}/|" "${INSTALL_ROOT}/etc/systemd/system/arkmanager@.service" if [ -z "${INSTALL_ROOT}" ]; then + systemctl daemon-reload systemctl enable arkmanager.service echo "Ark server will now start on boot, if you want to remove this feature run the following line" echo "systemctl disable arkmanager.service" @@ -117,29 +293,42 @@ if [ ! -z "$1" ]; then # Copy arkmanager.cfg inside linux configuation folder if it doesn't already exists mkdir -p "${INSTALL_ROOT}/etc/arkmanager" + cp arkmanager.cfg "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg.NEW" + chown "$1" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg.NEW" + 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}/etc/arkmanager/arkmanager.cfg.NEW" + if [ -f "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" ]; then - cp -n arkmanager.cfg "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg.NEW" - chown "$1" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg.NEW" + newopts=( arkbackupdir arkautorestartfile install_bindir install_libexecdir install_datadir mod_appid ) + newopt_steamcmd_appinfocache="/home/${steamcmd_user}/Steam/appcache/appinfo.vdf" + newopt_arkbackupdir="/home/${steamcmd_user}/ARK-Backups" + newopt_arkautorestartfile="ShooterGame/Saved/.autorestart" + newopt_install_bindir="${BINDIR}" + newopt_install_libexecdir="${LIBEXECDIR}" + newopt_install_datadir="${DATADIR}" + newopt_mod_appid=346110 + + if grep '^\(servermail\|arkstVersion\)=' "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" >/dev/null 2>&1; then + sed -i '/^\(servermail\|arkstVersion\)=/d' "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" + fi + + for optname in "${newopts[@]}"; do + if ! grep "^${optname}=" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" >/dev/null 2>&1; then + noptname="newopt_${optname}" + echo "${optname}='${!noptname}'" >>"${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" + fi + done + 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 - cp -n arkmanager.cfg "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" - chown "$1" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" - sed -i "s|^steamcmd_user=\"steam\"|steamcmd_user=\"$1\"|;s|\"/home/steam|\"/home/$1|" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" + mv -n "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg.NEW" "${INSTALL_ROOT}/etc/arkmanager/arkmanager.cfg" fi - fi -else - echo "You must specify your system steam user who own steamcmd directory to install ARK Tools." - echo "Specify the special used '--me' to perform a user-install." - echo "Usage: ./install.sh steam" - echo - echo "Environment variables affecting install:" - echo "EXECPREFIX: prefix in which to install arkmanager executable" - echo " [${EXECPREFIX}]" - echo "INSTALL_ROOT: staging directory in which to perform install" - echo " [${INSTALL_ROOT}]" - exit 1 fi exit 0 diff --git a/tools/lsb/arkdaemon b/tools/lsb/arkdaemon index f728ede..484d5d8 100755 --- a/tools/lsb/arkdaemon +++ b/tools/lsb/arkdaemon @@ -29,7 +29,7 @@ case "$1" in start) log_daemon_msg "Starting" "$NAME" ulimit -n 100000 - su -s /bin/sh -c "$DAEMON start" $steamcmd_user + su -s /bin/sh -c "$DAEMON start --all" $steamcmd_user sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then @@ -42,7 +42,7 @@ case "$1" in stop) log_daemon_msg "Stopping" "$NAME" - su -s /bin/sh -c "$DAEMON stop" $steamcmd_user + su -s /bin/sh -c "$DAEMON stop --all" $steamcmd_user sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then @@ -55,7 +55,7 @@ case "$1" in restart) ulimit -n 100000 - su -s /bin/sh -c "$DAEMON restart" $steamcmd_user + su -s /bin/sh -c "$DAEMON restart --all" $steamcmd_user ;; status) diff --git a/tools/openrc/arkdaemon b/tools/openrc/arkdaemon index 4c2ddd0..5aa9340 100644 --- a/tools/openrc/arkdaemon +++ b/tools/openrc/arkdaemon @@ -15,7 +15,7 @@ depend(){ start(){ ebegin "Starting ARK manager daemon" ulimit -n 100000 - su -s /bin/sh -c "$DAEMON start" $steamcmd_user + su -s /bin/sh -c "$DAEMON start --all" $steamcmd_user sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then @@ -27,7 +27,7 @@ start(){ stop(){ ebegin "Stopping ARK manager daemon" - su -s /bin/sh -c "$DAEMON start" $steamcmd_user + su -s /bin/sh -c "$DAEMON stop --all" $steamcmd_user sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then diff --git a/tools/redhat/arkdaemon b/tools/redhat/arkdaemon index 411bcd1..fa0ed1a 100755 --- a/tools/redhat/arkdaemon +++ b/tools/redhat/arkdaemon @@ -43,7 +43,7 @@ case "$1" in start) echo -n "Starting $NAME: " ulimit -n 100000 - su -s /bin/sh -c "$DAEMON start" $steamcmd_user > /dev/null + su -s /bin/sh -c "$DAEMON start --all" $steamcmd_user > /dev/null sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then @@ -59,7 +59,7 @@ case "$1" in stop) echo -n "Stopping $NAME: " - su -s /bin/sh -c "$DAEMON stop" $steamcmd_user > /dev/null + su -s /bin/sh -c "$DAEMON stop --all" $steamcmd_user > /dev/null sleep 5 PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` if [ -n "$PID" ]; then @@ -76,7 +76,7 @@ case "$1" in restart) echo -n "Restarting $NAME: " ulimit -n 100000 - su -s /bin/sh -c "$DAEMON restart" $steamcmd_user > /dev/null + su -s /bin/sh -c "$DAEMON restart --all" $steamcmd_user > /dev/null echo "OK" ;; diff --git a/tools/systemd/arkdaemon.init b/tools/systemd/arkdaemon.init deleted file mode 100755 index df83248..0000000 --- a/tools/systemd/arkdaemon.init +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash -# -# /usr/libexec/arkmanager/arkmanager.init -# -# ARK manager daemon -# -# chkconfig: 2345 80 20 -# description: ARK manager daemon used to start the server and keep it updated -# processname: ShooterGameServer -# config: /etc/arkmanager/arkmanager.cfg - -### BEGIN INIT INFO -# Provides: ARK manager deamon -# Required-Start: networking -# Required-Stop: networking -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: ARK manager deamon -# Description: ARK manager daemon used to start the server and keep it updated -# -### END INIT INFO - -# Set TERM to "dumb" if TERM is not set -export TERM=${TERM:-dumb} - -# Global variables -source /etc/arkmanager/arkmanager.cfg - -NAME="ShooterGameServer" -LOGFILE="${logdir}/${NAME}.log" -DAEMON="/usr/bin/arkmanager" - -GREEN="\\033[1;32m" -RED="\\033[1;31m" -NORMAL="\\033[0;39m" - -set -e - -# If the daemon is not there, then exit. -test -x $DAEMON || exit 5 - -case "$1" in - start) - echo -n "Starting $NAME: " - ulimit -n 100000 - su -s /bin/sh -c "$DAEMON start" $steamcmd_user > /dev/null - sleep 5 - PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` - if [ -n "$PID" ]; then - echo "$PID" >/var/run/arkmanager.pid - echo "[" "$GREEN" " OK " "$NORMAL" "]" - exit 0 - else - echo "[" "$RED" " FAILED " "$NORMAL" "]" - exit 1 - fi - ;; - - stop) - echo -n "Stopping $NAME: " - su -s /bin/sh -c "$DAEMON stop" $steamcmd_user > /dev/null - sleep 5 - PID=`ps -ef | grep $NAME | grep -v grep | awk '{print $2}'` - if [ -n "$PID" ]; then - echo "[" "$RED" " FAILED " "$NORMAL" "]" - exit 1 - else - echo "[" "$GREEN" " OK " "$NORMAL" "]" - rm /var/run/arkmanager.pid - exit 0 - fi - ;; - - restart) - echo -n "Restarting $NAME: " - ulimit -n 100000 - su -s /bin/sh -c "$DAEMON restart" $steamcmd_user > /dev/null - echo "OK" - ;; - - status) - su -s /bin/sh -c "$DAEMON status" $steamcmd_user - exit 0 - ;; - - *) - # For invalid arguments, print the usage message. - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac diff --git a/tools/systemd/arkmanager.init b/tools/systemd/arkmanager.init new file mode 100755 index 0000000..be25029 --- /dev/null +++ b/tools/systemd/arkmanager.init @@ -0,0 +1,5 @@ +#!/bin/bash + +for service in main $(grep -o '^configfile_[^=]*' /etc/arkmanager/arkmanager.cfg); do + systemctl start arkmanager@${service#configfile_} +done diff --git a/tools/systemd/arkdeamon.service b/tools/systemd/arkmanager.service similarity index 69% rename from tools/systemd/arkdeamon.service rename to tools/systemd/arkmanager.service index d1fb5da..c2d4053 100644 --- a/tools/systemd/arkdeamon.service +++ b/tools/systemd/arkmanager.service @@ -1,12 +1,11 @@ [Unit] -Description=Daemon to start ark server +Description=Starts and stops all ark server instances After=network.target [Service] ExecStart=/usr/libexec/arkmanager/arkmanager.init start ExecStop=/usr/libexec/arkmanager/arkmanager.init stop -Type=forking -PIDFile=/var/run/arkmanager.pid +Type=oneshot [Install] WantedBy=multi-user.target diff --git a/tools/systemd/arkmanager@.service b/tools/systemd/arkmanager@.service new file mode 100644 index 0000000..49b722c --- /dev/null +++ b/tools/systemd/arkmanager@.service @@ -0,0 +1,6 @@ +[Unit] +Description=Daemon to start an ark server instance + +[Service] +ExecStart=/usr/bin/arkmanager useconfig %i run +Type=simple diff --git a/tools/uninstall-user.sh b/tools/uninstall-user.sh new file mode 100644 index 0000000..77e7221 --- /dev/null +++ b/tools/uninstall-user.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# +# uninstall-user.sh + +BINDIR="/home/steam/bin" +DATADIR="/home/steam/.local/share/arkmanager" + +for f in "${BINDIR}/arkmanager" \ + "${DATADIR}/uninstall.sh" +do + if [ -f "$f" ]; then + rm "$f" + fi +done diff --git a/tools/uninstall.sh b/tools/uninstall.sh new file mode 100644 index 0000000..e4f20b5 --- /dev/null +++ b/tools/uninstall.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# uninstall.sh + +BINDIR="/usr/bin" +DATADIR="/usr/share/arkmanager" +LIBEXECDIR="/usr/libexec/arkmanager" +INITSCRIPT= + +if [ -f "/etc/rc.d/init.d/arkmanager" ]; then + INITSCRIPT="/etc/rc.d/init.d/arkmanager" + if [ -f "/etc/rc.d/init.d/functions" ]; then + chkconfig arkmanager off + fi +elif [ -f "/etc/init.d/arkmanager" ]; then + INITSCRIPT="/etc/init.d/arkmanager" + if [ -f "/lib/lsb/init-functions" ]; then + update-rc.d -f arkmanager remove + elif [ -f "/sbin/runscript" ]; then + rc-update del arkmanager default + fi +elif [ -f "/etc/systemd/system/arkmanager.service" ]; then + INITSCRIPT="/etc/systemd/system/arkmanager.service" + systemctl disable arkmanager.service +fi + +if [ -n "$INITSCRIPT" ]; then + for f in "${INITSCRIPT}" \ + "${BINDIR}/arkmanager" \ + "${LIBEXECDIR}/arkmanager.init" \ + "${LIBEXECDIR}/arkmanager-uninstall.sh" + do + if [ -f "$f" ]; then + rm "$f" + fi + done +fi diff --git a/tools/upstart/arkmanager-instance.conf b/tools/upstart/arkmanager-instance.conf new file mode 100644 index 0000000..0b219a4 --- /dev/null +++ b/tools/upstart/arkmanager-instance.conf @@ -0,0 +1,7 @@ +description "ARK Server Tools service" + +instance $service + +env DAEMON="/usr/bin/arkmanager" + +exec "$DAEMON" useconfig $service run diff --git a/tools/upstart/arkmanager.conf b/tools/upstart/arkmanager.conf new file mode 100644 index 0000000..688cbe8 --- /dev/null +++ b/tools/upstart/arkmanager.conf @@ -0,0 +1,8 @@ +start on runlevel [345] +stop on runlevel [!345] + +script + for service in main $(grep -o '^configfile_[^=]*' /etc/arkmanager/arkmanager.cfg); do + start arkmanager-instance service=${service#configfile_} + done +end script