Browse Source

All servers fully migrated to functions code

All servers have now been migrated to the new functions code. All
functions are now separated in there own file allowing to make quicker
changes to all servers code and simpler management of the code. For the
developer the code is now very scalable.
pull/254/merge
Daniel Gibbs 10 years ago
parent
commit
8f549d689c
  1. 650
      Arma3/arma3server
  2. 664
      BladeSymphony/bsserver
  3. 679
      CounterStrike/csserver
  4. 679
      CounterStrikeConditionZero/csczserver
  5. 732
      CounterStrikeGlobalOffensive/csgoserver
  6. 655
      CounterStrikeSource/cssserver
  7. 684
      DayOfDefeat/dodserver
  8. 663
      DayOfDefeatSource/dodsserver
  9. 698
      FistfulOfFrags/fofserver
  10. 736
      GarrysMod/gmodserver
  11. 655
      HalfLife2Deathmatch/hl2dmserver
  12. 682
      HalfLifeDeathmatchClassic/hldmcserver
  13. 670
      Insurgency/insserver
  14. 643
      JustCause2/jc2server
  15. 694
      KillingFloor/kfserver
  16. 668
      Left4Dead/l4dserver
  17. 655
      Left4Dead2/l4d2server
  18. 633
      NaturalSelection2/ns2server
  19. 664
      NoMoreRoomInHell/nmrihserver
  20. 694
      RedOrchestra/roserver
  21. 655
      TeamFortress2/tf2server
  22. 682
      TeamFortressClassic/tfcserver
  23. 720
      UnrealTournament2004/ut2k4server
  24. 697
      UnrealTournament99/ut99server

650
Arma3/arma3server

@ -4,7 +4,7 @@
# Author: Daniel Gibbs
# Contributor: Scarsz
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -72,7 +72,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -84,15 +84,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -101,11 +102,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -120,10 +117,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -134,398 +129,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -535,96 +205,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -632,161 +243,71 @@ echo ""
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "contributions by Scarsz"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
}
fn_arma3config(){
echo "Downloading CONFIG_Vanilla.cfg"
echo "================================="
sleep 1
cd "${systemdir}"
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/Arma3/CONFIG_Vanilla.cfg
echo "Creating ${servicename}.cfg config file."
sleep 1
cp -v CONFIG_Vanilla.cfg ${servercfgfullpath}
sleep 1
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
fn_arma3config
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -795,6 +316,11 @@ echo "${selfname} start"
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -828,8 +354,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

664
BladeSymphony/bsserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 121114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,175 +247,71 @@ echo ""
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -813,6 +320,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -846,8 +358,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

679
CounterStrike/csserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,190 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -827,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -860,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

679
CounterStrikeConditionZero/csczserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,190 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -827,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -860,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

732
CounterStrikeGlobalOffensive/csgoserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -93,7 +93,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -105,15 +105,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -122,11 +123,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -141,10 +138,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -155,398 +150,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -556,336 +226,109 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_startserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_csgoappidfix
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
sleep 1
echo ""
}
# Game Specific Functions
fn_csgoappidfix(){
if [ ! -f "${filesdir}/steam_appid.txt" ]; then
fn_printdots "Applying 730 steam_appid.txt Fix."
sleep 1
fn_printinfo "Applying 730 steam_appid.txt Fix."
sleep 1
echo -en "\n"
echo -n "730" >> ${filesdir}/steam_appid.txt
fi
}
# Fixes the following error
# Error parsing BotProfile.db - unknown attribute 'Rank"
fn_botprofilefix(){
if ! grep -q "//Rank" "${systemdir}/botprofile.db" ; then
echo "botprofile.db fix removes the following error from appearing on the console:"
echo " Error parsing BotProfile.db - unknown attribute 'Rank"
sleep 1
fn_printdots "Applying botprofile.db fix."
sleep 1
fn_printinfo "Applying botprofile.db fix."
sleep 1
sed -i 's/\tRank/\t\/\/Rank/g' "${systemdir}/botprofile.db"
echo -en "\n"
echo ""
fi
}
# Fixes errors simular to the following
# Unknown command "cl_bobamt_vert"
fn_valvetcfix(){
if ! grep -q "//exec default" "${servercfgdir}/valve.rc" || ! grep -q "//exec joystick" "${servercfgdir}/valve.rc"; then
echo "valve.rc fix removes the following error from appearing on the console:"
echo " Unknown command \"cl_bobamt_vert\""
sleep 1
fn_printdots "Applying valve.rc fix."
sleep 1
fn_printinfo "Applying valve.rc fix."
sleep 1
sed -i 's/exec default.cfg/\/\/exec default.cfg/g' "${servercfgdir}/valve.rc"
sed -i 's/exec joystick.cfg/\/\/exec joystick.cfg/g' "${servercfgdir}/valve.rc"
echo -en "\n"
echo ""
fi
}
# Fixes errors simular to the following
# http://forums.steampowered.com/forums/showthread.php?t=3170366
fn_workshopmapfix(){
if [ -f "${systemdir}/subscribed_collection_ids.txt" ]||[ -f "${systemdir}/subscribed_file_ids.txt" ]||[ -f "${systemdir}/ugc_collection_cache.txt" ]; then
echo "workshopmapfix fixes the following error:"
echo " http://forums.steampowered.com/forums/showthread.php?t=3170366"
sleep 1
fn_printdots "Applying workshopmap fix."
sleep 1
fn_printinfo "Applying workshopmap fix."
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
rm -f "${systemdir}/subscribed_collection_ids.txt"
rm -f "${systemdir}/subscribed_file_ids.txt"
rm -f "${systemdir}/ugc_collection_cache.txt"
echo -en "\n"
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_csgofix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
echo "Applying ${gamename} Fixes"
echo "================================="
fn_botprofilefix
fn_valvetcfix
fn_workshopmapfix
fn_serverconfig
fn_csgofix
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -894,6 +337,11 @@ echo "${selfname} start"
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -927,8 +375,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

655
CounterStrikeSource/cssserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,166 +247,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -804,6 +314,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -837,8 +352,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

684
DayOfDefeat/dodserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -31,7 +31,7 @@ parms="-game dod -strictportbind -ip ${ip} -port ${port} +clientport ${clientpor
#### Advanced Variables ####
# Steam
appid="90 -beta beta +app_set_config 90 mod dod"
appid="90 +app_set_config 90 mod dod"
# Server Details
servicename="dod-server"
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,193 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -830,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -863,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

663
DayOfDefeatSource/dodsserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,271 +209,103 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -812,6 +314,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -845,8 +352,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

698
FistfulOfFrags/fofserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,209 +247,71 @@ echo ""
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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"
echo -e "//Fistful of Frags"
echo -e ""
echo -e "//// Game Modes"
echo -e "// 1 = Shootout"
echo -e "// 2 = Teamplay/Objectives"
echo -e ""
echo -e "fof_sv_currentmode 1 "
echo -e ""
echo -e ""
echo -e "//// Teamplay"
echo -e "// 0 = Free-for-all"
echo -e "// 1 = Team Deathmatch"
echo -e ""
echo -e "mp_teamplay 0"
echo -e ""
echo -e ""
echo -e "//// Friendly Fire"
echo -e "// 0 = Friendly fire disabled"
echo -e "// 1 = Friendly fire enabled"
echo -e ""
echo -e "mp_friendlyfire 0"
echo -e ""
echo -e ""
echo -e "//// Team numbers"
echo -e "// 2 = Vigilantes & Desperados"
echo -e "// 3 = Vigilantes, Desperados & Bandidos"
echo -e "// 4 = Vigilantes, Desperados, Bandidos & Rangers"
echo -e ""
echo -e "fof_sv_maxteams 4"
echo -e ""
echo -e "//// Scrable Teams"
echo -e "// Teams get scrambled when 75% of kills come from same team"
echo -e "fof_sv_scrambleteams 1"
echo -e "fof_sv_scrambleteams_maxkillratio 0.75"
}|tee "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -847,6 +320,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -880,8 +358,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

736
GarrysMod/gmodserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -81,7 +81,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -93,15 +93,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -110,11 +111,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -129,10 +126,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -143,398 +138,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -544,96 +214,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -641,247 +252,71 @@ echo ""
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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"
echo -e "lua_log_sv 0"
echo -e "sv_rcon_banpenalty 0"
echo -e "sv_rcon_maxfailures 20"
echo -e "sv_rcon_minfailures 20"
echo -e "sv_rcon_minfailuretime 20"
echo -e ""
echo -e "// Network Settings"
echo -e "sv_downloadurl \"\""
echo -e "sv_loadingurl \"\""
echo -e "net_maxfilesize 64"
echo -e "sv_maxrate 40000"
echo -e "sv_minrate 40000"
echo -e "sv_maxupdaterate 66"
echo -e "sv_minupdaterate 10"
echo -e "sv_maxcmdrate 60"
echo -e "sv_mincmdrate 10"
echo -e ""
echo -e "// Server Settings"
echo -e "sv_airaccelerate 100"
echo -e "sv_gravity 600"
echo -e "sv_allow_wait_command 0"
echo -e "sv_allow_voice_from_file 0"
echo -e "sv_turbophysics 0"
echo -e "sv_max_usercmd_future_ticks 12"
echo -e "gmod_physiterations 2"
echo -e "sv_client_min_interp_ratio 1"
echo -e "sv_client_max_interp_ratio 2"
echo -e "think_limit 20"
echo -e "sv_region 0"
echo -e "sv_noclipspeed 5"
echo -e "sv_noclipaccelerate 5"
echo -e "sv_lan 0"
echo -e "sv_alltalk 1"
echo -e "sv_contact [email protected]"
echo -e "sv_cheats 0"
echo -e "sv_allowcslua 0"
echo -e "sv_pausable 0"
echo -e "sv_filterban 1"
echo -e "sv_forcepreload 1"
echo -e "sv_footsteps 1"
echo -e "sv_voiceenable 1"
echo -e "sv_voicecodec vaudio_speex"
echo -e "sv_timeout 120"
echo -e "sv_deltaprint 0"
echo -e "sv_allowupload 0"
echo -e "sv_allowdownload 0"
echo -e ""
echo -e "// Sandbox Settings"
echo -e "sbox_noclip 0"
echo -e "sbox_godmode 0"
echo -e "sbox_weapons 0"
echo -e "sbox_plpldamage 0"
echo -e "sbox_maxprops 100"
echo -e "sbox_maxragdolls 50"
echo -e "sbox_maxnpcs 10"
echo -e "sbox_maxballoons 10"
echo -e "sbox_maxeffects 0"
echo -e "sbox_maxdynamite 0"
echo -e "sbox_maxlamps 5"
echo -e "sbox_maxthrusters 20"
echo -e "sbox_maxwheels 20"
echo -e "sbox_maxhoverballs 20"
echo -e "sbox_maxvehicles 1"
echo -e "sbox_maxbuttons 20"
echo -e "sbox_maxemitters 0"
echo -e "sbox_maxspawners 0"
echo -e "sbox_maxturrets 0"
echo -e ""
echo -e "// Misc Config"
echo -e "exec banned_user.cfg"
echo -e "exec banned_ip.cfg"
echo -e "heartbeat"
}|tee "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -890,6 +325,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -923,8 +363,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

655
HalfLife2Deathmatch/hl2dmserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,166 +247,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -804,6 +314,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -837,8 +352,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

682
HalfLifeDeathmatchClassic/hldmcserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,193 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -830,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -863,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

670
Insurgency/insserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,272 +209,109 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_glibcfix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -813,6 +320,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -846,8 +358,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

643
JustCause2/jc2server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -70,7 +70,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -82,15 +82,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -99,11 +100,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -118,10 +115,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -132,398 +127,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -533,245 +203,103 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
fn_glibcfix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_jc2config(){
echo "Copying default_config.lua"
echo "================================="
sleep 1
cd "${filesdir}"
cp -v default_config.lua config.lua
sleep 1
echo ""
fn_loginstall(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_glibcfix
fn_loginstall
fn_jc2config
fn_getquery
fn_glibcfix
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -780,6 +308,11 @@ echo "${selfname} start"
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -813,8 +346,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

694
KillingFloor/kfserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -70,7 +70,7 @@ parms="server ${defaultmap}?game=KFmod.KFGameType?VACSecured=true -nohomedir ini
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -82,15 +82,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -99,11 +100,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -118,10 +115,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -132,398 +127,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -533,293 +203,114 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
fn_kfcompressmaps(){
fn_rootcheck
clear
echo "${gamename} Map Compressor"
echo "============================"
echo "Will compress all maps in:"
echo ""
pwd
echo ""
echo "Compressed maps saved to:"
echo ""
echo "${compressedmapsdir}"
echo ""
while true; do
read -p "Start compression [y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) echo Exiting; return 1;;
* ) echo "Please answer yes or no.";;
esac
done
mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1
rm -rfv "${filesdir}/Maps/*.uz2"
cd "${systemdir}"
for map in `ls "${filesdir}/Maps"`; do
./ucc-bin compress ../Maps/${map} --nohomedir
done
mv -fv "${filesdir}/Maps/*.uz2" "${compressedmapsdir}"
fn_unreal2compressmaps(){
functionfile="${FUNCNAME}"
fn_runfunction
}
#
## Installer
#
fn_kffix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
echo "Configuring ${gamename} Server"
echo "================================="
sleep 1
echo "Copying "${defaultcfg}" to ${systemdir}/${ini}"
cp "${defaultcfg}" "${systemdir}/${ini}"
sleep 1
echo "Applying WebAdmin ROOst.css fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13"
sed -i 's/none}/none;/g' ${filesdir}/Web/ServerAdmin/ROOst.css
sed -i 's/underline}/underline;/g' ${filesdir}/Web/ServerAdmin/ROOst.css
sleep 1
echo "Applying WebAdmin CharSet fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1"
sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' ${systemdir}/UWeb.int
sleep 1
echo "Setting WebAdmin username and password"
sed -i 's/AdminName=/AdminName=admin/g' ${systemdir}/${ini}
sed -i 's/AdminPassword=/AdminPassword=admin/g' ${systemdir}/${ini}
sleep 1
echo "Enabling WebAdmin"
sed -i 's/bEnabled=False/bEnabled=True/g' ${systemdir}/${ini}
sleep 1
echo "Forcing server to start to get ports/server name to display correctly"
sleep 1
cd "${rootdir}"
${selfname} start
sleep 5
${selfname} restart
sleep 5
${selfname} stop
sleep 5
fn_serverconfig
fn_kffix
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -828,6 +319,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -861,10 +357,12 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
map-compressor)
fn_kfcompressmaps;;
fn_unreal2compressmaps;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|map-compressor}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install|map-compressor}"
exit 1;;
esac
exit

668
Left4Dead/l4dserver

@ -2,8 +2,9 @@
# Left 4 Dead
# Server Management Script
# Author: Daniel Gibbs
# Contributor: Summit Singh Thakur
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,275 +209,103 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_l4ddeps(){
echo "Copying libstdc++.so.6"
echo "================================="
sleep 1
cd "${filesdir}"
cp -v "${rootdir}/steamcmd/linux32/libstdc++.so.6" "${filesdir}"
sleep 1
echo ""
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "contributions by Summit Singh Thakur"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
fn_l4ddeps
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -815,6 +314,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -848,8 +352,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

655
Left4Dead2/l4d2server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,166 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -803,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -836,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

633
NaturalSelection2/ns2server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,241 +208,103 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
## Installer
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_glibcfix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -781,6 +313,11 @@ fn_glibcfix
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -814,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

664
NoMoreRoomInHell/nmrihserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,175 +247,71 @@ echo ""
#
fn_glibcfix(){
if [ ! -f ${rootdir}/functions/fn_glibcfix ]; then
functionfile="fn_glibcfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_glibcfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_glibcfix
fn_loginstall
fn_getquery
fn_glibcfix
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 "${servercfgfullpath}"
{
echo -e "// Server Name"
echo -e "hostname \"${servername}\""
echo -e ""
echo -e "// RCON Password"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -813,6 +320,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -846,8 +358,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

694
RedOrchestra/roserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -66,7 +66,7 @@ parms="server ${defaultmap}?game=ROGame.ROTeamGame?VACSecured=true -nohomedir in
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -78,15 +78,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -95,11 +96,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -114,10 +111,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -128,398 +123,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -529,293 +199,114 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
fn_kfcompressmaps(){
fn_rootcheck
clear
echo "${gamename} Map Compressor"
echo "============================"
echo "Will compress all maps in:"
echo ""
pwd
echo ""
echo "Compressed maps saved to:"
echo ""
echo "${compressedmapsdir}"
echo ""
while true; do
read -p "Start compression [y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) echo Exiting; return 1;;
* ) echo "Please answer yes or no.";;
esac
done
mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1
rm -rfv "${filesdir}/Maps/*.uz2"
cd "${systemdir}"
for map in `ls "${filesdir}/Maps"`; do
./ucc-bin compress ../Maps/${map} --nohomedir
done
mv -fv "${filesdir}/Maps/*.uz2" "${compressedmapsdir}"
fn_unreal2compressmaps(){
functionfile="${FUNCNAME}"
fn_runfunction
}
#
## Installer
#
fn_rofix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
echo "Configuring ${gamename} Server"
echo "================================="
sleep 1
echo "Copying "${defaultcfg}" to ${systemdir}/${ini}"
cp "${defaultcfg}" "${systemdir}/${ini}"
sleep 1
echo "Applying WebAdmin ROOst.css fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13"
sed -i 's/none}/none;/g' ${filesdir}/Web/ServerAdmin/ROOst.css
sed -i 's/underline}/underline;/g' ${filesdir}/Web/ServerAdmin/ROOst.css
sleep 1
echo "Applying WebAdmin CharSet fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1"
sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' ${systemdir}/uweb.int
sleep 1
echo "Setting WebAdmin username and password"
sed -i 's/AdminName=/AdminName=admin/g' ${systemdir}/${ini}
sed -i 's/AdminPassword=/AdminPassword=ropass/g' ${systemdir}/${ini}
sleep 1
echo "Enabling WebAdmin"
sed -i 's/bEnabled=False/bEnabled=True/g' ${systemdir}/${ini}
sleep 1
echo "Forcing server to start to get ports/server name to display correctly"
sleep 1
cd "${rootdir}"
${selfname} start
sleep 5
${selfname} restart
sleep 5
${selfname} stop
sleep 5
fn_serverconfig
fn_rofix
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -824,6 +315,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -857,10 +353,12 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
map-compressor)
fn_kfcompressmaps;;
fn_unreal2compressmaps;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|map-compressor}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install|map-compressor}"
exit 1;;
esac
exit

655
TeamFortress2/tf2server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -76,7 +76,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -88,15 +88,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -105,11 +106,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -124,10 +121,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -138,398 +133,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -539,96 +209,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -636,166 +247,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
{
echo -e "// server name"
echo -e "hostname \"${servername}\""
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -804,6 +314,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -837,8 +352,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

682
TeamFortressClassic/tfcserver

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -75,7 +75,7 @@ consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -87,15 +87,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -104,11 +105,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -123,10 +120,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -137,398 +132,73 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_updateserver(){
fn_rootcheck
fn_syscheck
fn_printdots "Updating ${servicename}: ${servername}"
sleep 1
fn_printok "Updating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Updating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_validateserver(){
fn_rootcheck
fn_syscheck
fn_printwarn "Validating may overwrite some customised files."
sleep 1
echo -en "\n"
echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
sleep 5
echo -en "\n"
fn_printdots "Validating ${servicename}: ${servername}"
sleep 1
fn_printok "Validating ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Validating ${servername}"
cd "${rootdir}"
cd "steamcmd"
./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit|tee -a "${scriptlog}"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -538,96 +208,37 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
#
@ -635,193 +246,65 @@ echo ""
#
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamdl(){
echo "Installing SteamCMD"
echo "================================="
cd "${rootdir}"
mkdir -pv "steamcmd"
sleep 1
cd "steamcmd"
if [ ! -f steamcmd.sh ]; then
wget -nv -N 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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steaminstall(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${rootdir}/steamcmd"
STEAMEXE=steamcmd ./steamcmd.sh +login ${steamuser} "${steampass}" +force_install_dir "${filesdir}" +app_update ${appid} validate +quit
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 ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_steamfix(){
if [ ! -f ${rootdir}/functions/fn_steamfix ]; then
functionfile="fn_steamfix"
fn_fninstall
fi
source ${rootdir}/functions/fn_steamfix
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_steamdl
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steaminstall
fn_steamfix
fn_loginstall
fn_getquery
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 "${servercfgfullpath}"
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 "${servercfgfullpath}" > /dev/null 2>&1
sleep 1
echo ""
fn_serverconfig
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -830,6 +313,11 @@ echo "================================="
echo ""
}
fn_autoinstall(){
autoinstall=1
fn_install
}
case "$1" in
start)
fn_startserver;;
@ -863,8 +351,10 @@ case "$1" in
fn_debugserver;;
install)
fn_install;;
auto-install)
fn_autoinstall;;
*)
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install}"
echo "Usage: $0 {start|stop|restart|update|update-restart|validate|validate-restart|monitor|email-test|details|backup|console|debug|install|auto-install}"
exit 1;;
esac
exit

720
UnrealTournament2004/ut2k4server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -59,7 +59,7 @@ parms="server ${defaultmap}?game=XGame.xDeathMatch -nohomedir ini=${ini} log=${g
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -71,15 +71,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -88,11 +89,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -107,10 +104,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -121,366 +116,63 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -490,356 +182,114 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
fn_ut2k4compressmaps(){
fn_rootcheck
clear
echo "${gamename} Map Compressor"
echo "============================"
echo "Will compress all maps in:"
echo ""
pwd
echo ""
echo "Compressed maps saved to:"
echo ""
echo "${compressedmapsdir}"
echo ""
while true; do
read -p "Start compression [y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) echo Exiting; return 1;;
* ) echo "Please answer yes or no.";;
esac
done
mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1
rm -rfv "${filesdir}/Maps/*.uz2"
cd "${systemdir}"
for map in `ls "${filesdir}/Maps"`; do
if [ `getconf LONG_BIT` = "64" ]; then
./ucc-bin-linux-amd64 compress ../Maps/${map} --nohomedir
else
./ucc-bin compress ../Maps/${map} --nohomedir
fi
done
mv -fv "${filesdir}/Maps/*.uz2" "${compressedmapsdir}"
fn_unreal2compressmaps(){
functionfile="${FUNCNAME}"
fn_runfunction
}
#
## Installer
#
fn_ut2k4fix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_ut2k4filesdl(){
echo "Downloading Server Files"
echo "================================="
cd "${rootdir}"
mkdir -pv "${filesdir}"
cd "${filesdir}"
if [ ! -f dedicatedserver3339-bonuspack.zip ]; then
wget -nv -N http://downloads.unrealadmin.org/UT2004/Server/dedicatedserver3339-bonuspack.zip
else
echo "dedicatedserver3339-bonuspack.zip already downloaded!"
fi
echo "Running MD5 checksum to verify the file"
sleep 1
echo "MD5 checksum: d3f28c5245c4c02802d48e4f0ffd3e34"
md5check=$(md5sum dedicatedserver3339-bonuspack.zip|awk '{print $1;}')
echo "File returned: ${md5check}"
if [ "${md5check}" != "d3f28c5245c4c02802d48e4f0ffd3e34" ]; then
echo "MD5 checksum: FAILED!"
read -p "Retry download? [y/N]" yn
case $yn in
[Yy]* ) rm -fv dedicatedserver3339-bonuspack.zip; fn_ut2k4filesdl;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
else
echo "MD5 checksum: PASSED"
fi
if [ ! -f ut2004-lnxpatch3369-2.tar.bz2 ]; then
wget -nv -N http://downloads.unrealadmin.org/UT2004/Patches/Linux/ut2004-lnxpatch3369-2.tar.bz2
else
echo "ut2004-lnxpatch3369-2.tar.bz2 already downloaded!"
fi
echo "Running MD5 checksum to verify the file"
sleep 1
echo "MD5 checksum: 0fa447e05fe5a38e0e32adf171be405e"
md5check=$(md5sum ut2004-lnxpatch3369-2.tar.bz2|awk '{print $1;}')
echo "File returned: ${md5check}"
if [ "${md5check}" != "0fa447e05fe5a38e0e32adf171be405e" ]; then
echo "MD5 checksum: FAILED!"
read -p "Retry download? [y/N]" yn
case $yn in
[Yy]* ) rm -fv ut2004-lnxpatch3369-2.tar.bz2; fn_ut2k4filesdl;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
else
echo "MD5 checksum: PASSED"
fi
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_ut2k4key(){
echo "Enter ${gamename} CD Key"
echo "================================="
sleep 1
echo "To get your server listed on the Master Server list"
echo "you must get a free CD key. Get a key here:"
echo "http://www.unrealtournament.com/ut2004server/cdkey.php"
echo ""
echo "Once you have the key enter it below"
echo -n "KEY: "
read CODE
echo ""\""CDKey"\""="\""${CODE}"\""" > "${systemdir}/cdkey"
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_ut2k4install(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${filesdir}"
echo "Extracting dedicatedserver3339-bonuspack.zip"
sleep 1
unzip dedicatedserver3339-bonuspack.zip
echo "Extracting ut2004-lnxpatch3369-2.tar.bz2"
sleep 1
tar -xvjf ut2004-lnxpatch3369-2.tar.bz2 UT2004-Patch/ --strip-components=1
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
while true; do
read -p "Remove ut2004-lnxpatch3369-2.tar.bz2? [y/N]" yn
case $yn in
[Yy]* ) rm -fv ut2004-lnxpatch3369-2.tar.bz2; break;;
[Nn]* ) break;;
* ) echo "Please answer yes or no.";;
esac
done
while true; do
read -p "Remove dedicatedserver3339-bonuspack.zip? [y/N]" yn
case $yn in
[Yy]* ) rm -fv dedicatedserver3339-bonuspack.zip; break;;
[Nn]* ) break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_ut2k4filesdl
fn_ut2k4install
fn_ut2k4key
fn_utloginstall
fn_loginstall
fn_getquery
echo "Configuring ${gamename} Server"
echo "================================="
sleep 1
echo "Copying "${defaultcfg}" to ${systemdir}/${ini}"
cp "${defaultcfg}" "${systemdir}/${ini}"
sleep 1
echo "Applying WebAdmin ut2003.css fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13"
sed -i 's/none}/none;/g' "${filesdir}/Web/ServerAdmin/ut2003.css"
sed -i 's/underline}/underline;/g' "${filesdir}/Web/ServerAdmin/ut2003.css"
sleep 1
echo "Applying WebAdmin CharSet fix!"
echo "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1"
sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/UWeb.int"
sleep 1
echo "Setting WebAdmin username and password"
sed -i 's/AdminName=/AdminName=admin/g' "${systemdir}/${ini}"
sed -i 's/AdminPassword=/AdminPassword=admin/g' "${systemdir}/${ini}"
sleep 1
echo "Enabling WebAdmin"
sed -i 's/bEnabled=False/bEnabled=True/g' "${systemdir}/${ini}"
sleep 1
echo "Setting WebAdmin port to 8077"
sed -i 's/ListenPort=80/ListenPort=8077/g' "${systemdir}/${ini}"
sleep 1
echo "Forcing server to start to get ports/server name to display correctly"
sleep 1
cd "${rootdir}"
${selfname} start
sleep 5
${selfname} restart
sleep 5
${selfname} stop
sleep 5
fn_serverconfig
fn_ut2k4fix
fn_header
sleep 1
fn_details
sleep 1
echo "================================="
echo "Install Complete!"
echo ""
@ -870,7 +320,7 @@ case "$1" in
install)
fn_install;;
map-compressor)
fn_ut2k4compressmaps;;
fn_unreal2compressmaps;;
*)
echo "Usage: $0 {start|stop|restart|monitor|email-test|details|backup|console|debug|install|map-compressor}"
exit 1;;

697
UnrealTournament99/ut99server

@ -3,7 +3,7 @@
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 231114
# Version: 011214
#### Variables ####
@ -56,7 +56,7 @@ parms="server ${defaultmap}.unr ini=${systemdir}/${ini}"
# what you are doing
fn_scriptlog(){
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> ${scriptlog}
echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
}
# [ FAIL ]
@ -68,15 +68,16 @@ fn_printfailnl(){
echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}
# [ OK ]
fn_printok(){
echo -en "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ OK ]
fn_printoknl(){
echo -e "\r\033[K[\e[0;32m OK \e[0;39m] $@"
}
# [ INFO ]
fn_printinfo(){
echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
@ -85,11 +86,7 @@ fn_printinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ INFO ]
fn_printokinfonl(){
echo -e "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}
# [ WARN ]
fn_printwarn(){
echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}
@ -104,10 +101,8 @@ fn_printdots(){
}
fn_rootcheck(){
if [ `whoami` = "root" ]; then
fn_printfailnl "Script will not run as root!"
exit
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_syscheck(){
@ -118,366 +113,63 @@ 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)
getipwc=$(ip -o -4 addr|awk '{print $4 }'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0|wc -l)
if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
if [ "${getipwc}" -ge "2" ]; then
fn_printwarn "Multiple active network interfaces.\n\n"
echo -en "Manually specify the IP you want to use within the ${selfname} script.\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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting log cleaner"
sleep 1
fn_printok "Starting log cleaner"
fn_scriptlog "Starting log cleaner"
sleep 1
echo -en "\n"
fn_printinfo "Removing logs older than ${logdays} days"
fn_scriptlog "Removing logs older than ${logdays} days"
sleep 1
echo -en "\n"
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
fi
find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
if [ "${engine}" == "unreal2" ]; then
gamecount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
fi
scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
count=$((${scriptcount} + ${consolecount}))
if [ "${engine}" == "unreal2" ]; then
count=$((${scriptcount} + ${consolecount} + ${gamecount}))
else
count=$((${scriptcount} + ${consolecount}))
fi
if [ "${engine}" == "unreal2" ]; then
find "${gamelogdir}"/* -mtime +${logdays} -exec rm {} \;
fi
find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
fn_printok "Log cleaner removed ${count} log files"
fn_scriptlog "Log cleaner removed ${count} log files"
sleep 1
echo -en "\n"
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_debugserver(){
if [ ! -f ${rootdir}/functions/fn_debugserver ]; then
functionfile="fn_debugserver"
fn_fninstall
fi
source ${rootdir}/functions/fn_debugserver
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting ${servicename} console"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
fn_printoknl "Starting ${servicename} console"
fn_scriptlog "Console accessed"
sleep 1
tmux attach-session -t ${servicename}
else
fn_printfailnl "Starting ${servicename} console: ${servername} not running"
sleep 1
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
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "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"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
functionfile="${FUNCNAME}"
fn_runfunction
}
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}"
fn_printinfo "Sent email notification to ${email}"
fn_scriptlog "Sent email notification to ${email}"
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_printfailnl "Email notification not enabled"
fn_scriptlog "Email notification not enabled"
fi
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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))
elif [ "${engine}" == "realvirtuality" ]; then
port=${queryport}
fi
fn_printinfo "Monitoring ${servicename}: Detected gsquery.py"
fn_scriptlog "Detected gsquery.py"
sleep 1
fn_printdots "Monitoring ${servicename}: Querying port: ${ip}:${port}: QUERYING"
fn_scriptlog "Querying port: ${ip}:${port}: QUERYING"
sleep 1
serverquery=$(./gsquery.py -a ${ip} -p ${port} -e ${engine} 2>&1)
exitcode=$?
if [ "${exitcode}" == "1" ]||[ "${exitcode}" == "2" ]||[ "${exitcode}" == "3" ]||[ "${exitcode}" == "4" ]; then
fn_printfail "Monitoring ${servicename}: Querying port: ${ip}:${port}: ${serverquery}"
sleep 1
echo -en "\n"
fn_scriptlog "Querying port: ${ip}:${port}: ${serverquery}"
if [[ -z "${secondquery}" ]]; then
fn_printinfo "Monitoring ${servicename}: Waiting 30 seconds to re-query"
fn_scriptlog "Waiting 30 seconds to re-query"
sleep 30
secondquery=1
fn_serverquery
fi
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
fn_printok "Monitoring ${servicename}: Querying port: ${ip}:${port}: OK"
fn_scriptlog "Querying port: ${ip}:${port}: OK"
sleep 1
echo -en "\n"
exit
elif [ "${exitcode}" == "126" ]; then
fn_printfail "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
fn_printfail "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
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_monitorserver(){
fn_rootcheck
fn_syscheck
fn_autoip
fn_printdots "Monitoring ${servicename}: ${servername}"
fn_scriptlog "Monitoring ${servername}"
sleep 1
if [ ! -f ${lockselfname} ]; then
fn_printinfo "Monitoring ${servicename}: Monitor disabled: No lock file found"
fn_scriptlog "Monitor disabled: No lock file found"
sleep 1
echo -en "\n"
echo "To enable monitor run ${selfname} start"
exit
fi
updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
if [ "${updatecheck}" = "0" ]; then
fn_printdots "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
fn_printok "Monitoring ${servicename}: Checking session: OK"
fn_scriptlog "Checking session: OK"
sleep 1
echo -en "\n"
fn_serverquery
exit
else
fn_printfail "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
fn_printinfonl "Monitoring ${servicename}: Detected SteamCMD is checking for updates"
fn_scriptlog "Detected SteamCMD is checking for updates"
sleep 1
fn_printinfonl "Monitoring ${servicename}: When updates complete ${servicename} will start"
fn_scriptlog "When updates complete ${servicename} will start"
sleep 1
fi
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_restartserver(){
@ -487,332 +179,109 @@ fn_startserver
}
fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
fn_printdots "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopping ${servername}"
sleep 1
if [ "${pid}" == "0" ]; then
fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
fn_scriptlog "${servername} is already stopped"
else
tmux kill-session -t ${servicename}
fn_printok "Stopping ${servicename}: ${servername}"
fn_scriptlog "Stopped ${servername}"
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
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
fn_scriptlog "Rotating log files"
if [ "${engine}" == "unreal2" ]; then
mv "${gamelog}" "${gamelogdate}"
fi
mv "${scriptlog}" "${scriptlogdate}"
mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
fn_scriptlog "Starting ${servername}"
sleep 1
if [ ${tmuxwc} -eq 1 ]; then
fn_printinfo "Starting ${servicename}: ${servername} is already running"
fn_scriptlog "${servername} is already running"
sleep 1
echo -en "\n"
exit
fi
# Create lock file
date > "${rootdir}/${lockselfname}"
cd "${executabledir}"
tmux new-session -d -s ${servicename} "${executable} ${parms}" 2> ${scriptlogdir}/.${servicename}-tmux-error.tmp
tmux pipe-pane -o -t ${servicename} "exec cat >> '${consolelog}'"
sleep 1
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
fn_printfailnl "Starting ${servicename}: Failed to start ${servername}"
echo -en " Check log files: ${rootdir}/log"
fn_scriptlog "failed to start ${servername}"
if [ -a ${scriptlogdir}/.${servicename}-tmux-error.tmp ]; then
fn_scriptlog "tmux returned the following error"
cat ${scriptlogdir}/.${servicename}-tmux-error.tmp >> ${scriptlog}
fi
else
fn_printok "Starting ${servicename}: ${servername}"
fn_scriptlog "Started ${servername}"
fi
rm ${scriptlogdir}/.${servicename}-tmux-error.tmp
sleep 1
echo -en "\n"
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_details(){
if [ ! -f ${rootdir}/functions/fn_details ]; then
functionfile="fn_details"
fn_fninstall
fi
source ${rootdir}/functions/fn_details
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_fninstall(){
cd ${rootdir}
fn_runfunction(){
# Download function if missing
if [ ! -f "${rootdir}/functions/${functionfile}" ]; then
cd "${rootdir}"
if [ ! -d "functions" ]; then
mkdir functions
fi
echo ""
echo "loading ${functionfile}..."
cd functions
wget --no-check-certificate -nv -N https://raw.githubusercontent.com/dgibbs64/linuxgameservers/master/functions/${functionfile}
chmod +x ${functionfile}
cd ${rootdir}
chmod +x "${functionfile}"
cd "${rootdir}"
sleep 1
echo ""
fi
# Run function
source "${rootdir}/functions/${functionfile}"
}
fn_ut99compressmaps(){
fn_rootcheck
clear
echo "${gamename} Map Compressor"
echo "============================"
echo "Will compress all maps in:"
echo ""
pwd
echo ""
echo "Compressed maps saved to:"
echo ""
echo "${compressedmapsdir}"
echo ""
while true; do
read -p "Start compression [y/N]" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) echo Exiting; return 1;;
* ) echo "Please answer yes or no.";;
esac
done
mkdir -pv "${compressedmapsdir}" > /dev/null 2>&1
rm -rfv "${filesdir}/Maps/*.unr.uz"
cd "${systemdir}"
for map in `ls "${filesdir}/Maps"`; do
./ucc-bin compress ../Maps/${map} --nohomedir
done
mv -fv "${filesdir}/Maps/*.unr.uz" "${compressedmapsdir}"
functionfile="${FUNCNAME}"
fn_runfunction
}
#
## Installer
#
fn_ut99fix(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_header(){
clear
echo "================================="
echo "${gamename}"
echo "Linux Game Server Manager"
echo "by Daniel Gibbs"
echo "http://danielgibbs.co.uk"
echo "================================="
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_ut99filesdl(){
echo "Downloading Server Files"
echo "================================="
cd "${rootdir}"
mkdir -pv "${filesdir}"
cd "${filesdir}"
if [ ! -f ut-server-436.tar.gz ]; then
wget -nv -N http://danielgibbs.co.uk/wp-content/uploads/ut-server-436.tar.gz
else
echo "ut-server-436.tar.gz already downloaded!"
fi
echo "Running MD5 checksum to verify the file"
sleep 1
echo "MD5 checksum: 10cd7353aa9d758a075c600a6dd193fd"
md5check=$(md5sum ut-server-436.tar.gz|awk '{print $1;}')
echo "File returned: ${md5check}"
if [ "${md5check}" != "10cd7353aa9d758a075c600a6dd193fd" ]; then
echo "MD5 checksum: FAILED!"
read -p "Retry download? [y/N]" yn
case $yn in
[Yy]* ) rm -fv ut-server-436.tar.gz; fn_filesdl;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
else
echo "MD5 checksum: PASSED"
fi
if [ ! -f UTPGPatch451.tar.bz2 ]; then
wget -nv -N http://danielgibbs.co.uk/wp-content/uploads/UTPGPatch451.tar.bz2
else
echo "UTPGPatch451.tar.bz2 already downloaded!"
fi
echo "Running MD5 checksum to verify the file"
sleep 1
echo "MD5 checksum: 77a735a78b1eb819042338859900b83b"
md5check=$(md5sum UTPGPatch451.tar.bz2|awk '{print $1;}')
echo "File returned: ${md5check}"
if [ "${md5check}" != "77a735a78b1eb819042338859900b83b" ]; then
echo "MD5 checksum: FAILED!"
read -p "Retry download? [y/N]" yn
case $yn in
[Yy]* ) rm -fv UTPGPatch451.tar.bz2; fn_filesdl;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
else
echo "MD5 checksum: PASSED"
fi
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_ut99install(){
echo "Installing ${gamename} Server"
echo "================================="
sleep 1
mkdir -pv "${filesdir}"
cd "${filesdir}"
echo "Extracting ut-server-436.tar.gz"
sleep 1
tar -zxvf ut-server-436.tar.gz ut-server/ --strip-components=1
echo "Extracting UTPGPatch451.tar.bz2"
sleep 1
tar -jxvf UTPGPatch451.tar.bz2
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
while true; do
read -p "Remove ut-server-436.tar.gz? [y/N]" yn
case $yn in
[Yy]* ) rm -fv ut-server-436.tar.gz; break;;
[Nn]* ) break;;
* ) echo "Please answer yes or no.";;
esac
done
while true; do
read -p "Remove UTPGPatch451.tar.bz2? [y/N]" yn
case $yn in
[Yy]* ) rm -fv UTPGPatch451.tar.bz2; break;;
[Nn]* ) break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_loginstall(){
if [ ! -f ${rootdir}/functions/fn_loginstall ]; then
functionfile="fn_loginstall"
fn_fninstall
fi
source ${rootdir}/functions/fn_loginstall
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_getquery(){
echo "GameServerQuery"
echo "============================"
while true; do
read -p "Do you want to install GameServerQuery? [y/N]" yn
case $yn in
[Yy]* ) cd "${rootdir}"; wget -nv -N "http://danielgibbs.co.uk/dl/gsquery.py"; chmod +x gsquery.py; break;;
[Nn]* ) echo -e "Not installing GameServerQuery.";break;;
* ) echo "Please answer yes or no.";;
esac
done
echo ""
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_retryinstall(){
while true; do
read -p "Retry install? [y/N]" yn
case $yn in
[Yy]* ) fn_install; exit;;
[Nn]* ) echo Exiting; exit;;
* ) echo "Please answer yes or no.";;
esac
done
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverdirectory(){
functionfile="${FUNCNAME}"
fn_runfunction
}
fn_serverconfig(){
functionfile="${FUNCNAME}"
fn_runfunction
}
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
if [ -z "${autoinstall}" ]; then
fn_serverdirectory
fn_header
fi
fn_ut99filesdl
fn_ut99install
fn_utloginstall
fn_loginstall
fn_getquery
echo "Configuring ${gamename} Server"
echo "================================="
sleep 1
echo "Copying "${defaultcfg}" to ${systemdir}/${ini}"
tr -d '\r' < "${defaultcfg}" > "${systemdir}/${ini}"
sleep 1
echo "Enabling UdpServerUplink"
{
echo "[IpServer.UdpServerUplink]"
echo "DoUplink=True"
echo "UpdateMinutes=1"
echo "MasterServerAddress=unreal.epicgames.com"
echo "MasterServerPort=27900"
echo "Region=0"
}|tee -a "${systemdir}/${ini}" > /dev/null 2>&1
sleep 1
echo "Removing dead mplayer.com master server"
sed -i '/master.mplayer.com/d' "${systemdir}/${ini}"
sleep 1
echo "Inserting qtracker.com master server"
sed -i '66i\ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.qtracker.com MasterServerPort=27900' "${systemdir}/${ini}"
sleep 1
echo "Enabling WebAdmin"
sed -i 's/bEnabled=False/bEnabled=True/g' "${systemdir}/${ini}"
sleep 1
echo "Setting WebAdmin port to 8076"
sed -i '467i\ListenPort=8076' "${systemdir}/${ini}"
sleep 1
fn_serverconfig
fn_ut99fix
fn_header
sleep 1
fn_utdetails
sleep 1
fn_details
echo "================================="
echo "Install Complete!"
echo ""
@ -843,7 +312,7 @@ case "$1" in
install)
fn_install;;
map-compressor)
fn_ut2k4compressmaps;;
fn_ut99compressmaps;;
*)
echo "Usage: $0 {start|stop|restart|monitor|email-test|details|backup|console|debug|install|map-compressor}"
exit 1;;

Loading…
Cancel
Save