|
|
@ -0,0 +1,818 @@ |
|
|
|
#!/bin/bash |
|
|
|
# Counter Strike |
|
|
|
# Server Management Script |
|
|
|
# Author: Daniel Gibbs |
|
|
|
# Website: http://danielgibbs.co.uk |
|
|
|
# Version: 240114 |
|
|
|
|
|
|
|
#### Variables #### |
|
|
|
|
|
|
|
# Notification Email |
|
|
|
# (on|off) |
|
|
|
emailnotification="off" |
|
|
|
email="[email protected]" |
|
|
|
|
|
|
|
# Steam login |
|
|
|
steamuser="anonymous" |
|
|
|
steampass="" |
|
|
|
|
|
|
|
# Start Variables |
|
|
|
defaultmap="dod_Anzio" |
|
|
|
port="27015" |
|
|
|
clientport="27005" |
|
|
|
maxplayers="16" |
|
|
|
ip="0.0.0.0" |
|
|
|
# https://developer.valvesoftware.com/wiki/Command_Line_Options#Command-line_parameters_2 |
|
|
|
fn_parms(){ |
|
|
|
parms="-game dod +map ${defaultmap} -strictportbind -ip ${ip} -port ${port} +clientport ${clientport} -maxplayers ${maxplayers}" |
|
|
|
} |
|
|
|
|
|
|
|
#### Advanced Variables #### |
|
|
|
|
|
|
|
# Steam |
|
|
|
appid="90 -beta beta +app_set_config 90 mod dod" |
|
|
|
|
|
|
|
# Server Details |
|
|
|
servicename="dod-server" |
|
|
|
gamename="Day of Defeat" |
|
|
|
engine="goldsource" |
|
|
|
|
|
|
|
# Directorys |
|
|
|
rootdir="$(cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )" |
|
|
|
selfname="$0" |
|
|
|
filesdir="${rootdir}/serverfiles" |
|
|
|
systemdir="${filesdir}/dod" |
|
|
|
executabledir="${filesdir}" |
|
|
|
executable="./hlds_run" |
|
|
|
servercfg="${systemdir}/${servicename}.cfg" |
|
|
|
defaultcfg="${systemdir}/server.cfg" |
|
|
|
backupdir="backups" |
|
|
|
steamclient="${filesdir}/steamclient.so" |
|
|
|
|
|
|
|
# Server Details |
|
|
|
servername=$(grep -s hostname "${servercfg}"|sed 's/hostname //g'|sed 's/"//g') |
|
|
|
rcon=$(grep -s rcon_password "${servercfg}"|sed 's/rcon_password //g'|sed 's/"//g') |
|
|
|
|
|
|
|
# Logging |
|
|
|
logdays="7" |
|
|
|
gamelogdir="${systemdir}/logs" |
|
|
|
scriptlogdir="${rootdir}/log/script" |
|
|
|
consolelogdir="${rootdir}/log/console" |
|
|
|
|
|
|
|
scriptlog="${scriptlogdir}/${servicename}-script.log" |
|
|
|
consolelog="${consolelogdir}/${servicename}-console.log" |
|
|
|
emaillog="${scriptlogdir}/${servicename}-email.log" |
|
|
|
|
|
|
|
scriptlogdate="${scriptlogdir}/${servicename}-script-$(date '+%d-%m-%Y-%H-%M-%S').log" |
|
|
|
consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-%S').log" |
|
|
|
|
|
|
|
##### Script ##### |
|
|
|
# Do not edit |
|
|
|
# unless you know |
|
|
|
# what you are doing |
|
|
|
|
|
|
|
fn_scriptlog(){ |
|
|
|
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: '$1'" >> ${scriptlog} |
|
|
|
} |
|
|
|
|
|
|
|
fn_rootcheck(){ |
|
|
|
if [ `whoami` = "root" ]; then |
|
|
|
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] Script will not run as root!" |
|
|
|
exit |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_syscheck(){ |
|
|
|
if [ ! -e "${systemdir}" ]; then |
|
|
|
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] Cannot access ${systemdir}: No such directory" |
|
|
|
exit |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_autoip(){ |
|
|
|
# Identifies the server interface IP |
|
|
|
# If multiple interfaces this will need to be set manually |
|
|
|
getip=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0.1) |
|
|
|
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0.1|wc -l) |
|
|
|
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then |
|
|
|
if [ "${getipwc}" -ge "2" ]; then |
|
|
|
echo -en "[\e[1;33m WARN \e[0;39m] Multiple active network interfaces.\n\n" |
|
|
|
echo -en "Manually specify the IP you want to use in ${selfname}.\n" |
|
|
|
echo -en "Set ip=\"0.0.0.0\" to one of the following:\n" |
|
|
|
echo -en "${getip}\n" |
|
|
|
exit |
|
|
|
else |
|
|
|
ip=${getip} |
|
|
|
fi |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_logmanager(){ |
|
|
|
if [ ! -e "${consolelog}" ]; then |
|
|
|
touch "${consolelog}" |
|
|
|
fi |
|
|
|
# log manager will active if finds logs older than ${logdays} |
|
|
|
if [ `find "${scriptlogdir}"/* -mtime +${logdays}|wc -l` -ne "0" ]; then |
|
|
|
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] Starting log cleaner" |
|
|
|
fn_scriptlog "Starting log cleaner" |
|
|
|
sleep 1 |
|
|
|
echo -e "[\e[0;36m INFO \e[0;39m] Removing logs older than ${logdays} days" |
|
|
|
fn_scriptlog "Removing logs older than ${logdays} days" |
|
|
|
sleep 1 |
|
|
|
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" |
|
|
|
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" |
|
|
|
scriptcount=$(find "${scriptlogdir}/*" -mtime +${logdays}|wc -l) |
|
|
|
consolecount=$(find "${consolelogdir}/*" -mtime +${logdays}|wc -l) |
|
|
|
count=$((${scriptcount} + ${consolecount})) |
|
|
|
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \; |
|
|
|
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \; |
|
|
|
echo -e "[\e[0;36m INFO \e[0;39m] Log cleaner removed ${count} log files" |
|
|
|
fn_scriptlog "Log cleaner removed ${count} log files" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_debugserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
fn_autoip |
|
|
|
fn_parms |
|
|
|
echo "" |
|
|
|
echo "${gamename} Debug" |
|
|
|
echo "============================" |
|
|
|
echo "" |
|
|
|
echo -e "Use for identifying server issues only!" |
|
|
|
echo -e "Press CTRL+c to drop out of debug mode" |
|
|
|
echo -e "\e[0;31mWARNING!\e[0;39m If ${servicename} is already running it will be stopped" |
|
|
|
echo "" |
|
|
|
echo "Start parameters:" |
|
|
|
echo ${parms} |
|
|
|
echo "" |
|
|
|
while true; do |
|
|
|
read -p "Continue? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) break;; |
|
|
|
[Nn]* ) echo Exiting; return 1;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
fn_stopserver |
|
|
|
echo -en "\r\033[K[ .... ] Starting debug mode ${servicename}: ${servername}" |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Starting debug mode ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Started debug mode ${servername}" |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\n" |
|
|
|
cd "${executabledir}" |
|
|
|
${executable} ${parms} -debug |
|
|
|
} |
|
|
|
|
|
|
|
fn_console(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
echo "" |
|
|
|
echo "${gamename} Console" |
|
|
|
echo "============================" |
|
|
|
echo "" |
|
|
|
echo "Press \"CTRL+b d\" to exit console" |
|
|
|
echo -e "\e[0;31mWARNING!\e[0;39m Do NOT press CTRL+c to exit" |
|
|
|
echo "" |
|
|
|
while true; do |
|
|
|
read -p "Continue? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) break;; |
|
|
|
[Nn]* ) echo Exiting; return 1;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
echo -en "\r\033[K[ .... ] Starting ${servicename} console" |
|
|
|
sleep 0.5 |
|
|
|
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) |
|
|
|
if [ ${tmuxwc} -eq 1 ]; then |
|
|
|
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] Starting ${servicename} console" |
|
|
|
fn_scriptlog "Console accessed" |
|
|
|
sleep 1 |
|
|
|
tmux attach-session -t ${servicename} |
|
|
|
else |
|
|
|
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] Starting ${servicename} console: ${servername} not running" |
|
|
|
sleep 0.5 |
|
|
|
while true; do |
|
|
|
read -p "Do you want to start the server? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) fn_startserver;break;; |
|
|
|
[Nn]* ) break;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_backupserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
backupname="${servicename}-$(date '+%Y-%m-%d-%H%M%S')" |
|
|
|
echo "" |
|
|
|
echo "${gamename} Backup" |
|
|
|
echo "============================" |
|
|
|
echo "" |
|
|
|
echo "The following backup will be created." |
|
|
|
echo "" |
|
|
|
echo "${backupdir}/${backupname}.tar.gz" |
|
|
|
echo "" |
|
|
|
while true; do |
|
|
|
read -p "Continue? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) break;; |
|
|
|
[Nn]* ) echo Exiting; return 1;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) |
|
|
|
if [ ${tmuxwc} -eq 1 ]; then |
|
|
|
echo -e "\e[0;31mWARNING!\e[0;39m ${servicename} is currently running" |
|
|
|
while true; do |
|
|
|
read -p "Would you like to stop ${servicename} while running the backup? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) fn_stopserver;break;; |
|
|
|
[Nn]* ) break;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
fi |
|
|
|
echo -en "\r\033[K[ .... ] Starting backup ${servicename}: ${servername}" |
|
|
|
sleep 1 |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Starting backup ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Backup started" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
cd "${rootdir}" |
|
|
|
mkdir -pv "${backupdir}" > /dev/null 2>&1 |
|
|
|
tar -cvzf "${backupdir}/${backupname}.tar.gz" --exclude "${backupdir}" * |
|
|
|
echo -en "\r\033[K${servicename} Backup complete" |
|
|
|
fn_scriptlog "Backup complete" |
|
|
|
} |
|
|
|
|
|
|
|
fn_distro(){ |
|
|
|
arch=$(uname -m) |
|
|
|
kernel=$(uname -r) |
|
|
|
if [ -f /etc/lsb-release ]; then |
|
|
|
os=$(lsb_release -s -d) |
|
|
|
elif [ -f /etc/debian_version ]; then |
|
|
|
os="Debian $(cat /etc/debian_version)" |
|
|
|
elif [ -f /etc/redhat-release ]; then |
|
|
|
os=$(cat /etc/redhat-release) |
|
|
|
else |
|
|
|
os="$(uname -s) $(uname -r)" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_uptime(){ |
|
|
|
uptime=$(</proc/uptime) |
|
|
|
uptime=${uptime%%.*} |
|
|
|
minutes=$(( uptime/60%60 )) |
|
|
|
hours=$(( uptime/60/60%24 )) |
|
|
|
days=$(( uptime/60/60/24 )) |
|
|
|
} |
|
|
|
|
|
|
|
fn_load(){ |
|
|
|
load=$(uptime|awk -F 'load average' '{ print $2 }') |
|
|
|
} |
|
|
|
|
|
|
|
fn_emailnotification(){ |
|
|
|
fn_distro |
|
|
|
fn_uptime |
|
|
|
fn_load |
|
|
|
{ |
|
|
|
echo -e "========================================\n${servicename} details\n========================================\n" |
|
|
|
echo -e "Service: ${servicename}" |
|
|
|
echo -e "Server: ${servername}" |
|
|
|
echo -e "Game: ${gamename}" |
|
|
|
echo -e "Failure reason: ${failurereason}" |
|
|
|
echo -e "Action Taken: ${actiontaken}\n" |
|
|
|
echo -e "========================================\nServer details\n========================================\n" |
|
|
|
echo -e "Date: $(date)" |
|
|
|
echo -e "Distro: ${os}" |
|
|
|
echo -e "Arch: ${arch}" |
|
|
|
echo -e "Kernel: ${kernel}" |
|
|
|
echo -e "Hostname: $HOSTNAME" |
|
|
|
echo -e "Uptime: ${days}d, ${hours}h, ${minutes}m" |
|
|
|
echo -e "Avg Load${load}\n" |
|
|
|
echo -e "========================================\nLogs\n========================================\n" |
|
|
|
echo -e "Script log\n===================\n" |
|
|
|
}|tee "${scriptlogdir}/${servicename}-email.log" > /dev/null 2>&1 |
|
|
|
tail -25 "${scriptlog}" >> "${emaillog}" |
|
|
|
if [ ! -z "${consolelog}" ]; then |
|
|
|
echo -e "\n\nConsole log\n====================\n" >> "${emaillog}" |
|
|
|
tail -25 "${consolelog}" >> "${emaillog}" |
|
|
|
fi |
|
|
|
if [ ! -z "${gamelogdir}" ]; then |
|
|
|
echo -e "\n\nServer log\n====================\n" >> "${emaillog}" |
|
|
|
tail "${gamelogdir}"/*|grep -v "==>"|sed '/^$/d'|tail -25 >> "${emaillog}" |
|
|
|
fi |
|
|
|
mail -s "${subject}" ${email} < "${emaillog}" |
|
|
|
echo -en "[\e[0;36m INFO \e[0;39m] Sent email notification to ${email}" |
|
|
|
fn_scriptlog "Sent email notification to ${email}" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
} |
|
|
|
|
|
|
|
fn_emailtest(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
fn_scriptlog "Emailing test notification" |
|
|
|
if [ "${emailnotification}" = "on" ]; then |
|
|
|
subject="${servicename} Email Test Notification - Testing ${servername}" |
|
|
|
failurereason="Testing ${servicename} email notification" |
|
|
|
actiontaken="Sent test email...hello is this thing on?" |
|
|
|
fn_emailnotification |
|
|
|
else |
|
|
|
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] Email notification not enabled" |
|
|
|
fn_scriptlog "Email notification not enabled" |
|
|
|
fi |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\n" |
|
|
|
} |
|
|
|
|
|
|
|
fn_serverquery(){ |
|
|
|
# uses gsquery.py to directly query the server |
|
|
|
# detects if the server locks up |
|
|
|
if [ -f gsquery.py ]; then |
|
|
|
if [ "${engine}" == "unreal" ]||[ "${engine}" == "unreal2" ]; then |
|
|
|
gameport=$(grep Port= ${systemdir}/${ini}|grep -v Master|grep -v LAN|grep -v Proxy|grep -v Listen|sed 's/\Port=//g') |
|
|
|
port=$((${gameport} + 1)) |
|
|
|
elif [ "${engine}" == "spark" ]; then |
|
|
|
port=$((${port} + 1)) |
|
|
|
fi |
|
|
|
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] Monitoring ${servicename}: Detected gsquery.py" |
|
|
|
fn_scriptlog "Detected gsquery.py" |
|
|
|
sleep 1 |
|
|
|
echo -en "\r\033[K[ .... ] Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING" |
|
|
|
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING" |
|
|
|
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1) |
|
|
|
exitcode=$? |
|
|
|
sleep 1 |
|
|
|
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}" |
|
|
|
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
if [ "${emailnotification}" = "on" ]; then |
|
|
|
subject="${servicename} Monitor - Starting ${servername}" |
|
|
|
failurereason="Failed to query ${servicename}: ${serverquery}" |
|
|
|
actiontaken="restarted ${servicename}" |
|
|
|
fn_emailnotification |
|
|
|
fi |
|
|
|
fn_restartserver |
|
|
|
exit |
|
|
|
elif [ "${exitcode}" == "0" ]; then |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Monitoring ${servicename}: Querying port: ${ip}:${port}: OK" |
|
|
|
fn_scriptlog "Querying port: ${ip}:${port}: OK" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
exit |
|
|
|
elif [ "${exitcode}" == "126" ]; then |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Monitoring ${servicename}: Querying port: ${ip}:${port}: ERROR: ./gsquery.py: Permission denied" |
|
|
|
fn_scriptlog "Querying port: ${ip}:${port}: ./gsquery.py: Permission denied" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
echo "Attempting to resolve automatically" |
|
|
|
chmod +x -v gsquery.py |
|
|
|
exitcode=$? |
|
|
|
if [ "${exitcode}" == "0" ]; then |
|
|
|
fn_serverquery |
|
|
|
else |
|
|
|
echo -en "\nUnable to resolve automatically. Please manually fix permissions\n" |
|
|
|
owner=$(ls -al gsquery.py|awk '{ print $3 }') |
|
|
|
echo "As user ${owner} or root run the following command" |
|
|
|
whoami=$(whoami) |
|
|
|
echo -en "\nchown ${whoami}:${whoami} gsquery.py\n\n" |
|
|
|
exit |
|
|
|
fi |
|
|
|
else |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Monitoring ${servicename}: Querying port: ${ip}:${port}: UNKNOWN ERROR" |
|
|
|
fn_scriptlog "Querying port: ${ip}:${port}: UNKNOWN ERROR" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
./gsquery.py -a ${ip} -p ${port} -e ${engine} |
|
|
|
exit |
|
|
|
fi |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_monitorserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
fn_autoip |
|
|
|
echo -en "\r\033[K[ .... ] Monitoring ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Monitoring ${servername}" |
|
|
|
sleep 1 |
|
|
|
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l) |
|
|
|
if [ "${updatecheck}" = "0" ]; then |
|
|
|
echo -en "\r\033[K[ .... ] Monitoring ${servicename}: Checking session: CHECKING" |
|
|
|
fn_scriptlog "Checking session: CHECKING" |
|
|
|
sleep 1 |
|
|
|
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) |
|
|
|
if [ ${tmuxwc} -eq 1 ]; then |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Monitoring ${servicename}: Checking session: OK" |
|
|
|
fn_scriptlog "Checking session: OK" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
fn_serverquery |
|
|
|
exit |
|
|
|
else |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Monitoring ${servicename}: Checking session: FAIL" |
|
|
|
fn_scriptlog "Checking session: FAIL" |
|
|
|
sleep 1 |
|
|
|
echo -en "\n" |
|
|
|
if [ "${emailnotification}" = "on" ]; then |
|
|
|
subject="${servicename} Monitor - Starting ${servername}" |
|
|
|
failurereason="${servicename} process not running" |
|
|
|
actiontaken="${servicename} has been restarted" |
|
|
|
fn_emailnotification |
|
|
|
fi |
|
|
|
fn_scriptlog "Monitor is starting ${servername}" |
|
|
|
fn_startserver |
|
|
|
fi |
|
|
|
else |
|
|
|
echo -e "[\e[0;36m INFO \e[0;39m] Monitoring ${servicename}: Detected SteamCMD is checking for updates" |
|
|
|
fn_scriptlog "Detected SteamCMD is checking for updates" |
|
|
|
sleep 1 |
|
|
|
echo -e "[\e[0;36m INFO \e[0;39m] Monitoring ${servicename}: When updates complete ${servicename} will start" |
|
|
|
fn_scriptlog "When updates complete ${servicename} will start" |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_updateserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
echo -en "\r\033[K[ .... ] Updating ${servicename}: ${servername}" |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Updating ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Updating ${servername}" |
|
|
|
cd "${rootdir}" |
|
|
|
cd "steamcmd" |
|
|
|
./steamcmd.sh +login ${steamuser} ${steampass} +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}" |
|
|
|
} |
|
|
|
|
|
|
|
fn_restartserver(){ |
|
|
|
fn_scriptlog "Restarting ${servername}" |
|
|
|
fn_stopserver |
|
|
|
fn_startserver |
|
|
|
} |
|
|
|
|
|
|
|
fn_stopserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) |
|
|
|
echo -en "\r\033[K[ .... ] Stopping ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Stopping ${servername}" |
|
|
|
sleep 0.5 |
|
|
|
if [ "${pid}" == "0" ]; then |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Stopping ${servicename}: ${servername} is already stopped" |
|
|
|
fn_scriptlog "${servername} is already stopped" |
|
|
|
else |
|
|
|
tmux kill-session -t ${servicename} |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Stopping ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Stopped ${servername}" |
|
|
|
fi |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\n" |
|
|
|
} |
|
|
|
|
|
|
|
fn_startserver(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_syscheck |
|
|
|
fn_autoip |
|
|
|
fn_parms |
|
|
|
fn_logmanager |
|
|
|
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) |
|
|
|
if [ ${tmuxwc} -eq 0 ]; then |
|
|
|
mv "${scriptlog}" "${scriptlogdate}" |
|
|
|
mv "${consolelog}" "${consolelogdate}" |
|
|
|
fi |
|
|
|
echo -en "\r\033[K[ .... ] Starting ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Starting ${servername}" |
|
|
|
sleep 0.5 |
|
|
|
if [ ${tmuxwc} -eq 1 ]; then |
|
|
|
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] Starting ${servicename}: ${servername} is already running" |
|
|
|
fn_scriptlog "${servername} is already running" |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\n" |
|
|
|
exit |
|
|
|
fi |
|
|
|
cd "${executabledir}" |
|
|
|
tmux new-session -d -s ${servicename} "${executable} ${parms}|tee -a '${consolelog}'" |
|
|
|
sleep 1 |
|
|
|
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) |
|
|
|
if [ ${tmuxwc} -eq 0 ]; then |
|
|
|
echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] Starting ${servicename}: Failed to start ${servername}" |
|
|
|
fn_scriptlog "failed to start ${servername}" |
|
|
|
else |
|
|
|
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] Starting ${servicename}: ${servername}" |
|
|
|
fn_scriptlog "Started ${servername}" |
|
|
|
fi |
|
|
|
sleep 0.5 |
|
|
|
echo -en "\n" |
|
|
|
} |
|
|
|
|
|
|
|
fn_details(){ |
|
|
|
fn_autoip |
|
|
|
servername=$(grep -s hostname "${servercfg}"|sed 's/hostname //g'|sed 's/"//g') |
|
|
|
rcon=$(grep -s rcon_password "${servercfg}"|sed 's/rcon_password //g'|sed 's/"//g') |
|
|
|
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) |
|
|
|
echo "" |
|
|
|
echo "${gamename} Server Details" |
|
|
|
echo "============================" |
|
|
|
echo "Server name: ${servername}" |
|
|
|
echo "Server IP: ${ip}:${port}" |
|
|
|
echo "RCON password: ${rcon}" |
|
|
|
echo "Config file: ${servercfg}" |
|
|
|
echo "" |
|
|
|
echo "${servername} Ports" |
|
|
|
echo "============================" |
|
|
|
echo "Ports the server is currently using." |
|
|
|
echo "" |
|
|
|
echo "DIRECTION DESCRIPTION PORT" |
|
|
|
echo "INBOUND Game/RCON port ${port}" |
|
|
|
if [ "${engine}" = "source" ]; then |
|
|
|
echo "INBOUND SourceTV port ${sourcetvport}" |
|
|
|
fi |
|
|
|
echo "OUTBOUND Client port ${clientport}" |
|
|
|
echo "" |
|
|
|
echo "You can change ports by editing the" |
|
|
|
echo "start parameters in ${selfname}." |
|
|
|
echo "" |
|
|
|
if [ "${pid}" == "0" ]; then |
|
|
|
echo -e "Status:\e[0;31m OFFLINE\e[0;39m" |
|
|
|
else |
|
|
|
echo -e "Status:\e[0;32m ONLINE\e[0;39m" |
|
|
|
fi |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
# |
|
|
|
## Installer |
|
|
|
# |
|
|
|
|
|
|
|
fn_dodappmanifest(){ |
|
|
|
appdir="${filesdir}/8afa93e01174026686b12fbaf9ff54e7bffbe8fc" |
|
|
|
if [ ${pass} == 1 ]; then |
|
|
|
echo "Creating appmanifest directory. (app 90 fix)" |
|
|
|
sleep 2 |
|
|
|
mkdir -v "${filesdir}" |
|
|
|
mkdir -v "${appdir}" |
|
|
|
cd "${appdir}" |
|
|
|
echo "Removing any existing appmanifest files. (app 90 fix)" |
|
|
|
sleep 2 |
|
|
|
rm -rf "${appdir}/*" |
|
|
|
elif [ ${pass} == 2 ]; then |
|
|
|
echo "Downloading firstpass appmanifest files. (app 90 fix)" |
|
|
|
sleep 2 |
|
|
|
cd "${appdir}" |
|
|
|
wget http://danielgibbs.co.uk/appmanifest/firstpass/appmanifest_10.acf |
|
|
|
wget http://danielgibbs.co.uk/appmanifest/firstpass/appmanifest_70.acf |
|
|
|
wget http://danielgibbs.co.uk/appmanifest/firstpass/appmanifest_90.acf |
|
|
|
elif [ ${pass} == 3 ]; then |
|
|
|
echo "Downloading secondpass appmanifest files. (app 90 fix)" |
|
|
|
sleep 2 |
|
|
|
cd "${appdir}" |
|
|
|
rm -f appmanifest_90.acf |
|
|
|
wget http://danielgibbs.co.uk/appmanifest/secondpass/appmanifest_90.acf |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
fn_header(){ |
|
|
|
clear |
|
|
|
echo "=================================" |
|
|
|
echo "${gamename}" |
|
|
|
echo "Linux Game Server Manager" |
|
|
|
echo "by Daniel Gibbs" |
|
|
|
echo "http://danielgibbs.co.uk" |
|
|
|
echo "=================================" |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
fn_steamdl(){ |
|
|
|
echo "Installing SteamCMD" |
|
|
|
echo "=================================" |
|
|
|
cd "${rootdir}" |
|
|
|
mkdir -pv "steamcmd" |
|
|
|
sleep 1 |
|
|
|
cd "steamcmd" |
|
|
|
if [ ! -f steamcmd.sh ]; then |
|
|
|
wget http://media.steampowered.com/client/steamcmd_linux.tar.gz |
|
|
|
tar --verbose -zxf steamcmd_linux.tar.gz |
|
|
|
rm -v steamcmd_linux.tar.gz |
|
|
|
chmod +x steamcmd.sh |
|
|
|
sleep 1 |
|
|
|
else |
|
|
|
echo "" |
|
|
|
echo "Steam already installed!" |
|
|
|
fi |
|
|
|
sleep 1 |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
fn_steaminstall(){ |
|
|
|
sleep 1 |
|
|
|
mkdir -pv "${filesdir}" |
|
|
|
cd "${rootdir}/steamcmd" |
|
|
|
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} ${steampass} +force_install_dir "${filesdir}" +app_update ${appid} validate +quit |
|
|
|
} |
|
|
|
|
|
|
|
fn_success(){ |
|
|
|
echo "" |
|
|
|
echo "=================================" |
|
|
|
while true; do |
|
|
|
read -p "Was the install successful? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) break;; |
|
|
|
[Nn]* ) fn_retryinstall;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
fn_steamfix(){ |
|
|
|
echo "Applying steamclient.so fix" |
|
|
|
echo "=================================" |
|
|
|
sleep 1 |
|
|
|
mkdir -pv ${HOME}/.steam |
|
|
|
mkdir -pv ${HOME}/.steam/sdk32 |
|
|
|
cp -v "${steamclient}" "${HOME}/.steam/sdk32/steamclient.so" |
|
|
|
sleep 1 |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
fn_loginstall(){ |
|
|
|
echo "Creating log directorys" |
|
|
|
echo "=================================" |
|
|
|
sleep 1 |
|
|
|
mkdir -pv "${rootdir}/log" |
|
|
|
mkdir -pv "${scriptlogdir}" |
|
|
|
touch "${scriptlog}" |
|
|
|
mkdir -pv "${consolelogdir}" |
|
|
|
touch "${consolelog}" |
|
|
|
if [ ! -h ${rootdir}/log/server ]; then |
|
|
|
ln -sv "${gamelogdir}" "${rootdir}/log/server" |
|
|
|
else |
|
|
|
echo "Symbolic link ${gamelogdir} => ${rootdir}/log/server already exists!" |
|
|
|
fi |
|
|
|
sleep 1 |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
fn_retryinstall(){ |
|
|
|
while true; do |
|
|
|
read -p "Retry install? [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) fn_install;; |
|
|
|
[Nn]* ) echo Exiting; exit;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
} |
|
|
|
|
|
|
|
fn_install(){ |
|
|
|
fn_rootcheck |
|
|
|
fn_header |
|
|
|
if [ -d "${filesdir}" ]; then |
|
|
|
echo "${gamename} Server is already installed here:" |
|
|
|
pwd |
|
|
|
echo "" |
|
|
|
while true; do |
|
|
|
read -p "Continue [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) fn_header; break;; |
|
|
|
[Nn]* ) echo Exiting; return 1;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
fi |
|
|
|
echo "Install Directory:" |
|
|
|
pwd |
|
|
|
echo "" |
|
|
|
while true; do |
|
|
|
read -p "Continue [y/N]" yn |
|
|
|
case $yn in |
|
|
|
[Yy]* ) break;; |
|
|
|
[Nn]* ) echo Exiting; return 1;; |
|
|
|
* ) echo "Please answer yes or no.";; |
|
|
|
esac |
|
|
|
done |
|
|
|
fn_header |
|
|
|
fn_steamdl |
|
|
|
|
|
|
|
echo "Installing ${gamename} Server" |
|
|
|
echo "=================================" |
|
|
|
pass=1 |
|
|
|
fn_dodappmanifest |
|
|
|
pass=2 |
|
|
|
fn_dodappmanifest |
|
|
|
fn_steaminstall |
|
|
|
fn_steaminstall |
|
|
|
pass=3 |
|
|
|
fn_dodappmanifest |
|
|
|
fn_steaminstall |
|
|
|
fn_steaminstall |
|
|
|
fn_steaminstall |
|
|
|
fn_success |
|
|
|
fn_steamfix |
|
|
|
fn_loginstall |
|
|
|
echo "Configuring ${gamename} Server" |
|
|
|
echo "=================================" |
|
|
|
sleep 1 |
|
|
|
read -p "Enter server name: " servername |
|
|
|
read -p "Enter rcon password: " rconpass |
|
|
|
sleep 1 |
|
|
|
echo "Creating server.cfg." |
|
|
|
touch "${defaultcfg}" |
|
|
|
echo "exec ${servicename}.cfg" > "${defaultcfg}" |
|
|
|
sleep 1 |
|
|
|
echo "Creating ${servicename}.cfg config file." |
|
|
|
touch "${servercfg}" |
|
|
|
touch "${systemdir}/listip.cfg" |
|
|
|
touch "${systemdir}/banned.cfg" |
|
|
|
{ |
|
|
|
echo -e "// Use this file to configure your DEDICATED server." |
|
|
|
echo -e "// This config file is executed on server start." |
|
|
|
echo -e "" |
|
|
|
echo -e "// disable autoaim" |
|
|
|
echo -e "sv_aim 0" |
|
|
|
echo -e "" |
|
|
|
echo -e "// disable clients' ability to pause the server" |
|
|
|
echo -e "pausable 0" |
|
|
|
echo -e "" |
|
|
|
echo -e "// default server name. Change to \"Bob's Server\", etc." |
|
|
|
echo -e "hostname \"${servername}\"" |
|
|
|
echo -e "" |
|
|
|
echo -e "// maximum client movement speed " |
|
|
|
echo -e "sv_maxspeed 320" |
|
|
|
echo -e "" |
|
|
|
echo -e "// 20 minute timelimit" |
|
|
|
echo -e "mp_timelimit 20" |
|
|
|
echo -e "" |
|
|
|
echo -e "// cheats off" |
|
|
|
echo -e "sv_cheats 0" |
|
|
|
echo -e "" |
|
|
|
echo -e "// load ban files" |
|
|
|
echo -e "exec listip.cfg" |
|
|
|
echo -e "exec banned.cfg" |
|
|
|
echo -e "" |
|
|
|
echo -e "// rcon passsword" |
|
|
|
echo -e "rcon_password \"${rconpass}\"" |
|
|
|
echo -e "" |
|
|
|
echo -e "// Server password" |
|
|
|
echo -e "sv_password \"\"" |
|
|
|
echo -e "" |
|
|
|
echo -e "// server logging" |
|
|
|
echo -e "log on" |
|
|
|
echo -e "sv_logbans 1" |
|
|
|
echo -e "sv_logecho 1" |
|
|
|
echo -e "sv_logfile 1" |
|
|
|
echo -e "sv_log_onefile 0" |
|
|
|
}|tee "${servercfg}" > /dev/null 2>&1 |
|
|
|
sleep 1 |
|
|
|
echo "" |
|
|
|
fn_header |
|
|
|
sleep 1 |
|
|
|
fn_details |
|
|
|
sleep 1 |
|
|
|
echo "=================================" |
|
|
|
echo "Install Complete!" |
|
|
|
echo "" |
|
|
|
echo "To start server type:" |
|
|
|
echo "${selfname} start" |
|
|
|
echo "" |
|
|
|
} |
|
|
|
|
|
|
|
case "$1" in |
|
|
|
start) |
|
|
|
fn_startserver;; |
|
|
|
stop) |
|
|
|
fn_stopserver;; |
|
|
|
restart) |
|
|
|
fn_restartserver;; |
|
|
|
update) |
|
|
|
fn_stopserver |
|
|
|
fn_updateserver |
|
|
|
fn_startserver;; |
|
|
|
monitor) |
|
|
|
fn_monitorserver;; |
|
|
|
email-test) |
|
|
|
fn_emailtest;; |
|
|
|
details) |
|
|
|
fn_details;; |
|
|
|
backup) |
|
|
|
fn_backupserver;; |
|
|
|
console) |
|
|
|
fn_console;; |
|
|
|
debug) |
|
|
|
fn_debugserver;; |
|
|
|
install) |
|
|
|
fn_install;; |
|
|
|
*) |
|
|
|
echo "Usage: $0 {start|stop|restart|update|monitor|email-test|details|backup|console|debug|install}" |
|
|
|
exit 1;; |
|
|
|
esac |
|
|
|
exit |