[GH-ISSUE #206] Creating New Scripts (Which script should I base it on?) #170

Closed
opened 2026-02-27 01:59:55 +03:00 by kerem · 4 comments
Owner

Originally created by @JmactheAttack on GitHub (Oct 29, 2014).
Original GitHub issue: https://github.com/GameServerManagers/LinuxGSM/issues/206

I am looking/attempting/failing at porting your scripts over to run a few different game servers, specifically JK3, CoD4, and CoD:WAW along with possibly a few others (and of course hopefully getting them pulled into this repo. My first attempt at it was porting the Mumble server script over to run a CoD4 server because it seemed to be the most generic script mainly because it just manages a single executable, an .ini file and some variables, without any Steam or Unreal additions. I got the CoD4 script to start the server and it runs great, but when I stop it, it seems to stop all my other scripts (a 24/7 CSGO and Mumble server). I also noticed that the Mumble server script does not seem to run perfectly either, like sometimes when I stop it, it doesn't completely kill murmur.x86 process(s). The script stops and kills the tmux session (conf, but murmur continues to run, etc, etc.

My question: is the Mumble server script out of date and incompatible with the other server scripts because of recent changes to the others? If so, should I base my new scripts off of more recent ones like the CS:GO script and just hack-off/disable the unused parts (i.e. the install bits, etc)? Also, is it okay to run everything on one user (non-root)?

BTW, I'm running everything on Ubuntu 13.10. Everything else seems to run flawlessly.

-Jmac

Originally created by @JmactheAttack on GitHub (Oct 29, 2014). Original GitHub issue: https://github.com/GameServerManagers/LinuxGSM/issues/206 I am looking/attempting/failing at porting your scripts over to run a few different game servers, specifically JK3, CoD4, and CoD:WAW along with possibly a few others (and of course hopefully getting them pulled into this repo. My first attempt at it was porting the Mumble server script over to run a CoD4 server because it seemed to be the most generic script mainly because it just manages a single executable, an .ini file and some variables, without any Steam or Unreal additions. I got the CoD4 script to start the server and it runs great, but when I stop it, it seems to stop all my other scripts (a 24/7 CSGO and Mumble server). I also noticed that the Mumble server script does not seem to run perfectly either, like sometimes when I stop it, it doesn't completely kill murmur.x86 process(s). The script stops and kills the tmux session (conf, but murmur continues to run, etc, etc. My question: is the Mumble server script out of date and incompatible with the other server scripts because of recent changes to the others? If so, should I base my new scripts off of more recent ones like the CS:GO script and just hack-off/disable the unused parts (i.e. the install bits, etc)? Also, is it okay to run everything on one user (non-root)? BTW, I'm running everything on Ubuntu 13.10. Everything else seems to run flawlessly. -Jmac
kerem closed this issue 2026-02-27 01:59:55 +03:00
Author
Owner

@Scarsz commented on GitHub (Oct 29, 2014):

I wouldn't have a clue if the mumble script is very much used, but I would guess not. It's worth a shot to try and back up a script with another like the ts3server script though.

<!-- gh-comment-id:61005842 --> @Scarsz commented on GitHub (Oct 29, 2014): I wouldn't have a clue if the mumble script is very much used, but I would guess not. It's worth a shot to try and back up a script with another like the ts3server script though.
Author
Owner

@dgibbs64 commented on GitHub (Oct 29, 2014):

Its great that you want to do this. All my new scripts normally go off the Counter Strike:Source script however most scripts are steam based. It is relatively easy to not use the steam code....Simply remove/bypass it :). You can also use UT2K4 and UT99 for examples of this as they don't use steam at all and download the server files instead. Apart from that the base is pretty similar apart from specific vars for CoD:4 etc. You will need to change and remove the variables at the start of the script. as these will differ from steam based servers. This is why most the servers are steam based as its very easy for me to port them to a new steam based server.

I don't recommend using the mumble server script. As you can probably see it can be problematic and isnt as well maintained as the others. However if you want to have a go at fixing the bugs you are welcome to.

I hope you manage to get these working it would be great to get a few more servers added. Since I have limited time currently its great that other people are maintaining and adding more scripts :D

<!-- gh-comment-id:61009775 --> @dgibbs64 commented on GitHub (Oct 29, 2014): Its great that you want to do this. All my new scripts normally go off the Counter Strike:Source script however most scripts are steam based. It is relatively easy to not use the steam code....Simply remove/bypass it :). You can also use UT2K4 and UT99 for examples of this as they don't use steam at all and download the server files instead. Apart from that the base is pretty similar apart from specific vars for CoD:4 etc. You will need to change and remove the variables at the start of the script. as these will differ from steam based servers. This is why most the servers are steam based as its very easy for me to port them to a new steam based server. I don't recommend using the mumble server script. As you can probably see it can be problematic and isnt as well maintained as the others. However if you want to have a go at fixing the bugs you are welcome to. I hope you manage to get these working it would be great to get a few more servers added. Since I have limited time currently its great that other people are maintaining and adding more scripts :D
Author
Owner

@JmactheAttack commented on GitHub (Oct 29, 2014):

Thanks for the replies. I'm glad to see I was at least running down the correct path. Here's a rough example of where I was at with the script based on the mumble script:

#!/bin/bash
# CoD4
# Server Management Script
# Author: Daniel Gibbs
# Website: http://danielgibbs.co.uk
# Version: 250814

### Variables ####

# Notification Email
# (on|off)
emailnotification="off"
email="email@example.com"

# Start Variables
# https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Dedicated_Servers#Starting_the_Server
maxplayers="16"
punkbuster="1"
port="28960"
ip="0.0.0.0"

# Server Details
servername="CoD4"
servicename="cod4-server"

# Directorys
rootdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
selfname="$0"
lockselfname=$(echo ".${servicename}.lock")
filesdir="${rootdir}/serverfiles/cod4"
cfg="server.cfg"
executable="./cod4_lnxded +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +set sv_punkbuster ${punkbuster} +exec ${cfg} +map_rotate"
backupdir="backups"

# Logging
logdays="7"
logdir="${rootdir}/log"
scriptlogdir="${rootdir}/log/script"
consolelogdir="${rootdir}/log/console"

scriptlog="${scriptlogdir}/${servicename}-script.log"
consolelog="${consolelogdir}/${servicename}-console.log"
emaillog="${scriptlogdir}/${servicename}-email.log"

scriptlogdate="${scriptlogdir}/${servicename}-script-$(date '+%d-%m-%Y-%H-%M-%S').log"
consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-%S').log"

##### Script #####
# Do not edit
# unless you know
# what you are doing

fn_scriptlog(){
    echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: '$1'" >> ${scriptlog}
}

# [ FAIL ]
fn_printfail(){
    echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}

fn_printfailnl(){
    echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@"
}

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] $@"
}

fn_printinfo(){
    echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@"
}

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] $@"
}

fn_printwarn(){
    echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}

fn_printwarnnl(){
    echo -e "\r\033[K[\e[1;33m WARN \e[0;39m] $@"
}

# [ .... ]
fn_printdots(){
    echo -en "\r\033[K[ .... ] $@"
}

fn_rootcheck(){
if [ `whoami` = "root" ]; then
    fn_printfailnl "Script will not run as root!"
    exit
fi
}

fn_syscheck(){
if [ ! -e "${filesdir}" ]; then
    fn_printfailnl "Cannot access ${systemdir}: No such directory"
    exit
fi
}

fn_inicheck(){
if [ ! -e ${filesdir}/${ini} ]; then
    fn_printwarnnl "${servicename}: ${filesdir}/${ini} is missing"
    fn_scriptlog "${servername} ${filesdir}/${ini} is missing" >> ${scriptlog}
fi
}

fn_backupserver(){
fn_rootcheck
fn_syscheck
backupname="${servicename}-$(date '+%Y-%m-%d-%H%M%S')"
echo ""
echo "${gamename} Backup"
echo "============================"
echo ""
echo "The following backup will be created."
echo ""
echo "${backupdir}/${backupname}.tar.gz"
echo ""
while true; do
    read -p "Continue? [y/N]" yn
    case $yn in
    [Yy]* ) break;;
    [Nn]* ) echo Exiting; return 1;;
    * ) echo "Please answer yes or no.";;
esac
done
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 1 ]; then
    echo -e "\e[0;31mWARNING!\e[0;39m ${servicename} is currently running"
    while true; do
        read -p "Would you like to stop ${servicename} while running the backup? [y/N]" yn
        case $yn in
        [Yy]* ) fn_stopserver; break;;
        [Nn]* ) break;;
        * ) echo "Please answer yes or no.";;
    esac
    done
fi
fn_printdots "Starting backup ${servicename}: ${servername}"
sleep 1
fn_printok "Starting backup ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Backup started"
echo -en "\n"
cd "${rootdir}"
mkdir -pv "${backupdir}" > /dev/null 2>&1
tar -cvzf "${backupdir}/${backupname}.tar.gz" --exclude "${backupdir}" *
echo -en "\r\033[K${servicename} Backup complete"
fn_scriptlog "Backup complete"
}

fn_distro(){
arch=$(uname -m)
kernel=$(uname -r)
if [ -f /etc/lsb-release ]; then
    os=$(lsb_release -s -d)
elif [ -f /etc/debian_version ]; then
    os="Debian $(cat /etc/debian_version)"
elif [ -f /etc/redhat-release ]; then
    os=$(cat /etc/redhat-release)
else
    os="$(uname -s) $(uname -r)"
fi
}

fn_uptime(){
uptime=$(</proc/uptime)
uptime=${uptime%%.*}
minutes=$(( uptime/60%60 ))
hours=$(( uptime/60/60%24 ))
days=$(( uptime/60/60/24 ))
}

fn_load(){
load=$(uptime|awk -F 'load average' '{ print $2 }')
}

fn_emailnotification(){
fn_distro
fn_uptime
fn_load
{
    echo -e "========================================\n${servicename} details\n========================================\n"
    echo -e "Service: ${servicename}"
    echo -e "Server: ${servername}"
    echo -e "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}"
sleep 1
echo -en "\n"
fn_scriptlog "Sent email notification to ${email}"
}

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"
}

fn_monitorserver(){
fn_rootcheck
fn_syscheck
if [ ! -f ${lockselfname} ]; then 
    fn_printinfo "Monitoring ${servicename}: No lock file found: Monitor disabled"
    sleep 1
    echo -en "\n"
    exit
fi
fn_printdots "Monitoring ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Monitoring ${servername}"
fn_printdots "Monitoring ${servicename}: Checking session: CHECKING"
sleep 1 
fn_scriptlog "Checking session: CHECKING"
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"
    sleep 1     
    echo -en "\n"
    fn_scriptlog "Checking session: OK"
    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
}

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"
    sleep 1 
    fn_scriptlog "Starting log cleaner"
    sleep 1
    echo -en "\n"
    fn_printinfo "Removing logs older than ${logdays} days"
    sleep 1
    echo -en "\n"
    fn_scriptlog "Removing logs older than ${logdays} days"
    sleep 1
    find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
    find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}"
    scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l)
    consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l)
    count=$((${scriptcount} + ${consolecount}))
    find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \;
    find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \;
    fn_printok "Log cleaner removed ${count} log files"
    sleep 1
    echo -en "\n"
    fn_scriptlog "Log cleaner removed ${count} log files"
fi
}

fn_restartserver(){
fn_scriptlog "Restarting ${servername}"
fn_stopserver
fn_startserver
}

fn_stopserver(){
fn_rootcheck
fn_syscheck
pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l)
pidwc=$(screen -ls |grep -E "^${servicename}:" |awk -F . '{print $1}'|awk '{print $1}'|wc -l)

fn_printdots "Stopping ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Stopping ${servername}"
if [ "${pid}" == "0" ]; then
    fn_printfail "Stopping ${servicename}: ${servername} is already stopped"
    fn_scriptlog "${servername} is already stopped"
else
    #Kill CoD4 process that spawns separate to tmux process
    for s in `tmux list-sessions -F '#{session_name}'` ; do
        for pid in `tmux list-panes -s -F '#{pane_pid}' -t "$s"` ; do
        kill $pid
    done
    tmux kill-session -t ${servicename}
    fn_printok "Stopping ${servicename}: ${servername}"
    fn_scriptlog "Stopped ${servername}"
done    
fi
# Remove lock file
rm -f ${lockselfname}
sleep 1
echo -en "\n"
}

fn_startserver(){
if [ ! -d ${logdir} ];then
    mkdir ${logdir}
    mkdir ${scriptlogdir}
    mkdir ${consolelogdir}
    echo -e "[\e[0;36m INFO \e[0;39m] ${servicename}: ${servername} Creating log directory ${logdir}"
    fn_scriptlog " Creating log directory ${logdir}" >> ${scriptlog}
fi
fn_rootcheck
fn_syscheck
fn_logmanager
tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l)
if [ ${tmuxwc} -eq 0 ]; then
    mv "${scriptlog}" "${scriptlogdate}"
    mv "${consolelog}" "${consolelogdate}"
fi
fn_printdots "Starting ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Starting ${servername}"
if [ ${tmuxwc} -eq 1 ]; then
    fn_printinfo "Starting ${servicename}: ${servername} is already running"
    sleep 1
    echo -en "\n"
    fn_scriptlog "${servername} is already running"
    exit
fi
# Create lock file
date > ${lockselfname}
cd ${filesdir}
tmux new-session -d -s ${servicename} "${executable}"
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_printfail "Starting ${servicename}: Failed to start ${servername}"
    fn_scriptlog "failed to start ${servername}"
else
    fn_printok "Starting ${servicename}: ${servername}"
    fn_scriptlog "Started ${servername}"
fi
sleep 1
echo -en "\n"
}

fn_debugserver(){
fn_rootcheck
fn_syscheck
echo ""
echo "${gamename} Debug"
echo "============================"
echo ""
echo -e "Use for identifying server issues only!"
echo -e "Press CTRL+c to drop out of debug mode"
echo -e "\e[0;31mWARNING!\e[0;39m If ${servicename} is already running it will be stopped"
echo ""
echo "Start parameters:"
echo ${executable}
echo ""
while true; do
    read -p "Continue? [y/N]" yn
    case $yn in
    [Yy]* ) break;;
    [Nn]* ) echo Exiting; return 1;;
    * ) echo "Please answer yes or no.";;
esac
done
fn_stopserver
fn_printdots "Starting debug mode ${servicename}: ${servername}"
sleep 1
fn_printok "Starting debug mode ${servicename}: ${servername}"
sleep 1
fn_scriptlog "Started debug mode ${servername}"
echo -en "\n"
cd ${filesdir}
./cod4_lnxded +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +set sv_punkbuster ${punkbuster} +exec ${cfg} +map_rotate
}

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"
    sleep 1
    fn_scriptlog "Console accessed"
    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
}

case "$1" in
    start)
        fn_startserver;;
    stop)
        fn_stopserver;;
    restart)
        fn_restartserver;;
    monitor)
        fn_monitorserver;;
    email-test)
        fn_emailtest;;
    backup)
        fn_backupserver;;
    console)
        fn_console;;
    debug)
        fn_debugserver;;
    *)
        echo "Usage: $0 {start|stop|restart|monitor|debug|backup|email-test}"
        exit 1;;
esac
exit

As it is, I don't think I'll ever be able to create a real way of installing it beyond a README.md because CoD servers require assets that come from your game install and punkbuster no longer actually supports the game which makes installing it all through the script very complicated. Same for JK3, and CoD:World at War. Once I get it a little more settled I'll start committing this. I was also looking at using this to run a Minecraft(bukkit) server with this. This could present some interesting challenges with updating the server and working with plugins.

<!-- gh-comment-id:61021779 --> @JmactheAttack commented on GitHub (Oct 29, 2014): Thanks for the replies. I'm glad to see I was at least running down the correct path. Here's a rough example of where I was at with the script based on the mumble script: ``` shell #!/bin/bash # CoD4 # Server Management Script # Author: Daniel Gibbs # Website: http://danielgibbs.co.uk # Version: 250814 ### Variables #### # Notification Email # (on|off) emailnotification="off" email="email@example.com" # Start Variables # https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Dedicated_Servers#Starting_the_Server maxplayers="16" punkbuster="1" port="28960" ip="0.0.0.0" # Server Details servername="CoD4" servicename="cod4-server" # Directorys rootdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" selfname="$0" lockselfname=$(echo ".${servicename}.lock") filesdir="${rootdir}/serverfiles/cod4" cfg="server.cfg" executable="./cod4_lnxded +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +set sv_punkbuster ${punkbuster} +exec ${cfg} +map_rotate" backupdir="backups" # Logging logdays="7" logdir="${rootdir}/log" scriptlogdir="${rootdir}/log/script" consolelogdir="${rootdir}/log/console" scriptlog="${scriptlogdir}/${servicename}-script.log" consolelog="${consolelogdir}/${servicename}-console.log" emaillog="${scriptlogdir}/${servicename}-email.log" scriptlogdate="${scriptlogdir}/${servicename}-script-$(date '+%d-%m-%Y-%H-%M-%S').log" consolelogdate="${consolelogdir}/${servicename}-console-$(date '+%d-%m-%Y-%H-%M-%S').log" ##### Script ##### # Do not edit # unless you know # what you are doing fn_scriptlog(){ echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: '$1'" >> ${scriptlog} } # [ FAIL ] fn_printfail(){ echo -en "\r\033[K[\e[0;31m FAIL \e[0;39m] $@" } fn_printfailnl(){ echo -e "\r\033[K[\e[0;31m FAIL \e[0;39m] $@" } 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] $@" } fn_printinfo(){ echo -en "\r\033[K[\e[0;36m INFO \e[0;39m] $@" } 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] $@" } fn_printwarn(){ echo -en "\r\033[K[\e[1;33m WARN \e[0;39m] $@" } fn_printwarnnl(){ echo -e "\r\033[K[\e[1;33m WARN \e[0;39m] $@" } # [ .... ] fn_printdots(){ echo -en "\r\033[K[ .... ] $@" } fn_rootcheck(){ if [ `whoami` = "root" ]; then fn_printfailnl "Script will not run as root!" exit fi } fn_syscheck(){ if [ ! -e "${filesdir}" ]; then fn_printfailnl "Cannot access ${systemdir}: No such directory" exit fi } fn_inicheck(){ if [ ! -e ${filesdir}/${ini} ]; then fn_printwarnnl "${servicename}: ${filesdir}/${ini} is missing" fn_scriptlog "${servername} ${filesdir}/${ini} is missing" >> ${scriptlog} fi } fn_backupserver(){ fn_rootcheck fn_syscheck backupname="${servicename}-$(date '+%Y-%m-%d-%H%M%S')" echo "" echo "${gamename} Backup" echo "============================" echo "" echo "The following backup will be created." echo "" echo "${backupdir}/${backupname}.tar.gz" echo "" while true; do read -p "Continue? [y/N]" yn case $yn in [Yy]* ) break;; [Nn]* ) echo Exiting; return 1;; * ) echo "Please answer yes or no.";; esac done tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 1 ]; then echo -e "\e[0;31mWARNING!\e[0;39m ${servicename} is currently running" while true; do read -p "Would you like to stop ${servicename} while running the backup? [y/N]" yn case $yn in [Yy]* ) fn_stopserver; break;; [Nn]* ) break;; * ) echo "Please answer yes or no.";; esac done fi fn_printdots "Starting backup ${servicename}: ${servername}" sleep 1 fn_printok "Starting backup ${servicename}: ${servername}" sleep 1 fn_scriptlog "Backup started" echo -en "\n" cd "${rootdir}" mkdir -pv "${backupdir}" > /dev/null 2>&1 tar -cvzf "${backupdir}/${backupname}.tar.gz" --exclude "${backupdir}" * echo -en "\r\033[K${servicename} Backup complete" fn_scriptlog "Backup complete" } fn_distro(){ arch=$(uname -m) kernel=$(uname -r) if [ -f /etc/lsb-release ]; then os=$(lsb_release -s -d) elif [ -f /etc/debian_version ]; then os="Debian $(cat /etc/debian_version)" elif [ -f /etc/redhat-release ]; then os=$(cat /etc/redhat-release) else os="$(uname -s) $(uname -r)" fi } fn_uptime(){ uptime=$(</proc/uptime) uptime=${uptime%%.*} minutes=$(( uptime/60%60 )) hours=$(( uptime/60/60%24 )) days=$(( uptime/60/60/24 )) } fn_load(){ load=$(uptime|awk -F 'load average' '{ print $2 }') } fn_emailnotification(){ fn_distro fn_uptime fn_load { echo -e "========================================\n${servicename} details\n========================================\n" echo -e "Service: ${servicename}" echo -e "Server: ${servername}" echo -e "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}" sleep 1 echo -en "\n" fn_scriptlog "Sent email notification to ${email}" } 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" } fn_monitorserver(){ fn_rootcheck fn_syscheck if [ ! -f ${lockselfname} ]; then fn_printinfo "Monitoring ${servicename}: No lock file found: Monitor disabled" sleep 1 echo -en "\n" exit fi fn_printdots "Monitoring ${servicename}: ${servername}" sleep 1 fn_scriptlog "Monitoring ${servername}" fn_printdots "Monitoring ${servicename}: Checking session: CHECKING" sleep 1 fn_scriptlog "Checking session: CHECKING" 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" sleep 1 echo -en "\n" fn_scriptlog "Checking session: OK" 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 } 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" sleep 1 fn_scriptlog "Starting log cleaner" sleep 1 echo -en "\n" fn_printinfo "Removing logs older than ${logdays} days" sleep 1 echo -en "\n" fn_scriptlog "Removing logs older than ${logdays} days" sleep 1 find "${scriptlogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" find "${consolelogdir}"/* -mtime +${logdays}|tee >> "${scriptlog}" scriptcount=$(find "${scriptlogdir}"/* -mtime +${logdays}|wc -l) consolecount=$(find "${consolelogdir}"/* -mtime +${logdays}|wc -l) count=$((${scriptcount} + ${consolecount})) find "${scriptlogdir}"/* -mtime +${logdays} -exec rm {} \; find "${consolelogdir}"/* -mtime +${logdays} -exec rm {} \; fn_printok "Log cleaner removed ${count} log files" sleep 1 echo -en "\n" fn_scriptlog "Log cleaner removed ${count} log files" fi } fn_restartserver(){ fn_scriptlog "Restarting ${servername}" fn_stopserver fn_startserver } fn_stopserver(){ fn_rootcheck fn_syscheck pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -E "^${servicename}:"|wc -l) pidwc=$(screen -ls |grep -E "^${servicename}:" |awk -F . '{print $1}'|awk '{print $1}'|wc -l) fn_printdots "Stopping ${servicename}: ${servername}" sleep 1 fn_scriptlog "Stopping ${servername}" if [ "${pid}" == "0" ]; then fn_printfail "Stopping ${servicename}: ${servername} is already stopped" fn_scriptlog "${servername} is already stopped" else #Kill CoD4 process that spawns separate to tmux process for s in `tmux list-sessions -F '#{session_name}'` ; do for pid in `tmux list-panes -s -F '#{pane_pid}' -t "$s"` ; do kill $pid done tmux kill-session -t ${servicename} fn_printok "Stopping ${servicename}: ${servername}" fn_scriptlog "Stopped ${servername}" done fi # Remove lock file rm -f ${lockselfname} sleep 1 echo -en "\n" } fn_startserver(){ if [ ! -d ${logdir} ];then mkdir ${logdir} mkdir ${scriptlogdir} mkdir ${consolelogdir} echo -e "[\e[0;36m INFO \e[0;39m] ${servicename}: ${servername} Creating log directory ${logdir}" fn_scriptlog " Creating log directory ${logdir}" >> ${scriptlog} fi fn_rootcheck fn_syscheck fn_logmanager tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -E "^${servicename}:"|wc -l) if [ ${tmuxwc} -eq 0 ]; then mv "${scriptlog}" "${scriptlogdate}" mv "${consolelog}" "${consolelogdate}" fi fn_printdots "Starting ${servicename}: ${servername}" sleep 1 fn_scriptlog "Starting ${servername}" if [ ${tmuxwc} -eq 1 ]; then fn_printinfo "Starting ${servicename}: ${servername} is already running" sleep 1 echo -en "\n" fn_scriptlog "${servername} is already running" exit fi # Create lock file date > ${lockselfname} cd ${filesdir} tmux new-session -d -s ${servicename} "${executable}" 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_printfail "Starting ${servicename}: Failed to start ${servername}" fn_scriptlog "failed to start ${servername}" else fn_printok "Starting ${servicename}: ${servername}" fn_scriptlog "Started ${servername}" fi sleep 1 echo -en "\n" } fn_debugserver(){ fn_rootcheck fn_syscheck echo "" echo "${gamename} Debug" echo "============================" echo "" echo -e "Use for identifying server issues only!" echo -e "Press CTRL+c to drop out of debug mode" echo -e "\e[0;31mWARNING!\e[0;39m If ${servicename} is already running it will be stopped" echo "" echo "Start parameters:" echo ${executable} echo "" while true; do read -p "Continue? [y/N]" yn case $yn in [Yy]* ) break;; [Nn]* ) echo Exiting; return 1;; * ) echo "Please answer yes or no.";; esac done fn_stopserver fn_printdots "Starting debug mode ${servicename}: ${servername}" sleep 1 fn_printok "Starting debug mode ${servicename}: ${servername}" sleep 1 fn_scriptlog "Started debug mode ${servername}" echo -en "\n" cd ${filesdir} ./cod4_lnxded +set net_ip ${ip} +set net_port ${port} +set sv_maxclients ${maxplayers} +set sv_punkbuster ${punkbuster} +exec ${cfg} +map_rotate } 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" sleep 1 fn_scriptlog "Console accessed" 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 } case "$1" in start) fn_startserver;; stop) fn_stopserver;; restart) fn_restartserver;; monitor) fn_monitorserver;; email-test) fn_emailtest;; backup) fn_backupserver;; console) fn_console;; debug) fn_debugserver;; *) echo "Usage: $0 {start|stop|restart|monitor|debug|backup|email-test}" exit 1;; esac exit ``` As it is, I don't think I'll ever be able to create a real way of installing it beyond a README.md because CoD servers require assets that come from your game install and punkbuster no longer actually supports the game which makes installing it all through the script **very** complicated. Same for JK3, and CoD:World at War. Once I get it a little more settled I'll start committing this. I was also looking at using this to run a Minecraft(bukkit) server with this. This could present some interesting challenges with updating the server and working with plugins.
Author
Owner

@lock[bot] commented on GitHub (Jul 20, 2018):

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

<!-- gh-comment-id:406454811 --> @lock[bot] commented on GitHub (Jul 20, 2018): This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Sign in to join this conversation.
No labels
Atomic
Epic
cannot reproduce
command: backup
command: console
command: debug
command: details
command: fast-dl
command: install
command: mods
command: monitor
command: post-details
command: restart
command: send
command: start
command: stop
command: update
command: update-lgsm
command: validate
command: wipe
distro: AlmaLinux
distro: Arch Linux
distro: CentOS
distro: Debian
distro: Fedora
distro: RedHat
distro: Rocky Linux
distro: Ubuntu
distro: openSUSE
engine: goldsrc
engine: source
game: 7 Days to Die
game: ARMA 3
game: Ark: Survival Evolved
game: Assetto Corsa
game: Avorion
game: BATTALION: Legacy
game: Barotrauma
game: Battalion 1944
game: Battlefield 1942
game: Black Mesa: Deathmatch
game: Blade Symphony
game: Call of Duty 2
game: Call of Duty 4
game: Call of Duty: United Offensive
game: Counter-Strike 1.6
game: Counter-Strike 2
game: Counter-Strike: Global Offensive
game: Counter-Strike: Source
game: Day of Infamy
game: Dayz
game: Death Match Classic
game: Don't Starve Together
game: ET: Legacy
game: Eco
game: Factorio
game: Factorio
game: Garry's Mod
game: Half-Life
game: Hurtword
game: Insurgecy
game: Insurgecy
game: Insurgency: Sandstorm
game: Just Cause 3
game: Killing Floor
game: Killing Floor 2
game: Left 4 Dead 2
game: Minecraft
game: Minecraft Bedrock
game: Mordhau
game: Multi Theft Auto
game: Mumble
game: Natural Selection 2
game: No More Room in Hell
game: Pavlov VR
game: Post Scriptum
game: Project Zomboid
game: Quake 3
game: QuakeWorld
game: Red Orchestra: Ostfront 41-45
game: Return to Castle Wolfenstein
game: Rising World
game: Rust
game: San Andreas Multiplayer
game: Satisfactory
game: Soldat
game: Soldier of Fortune 2
game: Squad
game: Squad 44
game: Starbound
game: Stationeers
game: Sven Co-op
game: Team Fortress 2
game: Teamspeak 3
game: Teeworlds
game: Terraria
game: The Front
game: Unreal Tournament 2004
game: Unreal Tournament 3
game: Unreal Tournament 99
game: Unturned
game: Valheim
game: Wurm Unlimited
game: Zombie Master Reborn
game: label missing
good first issue
help wanted
info: alerts
info: dependency
info: docker
info: docs
info: email
info: query
info: steamcmd
info: systemd
info: tmux
info: website
info: website
needs more info
outcome: duplicate
outcome: issue resolved
outcome: issue resolved
outcome: issue unresolved
outcome: pr accepted
outcome: pr rejected
outcome: unconfirmed
outcome: wontfix
outcome: wrong forum
potential-duplicate
priority
pull-request
type: bug
type: feature
type: feature
type: feature request
type: game server request
type: refactor
waiting response
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/LinuxGSM#170
No description provided.