Jump to content

Script to update your Dedicated Servers automatically [GNU/Linux]


Recommended Posts

Hello!

I didn't find a clean way to automatically keep your Dedicated Servers up to date anywhere else, so I made a script (maybe for naught, please let me know if there are better ways)

#!/bin/bash

#crontab
#* * * * * user "/home/user/DST/DST_update_servers.sh"

#crontab for each server
#@reboot user sleep 30 && screen -d -m -S DST_server_0 "/home/user/DST/$SERVER_DIR/run.sh"

me=$(basename "$0")
if pidof -o %PPID -x "$me" >/dev/null; then
    #Another script instance is already running.
    exit 1
fi

dontstarve_dir="$HOME/.klei/DoNotStarveTogether"
install_dir="$dontstarve_dir/.steam"

export PATH="$PATH:/usr/games"
#^ Fix "steamcmd: command not found" in cron job
current_version=$(steamcmd +force_install_dir "$install_dir" +login anonymous +app_info_update 1 +app_status 343050 +quit | grep -Eo '(BuildID )([0-9]*)' | grep -Eo '[0-9]*')
latest_version=$(curl "https://api.steamcmd.net/v1/info/343050" --silent | grep -Eo '("public": {"buildid": ")([0-9]*)(")' | grep -Eo '[0-9]*')

if [[ -z "$current_version" || -z "$latest_version" ]]; then
    #Error while retrieving either version.
    exit 1
fi

if [ "$current_version" -ge "$latest_version" ]; then
    #Up to date.
    exit 0
fi

sleep 60 #Failsafe to prevent the following commands to run before the servers initially boot up

# Add all the servers to shutdown here
screen -S DST_server_0 -X stuff "^C"

###

sleep 10
steamcmd +force_install_dir "$install_dir" +login anonymous +app_update 343050 validate +quit

# Add all the servers to start again below
screen -d -m -S DST_server_0 "/home/user/DST/$SERVER_DIR/run.sh"

###

exit 0

- I do not use mods so this script may not be adapted for modded servers
- The "dontstarve_dir" and "install_dir" variables must be the sames as the ones inside the Klei's run script
- Adjust the cron tabs and $SERVER_DIR accordingly to your paths and files' names
- You can add as many DST_server_$COUNT as you want

 

Link to comment
Share on other sites

I'd say you are on a good start there. The cronjob to automaticially stop and restart the server is correct. Especially the check if the server is up to date before relaunching it is very neat!

If you use the script provided here in the dedicated server quick setup guide(s), they already update the server, if the server isn't up to date when launching, so a quick shutdown and startup of the DST server would already be sufficient, and no manual update needed.

Also your way to shutdown the server is rather crude (albeit simple and therefore reliable). It essentially just kills the process (unless I missed something), essentially risking to lose the process since the last "Morning Save". Iirc there was a way to send a command to a process running in the background, which would avoid this issue. (Essentially telling the DST server "c_shutdown()", or maybe even a "c_save()" followed by "c_shutdown()" to be extra safe.)
For example in screen (which I usually use to run processes in the background) you can do

#Launch Server using screen (in the background):
screen -DmS DSTServer "/home/user/DST/run.sh" &

#List active screens for good measure
screen -ls

#Reattach a screen session if you wanna see what's going on inside
screen -rx

#Finally send a command to inside the screen session from anywhere
screen -S DSTServer -p 0 -X "c_shutdown()^M"

Haven't tested these commands, but they should work according to for example this site.

 

While there is some polishing possible on your work, all in all good job! :-D

Link to comment
Share on other sites

Thanks for the feedback!

Yes, the entire point of my script is to check if there was an update after the servers were launched, I know the startup script provided by Klei update automatically at launch. The goal is to know when to shutdown the servers to make an update

The screen solution is fantastic, it indeed makes killing and relaunching the processes way cleaner. I will dig more into it and adjust the script accordingly :D

Edit:
After some testings, c_shutdown() or any other command just won't work from the command prompt (even without a screen session), probably due to how the Klei script is written. However a simple SIGINT seems to be well handled, it saves + shutdown the server correctly, so I'll use that.

Link to comment
Share on other sites

2 hours ago, Butterfly771 said:

Current version can be find at $installdir/version.txt

This is not the version needed by steam to verify if the game is updated. If I take the current version as an exemple, the "version.txt" file shows "550219", but the steam public build ID, the one we need, shows "10876759"

The latest game version, provided by the steamcmd API command, returns the steam public build ID, not the arbitrary version Klei decides to put in their version.txt file

Link to comment
Share on other sites

6 hours ago, b l a n k said:

This is not the version needed by steam to verify if the game is updated. If I take the current version as an exemple, the "version.txt" file shows "550219", but the steam public build ID, the one we need, shows "10876759"

The latest game version, provided by the steamcmd API command, returns the steam public build ID, not the arbitrary version Klei decides to put in their version.txt file

You are right. I just realized that this is a different logic. Your script is based on Steam's game build information, which enables it to detect game updates. I have also implemented an update logic, but it is based on the local version.txt and the latest version page.(https://forums.kleientertainment.com/game-updates/dst/)

server_version_file="$HOME/dst/version.txt"
local_v=$(cat $server_version_file)
remote_v=$(getLastRelease $check_url)
getLastRelease() {
  local url=$1
  latest_version=$(curl -s $url | xmllint --html --xpath '//h3[contains(@class,"ipsType_sectionHead")][not(span[contains(@class,"negative")])]/text()' - 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sort -V | tail -n 1)
  echo "$latest_version"
}
Link to comment
Share on other sites

On 3/30/2023 at 7:54 AM, Butterfly771 said:

You are right. I just realized that this is a different logic. Your script is based on Steam's game build information, which enables it to detect game updates. I have also implemented an update logic, but it is based on the local version.txt and the latest version page.(https://forums.kleientertainment.com/game-updates/dst/)

server_version_file="$HOME/dst/version.txt"
local_v=$(cat $server_version_file)
remote_v=$(getLastRelease $check_url)
getLastRelease() {
  local url=$1
  latest_version=$(curl -s $url | xmllint --html --xpath '//h3[contains(@class,"ipsType_sectionHead")][not(span[contains(@class,"negative")])]/text()' - 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sort -V | tail -n 1)
  echo "$latest_version"
}

Yes I thought about doing it that way too, but the cons of parsing a webpage to check the version were too much compared to using the API imo.

Since you're dependent of the Klei website, and the html structure of the webpage itself, the script can break pretty easily if anything changes. I have way too many workflows running and relying on webpages to know now unreliable it can become when web admins decide to make the slightest modification on their website... I usually avoid to parse/regex webpages when I can, and when an API is available!
Also, even though it doesn't matter as much, Don't Starve Together and Don't Starve Together Dedicated Server are two different "games" by steam. Klei always shared their version.txt number until now, but you never know and I am very picky, so I prefer to check the version of the actual DST Dedicated Server instead of DST itself.

That being said, this is a pretty command you got there to grab the latest version lol

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...