@ hustl4
Thanks for the idea. The script appears to be getting hung up. If you do happen to test it out - would you mind uploading it to github so I can include a direct download for the script I'm currently writing? Would be best if there was safeguards against situations where it might get hung up - maybe there could be a timeout feature if the server doesn't respond in x amount of time there's a certain return value. (Since this script is designed to get launched automatically from a cron job task.)
In regards to the auto-updating:
- I can use screen to log output to a file and successfully added update functionality there, but the problem is when you have multiple servers on the same machine and need to make a unique log file name that's the same as the screen session (socket) name.
- Some users say to use tmux instead of screen, so I spent the better part of a day writing out a script to handle auto-launching X amount of servers:
(I still have to make the tmux log.)
Spoiler
PHP Code:
#!/bin/bash
#######################
#
# This script should be launched every minute from a cron job task.
#
# It's mainly for lazy admins who prefer to have their servers & custom maps updated automatically,
# and who also likely have in-game sourcemod plugins installed which shut down
# the game server after certain events (e.g. https://forums.alliedmods.net/showthread.php?t=306494 )
#
# Session Names should be unique, one shouldn't overlap entirely from another.
# e.g. L4D2_server & L4D2_server2 would be problematic.
#
#######################
#how many game servers?
num_of_servers=2
SessionName=(
'left4dead2_server' #server 1
'CSGO_Server' #server 2
)
srcds_run=(
'/home/dustin/Steam/SteamFolder/L4D2/srcds_run' #server 1
'/home/dustin/Steam/SteamFolder/CSGO/srcds_run' #server 2 etc..
)
Parameters=(
'-game left4dead2 -debug -ip (private) -port 27015 +map c1m4_atrium +mp_gamemode survival'
'-game csgo -console -usercon +game_type 0 +game_mode 0 +mapgroup mg_active -ip (private) -port 27016 +map de_dust2 +sv_setsteamaccount (private) -net_port_try'
)
#auto-update functionality:
UpdateScript=(
'./steamcmd.sh +login anonymous +force_install_dir /home/dustin/Steam/SteamFolder/L4D2/ +app_update 222860 validate +quit'
'./steamcmd.sh +login (private) (private) +force_install_dir /home/dustin/Steam/SteamFolder/CSGO/ +app_update 740 validate +quit'
)
ServerPort=(
'27015'
'27016'
)
RconPassword=(
'(private)'
'(private)'
)
#optional
WorkShopDirectory=(
'/home/dustin/Steam/SteamFolder/L4D2/left4dead2/addons/workshop'
''
)
#optional
WorkshopCollection=(
'1381380872'
''
)
# Customization ends here
scriptcheck=`pgrep -c auto-restart.sh`
if [ $scriptcheck -gt 1 ]; then
echo "auto-restart.sh script already in use. Terminating.."
exit
fi
#########################
# Helper functions #
#########################
Launch_Any_Offline_Servers()
{
for ((j=0;j<$num_of_servers;j++)); do
Print_Configuration $j
#TODO: find better method for detecting if server's offline using tmux
# This method can (rarely) return a false positive ( https://i.imgur.com/UDsFTil.png ) hence the need for 3 checks before launching..
echo "Initiating server check."
sleep 3s
echo ""
alive=`ps ux | grep "${SessionName[$j]}" | wc -l | awk '{ print $1 }'`
if [ $alive -lt 2 ]; then
echo "First check: server ${SessionName[$j]} appears to be offline."
sleep 3s
alive2=`ps ux | grep "${SessionName[$j]}" | wc -l | awk '{ print $1 }'`
if [ $alive2 -lt 2 ]; then
echo "Second check: server ${SessionName[$j]} is still offline."
sleep 3s
alive3=`ps ux | grep "${SessionName[$j]}" | wc -l | awk '{ print $1 }'`
if [ $alive3 -lt 2 ]; then
echo "Third check: server ${SessionName[$j]} is still offline."
if [ -n "${WorkShopDirectory[$j]}" ]; then
if [ -n "${WorkshopCollection[$j]}" ]; then
echo ""
echo "Checking for workshop map updates before launching server."
sleep 2s
if [ ! -e "steam_workshop_downloader.py" ]; then
echo "Workshop downloader not found. Manually downloading file.."
#In case valve server is down - this version of workshop DL'er caps failed downloads at 25 retries
curl -o steam_workshop_downloader.py 'https://raw.githubusercontent.com/nosoop/steam_workshop_downloader/commed-patch/workshop.py'
chmod +x steam_workshop_downloader.py
fi
./steam_workshop_downloader.py -o "${WorkShopDirectory[$j]}" "${WorkshopCollection[$j]}"
echo ""
echo "Workshop Update Complete."
echo ""
fi
fi
#LAUNCH SERVER HERE
echo "Launching server.."
tmux new-session -d -s "${SessionName[$j]}" "${srcds_run[$j]} ${Parameters[$j]}"
#NEED TO ADD LOG HERE
sleep 3s
else
echo "Third check: ${SessionName[$j]} already online. Skipping.."
sleep 3s
fi
else
echo "Second check: ${SessionName[$j]} already running. Skipping.."
sleep 3s
fi
else
echo "First check: ${SessionName[$j]} already running. Skipping..."
sleep 3s
fi
done
}
Print_Configuration()
{
sleep 1s
echo "-----------------------------------------------------"
echo ""
echo "Checking for ${SessionName[$1]} in 3"
sleep 1s
echo "Checking for ${SessionName[$1]} in 2.."
sleep 1s
echo "Checking for ${SessionName[$1]} in 1"...
sleep 1s
clear
echo "###########################"
echo "SERVER CONFIGURATION:"
echo "Launch Path: ${srcds_run[$1]}"
echo
echo "Launch Parameters: ${Parameters[$1]}"
echo
echo "Update Script: ${UpdateScript[$1]}"
echo
echo
echo "CUSTOM MAP SETTINGS:"
if [ -n "${WorkShopDirectory[$1]}" ]; then
echo "Workshop Directory: ${WorkShopDirectory[$1]}"
else
echo "No workshop directory detected."
fi
echo
if [ -n "${WorkshopCollection[$1]}" ]; then
echo "Workshop Collection: ${WorkshopCollection[$1]}"
else
echo "No workshop collection detected."
fi
echo
echo
sleep 4s
echo "Continuing in 3"
sleep 1s
echo "Continuing in 2.."
sleep 1s
echo "Continuing in 1..."
sleep 1s
clear
}
Check_Input()
{
if [ -z "$num_of_servers" ]; then
echo "Error: Variable left blank: 'num_of_servers'."
exit 1
fi
#Make sure all non-optional fields are completed.
typeset -n x
for x in SessionName srcds_run Parameters UpdateScript ServerPort RconPassword; do
for((j=0;j<$num_of_servers;j++)); do
if [ -z "${x[$j]}" ]; then
echo "Error: One or more non-optional items left blank."
exit 1
fi
done
done
echo "Initialization Check successfull."
}
#########################
# Script
#########################
# This script is run every minute from a cron job task
# So this will get executed @ 3am every morning.
Time_Var=$(date +%H%M)
if [ "$Time_Var" -eq 0300 ]; then
echo "It is currently 3am. $(date +%H:%M:%S)" > /tmp/Test.output #test
#TODO add update functionality here
#TODO Python script: check each server (twice to be sure) for human players.
#TODO Shut down each server that's empty while counting
# If empty server count = num_of_servers, execute 'reboot' command.
fi
Check_Input
Launch_Any_Offline_Servers
- Come to find out after all that work, the latest version of tmux may not be compatible with creating dynamic log names (if i revert to an older version of tmux and ever 'apt-get update', it may break the script):
https://github.com/GameServerManager..._start.sh#L113
Anyway, if that's the case I'll just use something similar to what hustl4 posted. If all game servers are all detected as empty on some night, they'll all get an update then the physical server will do a reboot. The cron job task will relaunch the script ^ and the servers will be back online.