#!/bin/sh
# Script to start/stop game server on screen
# _KaszpiR_ kaszpir@gmail.com
# 2010.02.08
# writen from scratch  previous version got deleted (wrong key, doh...)
##########################################################################
##########################################################################
# Config:
CLIENT="etqwpro1";		# Unique handle this server uses.
ENABLED=0;

TITLE="ETQWPro 1";		# Name that is shown during start-up messages
DSPATH="/home/etqw/etqw";	# Where game  is installed, it better be absolute path
DSIP="94.23.94.196";		# IP address you want to use to start server with
DSPORT="27733";			# Game server listens on this UDP port
DSBIN="etqwded.x86";		# process to start
DSGAME="etqwpro";		# Game mod, in example cstrike, czero
DSMAP="";			# Load this map initially
DSUSER="etqw";			# Which user is running the process
DSSIZE="16";			# number of slots
DSRCON="";


SCREEN=`which screen`;
SCREENPID="$DSPATH/$CLIENT.pid";		# screen pid name
DSPID="$DSPATH/.$DSGAME-$DSPORT/etqw.pid";	# game server process pid, this should be auto created by game server iniit scripts

#starting parameters, split to dtwo lines for better readability
DSOPTS_PRE="+set fs_basepath $DSPATH +set fs_cdpath $DSPATH +set fs_savePath $DSPATH/.$DSGAME-$DSPORT +set fs_devpath $DSPATH +set fs_game $DSGAME "
DSOPTS="$DSOPTS_PRE +set net_serverDedicated 2 +set vm_game 0 +set in_tty 0 +set net_ip $DSIP +set net_port $DSPORT +set net_serverPunkbusterEnabled 0 +exec server.cfg +exec mapcycle.cfg "

QSTAT=`which qstat`
# path to qstat
Q_TYPE="-etqws"; # game server type, see qstat --help for more info
RETRY_TIME=10; # time in seconds to check server status
RETRY_MAX=3; # how many times server can be down, set it high to avoid killing server on map change
DATE_FORMAT="%Y-%m-%d %H:%M";	# date format, man date for more details, for informational purposes
LOGFILE="${DSPATH}/${CLIENT}.log";	# where to output messages about killed server
LOGAPPEND=0;			# 0 - overwrite log, 1 - append

# This is the caller for the screen process. Only change if this is different from where your screen process currently resides.
DSINIT="${SCREEN} -A -m -d -S ${CLIENT}"
DSSTART="${DSPATH}/${CLIENT}.sh"

##########################################################################
# End of config
##########################################################################
##########################################################################
THIS=`pwd`
THIS=${THIS}/$0
hash -r ; # this is used to refresh chached commands and binaries on linux, useful when you edit this script when server is running
##########################################################################
##########################################################################
##########################################################################
if [ ! ${ENABLED} ];then
echo "${CLIENT} not enabled, exiting."
exit
fi


service_start() {

if [ ! -x ${DSPATH}/${DSBIN} ]; then
echo "Error: ${DSPATH}/${DSBIN} is not executable, run chmod +x ${DSPATH}/${DSBIN}"
exit;
fi

if [ ! -x ${SCREEN} ]; then
echo "Error: screen command not found or not executable, talk with your admin"
exit
fi

if [ -f ${SCREENPID} ]; then
    kill -0 `cat ${SCREENPID}` > /dev/null 2>&1
    if [ "$?" == "0" ]; then
        echo "${CLIENT} screen is already running"
        service_status
        exit
    else
        echo "${CLIENT} scren is dead, wiping"
        service_clean
        exit
    fi
fi

if [ -f ${DSPID} ]; then
    kill -0 `cat ${DSPID}` >/dev/null 2>&1
    if [ "$?" == "0" ]; then
        echo "${CLIENT} server is already running."
        service_status
        exit
    else
        echo "${CLIENT} server is dead, wiping"
        service_clean
        exit
    fi
fi

    ${DSINIT} ${DSSTART} 2>&1 >/dev/null &
#    echo "I:${DSINIT} ${DSSTART} "
    FINDPID=`ps aux | grep -i "${DSINIT} ${DSSTART}" | grep -v grep | awk '{print $2}'`
    echo ${FINDPID} > ${SCREENPID}
#    echo "FINDPID ${FINDPID}"
#    screen -ls | grep \( | grep -v grep
#    echo "SCREENPID: ${SCREENPID}"
    echo "DSPID: ${DSPID}"
    echo "DSSTART: ${DSSTART}"
#    echo "COMMAND: ${DSBIN} ${DSOPTS}"
#    service_status

}
##########################################################################
##########################################################################
##########################################################################

service_stop() {


if [ -f ${SCREENPID} ]; then
    kill `cat ${SCREENPID}` > /dev/null 2>&1
    if [ "$?" == "0" ]; then
        echo "${CLIENT} screen killed"
        service_clean
        exit
    else
        echo "Error: ${CLIENT} screen not killed normally"
        service_status
        exit
    fi

else
    echo "${CLIENT} screen not found, trying to search."
    FINDPID=`screen -wipe 2>/dev/null |grep ${CLIENT}\$ |grep -v grep|grep \( |cut -d. -f1|awk '{print $1}'`
    if [ ! -z $FINDPID ]; then
	echo "Found pid at ${FINDPID}";
	echo ${FINDPID} > ${SCREENPID}
	service_stop
    else
	echo "Did not find pid of the ${CLIENT}. Looks like screen of given name is not running"
    fi
fi
}
##########################################################################
##########################################################################
##########################################################################

service_restart() {

# Simple enough. It is making a call to the stop service and then it waits for some time then it calls the start script

  service_stop
  sleep 2
#  service_clean

  service_start
}
##########################################################################
##########################################################################
##########################################################################

service_status() {
if [ -f ${SCREENPID} ]; then
    kill -0 `cat ${SCREENPID}` > /dev/null 2>&1
    if [ "$?" == "0" ]; then
        echo "${CLIENT} screen is already running"
#        service_status
        exit
    else
        echo "${CLIENT} screen is dead, wiping"
        service_clean
        exit
    fi
else
    echo "${CLIENT} screen pid not found"
    service_clean
fi

if [ -f ${DSPID} ]; then
    kill -0 `cat ${DSPID}` >/dev/null 2>&1
    if [ "$?" == "0" ]; then
        echo "${CLIENT} server is already running."
#        service_status
        exit
    else
        echo "${CLIENT} server is dead, wiping"
        service_clean
        exit
    fi
else
    echo "${CLIENT} server pid not found"
	service_clean
fi


#qsat info

$QSTAT $Q_TYPE $DSIP:$DSPORT -nh -u
}
##########################################################################
##########################################################################
##########################################################################

# This service is used watch the process that is currently running
service_watch(){

# Check if there is someone already attached
ATT=`screen -wipe | grep -i ${CLIENT} | grep -v grep | grep \( | awk '{ print $5 }'`
if [ "${ATT}" == "(Attached)" ]; then
	echo -e "Someone is already attached to the console of the server.\n Might want to check who" # Oops someone is already attached to it..... better wait your turn or go chew someone $%^ out
else

# Looks like noone is watching it right now.... peeping tom time !!!

	screen -r $CLIENT 
fi
}
##########################################################################
##########################################################################
##########################################################################

# This service is used force watch the process that is currently running
service_force_watch(){

# detach and reattach here
	screen -dr $CLIENT 
}
##########################################################################
##########################################################################
##########################################################################

# This service is used to clean house if the script is reporting erroneous info.

service_clean(){

    rm -rf ${SCREENPID}
    screen -wipe 2>&1 > /dev/null
    rm -rf ${DSPID}

}
##########################################################################
##########################################################################

# chekcs the server running and if needed restarts it

service_check(){

DATE_NOW=`date +"$DATE_FORMAT"`;
echo $DATE_NOW
echo "Checking server"
echo "  IP: $DSIP"
echo "Port: $DSPORT"
echo "Type: $Q_TYPE"

# qstat list only servers that are up

COUNTER=0
while [  $COUNTER -lt $RETRY_MAX ]; do
    echo -n "Server check $COUNTER/$RETRY_MAX: "
    if [ `$QSTAT $Q_TYPE $DSIP:$DSPORT -nh -u|wc -l` -eq 0 ]; then
        echo "down";
	let COUNTER=COUNTER+1;
	sleep $RETRY_TIME
    else
	echo "up";
	echo "We do nothing, exiting.";
	return 0;
    fi
done

echo "Looks like server is not responding, trying to restart..."
service_clean
service_restart
if [ -n $LOGFILE ]; then
	echo "$DATE_NOW,$DSIP:$DSPORT,$DSNAMESHORT,$COUNTER" >> $LOGFILE
fi

}


##########################################################################
##########################################################################
##########################################################################
service_makescript() {

echo "#!/bin/bash" > ${DSSTART}
echo "export LD_LIBRARY_PATH=\"\$LD_LIBRARY_PATH:.\"" >>${DSSTART}
echo "while [ true ] ;do " >> ${DSSTART}
echo "  cd ${DSPATH}" >> ${DSSTART}
echo "  ./${DSBIN} ${DSOPTS}" >> ${DSSTART}
echo "  echo Sleeping 5s" >> ${DSSTART}
echo "  sleep 5;" >> ${DSSTART}
echo "done" >> ${DSSTART}
echo "" >> ${DSSTART}
chmod 700 ${DSSTART}
echo "${CLIENT} start script recreated"
}

##########################################################################
##########################################################################
##########################################################################
service_addcron() {
if [ $LOGAPPEND = "1" ]; then
    echo "*/5 * * * * ${THIS} check 2>&1 >> ${LOGFILE}" 
    echo "00 6 * * * ${THIS} restart 2>&1 >> ${LOGFILE}" 
else
    echo "*/5 * * * * ${THIS} check 2>&1 > ${LOGFILE}" 
    echo "00 6 * * * ${THIS} restart 2>&1 > ${LOGFILE}" 
fi
}

##########################################################################
##########################################################################
##########################################################################
# main fucntion
case "$1" in
'start')
  service_start
  ;;
'stop')
  service_stop
  ;;
'restart')
  service_restart
  ;;
'status')
  service_status
  ;;
'watch')
  service_watch
  ;;
'force-watch')
  service_force_watch
  ;;
'clean')
  service_clean
  ;;
'check')
  service_check
  ;;
'makescript')
  service_makescript
  ;;
'addcron')
  service_addcron
  ;;
*)
  echo "usage $0 start|stop|restart|status|watch|force-watch|clean|check|makescript|addcron"
esac
exit 0
##########################################################################
# TODO




# eof
