Linux KF Dedicated Server Tutorial

  • Please make sure you are familiar with the forum rules. You can find them here: https://forums.tripwireinteractive.com/index.php?threads/forum-rules.2334636/

DeeZNutZ

FNG / Fresh Meat
May 26, 2009
90
4
0
Pacific Beach, CA USA
On a server with 4 gig of RAM running on CentOS 5.x, mine looks like this when full:
VIRT RES SHR S %CPU %MEM TIME+ COMMAND
351m 294m 9.9m S 21 8.6 171:50.91 ucc-bin-real


Not a big resource hog at all.
 

skilari

FNG / Fresh Meat
Feb 20, 2010
1
0
0
Kangasala, Finland
An excellent guide, thank you very much for taking the time to make it.

Couple of notes, though. Firstly, a tiny typo in:

[kfserver]$ ./hldsuptatetool.bin

<insert license agreement here and say "yes">

[kfserver]$ ./steam
hldsuptatetool.bin -> hldsupdatetool.bin

And secondly:

This command is fairly obvious in what it does; it will install
Killing Floor to the current directory. You can choose another directory
for the -dir if you wish.
However, that another directory must exist prior to running the command or it will hang without an error message. (If this happens just hit CTRL-C to terminate.)

Regardless, an awesome read. :)
 

juustro

FNG / Fresh Meat
Nov 7, 2010
37
0
0
First of all i would like to thank you for your work. Your tutorial helped me a lot setting up my server. By doing this I encountered some problems and found solutions everybody is asking here in the forum.
But first this link: http://wiki.fragaholics.de/index.code/EN:Linux_Kernel_Optimization

It should help you running your linux gameserver more stable. For beginners i would not use a 1000Hz Kernel. The importand things are the realtime,the to your hardware fitted kernel, and mostly importand the rescheduler and idler scipts. If you dont want a kernel try out the scheduler and the idler. Using Source Server (CS:S DOD:S etc) it helped me a lot.

You have to use another reschulder
Code:
#!/bin/sh

PIDS=`ps ax | grep sirq-hrtimer | grep -v grep | sed -e "s/^ *//" -e "s/ .*$//"`
for p in $PIDS; do
  chrt -f -p 99 $p
done

PIDS=`ps ax | grep sirq-timer | grep -v grep | sed -e "s/^ *//" -e "s/ .*$//"`
for p in $PIDS; do
 chrt -f -p 51 $p
done

PIDS=`pidof ucc-bin-real`
for p in $PIDS; do
  chrt -f -p 98 $p
done

Im wondering what this script accually does?
 

pirinto

FNG / Fresh Meat
Aug 14, 2010
14
0
0
quick n' dirty compression script

quick n' dirty compression script

Thanks for this tutorial. Saved me a lot of time.

A tip though. If you're compressing all maps at once:

You can do (in the "system" folder):

Code:
for i in ../maps/*; do ./ucc-bin compress $i; done

And it will compress _all_ the maps. Quite handy if you got a lot of custom maps that you're going to put up for redirection.

You can also use the -nohomedir option if you don't want it to end up inte the ~/.killingfloor/maps directory

Cheers :)
 

-=HoG=-Phantom

FNG / Fresh Meat
Jan 4, 2011
2
0
0
thanks for the tutorial! I followed the instructions to create a server and ours is working and automatically updating itself with the scripts provided. Thanks to all who contributed to this!
 

Knowing

FNG / Fresh Meat
Feb 19, 2011
2
0
0
Hello and thanks for this tutorial but i have a problem..can someone tell me what is the default port..because with 7707 it's offline in gametracker..

Edit: When i start my server and i add the ip in my LGSL the server appears to be offline


Regards,
Knowing.
 
Last edited:

Teddy

FNG / Fresh Meat
Feb 16, 2010
17
2
0
Hi I have a problem and hope I can help one so I now have a server running on linux debian also hosted just fine I just have a problem with my script, I think!

script:

#!/bin/sh

DIR=/home/kfserver1/system
UPDATEDIR=/home/kfserver1
DAEMON=$DIR/ucc-bin
PARAMS="server KF-BioticsLab.rom?game=KFmod.KFGameType?VACSecured=true?MaxPlayers=6?AdminName=Teddy?AdminPassword=myPW?multihome=myIP"
PARAMS2="-nohomedir ini=KillingFloor.ini"

NAME=killingfloor
DESC="killingfloor"

case "$1" in
start)
echo "Starting $DESC: $NAME"
if [ -e $DIR ];
then
cd $DIR
screen -d -m -S $NAME $DAEMON $PARAMS $PARAMS2
else echo "No such directory: $DIR!"
fi
;;

stop)
if [[ `screen -ls |grep $NAME` ]]
then
echo -n "Stopping $DESC: $NAME"
kill `screen -ls |grep $NAME |awk -F . '{print $1}'|awk '{print $1}'`
echo " ... done."
else
echo "Coulnd't find a running $DESC"
fi
;;

restart)
if [[ `screen -ls |grep $NAME` ]]
then
echo -n "Stopping $DESC: $NAME"
kill `screen -ls |grep $NAME |awk -F . '{print $1}'|awk '{print $1}'`
echo " ... done."
else
echo "Coulnd't find a running $DESC"
fi

echo -n "Starting $DESC: $NAME"
cd $DIR
screen -d -m -S $NAME $DAEMON $PARAMS $PARAMS2
echo " ... done."
;;

status)
if [[ `screen -ls |grep $NAME` ]]
then
echo "found running prozess: $DESC: $NAME"
else
echo "no running prozess: $DESC: $NAME"
fi
;;

check)
if [[ `screen -ls |grep $NAME` ]]
then
echo "running"
else
echo -n "Starting $DESC: $NAME"
cd $DIR
screen -d -m -S $NAME $DAEMON $PARAMS $PARAMS2
echo " ... done."
fi
;;

update)
if [[ `screen -ls |grep $NAME` ]]
then
echo -n "Stopping $DESC: $NAME"
kill `screen -ls |grep $NAME |awk -F . '{print $1}'|awk '{print $1}'`
echo " ... done."
else
echo "Coulnd't find a running $DESC"
fi

echo "Updating Installation"
cd
cd $UPDATEDIR
./steam -command update -game killingfloor -verify_all

echo -n "Starting $DESC: $NAME"
cd $DIR
screen -d -m -S $NAME $DAEMON $PARAMS $PARAMS2
echo " ... done."
;;
*)
echo "Usage: $0 {start|stop|restart|update}"
exit 1
;;
esac

exit 0



Then I entered the order it restarts itself and searches for updates:

crontab -e

0-59 * * * * cd /home/kfserver1/system && ./kfstart check >/dev/null 2>&1
55 6 * * * cd /home/kfserver1/system && ./kfstart update >/dev/null 2>&1


now my problem if I'm going to screen the server 2 times and every minute there is ne new number as well as

5968.killingfloor (06/03/2011 01:24:06 PM) (Detached)
2934.killingfloor (06/03/2011 01:23:06 PM) (Detached)
7465.killingfloor (06/03/2011 01:22:06 PM) (Detached)
2845.killingfloor (06/03/2011 01:21:06 PM) (Detached)
7367.killingfloor (06/03/2011 01:20:06 PM) (Detached)


and so the whole looks after 5 minutes of me can any one help as he is only there once or is it normal if I do everything so I set hope you know what I mean and can help me thank you ever xD
 

WeskerIG

FNG / Fresh Meat
Oct 14, 2011
2
0
0
I have now installed my dedicated KF server:

I launch the server:
./ucc-bin server KF-BioticsLab.rom?game=KFmod.KFGameType?VACSecured=true?MaxPlayers=6
I want to connect with my server ingame, but the it shows me ingame: "unknown server".


In my linux client, I get following msg:

RecvFrom returned SOCKET_ERROR 113
Does anybody knows a solution?

PS: I havent changed something in my KillingFloor.ini yet!
 

HEXPECTb

FNG / Fresh Meat
Sep 1, 2011
2
0
0
Sry for my bad english.
I have a problem. My windows steamID 76561201768821654, but linux steamID 3808555926. I'm use serverperks. How can I fix it in linux server?
 

mi9

FNG / Fresh Meat
Sep 16, 2011
6
1
0
Awesome Thread, especially the scripts by Terrorkarotte where very helpful.

check)
if [[ `screen -ls |grep $NAME` ]]
then

I found this didn't work on my sys. either. Don't know the reason, different shell versions might behave differently.

Here's script i'm using:

Code:
#!/bin/sh


DIR=~/kfserver/system
FULLLOGDIR=~/.killingfloor/System/log
LOGFILENAME="server1.log"

# you need to create the folder log first!
# If you do not no log will be written !

LOG=log

DAEMON=./ucc-bin

PARAMS="server KF-BioticsLab.rom?game=KFmod.KFGameType?VACSecured=true?MaxPlayers=6?AdminName=admin?AdminPassword=password?Mutator=MutKFAntiBlocker.MutKFAntiBlocker ini=KillingFloor.ini log=$LOG/"$LOGFILENAME

SCREEN_NAME=kfserver1
DESC="killingfloor server1"


start()
{
   echo "Starting $DESC: $SCREEN_NAME"
   if [ -e $DIR ];
   then
    cd $DIR
    screen -d -m -S $SCREEN_NAME $DAEMON $PARAMS
   else echo "No such directory: $DIR!"
   fi
}
stop()
{
   PID=`ps ax | grep $SCREEN_NAME | grep SCREEN | awk '{ print $1 }'`

   if [ $PID ]
   then
       echo -n "Stopping $DESC: $SCREEN_NAME pid $PID"
       kill $PID
       echo " ... done."
   else
       echo "Coulnd't find a running $DESC"
   fi
}

case "$1" in
 start)
   start
   ;;

 stop)
   stop
   ;;

 restart)
   stop
   start
   ;;

 watchdog)
   PID=`ps ax | grep $SCREEN_NAME | grep SCREEN | awk '{ print $1 }'`
   if [ $PID ]
   then
       echo '' > /dev/null
   else
      echo $SCREEN_NAME' not found, renaming old logfile and restarting...'
      cd $FULLLOGDIR
      DS=$(date +%s) 
      NN=$LOGFILENAME'.'$DS
      mv $LOGFILENAME $NN
      gzip $NN
      start
   fi
   ;;
 
 *)
   echo "Usage: $0 {start|stop|restart|watchdog}"
   exit 1
   ;;
esac

exit 0
 

Kingbob387

FNG / Fresh Meat
Dec 20, 2011
1
0
0
Hi I just got a linux server and tried to run a KF server.


I got to this bit:
[kfserver]$ ./hldsuptatetool.bin <insert license agreement here and say "yes"> [kfserver]$ ./steam

but then this error comes up: No such files or dictionary.

But the file is clearly there when I type ls in, help!
 

mi9

FNG / Fresh Meat
Sep 16, 2011
6
1
0
If you can, please cut&paste from terminal window exactly what your typed and exact error message the system is giving.
 

OCNRyahn

FNG / Fresh Meat
Apr 17, 2010
4
0
0
NOTE!!!!
Never EVER edit default.ini!!!!!!
http://forums.tripwireinteractive.com/showthread.php?t=30640

a) Copying default.ini as KillingFloor.ini (I have not tested this method myself)
Code:
[system]$ cp default.ini KillingFloor.ini

This doesnt apply anymore to linux. I ran into a problem where I couldnt access the web panel and few other things.

Its located here ~/.killingfloor/System

Most of all the settings except the ports and advanced settings can be done in the web admin.
 

djw

FNG / Fresh Meat
Aug 14, 2011
164
12
0
Im wondering what this script accually does?

$ man chrt

NAME

chrt - manipulate real-time attributes of a process

OPTIONS

-p, --pid
operate on an existing PID and do not launch a new task

-f, --fifo
set scheduling policy to SCHED_FIFO

The script looks for two kernel processes; sirq-hrtimer, sirq-timer and changes their scheduling to use FIFO (First In First Out). It also massively increases their priority in kernel scheduling, as in how much CPU time it gets given when other processes are demanding CPU time. On my Linux box I do not have those processes, so pointless trying to change them.

The 3rd for loop looks for all ucc-bin-real processes, which is the Killing Floor game server process and also makes it use FIFO and sets a very high priority.

You need to think before using a script like this. It may be worth increasing the priority but not so aggressively. It really depends on what else is running on the server, since it may give a negative effect to other processes on the server.
 

Whoknowsit

FNG / Fresh Meat
Feb 16, 2012
1
0
0
Here's mine:

Code:
#!/bin/sh

# Product: KFServer startup script
# Author:  Sascha Greuel (softcreatr@facebook.com)
# Usage:   update-rc.d kfserver defaults

### BEGIN INIT INFO
# Provides:          kfserver
# Required-Start:    $syslog $local_fs $network $remote_fs
# Required-Stop:     $syslog $local_fs $network $remote_fs
# Should-Start:      $remote_fs $named
# Should-Stop:       $remote_fs $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Killing Floor Server Daemon
# Description:       Starts the Killing Floor Server Daemon
### END INIT INFO

############################ OPTIONS ######################################################
TITLE='KFServer Daemon'
DIR='/home/killingfloor/kfserver/system'
DAEMON='ucc-bin'
USER='root'  # SHOULD BE CHANGED
GROUP='root' # SHOULD BE CHANGED
OPT='server KF-BioticsLab.rom?game=KFmod.KFGameType?VACSecured=true?MaxPlayers=6?AdminName=ADMIN?AdminPassword=PASSWORD -nohomedir'
LOGFILE='/var/log/kfserver.log'
PIDFILE='/var/run/kfserver.pid'

SUDO='/usr/bin/sudo'
AWK='/usr/bin/awk'
############################ END OPTIONS ##################################################

########################### NO NEED TO EDIT UNDER HERE ####################################

precheck() {
# Checking for sudo
if [ ! -x $SUDO ]; then
    echo
    echo "You do not have Sudo installed. Please install it and try again."
    echo "$(date +"%a, %d %b - %H:%M:%S"): You do not have Sudo installed." >> $LOGFILE
    echo
    exit 1
fi

# Checking for awk
if [ ! -x $AWK ]; then
    echo
    echo "You do not have Awk installed. Please install it and try again."
    echo "$(date +"%a, %d %b - %H:%M:%S"): You do not have awk installed." >> $LOGFILE
    echo
    exit 1
fi

# Checking for binary
if [ ! -x $DIR/$DAEMON ]; then
    echo
    echo "Can't find $DIR/$DAEMON."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Can't find $DIR/$DAEMON." >> $LOGFILE
    echo
  exit 1
fi

# Checking for user
if [ ! $(grep $USER /etc/passwd) ]; then
    echo
    echo "User '$USER' does not exist."
    echo "$(date +"%a, %d %b - %H:%M:%S"): User '$USER' does not exist." >> $LOGFILE
    echo
  exit 1
fi

# Everything seems fine
echo
echo "Everything seems fine, try $0 start."
echo
exit 1
}

service_start() {
TEST=$(ps ax | grep $DAEMON | grep -v export | grep -v grep | wc -l)

# Server not running and no pid-file found
if [ "$TEST" = "0" ] && [ ! -f $PIDFILE ]; then
    echo
    echo "Starting $TITLE..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Starting $TITLE..." >> $LOGFILE

    cd $DIR
    su $USER -c "$DAEMON $OPT" >> $LOGFILE 2>&1 &
    sleep 1
    sudo -u $USER ps ax | grep -v grep | grep $DAEMON | grep -v export | awk '{print $1}' > $PIDFILE
    chown $USER:$GROUP $PIDFILE

    echo "$TITLE screen process ID written to $PIDFILE."
    echo "$TITLE started."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE started." >> $LOGFILE
    echo
    exit 1
fi

# Server not running and a pid-file is found
if [ "$TEST" = "0" ] && [ -f $PIDFILE ]; then
    echo
    echo "Server not running but pid-file present."
    echo "Removing pid-file..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Server not running but pid-file present." >> $LOGFILE
    echo "$(date +"%a, %d %b - %H:%M:%S"): Removing pid-file..." >> $LOGFILE

    rm $PIDFILE

    echo "Old pid file removed."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Old pid file removed." >> $LOGFILE
    echo
    echo "Starting $TITLE..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Starting $TITLE." >> $LOGFILE

    cd $DIR
    su $USER -c "$DAEMON $OPT" >> $LOGFILE 2>&1 &
    sleep 1
    sudo -u $USER ps ax | grep -v grep | grep $DAEMON | grep -v export | awk '{print $1}' > $PIDFILE
    chown $USER:$GROUP $PIDFILE

    echo "$TITLE screen process ID written to $PIDFILE."
    echo "$TITLE started."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE started." >> $LOGFILE
    echo
    exit 1
fi

# Server running and no pid file-found, creates a new one!
if [ "$TEST" = "1" ] && [ ! -f $PIDFILE ]; then
    echo
    echo "Server is running but no pid file. Creating a new pid file..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Server is running but no pid file. Creating a new pid file..." >> $LOGFILE

    sudo -u $USER ps ax | grep -v grep | grep $DAEMON | grep -v export | awk '{print $1}' > $PIDFILE
    chown $USER:$GROUP $PIDFILE

    echo
    echo "$TITLE is running and new pid-file created."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE is running and new pid-file created." >> $LOGFILE
    echo
    exit 1
fi

# Server running and pid-file found
if [ "$TEST" = "1" ] && [ -f $PIDFILE ]; then
    echo
    echo "$TITLE is already running."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE is already running." >> $LOGFILE
    echo
    exit 1
fi
}

service_stop() {
TEST1=$(ps ax | grep -v grep | grep $DAEMON | grep -v export | wc -l)

# Server is not running and no pid-file found
if [ "$TEST1" = "0" ] && [ ! -f $PIDFILE ]; then
    echo
    echo "$TITLE is not running."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE is not running." >> $LOGFILE
    echo
fi

# Server is not running and pid-file found
if [ "$TEST1" = "0" ] && [ -f $PIDFILE ]; then
    echo
    echo "Server is not running but pid-file is present."
    echo "Removing pid-file..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Server is not running but pid-file is present." >> $LOGFILE
    echo "$(date +"%a, %d %b - %H:%M:%S"): Removing pid-file..." >> $LOGFILE

    rm $PIDFILE

    echo
    echo "Pid file removed."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Pid file removed." >> $LOGFILE
    echo
fi

# Server is running but no pid-file found
if [ "$TEST1" = "1" ] && [ ! -f $PIDFILE ]; then
    echo
    echo "$TITLE is running but no pid file found."
    echo "Stopping $TITLE..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE is running but no pid file found." >> $LOGFILE
    echo "$(date +"%a, %d %b - %H:%M:%S"): Stopping $TITLE..." >> $LOGFILE

    sudo -u $USER ps ax | grep -v grep | grep $DAEMON | grep -v export | awk '{print $1}' > $PIDFILE
    chown $USER:$GROUP $PIDFILE

    for id in $(cat $PIDFILE)
        do kill -TERM $id
        echo "Killing process ID $id..."
        echo "Removing $TITLE pid file..."
        rm -rf $PIDFILE
        break
    done

    echo "$TITLE stopped."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE stopped." >> $LOGFILE
    echo
fi

# Server running and pid-file found
if [ "$TEST1" = "1" ] && [ -f $PIDFILE ]; then
    echo
    echo "Stopping $TITLE..."
    echo "$(date +"%a, %d %b - %H:%M:%S"): Stopping $TITLE..." >> $LOGFILE

    for id in $(cat $PIDFILE)
        do kill -TERM $id
        echo "Killing process ID $id..."
        echo "Removing $TITLE pid file..."
        rm -rf $PIDFILE
        break
    done

    echo "$TITLE stopped."
    echo "$(date +"%a, %d %b - %H:%M:%S"): $TITLE stopped." >> $LOGFILE
    echo
fi
}

case "$1" in
    'start')
        service_start
    ;;
    'stop')
        service_stop
    ;;
    'restart')
        service_stop
        sleep 5
        service_start
    ;;
    'precheck')
        precheck
    ;;
*)
    echo
    echo "$0 start          ## Starts the server"
    echo "$0 stop           ## Stops the server"
    echo "$0 restart        ## Restarts the server"
    echo "$0 restart        ## Restarts the server"
    echo "$0 precheck       ## Dependency check"
    echo
esac

exit 0
 

Skillz

Member
May 3, 2012
893
6
18
High Point, NC
www.skillzservers.com
Just wanted to get this added to the tutorial. (I didn't bother reading past the first post. So if it's been mentioned I apologize.)

When I got to the step to

Code:
./hldsupdatetool.bin

I got an error that said

Code:
sh: uncompress: command not found

I then ran this as the ROOT user

Code:
ln -s /usr/bin/gunzip /usr/bin/uncompress

I was then able to continue.
 

poosh

Grizzled Veteran
Jan 6, 2011
3,404
327
83
Thank you guys for all the info you've provided!

Here is mine script, which also can display server status and allows to configure the server via switches (set player count, map, ini, mutators etc.):

Spoiler!

You can download the above file from here: View attachment kfservice.zip.
Archive contains also a systemd service config, whick allows you to automatically launch a KF server on your system startup on modern Linux systems (where SysV is replaced by systemd).