Go Back   Steam Users' Forums > Dedicated Server Discussions > Source DS (Linux)

Reply
 
Thread Tools Display Modes
Old 07-09-2007, 06:48 AM   #1
mianosm
 
Join Date: Jun 2007
Reputation: 1
Posts: 65
Autorun Servers on reboot

I was just wondering if someone proficient in Debian based servers could look at this for me....

What I would like to do is set up a cron job every day at 3am local time to have the server: shutdown -r 0

Then what I would like to do is put a startup.sh in the /etc/init.d/

================================================== =======

#!/bin/bash
#Starting of all servers on box

cd /srcds_l

screen -A -m -d -S css1 ./srcds_run -console -game cstrike -port 27015 +ip 24.94.149.11 +map de_dust +maxplayers 32 -autoupdate +exec server1.cfg

screen -A -m -d -S css2 ./srcds_run -console -game cstrike -port 27015 +ip 24.94.149.12 +map de_dust +maxplayers 32 -autoupdate +exec server2.cfg

screen -A -m -d -S hl2mp1 ./srcds_run -console -game hl2mp -port 27015 +ip 24.94.149.13 +map dm_steamlab +maxplayers 16 -autoupdate +exec server3.cfg

screen -A -m -d -S hl2mp2 ./srcds_run -console -game hl2mp -port 27015 +ip 24.94.149.14 +map dm_steamlab +maxplayers 16 -autoupdate +exec server4.cfg

screen -A -m -d -S DoDs ./srcds_run -console -game dod -port 27035 +ip 24.94.149.13 +map dod_anzio +maxplayers 32 -autoupdate +exec server.cfg

cd /hlds_l

screen -A -m -d -S cs16 ./hlds_run -console -game cstrike -port 27075 +ip 24.94.149.11 +map de_dust +maxplayers 32 -autoupdate +exec server.cfg

================================================== =======

I'm hoping that what this would do would be to have a fresh running server everyday. I know my uptime is never going to be eye opening, but I figure that this will allow me to provide a constantly fresh and updated base for my users to enjoy. : )

Thanks for the advice, time in advance guys. : )
mianosm is offline  
Reply With Quote
Old 07-09-2007, 06:01 PM   #2
TheMG
 
TheMG's Avatar
 
Volunteer Moderator
Join Date: Mar 2007
Reputation: 1899
Posts: 10,284
There's really no need. Consistent performance across very long uptimes is one thing Linux excels at. Performance drops over time are almost always caused by memory leaks in SRCDS itself.

In fact, you'll have better performance if you do not restart your machine all the time. Why? Each time you shut down anything that is cached in memory is cleared. Memory caching makes things that are frequently used load faster (map loads would be a big one here).

What you should do instead of restarting your whole box is to simply restart all the SRCDS instance once daily. Works like a charm. There is more than one way to go about doing this too.

Last edited by TheMG: 07-09-2007 at 06:03 PM.
TheMG is offline   Reply With Quote
Old 07-09-2007, 08:40 PM   #3
mianosm
 
Join Date: Jun 2007
Reputation: 1
Posts: 65
Hmm, great info there - but I have no idea how I would script it to stop the servers, update them, and then start them all...

I mean I understand how it would work - and I guess if I put it in as a daily cron it would be great - but I just don't know exactly how to script that to stop all six, update, and then restart....so reseting the server was the only option I could think of...
mianosm is offline   Reply With Quote
Old 07-09-2007, 10:41 PM   #4
TheMG
 
TheMG's Avatar
 
Volunteer Moderator
Join Date: Mar 2007
Reputation: 1899
Posts: 10,284
I've got just the script you're looking for!

Put this in startscript.conf (edit with your settings):
Code:
#!/bin/sh

CLIENT='srcds_1';					# Unique handle this server uses. Hostname
									# can be reset in your server.cfg

TITLE='SRCDS 1';					# Name that is shown during start-up messages
DSPATH='/css/1';					# Where Steam is installed
DSIP='69.41.180.58';				# IP address you want to use to start server with
DSNAME='srcds_run';					# Either hlds_run or srcds_run
DSNAMESHORT='srcds_1';				# Label only
DSGAME='cstrike';					# Game type (valve, cstrike, czero, etc)
DSIMAP='de_dust2';					# Load this map initially
DSPORT='27015';						# Game server listens on this UDP port
DSSIZE='35';						# Maximum number of players to allow
DSUSER='cstrike';					# Which user is running the process
DSTICKRATE='50';					# Tick Rate
DSSERVERFPS='600';					# Server FPS Rate


# Don't edit this unless you need the script to do something special
DSOPTS="-game $DSGAME +hostname \"$CLIENT\" +map $DSIMAP -ip $DSIP -port $DSPORT -rcon_port $DSPORT -autoupdate +maxplayers $DSSIZE -pidfile $DSNAMESHORT.pid -tickrate $DSTICKRATE +fps_max $DSSERVERFPS"

# This is the caller for the screen process. Only change if this is different from where your screen process currently resides.
DSINTERFACE="/usr/bin/screen -A -m -d -S $CLIENT"
Put this in startscript (edit line 5 with the absolute path to your SRCDS install so the script can be run from anywhere):
Code:
#!/bin/sh
# Start/stop/restart a Valve dedicated server
# All configuration changes should occur in <scriptname>.conf. Only change the name of the call below if you are using a different name for the script
cd /css/1/
. ./startscript.conf

service_start() {

# Checking to see if root is the current user you are using to start the script
if [ $DSUSER == 'root' ]; then
# Oops is caught you running as root shame on you >:). Well you gotta tell it yes or no.	
	echo -e "You are currently running as $DSUSER, This is dangerous and should be avoided\nAre you sure you want to do this? (yes or no please):"
	read
	case "$REPLY" in
	yes)
# Looks like you chose to run it as root... The script hates you for it but hey do whatever you feel hehe
		echo -e "Alright proceeding running program as $DSUSER"

# Currently checking to see if the pid files that is creates during the startup process exsist. If neither exsists it will go ahead.
		if [ ! -f $DSPATH/$DSNAME.pid ] && [ ! -f $DSPATH/cstrike/$DSNAMESHORT.pid ]; then
			if [ -x $DSPATH/$DSNAME ]; then
				echo "Starting $TITLE: Services"
				cd $DSPATH; $DSINTERFACE $DSPATH/$DSNAME $DSOPTS
				sleep 1 # prevent race condition on SMP kernels
				ps -ef | grep SCREEN | grep "$CLIENT" | grep -v grep | awk '{ print $2 }' > $DSNAME.pid # Finding and writing current process id of the screen process
				echo -e "$DSNAMESHORT Process ID Written to $DSNAME.pid\n$DSGAME Server Process ID Written to $DSNAMESHORT.pid"
			fi
		else
			echo -e "Server is Already running you sure you want to start this up?" # It found that one of the pid files exsists perhaps the server did not shut down with the script being used... if this is the case use <scriptname> clean to fix it
		fi
	;;
	no)
# Good choice you did not choose to run as root
		echo -e "Wise choice please login as a different user or run this with su - <username> -c 'command'. "
	;;
	*)
# What in the heck is wrong with you didn't I say YES or NO
		echo -e "I don't recognize $REPLY as a valid yes or no answer. Please user only yes or no only"
	;;
	esac
# The script found you were not running as root so it is running like normal. Uses same calls to activate script like above just no input is require to start it this time. You should not be prompted for yes or no if yo uare not root running it this time
else
		if [ ! -f $DSPATH/$DSNAME.pid ] && [ ! -f $DSPATH/$DSNAMESHORT.pid ]; then
			if [ -x $DSPATH/$DSNAME ]; then
				echo "Starting $TITLE: Services"
				echo "$DSPATH/$DSNAME $DSOPTS"
				cd $DSPATH; $DSINTERFACE $DSPATH/$DSNAME $DSOPTS
				sleep 1 # prevent race condition on SMP kernels
				ps -ef | grep SCREEN | grep "$CLIENT" | grep -v grep | awk '{ print $2 }' > $DSNAME.pid
				echo -e "$DSNAME Process ID Written to $DSNAME.pid\n$DSNAMESHORT Server Process ID Written to $DSNAMESHORT.pid"
			fi
		else
			echo -e "Server is Already running you sure you want to start this up?"
		fi
fi
	
}

service_stop() {

# This script is just getting the process id of the server that was written to the file it created earlier so it can kill it.   
    for vdspid in $(cat $DSPATH/$DSNAME.pid);
      do
        kill $vdspid;
	rm -rf $DSNAME.pid;
        break;
    done
    rm -rf $DSPATH/cstrike/$DSNAMESHORT.pid;
# This command is just clearing out any *DEAD* screen sessions. Those can become a pain really quick
    screen -wipe 1> /dev/null 2> /dev/null
}

service_restart() {

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

  service_stop
  sleep 1
  service_start
}

service_status() {
# This is checking to see if $DSNAME.pid file exsists
if [ -f $DSPATH/$DSNAME.pid ]; then
# Pulling in the values to evaulate if they are true or not
PROCESSRUN=`cat $DSPATH/$DSNAME.pid`
PROCSERV=`ps -ef | grep SCREEN | grep "$CLIENT" | grep -v grep | awk '{ print $2 }'`

# This is checking to see if the currently running process ID matches with the pid created when the server was started
	if [ "$PROCESSRUN" == "$PROCSERV" ]; then
	echo -e "$DSNAME is running on process `cat $DSPATH/$DSNAME.pid`\n" # It found this process ID matches and is outputting what it is currently running on
	fi
else
	echo -e "$DSNAME is offline. This could be due to someone or something else that killed it." # Apparently the server is offline 
			if [ "$PROCSERV" ]; then
			echo -e "However a Process Matching the same criteria was found at process ID $PROCSERV....\n Might be worth a investigation" # Wait, it found another server matching the same criteria running under a different process ID.
			fi
fi

#Checking to see if this file exsists

if [ -f $DSPATH/$DSNAME.pid ]; then
echo "$DSNAMESHORT Server is running on process `cat $DSPATH/cstrike/$DSNAMESHORT.pid`" # It found the file exsists and is outputting the info
else 
echo -e "$DSGAME Server is offline. This could be due to someone or something else that killed it\nor it is just rebooting" #Oops the server is active or the pid file got deleted.
fi
}

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

# Check if there is someone already attached

if [ `screen -wipe | grep $CLIENT | grep -v grep | awk '{ print $2 }'` == '(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 to clean house if the script is reporting erroneous info.

service_clean(){

rm -rf *.pid;
rm -rf $DSPATH/cstrike/*.pid;
screen -wipe 1> /dev/null 2> /dev/null;
}

case "$1" in
'start')
  service_start
  ;;
'stop')
  service_stop
  ;;
'restart')
  service_restart
  ;;
'status')
  service_status
  ;;
'watch')
  service_watch
  ;;
'clean')
  service_clean
  ;;
*)
  echo "usage $0 start|stop|restart|status|watch|clean"
esac
Place startscript.conf and startscript in the same directory as srcds_run. For ease of operation, place symbolic links to startscript with the name of each server in /usr/bin.

Then it becomes a simple matter of entering the correct command. Say I named my sym link "hl2mp1" then to start the server:

$ hl2mp1 start

or to restart:

$ hl2mp1 restart

"stop" to shutdown the server, "watch" to switch to server screen process.

I hope this made some sense. Then it becomes as simple as pluging the appropriate command("hl2mp1 restart" for example) into a cron job.
TheMG is offline   Reply With Quote
Old 07-10-2007, 05:00 AM   #5
mianosm
 
Join Date: Jun 2007
Reputation: 1
Posts: 65
Thank you very much, I'll see if I can make it work today. : )
mianosm is offline   Reply With Quote
Old 07-10-2007, 09:14 AM   #6
mianosm
 
Join Date: Jun 2007
Reputation: 1
Posts: 65
Awesome, Those work like a charm - now I just need to make 6 copies of them due to running six servers on one box though.....

Thanks again!
mianosm is offline   Reply With Quote
Old 07-10-2007, 01:01 PM   #7
SquareDisc
 
 
 
Join Date: Oct 2005
Reputation: 17
Posts: 210
heres the auto restart on crash i use on all my servers:

Filename: RESTART_srcds_run
Code:
#!/bin/sh
#
#       Copyright (c) 2004, Valve LLC. All rights reserved.
#
#	a wrapper script for the main Source engine dedicated server binary.
#	Performs auto-restarting of the server on crash. You can
#	extend this to log crashes and more.
#

# setup the libraries, local dir first!
export LD_LIBRARY_PATH=".:bin:$LD_LIBRARY_PATH"

init() {
	# Initialises the various variables
	# Set up the defaults
	GAME=""
	DEBUG=""
	RESTART="yes"
	HL=./srcds_i486
	HL_DETECT=1
	TIMEOUT=10 # time to wait after a crash (in seconds)
	CRASH_DEBUG_MSG="email debug.log to linux@valvesoftware.com"
	GDB="gdb" # the gdb binary to run
	DEBUG_LOG="debug.log"
	PID_FILE="" # only needed it DEBUG is set so init later
	STEAM=""
	PID_FILE_SET=0
	STEAMERR=""
	SIGINT_ACTION="quit 0" # exit normally on sig int
	NO_TRAP=0
	AUTO_UPDATE=""
	STEAM_USER=""
	STEAM_PASSWORD=""
	PARAMS=$*

	# Remove any old default pid files
	# Cant do this as they may be still running
	#rm -f hlds.*.pid

	# use the $FORCE environment variable if its set
	if test -n "$FORCE" ; then
		# Note: command line -binary will override this
		HL=$FORCE
		HL_DETECT=0
	fi

	while test $# -gt 0; do
		case "$1" in
		"-game")
			GAME="$2"
			shift ;;
		"-debug")
			DEBUG=1
			# Ensure that PID_FILE is set
			PID_FILE_SET=1
			if test -z "$PID_FILE"; then
				PID_FILE="hlds.$$.pid"
			fi ;;
		"-norestart")
			RESTART="" ;;
		"-pidfile")
			PID_FILE="$2"
			PID_FILE_SET=1
			shift ;;
		"-binary")
			HL="$2"
			HL_DETECT=0
			shift ;;
		"-timeout")
			TIMEOUT="$2"
			shift ;;
		"-gdb")
			GDB="$2"
			shift ;;
		"-debuglog")
			DEBUG_LOG="$2"
			shift ;;
		"-autoupdate")
			AUTO_UPDATE="yes"
			STEAM="./steam"
			RESTART="yes" ;;
		"-steamerr")
			STEAMERR=1 ;;
		"-ignoresigint")
			SIGINT_ACTION="" ;;
		"-notrap")
			NO_TRAP=1 ;;
		"-steamuser")
			STEAM_USER="$2";
			shift ;;
		"-steampass")
			STEAM_PASSWORD="$2";
			shift ;;
		"-help")
			# quit with syntax
			quit 2
			;;
		esac
		shift
	done

	# Ensure we have a game specified
	if test -z "$GAME"; then
		GAME="cstrike"
		PARAMS="$PARAMS -game $GAME"
	elif test ! -d "$GAME"; then
		echo "Invalid game type '$GAME' sepecified."
		quit 1
	fi

	if test 0 -eq "$NO_TRAP"; then
		# Set up the int handler
		# N.B. Dont use SIGINT symbolic value
		#  as its just INT under ksh
		trap "$SIGINT_ACTION" 2
	fi

	# Only detect the CPU if it hasnt been set with
	# either environment or command line
	if test "$HL_DETECT" -eq 1; then
		detectcpu
	fi

	if test ! -f "$HL"; then
		echo "Source Engine binary '$HL' not found, exiting"
		quit 1
	elif test ! -x "$HL"; then
		# Could try chmod but dont know what we will be
		# chmoding so just fail.
		echo "Source engine binary '$HL' not executable, exiting"
		quit 1
	fi

	# Setup debugging
	if test -n "$DEBUG" ; then
		#turn on core dumps :) (if possible)
		echo "Enabling debug mode"
		if test "unlimited" != `ulimit -c` && test "`ulimit -c`" -eq 0 ; then
			ulimit -c 2000
		fi
		GDB_TEST=`$GDB -v`
		if test -z "$GDB_TEST"; then
			echo "Please install gdb first."
			echo "goto http://www.gnu.org/software/gdb/ "
			DEBUG="" # turn off debugging cause gdb isn't installed
		fi
	fi

	if test -n "$STEAM_PASSWORD" && test -z "$STEAM_USER"; then
		echo "You must set both the steam username and password."
		quit 1
	fi

	#if test 1 -eq $PID_FILE_SET && test -n "$PID_FILE"; then
	#	HL_CMD="$HL $PARAMS -pidfile $PID_FILE"
	#else
		HL_CMD="$HL $PARAMS"
	#fi
}

syntax () {
	# Prints script syntax

	echo "Syntax:"
	echo "$0 [-game <game>] [-debug] [-norestart] [-pidfile]"
	echo "	[-binary [srcds_i486]"
	echo "	[-timeout <number>] [-gdb <gdb>] [-autoupdate]"
	echo "	[-steamerr] [-ignoresigint] [-steamuser <username>]"
	echo "	[-steampass <password>] [-debuglog <logname>]"
	echo "Params:"
	echo "-game <game>        	Specifies the <game> to run."
	echo "-debug              	Run debugging on failed servers if possible."
	echo "-debuglog <logname>	Log debug output to this file."
	echo "-norestart          	Don't attempt to restart failed servers."
	echo "-pidfile <pidfile>  	Use the specified <pidfile> to store the server pid."
	echo "-binary <binary>    	Use the specified binary ( no auto detection )."
	echo "-timeout <number>   	Sleep for <number> seconds before restarting"
	echo "			a failed server."
	echo "-gdb <gdb>          	Use <dbg> as the debugger of failed servers."
	echo "-steamerr     	  	Quit on steam update failure."
	echo "-steamuser <username>	Use this username for steam updates."  
	echo "-steampass <password>	Use this password for steam updates" 
	echo "			(-steamuser must be specified as well)."
	echo "-ignoresigint       	Ignore signal INT ( prevents CTRL+C quitting"
	echo "			the script )."
	echo "-notrap             	Don't use trap. This prevents automatic"
	echo "			removal of old lock files."
	echo ""
	echo "Note: All parameters specified as passed through to the server"
	echo "including any not listed."
}

debugcore () {
	# Debugs any core file if DEBUG is set and
	# the exitcode is none 0

	exitcode=$1

	if test $exitcode -ne 0; then
		if test -n "$DEBUG" ; then 
			echo "bt" > debug.cmds;
			echo "info locals" >> debug.cmds;
			echo "info sharedlibrary" >> debug.cmds
			echo "info frame" >> debug.cmds;  # works, but gives an error... must be last
			echo "----------------------------------------------" >> $DEBUG_LOG
			echo "CRASH: `date`" >> $DEBUG_LOG
			echo "Start Line: $HL_CMD" >> $DEBUG_LOG

			# check to see if a core was dumped
			if test -f core ; then
				CORE="core"
			elif test -f core.`cat $PID_FILE`; then
				CORE=core.`cat $PID_FILE`
			elif test -f "$HL.core" ; then
				CORE="$HL.core"
			fi
			
			if test -n "$CORE"; then
				$GDB $HL $CORE -x debug.cmds -batch >> $DEBUG_LOG
			fi
		
			echo "End of Source crash report" >> $DEBUG_LOG
			echo "----------------------------------------------" >> $DEBUG_LOG
			echo $CRASH_DEBUG_MSG
			rm debug.cmds
		else
			echo "Add \"-debug\" to the $0 command line to generate a debug.log to help with solving this problem"
		fi
	fi
}

detectcpu() {
	# Attempts to auto detect the CPU
	echo "Auto detecting CPU"

	if test -e /proc/cpuinfo; then
		CPU_VERSION="`grep "cpu family" /proc/cpuinfo | cut -f2 -d":" | tr -d " " | uniq`";
		if test $CPU_VERSION -lt 4; then
			echo "Error: srcds REQUIRES a 486 CPU or better";
			quit 1
		elif test $CPU_VERSION -ge 6; then
			FEATURES="`grep 'flags' /proc/cpuinfo`";
			SSE2="`echo $FEATURES |grep -i SSE2`"
			AMD="`grep AMD /proc/cpuinfo`";
			if test -n "$AMD"; then
				OPTERON="`grep Opteron /proc/cpuinfo`";
				PLATFORM="`uname -m`"
				if test -z "$OPTERON"; then
					OPTERON="`grep "Athlon HX" /proc/cpuinfo`";
					if test -z "$OPTERON"; then
						OPTERON="`grep "Athlon(tm) 64" /proc/cpuinfo`";
					fi
				fi

				if test -n "$OPTERON" && test "x86_64" = "$PLATFORM"; then
					echo "Using AMD-Opteron (64 bit) Optimised binary."
					HL=./srcds_amd
				else
					echo "Using AMD Optimised binary."
					HL=./srcds_amd
				fi
			elif  test -n "$SSE2"; then
				# CPU supports SSE2 P4 +
				echo "Using SSE2 Optimised binary."
				HL=./srcds_i686
			else
				echo "Using default binary."
			fi		
		else
			echo "Using default binary."
		fi

	elif test "FreeBSD" = `uname`; then
		CPU="`grep 'CPU:' /var/run/dmesg.boot`"
		FEATURES="`grep 'Features=' /var/run/dmesg.boot`"
		AMD="`echo $CPU |grep AMD`"
		I686="`echo $CPU |grep 686`"
		SSE2="`echo $FEATURES |grep -i SSE2`"
		if test -n "$AMD"; then
			echo "Using AMD Optimised binary."
			HL=./srcds_amd
		elif test -n "$SSE2" ; then
			echo "Using SSE2 Optimised binary."
			HL=./srcds_i686
		else
			echo "Using default binary."
		fi
	else
		echo "Using default binary."
	fi
}

update() {
	updatesingle
}

updatesingle() {
	# Run the steam update
	# exits on failure if STEAMERR is set

	if test -n "$AUTO_UPDATE"; then
		if test -f "$STEAM"; then
			echo "Updating server using Steam."
		
			if test "$GAME" = "cstrike"; then
				GAME="Counter-Strike Source";
			fi
			if test "$GAME" = "dod"; then
				GAME="dods";
			fi

			CMD="$STEAM -command update -dir ."; 
			if test -n "$STEAM_USER"; then
				CMD="$CMD -username $STEAM_USER";
			fi 
			if test -n "$STEAM_PASSWORD"; then
				CMD="$CMD -password $STEAM_PASSWORD";
			fi 

			$CMD -game "$GAME"
			if test $? -ne 0; then
				if test -n "$STEAMERR"; then
					echo "`date`: Steam Update failed, exiting."
					quit 1
				else
					echo "`date`: Steam Update failed, ignoring."
					return 0
				fi
			fi
		else
			if test -n "$STEAMERR"; then
				echo "Could not locate steam binary:$STEAM, exiting.";
				quit 1
			else
				echo "Could not locate steam binary:$STEAM, ignoring.";
				return 0
			fi
		fi
	fi

	return 1
}
	
run() {
	# Runs the steam update and server
	# Loops if RESTART is set
	# Debugs if server failure is detected
	# Note: if RESTART is not set then
	# 1. DEBUG is set then the server is NOT exec'd
	# 2. DEBUG is not set the the server is exec'd

	if test -n "$RESTART" ; then
		echo "Auto-restarting the server on crash"

		#loop forever
		while true
		do
			# Update if needed
			update

			# Run the server
			$HL_CMD
			retval=$?

			debugcore $retval

			echo "`date`: Server restart in $TIMEOUT seconds"

			# don't thrash the hard disk if the server dies, wait a little
			sleep $TIMEOUT
		done # while true 
	else
		# Update if needed
		update

		# Run the server
		if test -z "$DEBUG"; then
			# debug not requested we can exec
			exec $HL_CMD
		else
			# debug requested we can't exec
			$HL_CMD
			debugcore $?
		fi
	fi
}

quit() {
	# Exits with the give error code, 1
	# if none specified.
	# exit code 2 also prints syntax
	exitcode="$1"

	# default to failure
	if test -z "$exitcode"; then
		exitcode=1
	fi

	case "$exitcode" in
	0)
		echo "`date`: Server Quit" ;;
	2)
		syntax ;;
	*)
		echo "`date`: Server Failed" ;;
	esac

	# Remove pid file
	if test -n "$PID_FILE" && test -f "$PID_FILE" ; then
		# The specified pid file
		rm -f $PID_FILE
	fi

	# reset SIGINT and then kill ourselves properly
	trap - 2
	kill -2 $$
}

# Initialise
init $*

# Run
run

# Quit normally
quit 0
then i use this command to start the server:
Quote:
screen -dmS dust ./RESTART_srcds_run +game cstrike +maxplayers 21 +ip xx.xxx.xx.x -tickrate 66 +port 27015 +map de_dust2 +exec server.cfg +fps_max 300 +mp_dynamicpricing 0 +sv_pure 0
never once had a problem with this script
SquareDisc is offline   Reply With Quote
Old 07-10-2007, 02:28 PM   #8
RTL|Lee
 
Guest
Posts: n/a
Dont suppose you mind if I use that ??
  Reply With Quote
Old 07-10-2007, 02:55 PM   #9
mianosm
 
Join Date: Jun 2007
Reputation: 1
Posts: 65
0123456789

Last edited by mianosm: 05-20-2009 at 12:21 PM.
mianosm is offline   Reply With Quote
Old 07-10-2007, 05:40 PM   #10
TheMG
 
TheMG's Avatar
 
Volunteer Moderator
Join Date: Mar 2007
Reputation: 1899
Posts: 10,284
Quote:
Originally Posted by SquareDisc View Post
heres the auto restart on crash i use on all my servers:

Filename: RESTART_srcds_run
What you posted looks exactly like the contents of the original srcds_run (which is a script).

Or did you make modifications to it?

Quote:
Originally Posted by RTL|Lee View Post
Dont suppose you mind if I use that ??
Go right ahead. It's not even mine (aside from some light modifications). It was passed on from someone I know who also runs servers, and I don't know who that person got it from. I remember seing that script posted on a website somewhere but I can't seem to find it anymore.

Last edited by TheMG: 07-10-2007 at 05:43 PM.
TheMG is offline   Reply With Quote
Old 02-19-2009, 03:44 PM   #11
zerosin
 
Guest
Posts: n/a
Quote:
Originally Posted by SquareDisc View Post
heres the auto restart on crash i use on all my servers:

Filename: RESTART_srcds_run
Code:
#!/bin/sh
#
#       Copyright (c) 2004, Valve LLC. All rights reserved.
#
#	a wrapper script for the main Source engine dedicated server binary.
#	Performs auto-restarting of the server on crash. You can
#	extend this to log crashes and more.
#

# setup the libraries, local dir first!
export LD_LIBRARY_PATH=".:bin:$LD_LIBRARY_PATH"

init() {
	# Initialises the various variables
	# Set up the defaults
	GAME=""
	DEBUG=""
	RESTART="yes"
	HL=./srcds_i486
	HL_DETECT=1
	TIMEOUT=10 # time to wait after a crash (in seconds)
	CRASH_DEBUG_MSG="email debug.log to linux@valvesoftware.com"
	GDB="gdb" # the gdb binary to run
	DEBUG_LOG="debug.log"
	PID_FILE="" # only needed it DEBUG is set so init later
	STEAM=""
	PID_FILE_SET=0
	STEAMERR=""
	SIGINT_ACTION="quit 0" # exit normally on sig int
	NO_TRAP=0
	AUTO_UPDATE=""
	STEAM_USER=""
	STEAM_PASSWORD=""
	PARAMS=$*

	# Remove any old default pid files
	# Cant do this as they may be still running
	#rm -f hlds.*.pid

	# use the $FORCE environment variable if its set
	if test -n "$FORCE" ; then
		# Note: command line -binary will override this
		HL=$FORCE
		HL_DETECT=0
	fi

	while test $# -gt 0; do
		case "$1" in
		"-game")
			GAME="$2"
			shift ;;
		"-debug")
			DEBUG=1
			# Ensure that PID_FILE is set
			PID_FILE_SET=1
			if test -z "$PID_FILE"; then
				PID_FILE="hlds.$$.pid"
			fi ;;
		"-norestart")
			RESTART="" ;;
		"-pidfile")
			PID_FILE="$2"
			PID_FILE_SET=1
			shift ;;
		"-binary")
			HL="$2"
			HL_DETECT=0
			shift ;;
		"-timeout")
			TIMEOUT="$2"
			shift ;;
		"-gdb")
			GDB="$2"
			shift ;;
		"-debuglog")
			DEBUG_LOG="$2"
			shift ;;
		"-autoupdate")
			AUTO_UPDATE="yes"
			STEAM="./steam"
			RESTART="yes" ;;
		"-steamerr")
			STEAMERR=1 ;;
		"-ignoresigint")
			SIGINT_ACTION="" ;;
		"-notrap")
			NO_TRAP=1 ;;
		"-steamuser")
			STEAM_USER="$2";
			shift ;;
		"-steampass")
			STEAM_PASSWORD="$2";
			shift ;;
		"-help")
			# quit with syntax
			quit 2
			;;
		esac
		shift
	done

	# Ensure we have a game specified
	if test -z "$GAME"; then
		GAME="cstrike"
		PARAMS="$PARAMS -game $GAME"
	elif test ! -d "$GAME"; then
		echo "Invalid game type '$GAME' sepecified."
		quit 1
	fi

	if test 0 -eq "$NO_TRAP"; then
		# Set up the int handler
		# N.B. Dont use SIGINT symbolic value
		#  as its just INT under ksh
		trap "$SIGINT_ACTION" 2
	fi

	# Only detect the CPU if it hasnt been set with
	# either environment or command line
	if test "$HL_DETECT" -eq 1; then
		detectcpu
	fi

	if test ! -f "$HL"; then
		echo "Source Engine binary '$HL' not found, exiting"
		quit 1
	elif test ! -x "$HL"; then
		# Could try chmod but dont know what we will be
		# chmoding so just fail.
		echo "Source engine binary '$HL' not executable, exiting"
		quit 1
	fi

	# Setup debugging
	if test -n "$DEBUG" ; then
		#turn on core dumps :) (if possible)
		echo "Enabling debug mode"
		if test "unlimited" != `ulimit -c` && test "`ulimit -c`" -eq 0 ; then
			ulimit -c 2000
		fi
		GDB_TEST=`$GDB -v`
		if test -z "$GDB_TEST"; then
			echo "Please install gdb first."
			echo "goto http://www.gnu.org/software/gdb/ "
			DEBUG="" # turn off debugging cause gdb isn't installed
		fi
	fi

	if test -n "$STEAM_PASSWORD" && test -z "$STEAM_USER"; then
		echo "You must set both the steam username and password."
		quit 1
	fi

	#if test 1 -eq $PID_FILE_SET && test -n "$PID_FILE"; then
	#	HL_CMD="$HL $PARAMS -pidfile $PID_FILE"
	#else
		HL_CMD="$HL $PARAMS"
	#fi
}

syntax () {
	# Prints script syntax

	echo "Syntax:"
	echo "$0 [-game <game>] [-debug] [-norestart] [-pidfile]"
	echo "	[-binary [srcds_i486]"
	echo "	[-timeout <number>] [-gdb <gdb>] [-autoupdate]"
	echo "	[-steamerr] [-ignoresigint] [-steamuser <username>]"
	echo "	[-steampass <password>] [-debuglog <logname>]"
	echo "Params:"
	echo "-game <game>        	Specifies the <game> to run."
	echo "-debug              	Run debugging on failed servers if possible."
	echo "-debuglog <logname>	Log debug output to this file."
	echo "-norestart          	Don't attempt to restart failed servers."
	echo "-pidfile <pidfile>  	Use the specified <pidfile> to store the server pid."
	echo "-binary <binary>    	Use the specified binary ( no auto detection )."
	echo "-timeout <number>   	Sleep for <number> seconds before restarting"
	echo "			a failed server."
	echo "-gdb <gdb>          	Use <dbg> as the debugger of failed servers."
	echo "-steamerr     	  	Quit on steam update failure."
	echo "-steamuser <username>	Use this username for steam updates."  
	echo "-steampass <password>	Use this password for steam updates" 
	echo "			(-steamuser must be specified as well)."
	echo "-ignoresigint       	Ignore signal INT ( prevents CTRL+C quitting"
	echo "			the script )."
	echo "-notrap             	Don't use trap. This prevents automatic"
	echo "			removal of old lock files."
	echo ""
	echo "Note: All parameters specified as passed through to the server"
	echo "including any not listed."
}

debugcore () {
	# Debugs any core file if DEBUG is set and
	# the exitcode is none 0

	exitcode=$1

	if test $exitcode -ne 0; then
		if test -n "$DEBUG" ; then 
			echo "bt" > debug.cmds;
			echo "info locals" >> debug.cmds;
			echo "info sharedlibrary" >> debug.cmds
			echo "info frame" >> debug.cmds;  # works, but gives an error... must be last
			echo "----------------------------------------------" >> $DEBUG_LOG
			echo "CRASH: `date`" >> $DEBUG_LOG
			echo "Start Line: $HL_CMD" >> $DEBUG_LOG

			# check to see if a core was dumped
			if test -f core ; then
				CORE="core"
			elif test -f core.`cat $PID_FILE`; then
				CORE=core.`cat $PID_FILE`
			elif test -f "$HL.core" ; then
				CORE="$HL.core"
			fi
			
			if test -n "$CORE"; then
				$GDB $HL $CORE -x debug.cmds -batch >> $DEBUG_LOG
			fi
		
			echo "End of Source crash report" >> $DEBUG_LOG
			echo "----------------------------------------------" >> $DEBUG_LOG
			echo $CRASH_DEBUG_MSG
			rm debug.cmds
		else
			echo "Add \"-debug\" to the $0 command line to generate a debug.log to help with solving this problem"
		fi
	fi
}

detectcpu() {
	# Attempts to auto detect the CPU
	echo "Auto detecting CPU"

	if test -e /proc/cpuinfo; then
		CPU_VERSION="`grep "cpu family" /proc/cpuinfo | cut -f2 -d":" | tr -d " " | uniq`";
		if test $CPU_VERSION -lt 4; then
			echo "Error: srcds REQUIRES a 486 CPU or better";
			quit 1
		elif test $CPU_VERSION -ge 6; then
			FEATURES="`grep 'flags' /proc/cpuinfo`";
			SSE2="`echo $FEATURES |grep -i SSE2`"
			AMD="`grep AMD /proc/cpuinfo`";
			if test -n "$AMD"; then
				OPTERON="`grep Opteron /proc/cpuinfo`";
				PLATFORM="`uname -m`"
				if test -z "$OPTERON"; then
					OPTERON="`grep "Athlon HX" /proc/cpuinfo`";
					if test -z "$OPTERON"; then
						OPTERON="`grep "Athlon(tm) 64" /proc/cpuinfo`";
					fi
				fi

				if test -n "$OPTERON" && test "x86_64" = "$PLATFORM"; then
					echo "Using AMD-Opteron (64 bit) Optimised binary."
					HL=./srcds_amd
				else
					echo "Using AMD Optimised binary."
					HL=./srcds_amd
				fi
			elif  test -n "$SSE2"; then
				# CPU supports SSE2 P4 +
				echo "Using SSE2 Optimised binary."
				HL=./srcds_i686
			else
				echo "Using default binary."
			fi		
		else
			echo "Using default binary."
		fi

	elif test "FreeBSD" = `uname`; then
		CPU="`grep 'CPU:' /var/run/dmesg.boot`"
		FEATURES="`grep 'Features=' /var/run/dmesg.boot`"
		AMD="`echo $CPU |grep AMD`"
		I686="`echo $CPU |grep 686`"
		SSE2="`echo $FEATURES |grep -i SSE2`"
		if test -n "$AMD"; then
			echo "Using AMD Optimised binary."
			HL=./srcds_amd
		elif test -n "$SSE2" ; then
			echo "Using SSE2 Optimised binary."
			HL=./srcds_i686
		else
			echo "Using default binary."
		fi
	else
		echo "Using default binary."
	fi
}

update() {
	updatesingle
}

updatesingle() {
	# Run the steam update
	# exits on failure if STEAMERR is set

	if test -n "$AUTO_UPDATE"; then
		if test -f "$STEAM"; then
			echo "Updating server using Steam."
		
			if test "$GAME" = "cstrike"; then
				GAME="Counter-Strike Source";
			fi
			if test "$GAME" = "dod"; then
				GAME="dods";
			fi

			CMD="$STEAM -command update -dir ."; 
			if test -n "$STEAM_USER"; then
				CMD="$CMD -username $STEAM_USER";
			fi 
			if test -n "$STEAM_PASSWORD"; then
				CMD="$CMD -password $STEAM_PASSWORD";
			fi 

			$CMD -game "$GAME"
			if test $? -ne 0; then
				if test -n "$STEAMERR"; then
					echo "`date`: Steam Update failed, exiting."
					quit 1
				else
					echo "`date`: Steam Update failed, ignoring."
					return 0
				fi
			fi
		else
			if test -n "$STEAMERR"; then
				echo "Could not locate steam binary:$STEAM, exiting.";
				quit 1
			else
				echo "Could not locate steam binary:$STEAM, ignoring.";
				return 0
			fi
		fi
	fi

	return 1
}
	
run() {
	# Runs the steam update and server
	# Loops if RESTART is set
	# Debugs if server failure is detected
	# Note: if RESTART is not set then
	# 1. DEBUG is set then the server is NOT exec'd
	# 2. DEBUG is not set the the server is exec'd

	if test -n "$RESTART" ; then
		echo "Auto-restarting the server on crash"

		#loop forever
		while true
		do
			# Update if needed
			update

			# Run the server
			$HL_CMD
			retval=$?

			debugcore $retval

			echo "`date`: Server restart in $TIMEOUT seconds"

			# don't thrash the hard disk if the server dies, wait a little
			sleep $TIMEOUT
		done # while true 
	else
		# Update if needed
		update

		# Run the server
		if test -z "$DEBUG"; then
			# debug not requested we can exec
			exec $HL_CMD
		else
			# debug requested we can't exec
			$HL_CMD
			debugcore $?
		fi
	fi
}

quit() {
	# Exits with the give error code, 1
	# if none specified.
	# exit code 2 also prints syntax
	exitcode="$1"

	# default to failure
	if test -z "$exitcode"; then
		exitcode=1
	fi

	case "$exitcode" in
	0)
		echo "`date`: Server Quit" ;;
	2)
		syntax ;;
	*)
		echo "`date`: Server Failed" ;;
	esac

	# Remove pid file
	if test -n "$PID_FILE" && test -f "$PID_FILE" ; then
		# The specified pid file
		rm -f $PID_FILE
	fi

	# reset SIGINT and then kill ourselves properly
	trap - 2
	kill -2 $$
}

# Initialise
init $*

# Run
run

# Quit normally
quit 0
then i use this command to start the server:


never once had a problem with this script
Hi there,
I'm new to running linux servers, so pls bear with me.

For running a CS:S server, do I need to change anything in the script? And for TF2 and L4D, is there any other changes in the script that I need to do as well.

Where do I put this script?

Do I need this script to be in every server or does it only need to be only launched once for all game services?

One last question, what's the difference between the first, second script and this quoted one?

Thx in advance.

Last edited by zerosin: 02-19-2009 at 03:57 PM.
  Reply With Quote
Old 03-03-2009, 08:09 AM   #12
mardur
 
Guest
Posts: n/a
@zerosin
The script you quoted is basically identical to the main executable "srcds_run" of your server.

What you need are the two files from TheMG's post.

Say, your linux user name is zerosin, your home directory is '/home/zerosin' and your server directory is '/home/zerosin/server' (there you put your hldsupdatetool.bin and steam executable).

You probably downloaded the server files via
./steam -command update -game "cstrike" -dir .
Now you should see the following directories:
/home/zerosin/server/hl2
/home/zerosin/server/cstrike
/home/zerosin/server/cstrike/cfg
and some more subdirectories. The main server executable srcds_run can be found directly in /home/zerosin/server.

To start the server, you would type:
cd /home/zerosin/server/
./srcds_run -console -game cstrike -port 27015 +ip 123.123.123.123 +map de_dust +maxplayers 14
You will see the server console, so just type 'quit' to stop the server.

This has quite some disadvantages:
- The command is not easy to remember/fast to type
- You cannot close the Terminal without killing the server (which is ok if the server is in your flat with an own monitor/keyboard, but its bad if you manage the server remotely)

The provided script now solves those problems. Copy the two files 'startscript' and 'startscript.conf' directly into the folder '/home/zerosin/server'. You need to do the following modifications in startscript.conf:
Code:
DSPATH='/home/zerosin/server'
DSUSER='zerosin'
DSIP='whatever ip your server has'
and in startscript:
Code:
cd /home/zerosin/server   (changed from cd /css/1)
Then execute 'chmod +x starscript' to make the script executable.

Now you can start the server with the command
/home/zerosin/server/startscript start
(or just 'server/startscript start', if you are in your home directory)

To make that even easier, do the following:
cd /bin
sudo ln -s /home/zerosin/server/startscript server1

Now you can just call 'server1 start' no matter what directory you are in. The 'sudo' command may require you to type in your login password or maybe the root password.

You can stop the server with
server1 stop

And to open the server console
server1 watch
(to close the console without killing the server, use the key combination CTRL+A CTRL+D)

If you install a TF2 server in the same directory:
cd /home/zerosin/server
./steam -command update -game "tf" -dir .
then you will see a slightly different directory structure. Games from the Orange Box will create the 'hl2' folder (as CSS) but put everything else into an 'orangebox' folder:
/home/zerosin/server/hl2
/home/zerosin/server/orangebox/tf
/home/zerosin/server/orangebox/tf/cfg

Also the server executable resides in /home/zerosin/server/orangebox/tf. If you want to use the script for TF2, do the following:
cd /home/zerosin/server
cp startscript startscript2
cp startscript.conf startscript2.conf
And change those values in startscript.conf:
Code:
CLIENT='srcds_2'
TITLE='SRCDS 2'
(it is important that CLIENT and TITLE are different from your css server config)
DSPATH='/home/zerosin/server/orangebox'
(dont forget the 'orangebox)
DSNAMESHORT='srcds_2'
(also change this to a different value than your CSS config)
DSIP='whatever ip you have'
DSGAME='tf'
DSIMAP='cp_badlands'
DSPORT='27035'
(use your other port 27015 plus 20, always increment by 20 when you start a new server)
DSSIZE='16'
DSUSER='zerosin'
DSTICKRATE='66'
DSSERVERFPS='333'
(those rates are default for TF2, no need put something else here)
And change the '. ./startscript.conf' into '. ./startscript2.conf' in your startscript2 file.

Now use serverscript2 to start/stop your TF2 server. And create a link
sudo ln -s /home/zerosin/server/startscript2 /bin/server2
for simply calling 'server2 start', etc.

Last edited by mardur: 03-11-2009 at 10:06 AM.
  Reply With Quote
Old 03-03-2009, 08:44 AM   #13
mardur
 
Guest
Posts: n/a
(the post was getting too long, so please excuse the double posting here)

I am using a modified version of TheMG's script on my server. The list of modifications include:
- The original script is checking the user name, but it is not changing the user (sudo)
- Autodetecting configuration file name (based on script name)
- Added steam update/verify options
- Added options to edit main configuration files
- Added rcon command execution

Here is my runserver1.conf for a TF2 server (called master config in the script)
Code:
#!/bin/sh
DSID='tf2ds_1a';
DSTITLE='TF2 Server 1 a (20 slots)';
DSGAME='tf';
DSIMAP='cp_badlands';
DSPORT='27015';
DSSIZE='20';
DSCONF='server_a.cfg'

# Only modify if this game server has a separate directory.
STPATH='/home/hlds';			# Where Steam is installed
UPPATH='/home/hlds/server1';		# Base path for hlswupdatetool operations
DSPATH='/home/hlds/server1/orangebox';	# The gameservers subdirectory
CFPATH="$DSPATH/$DSGAME/cfg";		# Path to cfg files

# Don't modify these values.
DSIP='123.123.123.123';			# IP address you want to use to start server with
DSEXEC="$DSPATH/srcds_run";		# Either hlds_run or srcds_run
STEXEC="$STPATH/steam"			# Steam executable (for game server updates)
DSUSER='hlds'				# User account to run game server server and hlswupdatetool
DSTICK='66';				# Tick Rate
DSFPS='333';				# Server FPS Rate

# Don't edit this unless you need the script to do something special
DSSERVERPID="$DSID.server.pid"
DSSCREENPID="$DSID.screen.pid"
DSOPTS="-console -game $DSGAME +hostname \"$DSID\" +map $DSIMAP -ip $DSIP -port $DSPORT -autoupdate +maxplayers $DSSIZE -tickrate $DSTICK +fps_max $DSFPS +exec $DSCONF"

# This is the caller for the screen process.
# Only change if this is different from where your screen process currently resides.
DSINTERFACE="/usr/bin/screen -A -m -d -S $DSID"
If you have just one server directory containing the steam executables as well (use steam ... -dir .), then STPATH and UPPATH are the same. in the former config I am using 'steam ... -dir server1'. If you are running cstrike (or any non-orangebox game), then DSPATH is the same as well.

Here is my startscript
Code:
#!/bin/sh
# Start/stop/restart a Valve dedicated server
# All configuration changes should occur in <scriptname>.conf.

# Only change the name of the call below if you are using a different name for the script
BASEPATH='/home/hlds'

if [ ! -f "$BASEPATH/$0.conf" ]; then
    echo "master config file '$BASEPATH/$0.conf' not found"
    exit 0
fi

. "$BASEPATH/$0.conf"

WHOAMI=`whoami`
EDITOR='/bin/nano'
RCONCMD='/usr/bin/java -cp rcon.jar SourceRconCLI'

if [ "$WHOAMI" != "$DSUSER" ]; then
    if [ "$WHOAMI" = 'root' ]; then
	echo "Script called as root. Switch to user $DSUSER."
	sudo -u $DSUSER "$0" "$@"
	exit 0
    else
	ALLOWED="$DSUSER"
	if [ "$DSUSER" != 'root' ]; then
	    ALLOWED="root or $DSUSER"
	fi
	echo "Script called as $WHOAMI. Please login as $ALLOWED."
	exit 0
    fi
fi

if [ "$DSUSER" = 'root' ]; then
    echo "Running the script as root is not recommanded."
fi


service_start() {
    # Currently checking to see if the pid files that are creates during
    # the startup process exist. If neither exists it will go ahead.
    if [ ! -f $DSPATH/$DSSERVERPID ] && [ ! -f $DSPATH/$DSSCREENPID ]; then
	if [ -x $DSEXEC ]; then
	    echo "Starting '$DSTITLE' ..."

	    cd $DSPATH; $DSINTERFACE $DSEXEC $DSOPTS

	    # prevent race condition on SMP kernels
	    sleep 1

	    # Finding and writing current process id of the screen process
	    ps -ef | grep SCREEN | grep "$DSID" | grep -v grep | awk '{ print $2 }' > $DSPATH/$DSSCREENPID
	    ps -ef | grep srcds_run | grep "$DSID" | grep -v grep | grep -v SCREEN | awk '{ print $2 }' > $DSPATH/$DSSERVERPID
	else
	    echo "Cannot start '$DSTITLE': executable $DSEXEC not found."
	fi
    else
	# It found that one of the pid files exists. Perhaps the server
	# did not shut down with the script being used... if this is the
	# case use '<scriptname> clean' to fix it
	echo "Server '$DSTITLE' already started."

	# TODO: check whether there is no proper process running
	#       then delete the pid files and start the server
    fi
}


service_stop() {
    # This script is just getting the process id of the server that was
    # written to the file it created earlier so it can kill it.
    if [ -f $DSPATH/$DSSERVERPID ]; then
	echo "Stopping '$DSTITLE' ..."
	for vdspid in $(cat $DSPATH/$DSSERVERPID);
	do
            kill $vdspid;
            break;
	done
	rm -rf $DSPATH/$DSSERVERPID;
    else
	echo "Server '$DSTITLE' not running."
    fi
    rm -rf $DSPATH/$DSSCREENPID;
    # This command is just clearing out any *DEAD* screen sessions.
    # Those can become a pain really quick.
    screen -wipe 1> /dev/null 2> /dev/null
}


service_restart() {
    # Simple enough. It is making a call to the stop service and then
    # it waits for a second then it calls the start script.
    service_stop
    sleep 1
    service_start
}


service_status() {
    # This is checking to see if $DSNAME.pid file exists

    SCREEN_PID=`ps -ef | grep SCREEN | grep "$DSID" | grep -v grep | awk '{ print $2 }'`

    if [ -f $DSPATH/$DSSERVERPID ]; then
	# Pulling in the values to evaulate if they are true or not
	SCREEN_FILE_PID=`cat $DSPATH/$DSSCREENPID`
	SERVER_FILE_PID=`cat $DSPATH/$DSSERVERPID`

	# This is checking to see if the currently running process ID
	# matches with the pid created when the server was started.
	if [ "$SCREEN_PID" = "$SCREEN_FILE_PID" ]; then
	    # It found this process ID matches and is outputting what it is currently running on
	    echo "Server '$DSTITLE' is running"
	    if [ "$1" != 'quick' ]; then
		echo "screen process: $SCREEN_FILE_PID"
		echo "server process: $SERVER_FILE_PID"
	    fi
	fi
    else
	# Apparently the server is offline
	echo "Server '$DSTITLE' is offline."
	if [ "$SCREEN_PID" ]; then
	    # Wait, it found another server matching the same criteria running under a different process ID.
	    echo "screen process: $SCREEN_PID"
	fi
    fi

    if [ "$1" != 'quick' ]; then
	echo "directory     : $DSPATH"
	echo "address       : $DSIP:$DSPORT"
	echo "slots         : $DSSIZE"
	echo "pid files     : $DSPATH/$DSSCREENPID"
	echo "                $DSPATH/$DSSERVERPID"
	echo "script file   : $BASEPATH/$0"
    fi
}


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

    # Check if there is someone already attached
    if [ `screen -wipe | grep "$DSID" | grep -v grep | awk '{ print $2 }'` = '(Attached)' ]; then
	# Oops someone is already attached to it...
	# better wait your turn or go chew someone $%^ out
	echo -e "Someone is already attached to the console of the server.\nMight want to check who"
    else
	# Looks like noone is watching it right now...
	# peeping tom time !!!
	screen -r "$DSID"
    fi
}


parse_config_value() {
    FILE="$1"
    ENTRY="$2"
    grep "^$ENTRY" "$FILE" | sed -e "s/^$ENTRY//" -e 's/^[[:space:]]*//' -e 's/^["]//' -e 's/["]$//'
}


service_rcon() {
    PW=`parse_config_value "$CFPATH/$DSCONF" rcon_password`
    cd $BASEPATH; $RCONCMD "$DSIP:$DSPORT" "$PW" "$@"
}


service_clean() {
    # This service is used to clean house if the script is reporting erroneous info.
    rm -rf $DSPATH/$DSSERVERPID $DSPATH/$DSSCREENPID
    screen -wipe 1> /dev/null 2> /dev/null;
}


edit_file() {
    if [ -f "$1" ]; then
	$EDITOR "$1"
    else
	echo "Server '$DSTITLE' file not found: '$1'."
    fi
}


service_edit() {
    case "$1" in
	'')
	    edit_file "$CFPATH/$DSCONF"
	;;
	'cfg')
	    edit_file "$CFPATH/$DSCONF"
	;;
	'master')
	    edit_file "$BASEPATH/$0.conf"
	;;
	'mapcycle')
	    FILE=`parse_config_value "$CFPATH/$DSCONF" 'mapcyclefile'`
	    edit_file "$DSPATH/$DSGAME/$FILE"
  	;;
	'motd')
	    FILE=`parse_config_value "$CFPATH/$DSCONF" 'motdfile'`
	    edit_file "$DSPATH/$DSGAME/$FILE"
	;;
	*)
	    echo "Unknown edit entry: '$1'"
    esac
}


list_files() {
    DIR="$1"
    EXT="$2"
    cd "$DIR"; find -L -type f -name "*.$EXT" | sed -e "s/^[.][/]//" | sort
}


service_list() {
    case "$1" in
	'')
	    echo "Please select list type: maps demo cfg"
	    ;;
	'maps')
	    list_files "$DSPATH/$DSGAME/maps" bsp
	    ;;
	'demo')
	    list_files "$DSPATH/$DSGAME" dem
	    ;;
	'cfg')
	    list_files "$DSPATH/$DSGAME/cfg" cfg
	    ;;
	*)
	    echo "Unknown list entry: '$1'"
    esac
}


service_update() {
    if [ -x $STEXEC ]; then
	echo "Updating '$DSTITLE' ..."
	cd $STPATH; $STEXEC -command update -game "$DSGAME" -dir $UPPATH
    else
	echo "Cannot update '$DSTITLE': executable '$STEXEC' not found."
    fi
}


service_verify() {
    if [ -x $STEXEC ]; then
	echo "Verifying '$DSTITLE' ..."
	cd $STPATH; $STEXEC -command update -game "$DSGAME" -dir . -verify_all
    else
	echo "Cannot verify '$DSTITLE': executable '$STEXEC' not found."
    fi
}


case "$1" in
    'start')
	service_start
	;;
    'stop')
	service_stop
	;;
    'restart')
	service_restart
	;;
    'status')
	service_status
	;;
    'quickstatus')
	service_status quick
	;;
    'watch')
	service_watch
	;;
    'rcon')
	shift;
	service_rcon "$@"
	;;
    'clean')
	service_clean
	;;
    'edit')
	service_edit "$2"
	;;
    'editmaster')
	service_edit 'master'
	;;
    'list')
	service_list "$2"
	;;
    'update')
	service_update
	;;
    'verify')
	service_verify
	;;
    *)
	echo "usage $0 <action> <options>"
	echo "  <action> = start|stop|restart|status|watch|clean"
	echo "  <action> = rcon <command>"
	echo "    <command> = any command for the server console"
	echo "  <action> = edit <file>"
	echo "  <action> = update|verify"
	echo "    <file>    = cfg | master | motd | mapcycle"
	echo "  <action> = list <type>"
	echo "    <type>    = maps | demo | cfg"
esac
If we run the script as root (but DSUSER is not root) then just switch user and recall the script. The filenames for MotD and MapCycle files and the RCon password are directly parsed from the server config file. To execute rcon commands I am using a little Java program calling the Rconed Java Library. The Library and my little code are available under GPL.

For that script to work, you need the following directory structure:
/home/hlds (home directory of user hlds)
/home/hlds/hldsupdatetool.bin
/home/hlds/steam
/home/hlds/rcon.jar (available here)
/home/hlds/startscript (the script)
/home/hlds/runserver1 -> startscript (just a symlink)
/home/hlds/runserver1.conf
/home/hlds/runserver2 -> startscript
/home/hlds/runserver2.conf
/home/hlds/server1/orangebox/srcds_run
/home/hlds/server1/orangebox/tf/...

It is not necessary to copy the main script or to change anything in there for different servers. The script is loading appropriate settings based on the name of the symbolic link it was called with.

Now have fun using the following commands:
runserver1 start
runserver1 rcon mp_timelimit 30
runserver1 update
runserver1 edit cfg

If you have multiple servers running, then you could use a little script to start/stop/restart/update all servers with a single call. Here you go:
Code:
#!/bin/sh
# Start/stop/restart all Valve dedicated servers

SERVERS='runserver1 runserver2'


service_exec() {
    echo "Invoking command '$1' on all game servers"
    for server in $SERVERS;
    do
	echo
	sh $server $1
    done
}


case "$1" in
    'start')
	service_exec start
	;;
    'stop')
	service_exec stop
	;;
    'restart')
	service_exec restart
	;;
    'status')
	service_exec status
	;;
    'quickstatus')
	service_exec quickstatus
	;;
    'clean')
	service_exec clean
	;;
    'update')
	service_exec update
	;;
    'verify')
	service_exec verify
	;;
    *)
	echo "usage $0 start|stop|restart|status|quickstatus|clean|update|verify"
esac
Change the list of $SERVERs accordingly (the script could automatically retrieve that list from the set of .conf-files, but well).

The script still has some problems. If the server exits (quit on console or crash), the pid files are still there, so you need to 'runserver1 clean' and 'runserver1 start' to restart the server. instead 'runserver1 start' should recognize, that the pid files are there, but the server is not running. Due to the 'ps | grep' hacks, we don't need the pid files at all.

First I tried to disable the user 'hlds' (no password, no login, no shell; you can still 'sudo -u hlds'), but if you start a screen process, it tries to attach to the current 'tty' which does not belong to hlds, but to the user you logged in with. The server still works, but you cannot attach to the screen process (runserver1 watch). So I make hlds a regular login account.

Last edited by mardur: 03-04-2009 at 05:06 AM.
  Reply With Quote
Old 03-05-2009, 06:55 PM   #14
The009
 
Join Date: Sep 2007
Reputation: 113
Posts: 643
I cheated I use the scrip that MG uses for hey he is one of my main admins and I set a cron job to daily call restart from the script

that will keep your server running in top shape as well if there is any small update that needs to be done it will do that as well.
The009 is offline   Reply With Quote
Old 03-09-2009, 08:28 PM   #15
zerosin
 
Guest
Posts: n/a
@ MarDur,
Hey thanks for your indepth answers to my questions, I will try it out and let you know what the outcome is. I really appreciate the time that you are helping me out, it is very rare to see such people with integrity helping others out.

Again, thank you very much MarDur.

Peace,
zerosin
  Reply With Quote
Reply

Go Back   Steam Users' Forums > Dedicated Server Discussions > Source DS (Linux)


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



All times are GMT -7. The time now is 01:34 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site Content Copyright Valve Corporation 1998-2014, All Rights Reserved.