add this script to your /etc/init.d directory
Code:#!/bin/sh # Source Dedicated Server Init Script # Server options TITLE='Source Dedicated Server' # Script initialization title LONGNAME='Team Fortress 2' # Full title of game type NAME='tf2' # Server handle for the screen session DAEMON='srcds_run' # The server daemon STEAM='/home/tf2/orangebox' # STEAM to Steam installation USER='tf2' # Game options IP='72.52.248.250' # IP of the server PORT='27015' # Port number to MAP='ctf_2fort' # Initial map to start GAME='tf' # Game type (tf|cstrike|valve|hl2mp) SIZE='24' # Maximum number of players # Server options string OPTS="-game $GAME +hostname \"$CLIENT\" +map $MAP +ip $IP -port $PORT \ -autoupdate +maxplayers $SIZE -pidfile $STEAM/$GAME/$NAME.pid" # Screen command INTERFACE="/usr/bin/screen -A -m -d -S $NAME" service_start() { # Check if the pid files currently exist if [ ! -f $STEAM/$GAME/$NAME.pid ] && [ ! -f $STEAM/$GAME/$NAME-screen.pid ]; then if [ -x $STEAM/$DAEMON ]; then echo "Starting $TITLE - $LONGNAME" echo "Server IP: $IP" echo "Server port: $PORT" echo "Server size: $SIZE players" cd $STEAM $INTERFACE $STEAM/$DAEMON $OPTS # Prevent race condition on SMP kernels sleep 1 # Find and write current process id of the screen process ps -ef | grep SCREEN | grep "$NAME" | grep -v grep | awk '{ print $2}' > $STEAM/$GAME/$NAME-screen.pid echo "$TITLE screen process ID written to $STEAM/$GAME/$NAME-screen.pid" echo "$TITLE server process ID written to $STEAM/$GAME/$NAME.pid" echo "$TITLE started." fi else echo -e "Cannot start $TITLE. Server is already running." #exit 1 fi } service_stop() { if [ -f $STEAM/$GAME/$NAME.pid ] && [ -f $STEAM/$GAME/$NAME-screen.pid ]; then echo "Stopping $TITLE - $LONGNAME." # Get the process ID from the pid file we created earlier for id in `cat $STEAM/$GAME/$NAME-screen.pid` do kill -9 $id echo "Killing process ID $id" echo "Removing $TITLE screen pid file" rm -rf $STEAM/$GAME/$NAME-screen.pid break done # Remove server pid file echo "Removing $TITLE pid file" rm -rf $STEAM/$GAME/$NAME.pid # Wipe all old screen sessions screen -wipe 1> /dev/null 2> /dev/null echo "$TITLE stopped." else echo -e "Cannot stop $TITLE. Server is not running." #exit 1 fi } case "$1" in 'start') service_start ;; 'stop') service_stop ;; 'restart') service_stop sleep 1 service_start ;; *) echo "Usage $0 start|stop|restart" esac
Code:#Source Dedicated Server Init Script # Server options TITLE='Source Dedicated Server' # Script initialization title LONGNAME='Team Fortress 2' # Full title of game type NAME='tf2' # Server handle for the screen session DAEMON='srcds_run' # The server daemon UPDATER='/usr/srcds' # The Steam updater. I recommend keeping it one directory below orangebox for tf2 servers. STEAM='/usr/srcds/orangebox' # STEAM to Steam installation USER='srcds' # User that this will be running under. Currently not functional part of this script. # Game options CLIENT='Team Fortress 2' #Game Server name. IP='127.0.0.1' # IP of the server PORT='27015' # Port number to MAP='ctf_2fort' # Initial map to start GAME='tf' # Game type (tf|cstrike|valve|hl2mp) SIZE='32' # Maximum number of players HIGHPRIORITY=1 #Set server renice to -20 will make server take priority over all other applications on server. 1 being on and 0 being off. # Server options string OPTS="-game $GAME +hostname \"$CLIENT\" +map $MAP +ip $IP -port $PORT \ -autoupdate +maxplayers $SIZE -pidfile $STEAM/$GAME/$NAME.pid" # Screen command INTERFACE="/usr/bin/screen -A -m -d -S $NAME" service_start() { # Check if the pid files currently exist if [ -f $STEAM/$GAME/$NAME.pid ] || [ -f $STEAM/$GAME/$NAME-screen.pid ]; then # Pid files allready exist check if the process is still running. if [ "$(ps -p `cat $STEAM/$GAME/$NAME.pid` | wc -l)" -gt 1 ]; then # Process is still running. echo -e "Cannot start $TITLE. Server is already running." #exit 1 else # Process exited with out cleaning up pid files. if [ "$(ps -p `cat $STEAM/$GAME/$NAME.pid` | wc -l)" -gt 1 ]; then # Screen is still running. # Get the process ID from the pid file we created earlier for id in `cat $STEAM/$GAME/$NAME-screen.pid` do kill -9 $id echo "Killing process ID $id" echo "Removing $TITLE screen pid file" rm -rf $STEAM/$GAME/$NAME-screen.pid break done fi # Remove server pid file echo "Removing $TITLE pid file" rm -rf $STEAM/$GAME/$NAME.pid # Wipe all old screen sessions screen -wipe 1> /dev/null 2> /dev/null service_start fi else # Server is not running start the server. if [ -x $STEAM/$DAEMON ]; then echo "Starting $TITLE - $LONGNAME - $CLIENT" echo "Server IP: $IP" echo "Server port: $PORT" echo "Server size: $SIZE players" cd $STEAM $INTERFACE $STEAM/$DAEMON $OPTS # Prevent race condition on SMP kernels sleep 1 # Find and write current process id of the screen process ps -ef | grep SCREEN | grep "$NAME" | grep -v grep | awk '{ print $2}' > $STEAM/$GAME/$NAME-screen.pid echo "$TITLE screen process ID written to $STEAM/$GAME/$NAME-screen.pid" echo "$TITLE server process ID written to $STEAM/$GAME/$NAME.pid" echo "$TITLE started." # Was having problems with directory permisions due to ftp access making these files unreadable by users other than owner. chmod 666 $STEAM/$GAME/*.pid 1> /dev/null 2> /dev/null sleep 2 if [ $HIGHPRIORITY = 1 ]; then renice -20 `cat $STEAM/$GAME/$NAME.pid` >/dev/null 2>&1 fi fi fi } service_stop() { if [ -f $STEAM/$GAME/$NAME.pid ] || [ -f $STEAM/$GAME/$NAME-screen.pid ]; then echo "Stopping $TITLE - $LONGNAME." # Get the process ID from the pid file we created earlier for id in `cat $STEAM/$GAME/$NAME-screen.pid` do kill -9 $id echo "Killing process ID $id" echo "Removing $TITLE screen pid file" rm -rf $STEAM/$GAME/$NAME-screen.pid break done # Remove server pid file echo "Removing $TITLE pid file" rm -rf $STEAM/$GAME/$NAME.pid # Wipe all old screen sessions screen -wipe 1> /dev/null 2> /dev/null echo "$TITLE stopped." else echo -e "Cannot stop $TITLE. Server is not running." #exit 1 fi } service_clear() { # Removing all pid files echo "Removing all Service pid files." rm -rf $STEAM/$GAME/*.pid 1> /dev/null 2> /dev/null } service_update() { echo "Stopping and Clearing all Service files." service_stop sleep 2 service_clear sleep 2 echo "Updating Steam Updater" cd $UPDATER ./steam 1> /dev/null 2> /dev/null echo "Updating Game Files" ./steam -command update -game $GAME -dir . 1> /dev/null 2> /dev/null sleep 2 service_start } case "$1" in 'start') service_start ;; 'stop') service_stop ;; 'restart') service_stop sleep 1 service_start ;; 'clear') service_clear ;; 'update') service_update ;; *) echo "Usage $0 start|stop|restart|clear|update" esac
Code:Code: #Source Dedicated Server Init Script # Server options TITLE='Source Dedicated Server' # Script initialization title LONGNAME='Team Fortress 2' # Full title of game type NAME='tf2' # Server handle for the screen session DAEMON='srcds_run' # The server daemon UPDATER='/usr/srcds' # The Steam updater. I recommend keeping it one directory below orangebox for tf2 servers. STEAM='/usr/srcds/orangebox' # STEAM to Steam installation USER='srcds' # User that this will be running under. Currently not functional part of this script. # Game options CLIENT='Team Fortress 2' #Game Server name. IP='127.0.0.1' # IP of the server PORT='27015' # Port number to MAP='ctf_2fort' # Initial map to start GAME='tf' # Game type (tf|cstrike|valve|hl2mp) SIZE='32' # Maximum number of players HIGHPRIORITY=1 #Set server renice to -20 will make server take priority over all other applications on server. 1 being on and 0 being off. # Server options string OPTS="-game $GAME +hostname \"$CLIENT\" +map $MAP +ip $IP -port $PORT \ -autoupdate +maxplayers $SIZE -pidfile $STEAM/$GAME/$NAME.pid" # Screen command CURRENT_USER=$(/usr/bin/whoami) if [ "$CURRENT_USER" = "$USER" ]; then INTERFACE="/usr/bin/screen -A -m -d -S $NAME" else INTERFACE="sudo -u $USER /usr/bin/screen -A -m -d -S $NAME" fi service_start() { # Check if the pid files currently exist if [ -f $STEAM/$GAME/$NAME.pid ] || [ -f $STEAM/$GAME/$NAME-screen.pid ]; then # Pid files allready exist check if the process is still running. if [ "$(ps -p `cat $STEAM/$GAME/$NAME.pid` | wc -l)" -gt 1 ]; then # Process is still running. echo -e "Cannot start $TITLE. Server is already running." #exit 1 else # Process exited with out cleaning up pid files. if [ "$(ps -p `cat $STEAM/$GAME/$NAME.pid` | wc -l)" -gt 1 ]; then # Screen is still running. # Get the process ID from the pid file we created earlier for id in `cat $STEAM/$GAME/$NAME-screen.pid` do kill -9 $id echo "Killing process ID $id" echo "Removing $TITLE screen pid file" rm -rf $STEAM/$GAME/$NAME-screen.pid break done fi # Remove server pid file echo "Removing $TITLE pid file" rm -rf $STEAM/$GAME/$NAME.pid # Wipe all old screen sessions screen -wipe 1> /dev/null 2> /dev/null service_start fi else # Server is not running start the server. if [ -x $STEAM/$DAEMON ]; then echo "Starting $TITLE - $LONGNAME - $CLIENT" echo "Server IP: $IP" echo "Server port: $PORT" echo "Server size: $SIZE players" cd $STEAM $INTERFACE $STEAM/$DAEMON $OPTS # Prevent race condition on SMP kernels sleep 1 # Find and write current process id of the screen process ps -ef | grep SCREEN | grep "$NAME" | grep -v grep | awk '{ print $2}' > $STEAM/$GAME/$NAME-screen.pid echo "$TITLE screen process ID written to $STEAM/$GAME/$NAME-screen.pid" echo "$TITLE server process ID written to $STEAM/$GAME/$NAME.pid" echo "$TITLE started." # Was having problems with directory permisions due to ftp access making these files unreadable by users other than owner. chmod 666 $STEAM/$GAME/*.pid 1> /dev/null 2> /dev/null # Make any pid files created by different users owned by the set user. chown $USER $STEAM/$GAME/*.pid 1> /dev/null 2> /dev/null sleep 2 if [ $HIGHPRIORITY = 1 ]; then renice -20 `cat $STEAM/$GAME/$NAME.pid` >/dev/null 2>&1 fi fi fi } service_stop() { if [ -f $STEAM/$GAME/$NAME.pid ] || [ -f $STEAM/$GAME/$NAME-screen.pid ]; then echo "Stopping $TITLE - $LONGNAME." # Get the process ID from the pid file we created earlier for id in `cat $STEAM/$GAME/$NAME-screen.pid` do kill -9 $id echo "Killing process ID $id" echo "Removing $TITLE screen pid file" rm -rf $STEAM/$GAME/$NAME-screen.pid break done # Remove server pid file echo "Removing $TITLE pid file" rm -rf $STEAM/$GAME/$NAME.pid # Wipe all old screen sessions screen -wipe 1> /dev/null 2> /dev/null echo "$TITLE stopped." else echo -e "Cannot stop $TITLE. Server is not running." #exit 1 fi } service_clear() { # Removing all pid files echo "Removing all Service pid files." rm -rf $STEAM/$GAME/*.pid 1> /dev/null 2> /dev/null } service_update() { echo "Stopping and Clearing all Service files." service_stop sleep 2 service_clear sleep 2 echo "Updating Steam Updater" cd $UPDATER ./steam 1> /dev/null 2> /dev/null echo "Updating Game Files" ./steam -command update -game $GAME -dir . 1> /dev/null 2> /dev/null sleep 2 service_start } case "$1" in 'start') service_start ;; 'stop') service_stop ;; 'restart') service_stop sleep 1 service_start ;; 'clear') service_clear ;; 'update') service_update ;; *) echo "Usage $0 start|stop|restart|clear|update" esacCode:Ok for all you guys out there I have a start.sh and stop.sh for my CSS server. Makes things a whole lot easier. Start.sh: #!/bin/sh ./srcds_run -game cstrike +map de_prodigy +maxplayers MAX_PLAYERS +ip SERVER_IP -autoupdate & You need to change SERVER_IP and MAX_PLAYERS to the settings you want for your server, Stop.sh: #!/bin/sh kill `ps xww | grep "srcds" | cut -c1-5` 2>/dev/null ps xww | grep "srcds" | cut -c1-5 | xargs kill 2>/dev/null Simply copy and past these commands in two text files then rename them to start.sh and stop.sh. When logged in via SSH to your server run the scripts like this: ./start.sh - to start the server ./stop.sh - to stop the server These files must be saved in the same dir as srcds_run
Code:Use this script to run srcds as a deamon via 'screen': (apt-get update && apt-get install screen if you don't already have it) Put this in a file in the /etc/init.d folder #! /bin/sh # # Start the Counter-Strike Source dedicated server as non-root. # # A modification of the CS Server startup script, to run the server # as a non-root user. # # ORIGINAL AUTHORS : # # Julien Escario ( pandemik@asylog.net ) # & # Cedric Rochat ( crochat@younics.org ) # # =========================================== # # What you need: # # Linux :) # awk # screen # srcds & cstrike-files OR # # YES, this script works fine with fine with CS 1.6 # # How to use: # # Edit the DIR-var to fit your system (just contains the path to the dir that contains hlds_run) # Edit the PARAMS-var to fit your needs # Edit the CS_USER-var to the name of the user that will run the server # # How to see the server-console: # # Just type in: screen -r srcds (or whatever you set $NAME to) # More info about screen can be found by typing "man screen" or using this nice link # http://server.counter-strike.net/server.php?cmd=howto&show=screen # # The easist way is to use this script simple as a start-script for your server # If you want to use it as a script to start the server at boot-time: # # When this is done, copy the file to /etc/rc.d/init.d (or whereever your system stores the # scripts for starting the services # Now you can link the script to your runlevel-dir, here's an example for runlevel 3: # (THIS IS FOR DEBIAN! If you use e.g. Redhat you must change these dirs!!!) # # ln -s /etc/init.d/hlds /etc/rc3.d/S90hlds # ln -s /etc/init.d/hlds /etc/rc6.d/K50hlds # # Or use it manualy like: # /etc/rc.d/init.d/hlds start # /etc/rc.d/init.d/hlds stop # # If you don't want to start the server as root you have to change this: # add the var CS_USER and uncomment it # change the lines at the "start-block" # # You must be logged in as this user to re-attach the screen! # # DOC by jwm (jwm@counter-strike.de) # The user that will run the server CS_USER=source # Leave this alone. NAME=css PATH=/bin:/usr/bin:/sbin:/usr/sbin # DON'T FORGET TO CHANGE THE PATH TO YOUR NEEDS! DIR=/games/steam/source # Leave this alone. DAEMON=srcds_run # Internet-server: PARAMS="-game cstrike +map playground_x_s +maxplayers 16 +ip 12.170.232.150 -port 27015 -steamuser <user> -steampass <pass> -autoupdate" # Leave this alone. DESC="Counter-Strike Source Dedicated Server" case "$1" in start) if [[ `su $CS_USER -c "screen -ls |grep $NAME"` ]] then echo "$DESC is already running" else echo "Starting $DESC: $NAME" su $CS_USER -c "cd $DIR; screen -m -d -S css ./$DAEMON $PARAMS" fi ;; stop) if [[ `su $CS_USER -c "screen -ls |grep $NAME"` ]] then echo -n "Stopping $DESC: $NAME" kill `ps aux | grep -v grep | grep -i $CS_USER | grep -i screen | grep -i $NAME | awk '{print $2}'` echo " ... done." else echo "Coulnd't find a running $DESC" fi ;; restart) if [[ `su $CS_USER -c "screen -ls |grep $NAME"` ]] then echo -n "Stopping $DESC: $NAME" kill `ps aux | grep -v grep | grep -i $CS_USER | grep -i screen | grep -i $NAME | awk '{print $2}'` echo " ... done." else echo "Coulnd't find a running $DESC" fi echo -n "Starting $DESC: $NAME" su $CS_USER -c "cd $DIR; screen -m -d -S css ./$DAEMON $PARAMS" echo " ... done." ;; status) ps aux | grep -v grep | grep srcds_r > /dev/null CHECK=$? [ $CHECK -eq 0 ] && echo "$DESC is UP" || echo "$DESC is DOWN" ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 1 ;; esac exit 0 This script assumes you have a user 'source' on your machine but you can change it to whatever you want. For each server just changed the 'PARAMS' argument to match your configuration and change the 'screen' name. When you use screen you can disconnect from the machine and come back later. In the example above you would do:screen -r cssto access this program, and Ctrl+A Ctrl+D to retrun to the shell. I run two servers as well so I have two similar versions of the script in /etc/init.d. The last part is getting it to run on startup. As in the comments above, you need to make static links to these scripts from the appropriate startup folders. Assuming you have two scripts /etc/init.d/css1 & css2:ln -s /etc/init.d/css1 /etc/rc2.d/S90css1 ln -s /etc/init.d/css1 /etc/rc6.d/K90css1 ln -s /etc/init.d/css2 /etc/rc2.d/S90css2 ln -s /etc/init.d/css2 /etc/rc6.d/K90css2 S and K refer to start and kill. since your default run level on a debian server is 2, hence all the scripts in rc2.d will be run at startup. run level 6 is the reboot runlevel, so then the serer is rebooting, the servers are killed. You can therefor restart your server by:/etc/init.d/css1 restartmore to comeCode:#!/bin/sh dir="/home/user/office/cstrike" sreen="home/user/screen" # change this to how you normally run your srcds: srcdexe="$sreen -A -m -d -S office-server taskset 0x4 ./srcds_run -console -game cstrike +map cs_office_unlimited_fixed +mp_dynamicpricing 0 +fps_max 0 -tickrate 66 +ip xxx.xxx.xxx.xxx -port 27015 +maxplayers 50 -binary ./srcds_i486 -pidfile office.pid" # I wouldn't touch this if I were you. srcdname="office.pid" ########## you probably don't need to change anything below here ########## cd $dir if test -r $srcdname; then # there is a pid file -- is it current? srcdpid=`cat $srcdname` if `kill -CHLD $srcdpid >/dev/null 2>&1`; then # it's still going # back out quietly exit 0 fi echo "Source Dedicated Server Crontab notice:" echo "" echo "Stale $srcdname file (erasing it)" rm -f $srcdname fi echo "" echo "Couldn't find the srcds running. Reloading it..." echo "" cd .. /$srcdexe
---------------------------------------------------------------------------------------------------------------------
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
Now you should see the following directories:Code:./steam -command update -game "cstrike" -dir .
/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:
You will see the server console, so just type 'quit' to stop the server.Code:cd /home/zerosin/server/ ./srcds_run -console -game cstrike -port 27015 +ip 123.123.123.123 +map de_dust +maxplayers 14
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:
Code:Code:DSPATH='/home/zerosin/server' DSUSER='zerosin' DSIP='whatever ip your server has'and in startscript:
Then execute 'chmod +x starscript' to make the script executable.Code:cd /home/zerosin/server (changed from cd /css/1)
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:
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.Code:cd /bin sudo ln -s /home/zerosin/server/startscript server1
You can stop the server with
And to open the server consoleCode:server1 stop
(to close the console without killing the server, use the key combination CTRL+A CTRL+D)Code:server1 watch
If you install a TF2 server in the same directory:
Also the server executable resides in /home/zerosin/server/orangebox/tf. If you want to use the script for TF2, do the following:Code: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
And change those values in startscript.conf:Code:cd /home/zerosin/server cp startscript startscript2 cp startscript.conf startscript2.conf
Code:
(those rates are default for TF2, no need put something else here)And change the '. ./startscript.conf' into '. ./startscript2.conf' in your startscript2 file.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'
Now use serverscript2 to start/stop your TF2 server. And create a link
for simply calling 'server2 start', etc.Code:sudo ln -s /home/zerosin/server/startscript2 /bin/server2
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:
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.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"
Here is my startscript
Code:
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.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
For that script to work, you need the following directory structure:
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.Code:/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/...
Now have fun using the following commands:
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:runserver1 start runserver1 rcon mp_timelimit 30 runserver1 update runserver1 edit cfg
Code:
Change the list of $SERVERs accordingly (the script could automatically retrieve that list from the set of .conf-files, but well).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
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 siosios; 03-15-2009 at 07:34 PM. Reason: Automerged Doublepost
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks