#!/bin/sh
#
#       Copyright (c) 2002, Valve LLC. All rights reserved.
#

export LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH"

init() {
	GAME="valve"
	DEBUG=0
	RESTART="yes"
	HL=./hlds_linux
	HL_DETECT=1
	TIMEOUT=10
	CRASH_DEBUG_MSG="email debug.log to linux@valvesoftware.com"
	GDB="gdb"
	DEBUG_LOG="debug.log"
	PID_FILE=""
	STEAM=""
	STEAMERR=""
	SIGINT_ACTION="quit 0"
	NO_TRAP=0
	AUTO_UPDATE=""
	BETA_VERSION=""
	PARAMS=$*

	if test -n "$FORCE" ; then
		HL=$FORCE
		HL_DETECT=0
	fi

	while test $# -gt 0; do
		case "$1" in
		"-game")
			GAME="$2"
			shift ;;
		"-debug")
			DEBUG=1
			if test -z "$PID_FILE"; then
				PID_FILE="hlds.$$.pid"
			fi ;;
		"-norestart")
			RESTART="" ;;
		"-pidfile")
			PID_FILE="$2"
			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="steamcmd/steamcmd.sh"
			RESTART="yes" ;;
		"-steamerr")
			STEAMERR=1 ;;
		"-ignoresigint")
			SIGINT_ACTION="" ;;
		"-notrap")
			NO_TRAP=1 ;;
		"-beta")
			BETA_VERSION="$2"
			shift ;;
		"-help")
			quit 2
			;;
		esac
		shift
	done

	if test -z "$GAME"; then
		echo "Unable to determine game type from command line."
		quit 1
	elif test ! -d "$GAME"; then
		echo "Invalid game type '$GAME' sepecified."
		quit 1
	fi

	if test ! -f "$HL"; then
		echo "Half-life binary '$HL' not found, exiting"
		quit 1
	elif test ! -x "$HL"; then
		echo "Half-life binary '$HL' not executable, exiting"
		quit 1
	fi

	if test "$DEBUG" -eq 1; then
		echo "Enabling debug mode"
		if 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=0
		fi
	fi

	PID_IN_PARAMS="`echo $PARAMS | grep -e -pidfile`"

	if test -z "$PID_IN_PARAMS" && test -n "$PID_FILE"; then
		HL_CMD="$HL $PARAMS -pidfile $PID_FILE"
	else
		HL_CMD="$HL $PARAMS"
	fi
}

syntax () {
	echo "Syntax:"
	echo "$0 [-game <game>] [-debug] [-norestart] [-pidfile]"
	echo "	[-binary [hlds_linux]"
	echo "	[-timeout <number>] [-gdb <gdb>] [-autoupdate]"
	echo "	[-steamerr] [-ignoresigint] [-beta <version>]"
	echo "  [-debuglog <logname>]"
}

debugcore () {
	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;
			echo "----------------------------------------------" >> $DEBUG_LOG
			echo "CRASH: `date`" >> $DEBUG_LOG
			echo "Start Line: $HL_CMD" >> $DEBUG_LOG
			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 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
}

update() {
	updatesingle
}

updatesingle() {
	if test -n "$AUTO_UPDATE"; then
		if test -f "$STEAM"; then
			echo "Updating server using Steam."
			CMD="$STEAM +logon anonymous +force_install_dir .. +app_update 90 +quit"; 
			if test -n "$BETA_VERSION"; then
			  CMD="$CMD -beta $BETA_VERSION";
			fi
			STEAMEXE=steamcmd $CMD
			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() {
	if test -n "$RESTART" ; then
		echo "Auto-restarting the server on crash"
		while true
		do
			update
			$HL_CMD
			retval=$?
			if test $retval -eq 0; then
				break;
			fi
			debugcore $retval
			echo "`date`: Server restart in $TIMEOUT seconds"
			sleep $TIMEOUT
		done
	else
		update
		if test "$DEBUG" -eq 0; then
			exec $HL_CMD
		else
			$HL_CMD
			debugcore $?
		fi
	fi
}

quit() {
	exitcode="$1"
	if test -z "$exitcode"; then
		exitcode=1
	fi
	case "$exitcode" in
	0)
		echo "`date`: Server Quit" ;;
	2)
		syntax ;;
	*)
		echo "`date`: Server Failed" ;;
	esac
	if test -n "$PID_FILE" && test -f "$PID_FILE" ; then
		rm -f $PID_FILE
	fi
	trap - 2
	kill -2 $$
}

init $*
run
quit 0