Răsfoiți Sursa

moved functions to lgsm dir

Daniel Gibbs 10 ani în urmă
părinte
comite
841a65b2f7
69 a modificat fișierele cu 6202 adăugiri și 0 ștergeri
  1. 1 0
      JustCause2/jc2server
  2. 0 0
      lgsm/functions/README.md
  3. 67 0
      lgsm/functions/check.sh
  4. 17 0
      lgsm/functions/check_config.sh
  5. 218 0
      lgsm/functions/check_deps.sh
  6. 33 0
      lgsm/functions/check_ip.sh
  7. 16 0
      lgsm/functions/check_logs.sh
  8. 13 0
      lgsm/functions/check_root.sh
  9. 73 0
      lgsm/functions/check_steamcmd.sh
  10. 13 0
      lgsm/functions/check_system_dir.sh
  11. 20 0
      lgsm/functions/check_tmux.sh
  12. 64 0
      lgsm/functions/command_backup.sh
  13. 48 0
      lgsm/functions/command_console.sh
  14. 59 0
      lgsm/functions/command_debug.sh
  15. 682 0
      lgsm/functions/command_details.sh
  16. 17 0
      lgsm/functions/command_dev_debug.sh
  17. 0 0
      lgsm/functions/command_dev_detect_deps.sh
  18. 22 0
      lgsm/functions/command_email_test.sh
  19. 0 0
      lgsm/functions/command_fastdl.sh
  20. 38 0
      lgsm/functions/command_install.sh
  21. 110 0
      lgsm/functions/command_monitor.sh
  22. 182 0
      lgsm/functions/command_start.sh
  23. 217 0
      lgsm/functions/command_stop.sh
  24. 62 0
      lgsm/functions/command_ts3_server_pass.sh
  25. 0 0
      lgsm/functions/command_update.sh
  26. 37 0
      lgsm/functions/command_update_functions.sh
  27. 47 0
      lgsm/functions/command_validate.sh
  28. 0 0
      lgsm/functions/compress_unreal2_maps.sh
  29. 0 0
      lgsm/functions/compress_ut99_maps.sh
  30. 202 0
      lgsm/functions/core_dl.sh
  31. 454 0
      lgsm/functions/core_functions.sh
  32. 441 0
      lgsm/functions/core_getopt.sh
  33. 204 0
      lgsm/functions/core_messages.sh
  34. 68 0
      lgsm/functions/email.sh
  35. 75 0
      lgsm/functions/fix.sh
  36. 13 0
      lgsm/functions/fix_arma3.sh
  37. 43 0
      lgsm/functions/fix_csgo.sh
  38. 16 0
      lgsm/functions/fix_dst.sh
  39. 0 0
      lgsm/functions/fix_ins.sh
  40. 0 0
      lgsm/functions/fix_kf.sh
  41. 27 0
      lgsm/functions/fix_ro.sh
  42. 41 0
      lgsm/functions/fix_steamcmd.sh
  43. 27 0
      lgsm/functions/fix_ut2k4.sh
  44. 25 0
      lgsm/functions/fix_ut99.sh
  45. 0 0
      lgsm/functions/fn_functions
  46. 0 0
      lgsm/functions/fn_getopt
  47. 22 0
      lgsm/functions/fn_update_functions
  48. 125 0
      lgsm/functions/gsquery.py
  49. 868 0
      lgsm/functions/info_config.sh
  50. 0 0
      lgsm/functions/info_distro.sh
  51. 71 0
      lgsm/functions/info_glibc.sh
  52. 0 0
      lgsm/functions/info_ts3status.sh
  53. 21 0
      lgsm/functions/install_complete.sh
  54. 349 0
      lgsm/functions/install_config.sh
  55. 37 0
      lgsm/functions/install_gslt.sh
  56. 0 0
      lgsm/functions/install_gsquery.sh
  57. 16 0
      lgsm/functions/install_header.sh
  58. 43 0
      lgsm/functions/install_logs.sh
  59. 16 0
      lgsm/functions/install_retry.sh
  60. 32 0
      lgsm/functions/install_server_dir.sh
  61. 110 0
      lgsm/functions/install_server_files.sh
  62. 15 0
      lgsm/functions/install_steamcmd.sh
  63. 82 0
      lgsm/functions/install_ts3.sh
  64. 71 0
      lgsm/functions/install_ts3db.sh
  65. 28 0
      lgsm/functions/install_ut2k4_key.sh
  66. 102 0
      lgsm/functions/logs.sh
  67. 93 0
      lgsm/functions/monitor_gsquery.sh
  68. 326 0
      lgsm/functions/update_check.sh
  69. 83 0
      lgsm/functions/update_dl.sh

+ 1 - 0
JustCause2/jc2server

@@ -52,6 +52,7 @@ selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
 lockselfname=".${servicename}.lock"
 lockselfname=".${servicename}.lock"
 lgsmdir="${rootdir}/lgsm"
 lgsmdir="${rootdir}/lgsm"
 functionsdir="${lgsmdir}/functions"
 functionsdir="${lgsmdir}/functions"
+libdir="${lgsmdir}/lib"
 filesdir="${rootdir}/serverfiles"
 filesdir="${rootdir}/serverfiles"
 systemdir="${filesdir}"
 systemdir="${filesdir}"
 executabledir="${filesdir}"
 executabledir="${filesdir}"

+ 0 - 0
functions/README.md → lgsm/functions/README.md


+ 67 - 0
lgsm/functions/check.sh

@@ -0,0 +1,67 @@
+#!/bin/bash
+# LGSM fn_check function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="060316"
+
+# Description: Overall function for managing checks.
+# Runs checks that will either halt on or fix an issue.
+
+# Every command that requires checks just references check.sh
+# check.sh selects which checks to run by using arrays
+
+check_root.sh
+
+if [ "${function_selfname}" != "command_install.sh" ] && [ "${function_selfname}" != "command_update_functions.sh" ]; then
+	check_system_dir.sh
+fi
+
+local allowed_commands_array=( command_backup.sh command_console.sh command_debug.sh command_details.sh command_unreal2_maps.sh command_ut99_maps.sh command_monitor.sh command_start.sh command_stop.sh update_check.sh command_validate.sh command_update_functions.sh command_email_test.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		check_logs.sh
+	fi
+done
+
+local allowed_commands_array=( command_debug.sh command_start.sh command_stop.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		check_deps.sh
+	fi
+done
+
+local allowed_commands_array=( command_debug.sh command_details.sh command_monitor.sh command_start.sh command_stop.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		check_ip.sh
+	fi
+done
+
+local allowed_commands_array=( update_check.sh command_debug.sh command_start.sh command_validate.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		if [ -n "${appid}" ]; then
+			check_steamcmd.sh
+		fi
+	fi
+done
+
+local allowed_commands_array=( command_console.sh command_start.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		check_tmux.sh
+	fi
+done
+
+local allowed_commands_array=( command_console.sh command_debug.sh command_details.sh command_monitor.sh command_start.sh command_stop.sh )
+for allowed_command in "${allowed_commands_array[@]}"
+do
+	if [ "${allowed_command}" == "${function_selfname}" ]; then
+		check_config.sh
+	fi
+done

+ 17 - 0
lgsm/functions/check_config.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+# LGSM check_config.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="060116"
+
+# Description: If server config missing warn user.
+
+if [ ! -e "${servercfgfullpath}" ]; then
+	if [ "${gamename}" != "Hurtworld" ]; then
+		fn_print_warn_nl "Config file missing!"
+		echo "${servercfgfullpath}"
+		fn_scriptlog "Configuration file missing!"
+		fn_scriptlog "${servercfgfullpath}"
+		sleep 2
+	fi
+fi

+ 218 - 0
lgsm/functions/check_deps.sh

@@ -0,0 +1,218 @@
+#!/bin/bash
+# LGSM check_deps.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="060316"
+
+# Description: Checks that the requires dependencies are installed for LGSM.
+
+
+fn_deps_detector(){
+	# Checks if dependency is missing
+	if [ -n "$(command -v dpkg-query)" ]; then
+		dpkg-query -W -f='${Status}' ${deptocheck} 2>/dev/null| grep -q -P '^install ok installed$'
+		depstatus=$?
+	elif [ -n "$(command -v yum)" ]; then
+		yum -q list installed ${deptocheck} > /dev/null 2>&1
+		depstatus=$?
+	fi	
+	if [ "${depstatus}" == "0" ]; then
+		missingdep=0
+		if [ "${function_selfname}" == "command_install.sh" ]; then
+			echo -e "\e[0;32m${deptocheck}\e[0m"
+			sleep 0.5
+		fi
+	else
+		# if missing dependency is found
+		missingdep=1
+		if [ "${function_selfname}" == "command_install.sh" ]; then
+			echo -e "\e[0;31m${deptocheck}\e[0m"
+			sleep 0.5
+		fi	
+	fi
+
+	# Missing dependencies are added to array_deps_missing
+	if [ "${missingdep}" == "1" ]; then
+		array_deps_missing+=("${deptocheck}")
+	fi
+}
+
+fn_deps_email(){
+	# Adds postfix to required dependencies if email notification is enabled
+	if [ "${emailnotification}" == "on" ]; then
+		if [ -f /usr/bin/mailx ]; then
+			if [ -d /etc/exim4 ]; then
+				array_deps_required+=( exim4 )
+			elif [ -d /etc/sendmail ]; then
+				array_deps_required+=( sendmail )
+			elif [ -n "$(command -v dpkg-query)" ]; then
+				array_deps_required+=( mailutils postfix )
+			elif [ -n "$(command -v yum)" ]; then
+				array_deps_required+=( mailx postfix )
+			fi	
+		else 
+			if [ -n "$(command -v dpkg-query)" ]; then
+				array_deps_required+=( mailutils postfix )
+			elif [ -n "$(command -v yum)" ]; then
+				array_deps_required+=( mailx postfix )
+			fi
+		fi
+	fi
+}
+
+fn_found_missing_deps(){
+	if [ "${#array_deps_missing[@]}" != "0" ]; then
+		fn_print_dots "Checking dependencies"
+		sleep 2
+		fn_print_warn "Checking dependencies: missing: \e[0;31m${array_deps_missing[@]}\e[0m"
+		fn_scriptlog "Checking dependencies: missing: \e[0;31m${array_deps_missing[@]}\e[0m"
+		sleep 1
+		echo -e ""
+		sudo -n true > /dev/null 2>&1
+		if [ $? -eq 0 ]; then
+			fn_print_info_nl "Attempting to install missing dependencies automatically"
+			echo -en ".\r"
+			sleep 1
+			echo -en "..\r"
+			sleep 1
+			echo -en "...\r"
+			sleep 1
+			echo -en "   \r"	
+			if [ -n "$(command -v dpkg-query)" ]; then
+				echo "sudo dpkg --add-architecture i386; sudo apt-get install ${array_deps_missing[@]}"
+			elif [ -n "$(command -v yum)" ]; then
+				echo "yum install ${array_deps_missing[@]}"
+			fi	
+		else
+			echo ""
+			fn_print_infomation_nl "$(whoami) does not have sudo access. Please manually install dependencies"
+			fn_scriptlog "$(whoami) does not have sudo access. Please manually install dependencies"
+			echo ""
+			if [ -n "$(command -v dpkg-query)" ]; then
+				echo "sudo dpkg --add-architecture i386; sudo apt-get install ${array_deps_missing[@]}"
+			elif [ -n "$(command -v yum)" ]; then
+				echo "yum install ${array_deps_missing[@]}"
+			fi	
+			echo ""
+		fi
+		if [ "${function_selfname}" == "command_install.sh" ]; then
+			sleep 5
+		fi
+	fi	
+}
+
+fn_check_loop(){
+	# Loop though required depenencies
+	for deptocheck in "${array_deps_required[@]}"
+	do
+		fn_deps_detector
+	done
+
+	# user to be informaed of any missing dependecies 
+	fn_found_missing_deps
+}
+
+if [ "${function_selfname}" == "command_install.sh" ]; then
+	echo ""
+	echo "Checking Dependecies"
+	echo "================================="
+fi
+
+
+# Check will only run if using apt-get or yum
+if [ -n "$(command -v dpkg-query)" ]; then
+	# Generate array of missing deps
+	array_deps_missing=()
+
+	# LGSM requirement for curl
+	array_deps_required=( curl ca-certificates )
+
+	# All servers except ts3 require tmux
+	if [ "${executable}" != "./ts3server_startscript.sh" ]; then
+		array_deps_required+=( tmux )
+	fi
+
+	# All servers except ts3 & mumble require libstdc++6, lib32gcc1
+	if [ "${executable}" != "./ts3server_startscript.sh" ]||[ "${executable}" != "./murmur.x86" ]; then
+		if [ "${arch}" == "x86_64" ]; then
+			array_deps_required+=( lib32gcc1 libstdc++6:i386 )
+		else
+			array_deps_required+=( libstdc++6:i386 )
+		fi	
+	fi
+
+	# Game Specific requirements
+
+	# Spark
+	if [ "${engine}" ==  "spark" ]; then
+		array_deps_required+=( speex:i386 libtbb2 )
+	# 7 Days to Die	
+	elif [ "${gamename}" ==  "7 Days To Die" ]; then
+		array_deps_required+=( telnet expect )
+	# No More Room in Hell	
+	elif [ "${gamename}" == "No More Room in Hell" ]; then
+		array_deps_required+=( lib32tinfo5 )
+	# Brainbread 2 and Don't Starve Together
+	elif [ "${gamename}" == "Brainbread 2" ]||[ "${gamename}" == "Don't Starve Together" ]; then
+		array_deps_required+=( libcurl4-gnutls-dev:i386 )
+	elif [ "${engine}" ==  "projectzomboid" ]; then
+		array_deps_required+=( openjdk-7-jre )
+	# Unreal engine
+	elif [ "${executable}" ==  "./ucc-bin" ]; then
+		#UT2K4
+		if [ -f "${executabledir}/ut2004-bin" ]; then
+			array_deps_required+=( libsdl1.2debian libstdc++5:i386 bzip2 )
+		#UT99
+		else
+			array_deps_required+=( libsdl1.2debian bzip2 )
+		fi	
+	fi
+	fn_deps_email
+	fn_check_loop
+
+elif [ -n "$(command -v yum)" ]; then
+	# Generate array of missing deps
+	array_deps_missing=()
+
+	# LGSM requirement for curl
+	array_deps_required=( curl )
+
+	# All servers except ts3 require tmux
+	if [ "${executable}" != "./ts3server_startscript.sh" ]; then
+		array_deps_required+=( tmux )
+	fi
+
+	# All servers excelts ts3 & mumble require glibc.i686 libstdc++.i686
+	if [ "${executable}" != "./ts3server_startscript.sh" ]||[ "${executable}" != "./murmur.x86" ]; then
+		array_deps_required+=( glibc.i686 libstdc++.i686 )
+	fi
+
+	# Game Specific requirements
+
+	# Spark
+	if [ "${engine}" ==  "spark" ]; then
+		array_deps_required+=( speex.i686 tbb.i686 )
+	# 7 Days to Die	
+	elif [ "${gamename}" ==  "7 Days To Die" ]; then
+		array_deps_required+=( telnet expect )
+	# No More Room in Hell	
+	elif [ "${gamename}" == "No More Room in Hell" ]; then
+		array_deps_required+=( ncurses-libs.i686 )
+	# Brainbread 2 and Don't Starve Together
+	elif [ "${gamename}" == "Brainbread 2" ]||[ "${gamename}" == "Don't Starve Together" ]; then
+		array_deps_required+=( libcurl.i686 )
+	elif [ "${engine}" ==  "projectzomboid" ]; then
+		array_deps_required+=( java-1.7.0-openjdk )
+	# Unreal engine
+	elif [ "${executable}" ==  "./ucc-bin" ]; then
+		#UT2K4
+		if [ -f "${executabledir}/ut2004-bin" ]; then
+			array_deps_required+=( compat-libstdc++-33.i686 SDL.i686 bzip2 )
+		#UT99
+		else
+			array_deps_required+=( SDL.i686 bzip2 )
+		fi	
+	fi
+	fn_deps_email
+	fn_check_loop
+fi

+ 33 - 0
lgsm/functions/check_ip.sh

@@ -0,0 +1,33 @@
+#!/bin/bash
+# LGSM check_ip.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Automatically identifies the server interface IP.
+# If multiple interfaces are detected the user will need to manualy set using ip="0.0.0.0".
+
+if [ "${gamename}" != "Teamspeak 3" ]; then
+	if [ ! -f "/bin/ip" ]; then
+		ipcommand="/sbin/ip"
+	else
+		ipcommand="ip"
+	fi
+	getip=$(${ipcommand} -o -4 addr|awk '{print $4}'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -v 127.0.0)
+	getipwc=$(${ipcommand} -o -4 addr|awk '{print $4}'|grep -oe '\([0-9]\{1,3\}\.\?\)\{4\}'|grep -vc 127.0.0)
+
+	if [ "${ip}" == "0.0.0.0" ]||[ "${ip}" == "" ]; then
+		if [ "${getipwc}" -ge "2" ]; then
+			fn_print_warn "Multiple active network interfaces found.\n\n"
+			echo -en "Manually specify the IP you want to use within the ${selfname} script.\n"
+			echo -en "Set ip=\"0.0.0.0\" to one of the following:\n"
+			echo -en "${getip}\n"
+			echo -en ""
+			echo -en "http://gameservermanagers.com/network-interfaces\n"
+			echo -en ""
+			exit 1
+		else
+			ip=${getip}
+		fi
+	fi
+fi

+ 16 - 0
lgsm/functions/check_logs.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+# LGSM check_logs.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Checks that log files exist on server start
+
+# Create dir's for the script and console logs
+if [ ! -d "${scriptlogdir}" ]; then
+	fn_print_dots "Checking for log files"
+	sleep 1
+	fn_print_info_nl "Checking for log files: Creating log files"
+	checklogs=1
+	install_logs.sh
+fi

+ 13 - 0
lgsm/functions/check_root.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+# LGSM check_root.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="060316"
+
+if [ $(whoami) = "root" ]; then
+	fn_print_fail_nl "Do NOT run this script as root!"
+	if [ -d "${scriptlogdir}" ]; then
+		fn_scriptlog "${selfname} attempted to run as root."
+	fi	
+	exit 1
+fi

+ 73 - 0
lgsm/functions/check_steamcmd.sh

@@ -0,0 +1,73 @@
+#!/bin/bash
+# LGSM check_steamcmd.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="160316"
+
+# Description: Checks SteamCMD is installed and correct.
+
+
+fn_install_steamcmd(){
+	if [ ! -d "${steamcmddir}" ]; then
+		mkdir -v "${steamcmddir}"
+	fi
+	fn_fetch_file "http://media.steampowered.com/client/steamcmd_linux.tar.gz" "${lgsmdir}/tmp" "steamcmd_linux.tar.gz"
+	fn_dl_extract "${lgsmdir}/tmp" "steamcmd_linux.tar.gz" "${steamcmddir}"
+	chmod +x "${steamcmddir}/steamcmd.sh"
+}
+
+
+fn_check_steamcmd_user(){
+	# Checks steamuser is setup. 
+	if [ "${steamuser}" == "username" ]; then
+		fn_print_fail_nl "Steam login not set. Update steamuser."	
+		echo "	* Change steamuser=\"username\" to a valid steam login."
+		if [ -d "${scriptlogdir}" ]; then
+			fn_scriptlog "edit ${selfname}. change steamuser=\"username\" to a valid steam login."
+			exit 1
+		fi
+	fi
+	# Anonymous user is set if steamuser is missing
+	if [ -z "${steamuser}" ]; then
+		fn_print_warn_nl "Steam login not set. Using anonymous login."
+		if [ -d "${scriptlogdir}" ]; then
+			fn_scriptlog "Steam login not set. Using anonymous login."
+		fi
+		steamuser="anonymous"
+		steampass=""
+		sleep 2
+	fi	
+}
+
+fn_check_steamcmd_sh(){
+	# Checks if SteamCMD exists when starting or updating a server.
+	# Installs if missing.
+	steamcmddir="${rootdir}/steamcmd"
+	if [ ! -f "${steamcmddir}/steamcmd.sh" ]; then
+		if [ "${function_selfname}" == "command_install.sh" ]; then
+			fn_install_steamcmd
+		else	
+			fn_print_warn_nl "SteamCMD is missing"
+			fn_scriptlog "SteamCMD is missing"
+			sleep 1
+			fn_install_steamcmd
+		fi
+	elif [ "${function_selfname}" == "command_install.sh" ]; then
+		fn_print_infomation "SteamCMD is already installed..."
+		fn_print_ok_eol_nl
+	fi
+}
+
+fn_check_steamcmd_guard(){
+	if [ "${function_selfname}" == "command_update.sh" ]||[ "${function_selfname}" == "command_validate.sh" ]; then
+		# Checks that steamcmd is working correctly and will prompt Steam Guard if required.
+		"${steamcmddir}"/steamcmd.sh +login "${steamuser}" "${steampass}" +quit
+		if [ $? -ne 0 ]; then
+			fn_print_failure_nl "Error running SteamCMD"	
+		fi		
+	fi		
+}
+
+fn_check_steamcmd_user
+fn_check_steamcmd_sh
+fn_check_steamcmd_guard

+ 13 - 0
lgsm/functions/check_system_dir.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+# LGSM check_system_dir.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+if [ ! -d "${systemdir}" ]; then
+	fn_print_fail_nl "Cannot access ${systemdir}: No such directory"
+	if [ -d "${scriptlogdir}" ]; then
+		fn_scriptlog "Cannot access ${systemdir}: No such directory."
+	fi		
+	exit 1
+fi

+ 20 - 0
lgsm/functions/check_tmux.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+# LGSM check_tmux.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Checks if tmux is installed as too many users do not RTFM or know how to use Google.
+
+if [ "$(command -v tmux)" ]||[ "$(which tmux >/dev/null 2>&1)" ]||[ -f "/usr/bin/tmux" ]||[ -f "/bin/tmux" ]; then
+	:
+else
+	fn_print_fail_nl "Tmux not installed"
+	sleep 1
+	fn_scriptlog "Tmux is not installed"
+	echo "	* Tmux is required to run this server."
+	# Suitable passive agressive message
+	echo "	* Please see the the following link."
+	echo "	* http://gameservermanagers.com/tmux-not-found"
+	exit 127
+fi

+ 64 - 0
lgsm/functions/command_backup.sh

@@ -0,0 +1,64 @@
+#!/bin/bash
+# LGSM command_backup.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Creates a .tar.gz file in the backup directory.
+
+local modulename="Backup"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+check.sh
+backupname="${servicename}-$(date '+%Y-%m-%d-%H%M%S')"
+echo ""
+echo "${gamename} Backup"
+echo "============================"
+echo ""
+echo "The following backup will be created:"
+echo ""
+echo "${backupdir}/${backupname}.tar.gz"
+echo ""
+while true; do
+	read -p "Continue? [y/N]" yn
+	case $yn in
+	[Yy]* ) break;;
+	[Nn]* ) echo Exiting; return;;
+	* ) echo "Please answer yes or no.";;
+esac
+done
+tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+if [ "${tmuxwc}" -eq 1 ]; then
+	echo ""
+	fn_print_warning_nl "${servicename} is currently running."
+	sleep 1
+	while true; do
+		read -p "Stop ${servicename} while running the backup? [y/N]" yn
+		case $yn in
+		[Yy]* ) command_stop.sh; break;;
+		[Nn]* ) break;;
+		* ) echo "Please answer yes or no.";;
+	esac
+	done
+fi
+fn_scriptlog "Started"
+echo -en "starting backup.\r"
+sleep 1
+echo -en "starting backup..\r"
+sleep 1
+echo -en "starting backup...\r"
+sleep 1
+echo -en "\n"
+cd "${rootdir}"
+if [ ! -d "${backupdir}" ]; then
+	mkdir -v "${backupdir}"
+fi
+tar -cvzf "${backupdir}/${backupname}.tar.gz" --exclude "${backupdir}" ./*
+echo ""
+echo "Backup created: ${backupdir}/${backupname}.tar.gz"
+fn_scriptlog "Created: ${backupdir}/${backupname}.tar.gz"
+sleep 1
+echo ""
+fn_print_complete_nl "Complete."
+fn_scriptlog "Complete"
+echo ""

+ 48 - 0
lgsm/functions/command_console.sh

@@ -0,0 +1,48 @@
+#!/bin/bash
+# LGSM command_console.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Gives access to the server tmux console.
+
+local modulename="Console"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+check.sh
+echo ""
+echo "${gamename} Console"
+echo "============================"
+echo ""
+echo "Press \"CTRL+b d\" to exit console."
+fn_print_warning_nl "Do NOT press CTRL+c to exit."
+echo ""
+while true; do
+	read -e -i "y" -p "Continue? [y/N]" yn
+	case $yn in
+	[Yy]* ) break;;
+	[Nn]* ) echo Exiting; return;;
+	* ) echo "Please answer yes or no.";;
+esac
+done
+fn_print_dots "Starting"
+sleep 1
+tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+if [ "${tmuxwc}" -eq 1 ]; then
+	fn_print_ok_nl "Starting"
+	fn_scriptlog "accessed"
+	sleep 1
+	tmux attach-session -t ${servicename}
+else
+	fn_print_fail_nl "Server not running"
+	fn_scriptlog "Failed to access: Server not running"
+	sleep 1
+	while true; do
+		read -p "Do you want to start the server? [y/N]" yn
+		case $yn in
+		[Yy]* ) command_start.sh; break;;
+		[Nn]* ) break;;
+		* ) echo "Please answer yes or no.";;
+	esac
+	done
+fi

+ 59 - 0
lgsm/functions/command_debug.sh

@@ -0,0 +1,59 @@
+#!/bin/bash
+# LGSM command_debug.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Runs the server without tmux. Runs direct from the terminal.
+
+local modulename="Debug"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+check.sh
+fix.sh
+info_distro.sh
+fn_parms
+echo ""
+echo "${gamename} Debug"
+echo "============================"
+echo ""
+echo -e "Distro: ${os}"
+echo -e "Arch: ${arch}"
+echo -e "Kernel: ${kernel}"
+echo -e "Hostname: $HOSTNAME"
+echo ""
+echo "Start parameters:"
+if [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then
+	echo "${executable} ${parms} -debug"
+else
+	echo "${executable} ${parms}"
+fi
+echo ""
+echo -e "Use for identifying server issues only!"
+echo -e "Press CTRL+c to drop out of debug mode."
+fn_print_warning_nl "If ${servicename} is already running it will be stopped."
+echo ""
+while true; do
+	read -e -i "y" -p "Continue? [Y/n]" yn
+	case $yn in
+	[Yy]* ) break;;
+	[Nn]* ) echo Exiting; return;;
+	* ) echo "Please answer yes or no.";;
+esac
+done
+fn_scriptlog "Starting debug"
+fn_print_info_nl "Stopping any running servers"
+fn_scriptlog "Stopping any running servers"
+sleep 1
+command_stop.sh
+fn_print_dots "Starting debug"
+sleep 1
+fn_print_ok_nl "Starting debug"
+fn_scriptlog "Started debug"
+cd "${executabledir}"
+fix.sh
+if [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then
+	${executable} ${parms} -debug
+else
+	${executable} ${parms}
+fi

+ 682 - 0
lgsm/functions/command_details.sh

@@ -0,0 +1,682 @@
+#!/bin/bash
+# LGSM command_details.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="230216"
+
+# Description: Displays server infomation.
+
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+# Standard Details
+# This applies to all engines
+
+fn_details_os(){
+echo -e ""
+echo -e "\e[93mDistro Details\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mDistro:\t\e[0m${os}"
+	echo -e "\e[34mArch:\t\e[0m${arch}"
+	echo -e "\e[34mKernel:\t\e[0m${kernel}"
+	echo -e "\e[34mHostname:\t\e[0m$HOSTNAME"
+	echo -e "\e[34mtmux:\t\e[0m${tmuxv}"
+	echo -e "\e[34mGLIBC:\t\e[0m${glibcv}"
+} | column -s $'\t' -t 
+}
+
+fn_details_performance(){
+echo -e ""
+echo -e "\e[93mPerformance\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mUptime:\t\e[0m${days}d, ${hours}h, ${minutes}m"
+	echo -e "\e[34mAvg Load:\t\e[0m${load}"
+} | column -s $'\t' -t 
+echo -e ""
+{
+	echo -e "\e[34mMem:\t\e[34mtotal\t used\t free\e[0m"
+	echo -e "\e[34mPhysical:\t\e[0m${physmemtotal}\t${physmemused}\t${physmemfree}\e[0m"
+	echo -e "\e[34mSwap:\t\e[0m${swaptotal}\t${swapused}\t${swapfree}\e[0m"
+} | column -s $'\t' -t 
+}
+
+fn_details_disk(){
+echo -e ""
+echo -e "\e[93mStorage\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mFilesystem:\t\e[0m${filesystem}"
+	echo -e "\e[34mTotal:\t\e[0m${totalspace}"
+	echo -e "\e[34mUsed:\t\e[0m${usedspace}"
+	echo -e "\e[34mAvailable:\t\e[0m${availspace}"
+	echo -e "\e[34mServerfiles:\t\e[0m${filesdirdu}"
+	if [ -d "${backupdir}" ]; then
+		echo -e "\e[34mBackups:\t\e[0m${backupdirdu}"
+	fi
+} | column -s $'\t' -t 
+}
+
+fn_details_gameserver(){
+echo -e ""
+
+## server details
+echo -e "\e[92m${gamename} Server Details\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	# server name
+	echo -e "\e[34mServer name:\t\e[0m${servername}"
+
+	# server ip
+	echo -e "\e[34mServer IP:\t\e[0m${ip}:${port}"
+
+	# rcon password
+	if [ -n "${rconpassword}" ]; then
+		echo -e "\e[34mRCON password:\t\e[0m${rconpassword}"
+	fi
+
+	# server password
+	if [ -n "${serverpassword}" ]; then
+		echo -e "\e[34mServer password:\t\e[0m${serverpassword}"
+	fi
+
+	# admin password
+	if [ -n "${adminpassword}" ]; then
+		echo -e "\e[34mAdmin password:\t\e[0m${adminpassword}"
+	fi
+
+	# slots
+	if [ -n "${slots}" ]; then
+		echo -e "\e[34mSlots:\t\e[0m${slots}"
+	fi
+
+	# game mode
+	if [ -n "${gamemode}" ]; then
+		echo -e "\e[34mGame mode:\t\e[0m${gamemode}"
+	fi
+
+	# game world
+	if [ -n "${gameworld}" ]; then
+		echo -e "\e[34mGame world:\t\e[0m${gameworld}"
+	fi
+
+	# tick rate
+	if [ -n "${tickrate}" ]; then
+		echo -e "\e[34mTick rate:\t\e[0m${tickrate}"
+	fi
+
+	# online status
+	if [ "${gamename}" == "Teamspeak 3" ]; then
+		info_ts3status.sh
+		if [ "${ts3status}" = "Server seems to have died" ]||[ "${ts3status}"	= "No server running (ts3server.pid is missing)" ]; then
+			echo -e "\e[34mStatus:\t\e[0;31mOFFLINE\e[0m"
+		else
+			echo -e "\e[34mStatus:\t\e[0;32mONLINE\e[0m"
+		fi
+	else
+		pid=$(tmux list-sessions 2>&1 | awk '{print $1}' | grep -Ec "^${servicename}:")
+		if [ "${pid}" == "0" ]; then
+			echo -e "\e[34mStatus:\t\e[0;31mOFFLINE\e[0m"
+		else
+			echo -e "\e[34mStatus:\t\e[0;32mONLINE\e[0m"
+		fi
+	fi
+
+	# teamspeak dbplugin
+	if [ -n "${dbplugin}" ]; then
+		echo -e "\e[34mdbplugin:\t\e[0m${dbplugin}"
+	fi
+} | column -s $'\t' -t 
+echo -e ""
+
+## script details
+echo -e "\e[92m${selfname} Script Details\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	# service name
+	echo -e "\e[34mService name:\t\e[0m${servicename}"
+
+	# script version
+	if [ -n "${version}" ]; then
+		echo -e "\e[34m${selfname} version:\t\e[0m${version}"
+	fi
+
+	# script user
+	echo -e "\e[34mUser:\t\e[0m$(whoami)"
+
+	# GLIBC required
+	if [ -n "${glibcrequired}" ]; then
+		if [ "$(ldd --version | sed -n '1 p' | tr -cd '[:digit:]' | tail -c 3)" -lt "$(echo "${glibcrequired}" | sed -n '1 p' | tr -cd '[:digit:]' | tail -c 3)" ]; then
+			if [ "${glibcfix}" == "yes" ]; then
+				echo -e "\e[34mGLIBC required:\t\e[0;31m${glibcrequired} \e[0m(\e[0;32mUsing GLIBC fix\e[0m)"
+			else
+				echo -e "\e[34mGLIBC required:\t\e[0;31m${glibcrequired}\e[0m(\e[0;32mGLIBC version too old\e[0m)"
+			fi
+		else
+			echo -e "\e[34mGLIBC required:\t\e[0;32m${glibcrequired}\e[0m"
+		fi
+	fi
+
+	# email notification
+	if [ -n "${emailnotification}" ]; then
+		echo -e "\e[34mEmail notification:\t\e[0m${emailnotification}"
+	fi
+
+	# update on start
+	if [ -n "${updateonstart}" ]; then
+		echo -e "\e[34mUpdate on start:\t\e[0m${updateonstart}"
+	fi
+
+	# script location
+	echo -e "\e[34mLocation:\t\e[0m${rootdir}"
+
+	# config file location
+	if [ -n "${servercfgfullpath}" ]; then
+		echo -e "\e[34mConfig file:\t\e[0m${servercfgfullpath}"
+	fi
+
+	# network config file location (ARMA 3)
+	if [ -n "${networkcfgfullpath}" ]; then
+		echo -e "\e[34mNetwork config file:\t\e[0m${networkcfgfullpath}"
+	fi
+} | column -s $'\t' -t 
+}
+
+fn_details_backup(){
+echo -e ""
+echo -e "\e[92mBackups\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+if [ ! -d "${backupdir}" ]||[ "${backupcount}" == "0" ]; then
+	echo -e "No Backups created"
+else
+	{
+		echo -e "\e[34mNo. of backups:\t\e[0m${backupcount}"
+		echo -e "\e[34mLatest backup:\e[0m"
+		echo -e "\e[34m    date:\t\e[0m${lastbackupdate}"
+		echo -e "\e[34m    file:\t\e[0m${lastbackup}"
+		echo -e "\e[34m    size:\t\e[0m${lastbackupsize}"
+	} | column -s $'\t' -t 
+fi
+}
+
+fn_details_commandlineparms(){
+echo -e ""
+echo -e "\e[92mCommand-line Parameters\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "${executable} ${parms}"
+}
+
+fn_details_statusbottom(){
+echo -e ""
+if [ "${gamename}" == "Teamspeak 3" ]; then
+	if [ "${ts3status}" = "Server seems to have died" ]||[ "${ts3status}"	= "No server running (ts3server.pid is missing)" ]; then
+        echo -e "\e[34mStatus: \e[0;31mOFFLINE\e[0m"
+	else
+		echo -e "\e[34mStatus: \e[0;32mONLINE\e[0m"
+	fi
+else
+	pid=$(tmux list-sessions 2>&1 | awk '{print $1}' | grep -Ec "^${servicename}:")
+	if [ "${pid}" == "0" ]; then
+		echo -e "\e[34mStatus: \e[0;31mOFFLINE\e[0m"
+	else
+		echo -e "\e[34mStatus: \e[0;32mONLINE\e[0m"
+	fi
+fi
+echo -e ""
+}
+
+# Engine Specific details
+
+fn_details_avalanche(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep Jcmp-Server"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+fn_details_dontstarve(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep dontstarve"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+fn_details_projectzomboid(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep java"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+
+fn_details_realvirtuality(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep arma3server"
+echo -e ""
+if [ -z "${port}" ]||[ -z "${queryport}" ]||[ -z "${masterport}" ]; then
+	echo -e "\e[0;31mERROR!\e[0m Missing/commented ports in ${servercfg}."
+	echo -e ""
+fi
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\tudp"
+	echo -e "> Steam: Query\tINBOUND\t${queryport}\tudp"
+	echo -e "> Steam: Master traffic\tINBOUND\t${masterport}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+fn_details_idtech3(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep qzeroded"
+echo -e ""
+if [ -z "${port}" ]||[ -z "${rconport}" ]||[ -z "${statsport}" ]; then
+	echo -e "\e[0;31mERROR!\e[0m Missing/commented ports in ${servercfg}."
+	echo -e ""
+fi
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\tudp"
+	echo -e "> Rcon\tINBOUND\t${rconport}\tudp"
+	echo -e "> Stats\tINBOUND\t${statsport}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+
+fn_details_seriousengine35(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep Sam3_Dedicate"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/RCON\tINBOUND\t${port}\ttcp"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+} | column -s $'\t' -t 
+
+fn_details_statusbottom
+}
+
+fn_details_source(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the command-line"
+echo -e "parameters in ${selfname}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep srcds_linux"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/RCON\tINBOUND\t${port}\ttcp/udp"
+	if [ -n "${sourcetvport}" ]; then
+	        echo -e "> SourceTV\tINBOUND\t${sourcetvport}\tudp"
+	fi
+	echo -e "< Client\tOUTBOUND\t${clientport}\tudp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_spark(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the command-line"
+echo -e "parameters in ${selfname}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep server_linux3"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/RCON\tINBOUND\t${port}\tudp"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+	echo -e "> WebAdmin\tINBOUND\t${webadminport}\ttcp"
+} | column -s $'\t' -t
+echo -e ""
+echo -e "\e[92m${servername} WebAdmin\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mWebAdmin url:\t\e[0mhttp://${ip}:${webadminport}/index.html"
+	echo -e "\e[34mWebAdmin username:\t\e[0m${webadminuser}"
+	echo -e "\e[34mWebAdmin password:\t\e[0m${webadminpass}"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_starbound(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the command-line"
+echo -e "parameters in ${selfname}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep starbound"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\ttcp"
+	echo -e "> Query\tINBOUND\t${queryport}\ttcp"
+	echo -e "> Rcon\tINBOUND\t${rconport}\ttcp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+
+}
+
+fn_details_teamspeak3(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep ts3server"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Voice\tINBOUND\t${port}\tudp"
+	echo -e "> ServerQuery\tINBOUND\t${queryport}\ttcp"
+	echo -e "> File transfer\tINBOUND\t${fileport}\ttcp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_teeworlds(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the command-line"
+echo -e "parameters in ${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep teeworlds_srv"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\ttcp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_terraria(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the command-line"
+echo -e "parameters in ${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep terraia"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game\tINBOUND\t${port}\ttcp"
+	echo -e "> Query\tINBOUND\t${queryport}\ttcp"
+	echo -e "> Rcon\tINBOUND\t${rconport}\ttcp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_sdtd(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep 7DaysToDie"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/RCON\tINBOUND\t${port}\tudp"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+	echo -e "> WebAdmin\tINBOUND\t${webadminport}\ttcp"
+	echo -e "> Telnet\tINBOUND\t${telnetport}\ttcp"
+} | column -s $'\t' -t
+echo -e ""
+echo -e "\e[92m${servername} WebAdmin\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mWebAdmin enabled:\t\e[0m${webadminenabled}"
+	echo -e "\e[34mWebAdmin url:\t\e[0mhttp://${ip}:${webadminport}"
+	echo -e "\e[34mWebAdmin password:\t\e[0m${webadminpass}"
+} | column -s $'\t' -t
+echo -e ""
+echo -e "\e[92m${servername} Telnet\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mTelnet enabled:\t\e[0m${telnetenabled}"
+	echo -e "\e[34mTelnet address:\t\e[0m${ip} ${telnetport}"
+	echo -e "\e[34mTelnet password:\t\e[0m${telnetpass}"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_hurtworld(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "hwserver script"
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep Hurtworld"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/RCON\tINBOUND\t${port}\tudp"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+
+} | column -s $'\t' -t
+echo -e ""
+
+fn_details_statusbottom
+}
+
+fn_details_rust(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "rustserver script"
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep Rust"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL"
+	echo -e "> Game/Query\tINBOUND\t${port}\tudp"
+	echo -e "> RCON\tINBOUND\t${rconport}\ttcp"
+
+} | column -s $'\t' -t
+echo -e ""
+
+fn_details_statusbottom
+}
+
+fn_details_unreal(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep ucc-bin"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL\tINI VARIABLE"
+	echo -e "> Game\tINBOUND\t${port}\tudp\tPort=${port}"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+	if [ "${engine}" == "unreal" ]; then
+		echo -e "< UdpLink Port (random)\tOUTBOUND\t${udplinkport}+\tudp"
+	fi
+	if [ "${engine}" != "unreal" ] && [ "${appid}" != "223250" ]; then
+		echo -e "> GameSpy query\tINBOUND\t${gsqueryport}\tudp\tOldQueryPortNumber=${gsqueryport}"
+	fi
+	if [ "${appid}" == "215360" ]; then
+		echo -e "< Master server\tOUTBOUND\t28852\ttcp/udp"
+	else
+		echo -e "< Master server\tOUTBOUND\t28900/28902\ttcp/udp"
+	fi
+	if [ "${appid}" ]; then
+		if [ "${appid}" == "223250" ]; then
+			echo -e "< Steam\tOUTBOUND\t20610\tudp"
+		else
+			echo -e "< Steam\tOUTBOUND\t20660\tudp"
+		fi
+	fi
+	echo -e "> WebAdmin\tINBOUND\t${webadminport}\ttcp\tListenPort=${webadminport}"
+} | column -s $'\t' -t
+echo -e ""
+echo -e "\e[92m${servername} WebAdmin\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+{
+	echo -e "\e[34mWebAdmin enabled:\t\e[0m${webadminenabled}"
+	echo -e "\e[34mWebAdmin url:\t\e[0mhttp://${ip}:${webadminport}"
+	echo -e "\e[34mWebAdmin username:\t\e[0m${webadminuser}"
+	echo -e "\e[34mWebAdmin password:\t\e[0m${webadminpass}"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+fn_details_ark(){
+echo -e ""
+echo -e "\e[92mPorts\e[0m"
+printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' =
+echo -e "Change ports by editing the parameters in"
+echo -e "${servercfgfullpath}."
+echo -e ""
+echo -e "Useful port diagnostic command:"
+echo -e "netstat -atunp | grep ShooterGame"
+echo -e ""
+{
+	echo -e "DESCRIPTION\tDIRECTION\tPORT\tPROTOCOL\tINI VARIABLE"
+	echo -e "> Game\tINBOUND\t${port}\tudp\tPort=${port}"
+	echo -e "> Query\tINBOUND\t${queryport}\tudp"
+} | column -s $'\t' -t
+
+fn_details_statusbottom
+}
+
+
+# Run checks and gathers details to display.
+check.sh 
+info_config.sh
+info_distro.sh
+info_glibc.sh
+fn_details_os
+fn_details_performance
+fn_details_disk
+fn_details_gameserver
+fn_details_backup
+# Some game servers do not have parms.
+if [ "${gamename}" != "Teamspeak 3" ]||[ "${engine}" != "avalanche" ]||[ "${engine}" != "dontstarve" ]||[ "${engine}" != "projectzomboid" ]; then
+	fn_parms
+	fn_details_commandlineparms
+fi
+
+
+# Display details depending on game or engine.
+if [ "${engine}" == "avalanche" ]; then
+	fn_details_avalanche
+elif [ "${engine}" == "dontstarve" ]; then
+		fn_details_dontstarve
+elif [ "${engine}" == "projectzomboid" ]; then
+	fn_details_projectzomboid
+elif [ "${engine}" == "idtech3" ]; then
+	fn_details_idtech3
+elif [ "${engine}" == "realvirtuality" ]; then
+	fn_details_realvirtuality
+elif [ "${engine}" == "seriousengine35" ]; then
+	fn_details_seriousengine35
+elif [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then
+	fn_details_source
+elif [ "${engine}" == "spark" ]; then
+	fn_details_spark
+elif [ "${engine}" == "starbound" ]; then
+	fn_details_starbound
+elif [ "${engine}" == "teeworlds" ]; then
+	fn_details_teeworlds
+elif [ "${engine}" == "terraria" ]; then
+	fn_details_terraria
+elif [ "${engine}" == "unreal" ]||[ "${engine}" == "unreal2" ]; then
+	fn_details_unreal
+elif [ "${gamename}" == "ARK: Survivial Evolved" ]; then
+	fn_details_ark
+elif [ "${gamename}" == "Hurtworld" ]; then
+	fn_details_hurtworld
+elif [ "${gamename}" == "7 Days To Die" ]; then
+	fn_details_sdtd
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_details_teamspeak3
+elif [ "${gamename}" == "Rust" ]; then
+	fn_details_rust
+else
+	fn_print_error_nl "Unable to detect server engine."
+fi

+ 17 - 0
lgsm/functions/command_dev_debug.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+# LGSM dev_debug.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="281215"
+
+# Description: Dev only: enables debuging log to be saved to dev-debug.log.
+
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+if [ -f ".dev-debug" ]; then
+	rm .dev-debug
+	fn_print_ok_nl "Disabled dev-debug"
+else
+	date > .dev-debug
+	fn_print_ok_nl "Enabled dev-debug"
+fi

+ 0 - 0
functions/command_dev_detect_deps.sh → lgsm/functions/command_dev_detect_deps.sh


+ 22 - 0
lgsm/functions/command_email_test.sh

@@ -0,0 +1,22 @@
+#!/bin/bash
+# LGSM command_email_test.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Sends a test email notification.
+
+local modulename="Email"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+check.sh
+info_config.sh
+if [ "${emailnotification}" = "on" ]; then
+	fn_scriptlog "Sending test notification"
+	subject="${servicename} Email Test Notification - Testing ${servername}"
+	failurereason="Testing ${servicename} email notification"
+	actiontaken="Sent test email...hello is this thing on?"
+	email.sh
+else
+	fn_print_fail_nl "Notifications not enabled"
+	fn_scriptlog "Notifications not enabled"
+fi

+ 0 - 0
functions/command_fastdl.sh → lgsm/functions/command_fastdl.sh


+ 38 - 0
lgsm/functions/command_install.sh

@@ -0,0 +1,38 @@
+#!/bin/bash
+# LGSM fn_install function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="260216"
+
+# Description: Overall function for the installer.
+
+local modulename="Install"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+check.sh
+install_header.sh
+install_server_dir.sh
+install_logs.sh
+check_deps.sh 
+# Download and install
+if [ "${gamename}" == "Unreal Tournament 2004" ]; then
+	install_server_files.sh
+	install_ut2k4_key.sh
+elif [ "${gamename}" == "Unreal Tournament 99" ]; then
+	install_server_files.sh
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+	install_ts3.sh
+elif [ -n "${appid}" ]; then
+	install_steamcmd.sh
+	install_server_files.sh
+fi
+
+# Configuration
+install_config.sh
+if [ "${gamename}" == "Counter Strike: Global Offensive" ]||[ "${gamename}" == "Team Fortress 2" ]||[ "${gamename}" == "BrainBread 2" ]; then
+	install_gslt.sh
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+	install_ts3db.sh
+fi
+fix.sh
+install_complete.sh

+ 110 - 0
lgsm/functions/command_monitor.sh

@@ -0,0 +1,110 @@
+#!/bin/bash
+# LGSM command_monitor.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Monitors server by checking for running proccesses
+# then passes to monitor_gsquery.sh.
+
+local modulename="Monitor"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+fn_monitor_check_lockfile(){
+	# Monitor does not run it lockfile is not found
+	if [ ! -f "${rootdir}/${lockselfname}" ]; then
+		fn_print_info_nl "Disabled: No lock file found"
+		fn_scriptlog "Disabled: No lock file found"
+		echo "	* To enable monitor run ./${selfname} start"
+		exit 1
+	fi
+}
+
+fn_monitor_check_update(){
+	# Monitor will not check if update is running.
+	updatecheck=$(ps -ef|grep "${selfname} update"|grep -v grep|wc -l)
+	if [ "${updatecheck}" >= "1" ]; then
+		fn_print_info_nl "SteamCMD is currently checking for updates"
+		fn_scriptlog "SteamCMD is currently checking for updates"
+		sleep 1
+		exit
+	fi
+}
+
+fn_monitor_msg_checking(){
+	fn_print_dots "Checking session: "
+	fn_print_checking_eol
+	fn_scriptlog "Checking session: CHECKING"
+	sleep 1	
+}
+
+fn_monitor_email_notification(){
+	# Email will be sent if enabled
+	if [ "${emailnotification}" = "on" ]; then
+		subject="${servicename} Monitor - Starting ${servername}"
+		failurereason="${servicename} process not running"
+		actiontaken="${servicename} has been restarted"
+		email.sh
+	fi	
+}
+
+fn_monitor_teamspeak3(){
+	info_ts3status.sh
+	if [ "${ts3status}" = "Server is running" ]; then
+		fn_print_ok "Checking session: "
+		fn_print_ok_eol_nl
+		fn_scriptlog "Checking session: OK"
+		exit
+	else
+		fn_print_fail "Checking session: ${ts3status}: "
+		fn_print_fail_eol_nl
+		fn_scriptlog "Checking session: ${ts3status}: FAIL"
+		failurereason="${ts3status}"
+		fn_monitor_email_notification
+	fi
+	fn_scriptlog "Monitor is starting ${servername}"
+	sleep 1
+	fn_restart
+}
+
+fn_monitor_tmux(){
+	# checks that tmux session is running
+	tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:")
+	if [ "${tmuxwc}" == "1" ]; then
+		fn_print_ok "Checking session: OK"
+		fn_print_ok_eol_nl
+		fn_scriptlog "Checking session: OK"
+		# runs gsquery check on game with specific engines.
+		local allowed_engines_array=( avalanche goldsource realvirtuality source spark unity3d unreal unreal2 )
+		for allowed_engine in "${allowed_engines_array[@]}"
+		do
+			if [ "${allowed_engine}" == "${function_selfname}" ]; then
+				monitor_gsquery.sh
+			fi
+		done
+		exit
+	else
+		fn_print_fail "Checking session: "
+		fn_print_fail_eol_nl
+		fn_scriptlog "Checking session: FAIL"
+		fn_monitor_email_notification
+		fn_scriptlog "Monitor is starting ${servername}"
+		sleep 1
+		command_start.sh
+	fi
+}
+
+check.sh
+logs.sh
+info_config.sh
+fn_print_dots "${servername}"
+fn_scriptlog "${servername}"
+sleep 1
+fn_monitor_check_lockfile
+fn_monitor_check_update
+fn_monitor_msg_checking
+if [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_monitor_teamspeak3
+else
+	fn_monitor_tmux
+fi

+ 182 - 0
lgsm/functions/command_start.sh

@@ -0,0 +1,182 @@
+#!/bin/bash
+# LGSM command_start.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="070116"
+
+# Description: Starts the server.
+
+local modulename="Starting"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+fn_start_teamspeak3(){
+	check.sh
+	info_ts3status.sh
+
+	if [ "${ts3status}" != "Server is running" ]; then
+		# Will check for updates is updateonstart is yes
+		if [ "${updateonstart}" == "yes" ]||[ "${updateonstart}" == "1" ]||[ "${updateonstart}" == "on" ]; then
+			update_check.sh
+		fi	
+	fi
+
+	if [ ! -e "${servercfgfullpath}" ]; then
+		fn_print_warn_nl "${servercfgfullpath} is missing"
+		fn_scriptlog "${servercfgfullpath} is missing"
+		echo  "	* Creating blank ${servercfg}"
+		fn_scriptlog "Creating blank ${servercfg}"
+		sleep 2
+		echo  "	* ${servercfg} can remain blank by default."
+		fn_scriptlog "${servercfgfullpath} can remain blank by default."
+		sleep 2
+		echo  "	* ${servercfg} is located in ${servercfgfullpath}."
+		fn_scriptlog "${servercfg} is located in ${servercfgfullpath}."
+		sleep 5
+		touch "${servercfgfullpath}"
+	fi
+
+	logs.sh
+
+	fn_print_dots "${servername}"
+	fn_scriptlog "${servername}"
+	sleep 1
+
+	if [ "${ts3status}" == "Server is running" ]; then
+		fn_print_info_nl "${servername} is already running"
+		fn_scriptlog "${servername} is already running"
+		exit
+	fi
+
+	mv "${scriptlog}" "${scriptlogdate}"
+	# Create lock file
+	date > "${rootdir}/${lockselfname}"
+	cd "${executabledir}"
+	if [ "${ts3serverpass}" == "1" ];then
+		./ts3server_startscript.sh start serveradmin_password="${newpassword}" 
+	else
+		./ts3server_startscript.sh start inifile="${servercfgfullpath}" > /dev/null 2>&1
+	fi
+	sleep 1
+	info_ts3status.sh
+	if [ "${ts3status}" = "Server seems to have died" ]||[ "${ts3status}"	= "No server running (ts3server.pid is missing)" ]; then
+		fn_print_fail_nl "Unable to start ${servername}"
+		fn_scriptlog "Unable to start ${servername}"
+		echo -e "	Check log files: ${rootdir}/log"
+		exit 1
+	else
+		fn_print_ok_nl "${servername}"
+		fn_scriptlog "Started ${servername}"
+	fi
+}
+
+fn_start_tmux(){
+check.sh
+fix.sh
+info_config.sh
+fn_parms
+logs.sh
+
+tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+# Will check for updates if updateonstart is yes
+if [ "${tmuxwc}" -eq 0 ]; then
+	if [ "${updateonstart}" == "yes" ]||[ "${updateonstart}" == "1" ]||[ "${updateonstart}" == "on" ]; then
+		update_check.sh
+	fi
+fi
+
+fn_print_dots "${servername}"
+fn_scriptlog "${servername}"
+sleep 1
+
+if [ "${tmuxwc}" -eq 0 ]; then
+	fn_scriptlog "Rotating log files"
+	if [ "${engine}" == "unreal2" ]; then
+		mv "${gamelog}" "${gamelogdate}"
+	fi
+	mv "${scriptlog}" "${scriptlogdate}"
+	mv "${consolelog}" "${consolelogdate}"
+fi
+
+if [ "${tmuxwc}" -eq 1 ]; then
+	fn_print_info_nl "${servername} is already running"
+	fn_scriptlog "${servername} is already running"
+	exit
+fi
+
+# Create lock file
+date > "${rootdir}/${lockselfname}"
+cd "${executabledir}"
+tmux new-session -d -s "${servicename}" "${executable} ${parms}" 2> "${scriptlogdir}/.${servicename}-tmux-error.tmp"
+# tmux pipe-pane not supported in tmux versions < 1.6
+if [ "$(tmux -V|sed "s/tmux //"|sed -n '1 p'|tr -cd '[:digit:]')" -lt "16" ]; then
+	echo "Console logging disabled: Tmux => 1.6 required" >> "${consolelog}"
+	echo "http://gameservermanagers.com/tmux-upgrade" >> "${consolelog}"
+	echo "Currently installed: $(tmux -V)" >> "${consolelog}"
+elif [ "$(tmux -V|sed "s/tmux //"|sed -n '1 p'|tr -cd '[:digit:]')" -eq "18" ]; then
+	echo "Console logging disabled: Bug in tmux 1.8 breaks logging" >> "${consolelog}"
+	echo "http://gameservermanagers.com/tmux-upgrade" >> "${consolelog}"
+	echo "Currently installed: $(tmux -V)" >> "${consolelog}"
+else
+	touch "${consolelog}"
+	tmux pipe-pane -o -t "${servicename}" "exec cat >> '${consolelog}'"
+fi
+sleep 1
+tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:")
+# If the server fails to start
+if [ "${tmuxwc}" -eq 0 ]; then
+	fn_print_fail_nl "Unable to start ${servername}"
+	fn_scriptlog "Unable to start ${servername}"
+	sleep 1
+	if [ -s "${scriptlogdir}/.${servicename}-tmux-error.tmp" ]; then
+		fn_print_fail_nl "Unable to start ${servername}: Tmux error:"
+		fn_scriptlog "Tmux error"
+		echo ""
+		echo "Command"
+		echo "================================="
+		echo "tmux new-session -d -s \"${servicename}\" \"${executable} ${parms}\"" | tee -a "${scriptlog}"
+		echo ""
+		echo "Error"
+		echo "================================="
+		cat "${scriptlogdir}/.${servicename}-tmux-error.tmp" | tee -a "${scriptlog}"
+
+		# Detected error http://gameservermanagers.com/issues
+		if [ $(grep -c "Operation not permitted" "${scriptlogdir}/.${servicename}-tmux-error.tmp") ]; then
+		echo ""
+		echo "Fix"
+		echo "================================="
+			if [ ! $(grep "tty:" /etc/group|grep "$(whoami)") ]; then
+				echo "$(whoami) is not part of the tty group."
+				fn_scriptlog "$(whoami) is not part of the tty group."
+				group=$(grep tty /etc/group)
+				echo ""
+				echo "	${group}"
+				fn_scriptlog "${group}"
+				echo ""
+				echo "Run the following command with root privileges."
+				echo ""
+				echo "	usermod -G tty $(whoami)"
+				echo ""
+				echo "http://gameservermanagers.com/tmux-op-perm"
+				fn_scriptlog "http://gameservermanagers.com/tmux-op-perm"
+			else
+				echo "No known fix currently. Please log an issue."
+				fn_scriptlog "No known fix currently. Please log an issue."
+				echo "http://gameservermanagers.com/issues"
+				fn_scriptlog "http://gameservermanagers.com/issues"
+			fi
+		fi
+	fi
+exit 1	
+else
+	fn_print_ok "${servername}"
+	fn_scriptlog "Started ${servername}"
+fi
+rm "${scriptlogdir}/.${servicename}-tmux-error.tmp"
+echo -en "\n"
+}
+
+if [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_start_teamspeak3
+else
+	fn_start_tmux
+fi

+ 217 - 0
lgsm/functions/command_stop.sh

@@ -0,0 +1,217 @@
+#!/bin/bash
+# LGSM command_stop.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Stops the server.
+
+local modulename="Stopping"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+# Attempts Graceful of source using rcon 'quit' command.
+fn_stop_graceful_source(){
+	fn_print_dots "Graceful: rcon quit"
+	fn_scriptlog "Graceful: rcon quit"
+	# sends quit
+	tmux send -t "${servicename}" quit ENTER > /dev/null 2>&1
+	# waits up to 30 seconds giving the server time to shutdown gracefuly
+	for seconds in {1..30}; do
+		pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:")
+		if [ "${pid}" == "0" ]; then
+			fn_print_ok "Graceful: rcon quit: ${seconds}: "
+			fn_print_ok_eol_nl
+			fn_scriptlog "Graceful: rcon quit: OK: ${seconds} seconds"
+			break
+		fi
+		sleep 1
+		fn_print_dots "Graceful: rcon quit: ${seconds}"
+	done
+	if [ "${pid}" != "0" ]; then
+		fn_print_fail "Graceful: rcon quit"
+		fn_print_fail_eol_nl
+		fn_scriptlog "Graceful: rcon quit: FAIL"
+		fn_stop_tmux
+	fi
+	sleep 1
+}
+
+# Attempts Graceful of goldsource using rcon 'quit' command.
+# Goldsource 'quit' command restarts rather than shutsdown
+# this function will only wait 3 seconds then force a tmux shutdown.
+# preventing the server from coming back online.
+fn_stop_graceful_goldsource(){
+	fn_print_dots "Graceful: rcon quit"
+	fn_scriptlog "Graceful: rcon quit"
+	# sends quit
+	tmux send -t "${servicename}" quit ENTER > /dev/null 2>&1
+	# waits 3 seconds as goldsource servers restart with the quit command
+	for seconds in {1..3}; do
+		sleep 1
+		fn_print_dots "Graceful: rcon quit: ${seconds}"
+	done
+	fn_print_ok "Graceful: rcon quit: ${seconds}: "
+	fn_print_ok_eol_nl
+	fn_scriptlog "Graceful: rcon quit: OK: ${seconds} seconds"
+	sleep 1
+	fn_stop_tmux
+}
+
+# Attempts Graceful of 7 Days To Die using telnet.
+fn_stop_telnet_sdtd(){
+	sdtd_telnet_shutdown=$( expect -c '
+	proc abort {} {
+		puts "Timeout or EOF\n"
+		exit 1
+	}
+	spawn telnet '"${telnetip}"' '"${telnetport}"'
+	expect {
+		"password:"     { send "'"${telnetpass}"'\r" }
+		default         abort
+	}
+	expect {
+		"session."  { send "shutdown\r" }
+		default         abort
+	}
+	expect { eof }
+	puts "Completed.\n"
+	')
+	
+}
+
+fn_stop_graceful_sdtd(){
+	fn_print_dots "Graceful: telnet"
+	fn_scriptlog "Graceful: telnet"
+	sleep 1
+	if [ "${telnetenabled}" == "false" ]; then
+		fn_print_info_nl "Graceful: telnet: DISABLED: Enable in ${servercfg}"
+	elif [ "$(command -v expect)" ]||[ "$(which expect >/dev/null 2>&1)" ]; then
+		# Tries to shutdown with both localhost and server IP.
+		for telnetip in 127.0.0.1 ${ip}; do
+			fn_print_dots "Graceful: telnet: ${telnetip}"
+			fn_scriptlog "Graceful: telnet: ${telnetip}"
+			sleep 1
+			fn_stop_telnet_sdtd
+			completed=$(echo -en "\n ${sdtd_telnet_shutdown}"|grep "Completed.")
+			refused=$(echo -en "\n ${sdtd_telnet_shutdown}"|grep "Timeout or EOF")
+			if [ -n "${refused}" ]; then
+				fn_print_warn "Graceful: telnet: ${telnetip}: "
+				fn_print_fail_eol_nl
+				fn_scriptlog "Graceful: telnet: ${telnetip}: FAIL"
+				sleep 1
+			elif [ -n "${completed}" ]; then
+				break
+			fi
+		done
+
+		# If telnet was successful will use telnet again to check the connection has closed
+		# This confirms that the tmux session can now be killed.
+		if [ -n "${completed}" ]; then
+			for seconds in {1..30}; do
+				fn_stop_telnet_sdtd
+				refused=$(echo -en "\n ${sdtd_telnet_shutdown}"|grep "Timeout or EOF")
+				if [ -n "${refused}" ]; then
+					fn_print_ok "Graceful: telnet: ${telnetip}: "
+					fn_print_ok_eol_nl
+					fn_scriptlog "Graceful: telnet: ${telnetip}: ${seconds} seconds"
+					break
+				fi
+				sleep 1
+				fn_print_dots "Graceful: rcon quit: ${seconds}"
+			done
+		# If telnet failed will go straight to tmux shutdown. 
+		# If cannot shutdown correctly world save may be lost
+		else
+			if [ -n "${refused}" ]; then
+				fn_print_fail "Graceful: telnet: "
+				fn_print_fail_eol_nl
+				fn_scriptlog "Graceful: telnet: ${telnetip}: FAIL"
+			else
+				fn_print_fail_nl "Graceful: telnet: Unknown error"
+				fn_scriptlog "Graceful: telnet: Unknown error"
+			fi
+			echo -en "\n" | tee -a "${scriptlog}"
+			echo -en "Telnet output:" | tee -a "${scriptlog}"
+			echo -en "\n ${sdtd_telnet_shutdown}" | tee -a "${scriptlog}"
+			echo -en "\n\n" | tee -a "${scriptlog}"
+		fi
+	else
+		fn_print_dots "Graceful: telnet: "
+		fn_scriptlog "Graceful: telnet: "
+		fn_print_fail "Graceful: telnet: expect not installed: "
+		fn_print_fail_eol_nl
+		fn_scriptlog "Graceful: telnet: expect not installed: FAIL"
+	fi
+	sleep 1
+	fn_stop_tmux
+}
+
+fn_stop_graceful_select(){
+	if [ "${gamename}" == "7 Days To Die" ]; then
+		fn_stop_graceful_sdtd
+	elif [ "${engine}" == "source" ]; then
+		fn_stop_graceful_source
+	elif [ "${engine}" == "goldsource" ]; then
+		fn_stop_graceful_goldsource
+	else
+		fn_stop_tmux
+	fi		
+}
+
+fn_stop_teamspeak3(){
+	fn_print_dots "${servername}"
+	fn_scriptlog "${servername}"
+	sleep 1
+	${filesdir}/ts3server_startscript.sh stop > /dev/null 2>&1
+	# Remove lock file
+	rm -f "${rootdir}/${lockselfname}"
+	fn_print_ok_nl "${servername}"
+	fn_scriptlog "Stopped ${servername}"
+	}
+
+	fn_stop_tmux(){
+	fn_print_dots "${servername}"
+	fn_scriptlog "tmux kill-session: ${servername}"
+	sleep 1
+	# Kill tmux session
+	tmux kill-session -t "${servicename}" > /dev/null 2>&1
+	sleep 0.5
+	pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:")
+	if [ "${pid}" == "0" ]; then
+		# Remove lock file
+		rm -f "${rootdir}/${lockselfname}"
+		fn_print_ok_nl "${servername}"
+		fn_scriptlog "Stopped ${servername}"
+	else
+		fn_print_fail_nl "Unable to stop${servername}"
+		fn_scriptlog "Unable to stop${servername}"
+	fi
+}
+
+# checks if the server is already stopped before trying to stop.
+fn_stop_pre_check(){
+	if [ "${gamename}" == "Teamspeak 3" ]; then
+		info_ts3status.sh
+		if [ "${ts3status}" = "No server running (ts3server.pid is missing)" ]; then
+			fn_print_ok_nl "${servername} is already stopped"
+			fn_scriptlog "${servername} is already stopped"
+		else
+			fn_stop_teamspeak3
+		fi      
+	else
+		pid=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -Ec "^${servicename}:")
+		if [ "${pid}" == "0" ]; then
+			fn_print_ok_nl "${servername} is already stopped"
+			fn_scriptlog "${servername} is already stopped"
+		else
+			fn_stop_graceful_select
+		fi
+	fi
+}
+
+check.sh
+info_config.sh
+fn_print_dots "${servername}"
+fn_scriptlog "${servername}"
+sleep 1
+fn_stop_pre_check

+ 62 - 0
lgsm/functions/command_ts3_server_pass.sh

@@ -0,0 +1,62 @@
+#!/bin/bash
+# LGSM command_serveradmin_password.sh function
+# Author: Daniel Gibbs
+# Contributor : UltimateByte
+# Website: http://gameservermanagers.com
+lgsm_version="080116"
+
+# Description: Changes TS3 serveradmin password
+
+local modulename="Change password"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+
+fn_serveradmin_password_prompt(){
+echo ""
+echo "${gamename} ServerAdmin Password Change"
+echo "============================"
+echo ""
+echo "Press \"CTRL+b d\" to exit console."
+fn_print_infomation_nl "You are about to change the ${gamename} ServerAdmin password."
+fn_print_warning_nl "${gamename} will restart during this process."
+echo ""
+while true; do
+	read -e -i "y" -p "Continue? [y/N]" yn
+	case $yn in
+	[Yy]* ) break;;
+	[Nn]* ) echo Exiting; return;;
+	* ) echo "Please answer yes or no.";;
+esac
+done
+fn_scriptlog "Initiating ${gamename} ServerAdmin password change"
+read -p "Enter new password : " newpassword
+}
+
+
+fn_serveradmin_password_set(){
+fn_print_info_nl "Applying new password"
+fn_scriptlog "Applying new password"
+sleep 1
+# Stop any running server
+command_stop.sh
+# Start server in "new password mode"
+ts3serverpass="1"
+fn_print_info_nl "Starting server with new password"
+command_start.sh
+# Stop server in "new password mode"
+command_stop.sh
+fn_print_ok_nl "Password applied"
+fn_scriptlog "New ServerAdmin password applied"
+sleep 1
+}
+
+# Running functions
+check.sh
+fn_serveradmin_password_prompt
+info_ts3status.sh
+if [ "${ts3status}" == "Server is running" ]; then
+	fn_serveradmin_password_set
+	command_start.sh
+else
+	fn_serveradmin_password_set
+fi

+ 0 - 0
functions/command_update.sh → lgsm/functions/command_update.sh


+ 37 - 0
lgsm/functions/command_update_functions.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+# LGSM update_functions.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+# Description: Deletes the functions dir to allow re-downloading of functions from GitHub.
+
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+check.sh
+fn_print_dots "Updating functions"
+fn_scriptlog "Updating functions"
+sleep 1
+echo -ne "\n"
+
+# Removed legecy functions dir
+if [ -d "${rootdir}/functions/" ]; then
+	rm -rfv "${rootdir}/functions/"
+	exitcode=$?
+fi
+
+if [ -n "${functionsdir}" ]; then
+	rm -rfv "${functionsdir}/"*
+	exitcode=$?
+else
+	fn_print_fail "Updating functions"
+	fn_scriptlog "Failure! Updating functions"	
+fi
+
+if [ "${exitcode}" == "0" ]; then
+	fn_print_ok "Updating functions"
+	fn_scriptlog "Success! Updating functions"
+else
+	fn_print_fail "Updating functions"
+	fn_scriptlog "Failure! Updating functions"
+fi
+echo -ne "\n"

+ 47 - 0
lgsm/functions/command_validate.sh

@@ -0,0 +1,47 @@
+#!/bin/bash
+# LGSM command_validate.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Runs a server validation.
+
+local modulename="Validate"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+fn_validation(){
+fn_print_warn_nl "Validating may overwrite some customised files."
+echo -en "https://developer.valvesoftware.com/wiki/SteamCMD#Validate"
+sleep 5
+echo -en "\n"
+fn_print_dots "Checking server files"
+sleep 1
+fn_print_ok "Checking server files"
+fn_scriptlog "Checking server files"
+sleep 1
+
+cd "${rootdir}/steamcmd"
+
+if [ $(command -v unbuffer) ]; then
+	unbuffer=unbuffer
+fi
+
+if [ "${engine}" == "goldsource" ]; then
+	${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_set_config 90 mod ${appidmod} +app_update "${appid}" +app_update "${appid}" validate +quit| tee -a "${scriptlog}"
+else
+	${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_update "${appid}" validate +quit| tee -a "${scriptlog}"
+fi
+
+fix.sh
+fn_scriptlog "Checking complete"
+}
+
+check.sh
+tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+if [ "${tmuxwc}" -eq 1 ]; then
+    command_stop.sh
+    fn_validation
+    command_start.sh
+else
+    fn_validation
+fi

+ 0 - 0
functions/compress_unreal2_maps.sh → lgsm/functions/compress_unreal2_maps.sh


+ 0 - 0
functions/compress_ut99_maps.sh → lgsm/functions/compress_ut99_maps.sh


+ 202 - 0
lgsm/functions/core_dl.sh

@@ -0,0 +1,202 @@
+#!/bin/bash
+# LGSM core_dl.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="050216"
+
+# Description: Deals with all downloads for LGSM.
+
+# fileurl: The URL of the file: http://example.com/dl/File.tar.bz2
+# filedir: location the file is to be saved: /home/server/lgsm/tmp
+# filename: name of file (this can be different from the url name): file.tar.bz2
+# executecmd: Optional, set to "executecmd" to make file executable using chmod +x
+# run: Optional, set to run to execute the file
+# force: Optional, force re-download of file even if exists
+# md5: Optional, Checks file against an md5 sum
+#
+# Downloads can be defined in code like so:
+# fn_fetch_file "${fileurl}" "${filedir}" "${filename}" "${executecmd}" "${run}" "${force}" "${md5}"
+# fn_fetch_file "http://example.com/file.tar.bz2" "/some/dir" "file.tar.bz2" "executecmd" "run" "force" "10cd7353aa9d758a075c600a6dd193fd"
+
+fn_dl_md5(){
+# Runs MD5 Check if available
+if [ "${md5}" != "0" ]&&[ "${md5}" != "nomd5" ]; then
+	echo -ne "verifying ${filename} with MD5..."
+	sleep 1
+	local md5sumcmd=$(md5sum "${filedir}/${filename}"|awk '{print $1;}')
+	if [ "${md5sumcmd}" != "${md5}" ]; then
+		fn_print_fail_eol_nl
+		echo "${filename} returned MD5 checksum: ${md5sumcmd}"
+		echo "expected MD5 checksum: ${md5}"
+		fn_scriptlog "verifying ${filename} with MD5: FAIL"
+		fn_scriptlog "${filename} returned MD5 checksum: ${md5sumcmd}"
+		fn_scriptlog "expected MD5 checksum: ${md5}"
+		exit 1	
+	else
+		fn_print_ok_eol_nl
+		fn_scriptlog "verifying ${filename} with MD5: OK"
+		fn_scriptlog "${filename} returned MD5 checksum: ${md5sumcmd}"
+		fn_scriptlog "expected MD5 checksum: ${md5}"		
+	fi
+fi	
+}
+
+# Extracts bzip2 or gzip files
+# Extracts can be defined in code like so:
+# fn_dl_extract "${filedir}" "${filename}" "${extractdir}"
+# fn_dl_extract "/home/gameserver/lgsm/tmp" "file.tar.bz2" "/home/gamserver/serverfiles"
+fn_dl_extract(){
+filedir="${1}"
+filename="${2}"
+extractdir="${3}"
+# extracts archives
+echo -ne "extracting ${filename}..."
+fn_scriptlog "extracting download"
+mime=$(file -b --mime-type "${filedir}/${filename}")
+
+if [ "${mime}" == "application/gzip" ]; then
+	tarcmd=$(tar -zxf "${filedir}/${filename}" -C "${extractdir}")
+elif [ "${mime}" == "application/x-bzip2" ]; then
+	tarcmd=$(tar -jxf "${filedir}/${filename}" -C "${extractdir}")
+fi
+local exitcode=$?
+if [ ${exitcode} -ne 0 ]; then
+	fn_print_fail_eol_nl
+	fn_scriptlog "extracting download: FAIL"
+	echo "${tarcmd}" | tee -a "${scriptlog}"
+	exit ${exitcode}
+else
+	fn_print_ok_eol_nl
+fi
+}
+
+# Trap to remove file download if canceled before completed
+fn_fetch_trap() {
+	echo ""
+	echo -ne "downloading ${filename}: "
+	fn_print_canceled_eol_nl
+	fn_scriptlog "downloading ${filename}: CANCELED"
+	sleep 1
+	rm -f "${filedir}/${filename}" | tee -a "${scriptlog}"
+	echo -ne "downloading ${filename}: "
+	fn_print_removed_eol_nl
+	fn_scriptlog "downloading ${filename}: REMOVED"
+	exit
+}
+
+fn_fetch_file(){
+fileurl="${1}"
+filedir="${2}"
+filename="${3}"
+executecmd="${4:-0}"
+run="${5:-0}"
+force="${6:-0}"
+md5="${7:-0}"
+
+# If the file is missing, then download
+if [ ! -f "${filedir}/${filename}" ]; then
+	if [ ! -d "${filedir}" ]; then
+		mkdir -p "${filedir}"
+	fi
+	
+	# Check curl exists and use available path
+	curlpaths="$(command -v curl 2>/dev/null) $(which curl >/dev/null 2>&1) /usr/bin/curl /bin/curl /usr/sbin/curl /sbin/curl)"
+	for curlcmd in ${curlpaths}
+	do
+		if [ -x "${curlcmd}" ]; then
+			break
+		fi
+	done
+	# If curl exists download file
+	if [ "$(basename ${curlcmd})" == "curl" ]; then
+		# trap to remove part downloaded files
+		trap fn_fetch_trap INT
+		# if larger file shows progress bar
+		if [ ${filename##*.} == "bz2" ]; then
+			echo -ne "downloading ${filename}..."
+			sleep 1
+			curlcmd=$(${curlcmd} --progress-bar --fail -o "${filedir}/${filename}" "${fileurl}")
+			echo -ne "downloading ${filename}..."
+		else
+			echo -ne "    fetching ${filename}...\c"
+			curlcmd=$(${curlcmd} -s --fail -o "${filedir}/${filename}" "${fileurl}" 2>&1)
+		fi
+		local exitcode=$?
+		if [ ${exitcode} -ne 0 ]; then
+			fn_print_fail_eol_nl
+			if [ -f "${scriptlog}" ]; then
+				fn_scriptlog "downloading ${filename}: FAIL"
+			fi	
+			echo "${curlcmd}" | tee -a "${scriptlog}"
+			echo -e "${fileurl}\n" | tee -a "${scriptlog}"
+			exit ${exitcode}
+		else
+			fn_print_ok_eol_nl
+			if [ -f "${scriptlog}" ]; then
+				fn_scriptlog "downloading ${filename}: OK"
+			fi	
+		fi
+		# remove trap
+		trap - INT	
+	else
+		fn_print_fail_eol_nl
+		echo "Curl is not installed!"
+		echo -e ""
+		exit 1
+	fi
+	# make file executecmd if executecmd is set
+	if [ "${executecmd}" == "executecmd" ]; then
+		chmod +x "${filedir}/${filename}"
+	fi	
+fi
+
+if [ -f "${filedir}/${filename}" ]; then
+	fn_dl_md5
+	# run file if run is set
+	if [ "${run}" == "run" ]; then
+		source "${filedir}/${filename}"
+	fi
+fi	
+}
+
+
+
+# fileurl: The directory the file is located in teh GitHub repo
+# filedir: name of file
+# filename: location file to be saved
+# executecmd: set to "executecmd" to make file executecmd
+# run: Optional, set to run to execute the file
+# force: force download of file even if exists
+# md5: Checks fail against an md5 sum
+
+
+# Fetches files from the github repo
+fn_fetch_file_github(){
+github_file_url_dir="${1}"
+github_file_url_name="${2}"
+githuburl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}"
+fileurl="${githuburl}"
+filedir="${3}"
+filename="${github_file_url_name}"
+executecmd="${4:-0}"
+run="${5:-0}"
+force="${6:-0}"
+md5="${7:-0}"
+fn_fetch_file "${fileurl}" "${filedir}" "${filename}" "${executecmd}" "${run}" "${force}" "${md5}"
+}
+
+
+# Fetches functions
+fn_fetch_function(){
+github_file_url_dir="functions" # github dir containing the file
+github_file_url_name="${functionfile}" # name of the github file
+githuburl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}"
+fileurl="${githuburl}"
+filedir="${functionsdir}"
+filename="${github_file_url_name}"
+executecmd="executecmd"
+run="run"
+force="noforce"
+md5="nomd5"
+fn_fetch_file "${fileurl}" "${filedir}" "${filename}" "${executecmd}" "${run}" "${force}" "${md5}"
+}

+ 454 - 0
lgsm/functions/core_functions.sh

@@ -0,0 +1,454 @@
+#!/bin/bash
+# LGSM core_functions.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+# Description: Defines all functions to allow download and execution of functions using fn_fetch_function.
+# This function is called first before any other function. Without this file other functions would not load.
+
+# Code/functions for legacy servers
+
+fn_functions(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fn_getopt(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+# fn_fetch_core_dl also placed here to allow legecy servers to still download core functions
+if [ -z "${lgsmdir}" ]; then
+	lgsmdir="${rootdir}/lgsm"
+	functionsdir="${lgsmdir}/functions"
+fi 
+
+fn_fetch_core_dl(){
+github_file_url_dir="functions"
+github_file_url_name="${functionfile}"
+filedir="${functionsdir}"
+filename="${github_file_url_name}"
+githuburl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}/${github_file_url_dir}/${github_file_url_name}"
+# If the file is missing, then download
+if [ ! -f "${filedir}/${filename}" ]; then
+	if [ ! -d "${filedir}" ]; then
+		mkdir -p "${filedir}"
+	fi
+	echo -e "    fetching ${filename}...\c"
+	# Check curl exists and use available path
+	curlpaths="$(command -v curl 2>/dev/null) $(which curl >/dev/null 2>&1) /usr/bin/curl /bin/curl /usr/sbin/curl /sbin/curl)"
+	for curlcmd in ${curlpaths}
+	do
+		if [ -x "${curlcmd}" ]; then
+			break
+		fi
+	done
+	# If curl exists download file
+	if [ "$(basename ${curlcmd})" == "curl" ]; then
+		curlfetch=$(${curlcmd} -s --fail -o "${filedir}/${filename}" "${githuburl}" 2>&1)
+		if [ $? -ne 0 ]; then
+			echo -e "\e[0;31mFAIL\e[0m\n"
+			echo "${curlfetch}"
+			echo -e "${githuburl}\n"
+			exit 1
+		else
+			echo -e "\e[0;32mOK\e[0m"
+		fi		
+	else
+		echo -e "\e[0;31mFAIL\e[0m\n"
+		echo "Curl is not installed!"
+		echo -e ""
+		exit 1
+	fi
+	chmod +x "${filedir}/${filename}"
+fi
+source "${filedir}/${filename}"
+}
+
+
+# Core
+
+core_dl.sh(){
+# Functions are defined in core_functions.sh.
+functionfile="${FUNCNAME}"
+fn_fetch_core_dl
+}
+
+core_getopt.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_core_dl
+}
+
+core_messages.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_core_dl
+}
+
+core_dl.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_core_dl
+}
+
+# Command
+
+command_console.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_debug.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_details.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_email_test.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_backup.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_monitor.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_start.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_stop.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_validate.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_install.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_fastdl.sh(){
+functionfile="${FUNCNAME}"
+fn_runfunction
+}
+
+command_ts3_server_pass.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fn_restart(){
+local modulename="Restarting"
+info_config.sh
+if [ -d "${scriptlogdir}" ]; then
+	fn_scriptlog "${servername}"
+fi	
+command_stop.sh
+command_start.sh
+}
+
+
+# Checks
+
+check.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_config.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_deps.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_ip.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_logs.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_root.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_steamcmd.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_system_dir.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+check_tmux.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Compress
+
+compress_unreal2_maps.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+compress_ut99_maps.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Dev
+
+command_dev_debug.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_dev_detect_deps.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Fix
+
+fix.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_arma3.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_csgo.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_dst.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_ins.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_steamcmd.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_glibc.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_ro.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_kf.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_ut2k4.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Info
+
+info_config.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+info_distro.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+info_glibc.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+info_ts3status.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Email
+
+email.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+# Logs
+
+logs.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+# Monitor
+
+monitor_gsquery.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+# Update
+
+update_check.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+command_update_functions.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+update_dl.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fn_update_functions.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+
+#
+## Installer functions
+#
+
+fn_autoinstall(){
+autoinstall=1
+command_install.sh
+}
+
+install_complete.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_config.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_gsquery.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_gslt.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_header.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_logs.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_retry.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_server_dir.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+install_server_files.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_steamcmd.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_ts3.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_ts3db.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_ut2k4.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_dl_ut2k4.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+install_ut2k4_key.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+fix_ut99.sh(){
+functionfile="${FUNCNAME}"
+fn_fetch_function
+}
+
+# Calls on-screen messages
+core_messages.sh
+
+#Calls file downloader
+core_dl.sh

+ 441 - 0
lgsm/functions/core_getopt.sh

@@ -0,0 +1,441 @@
+#!/bin/bash
+# LGSM core_getopt.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="070116"
+
+# Description: getopt arguments.
+
+fn_getopt_generic(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	u|update)
+		update_check.sh;;
+	fu|force-update|update-restart)
+		forceupdate=1;
+		update_check.sh;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	v|validate)
+		command_validate.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	c|console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate\t\e[0mChecks and applies updates from SteamCMD."
+		echo -e "\e[34mforce-update\t\e[0mBypasses the check and applies updates from SteamCMD."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mvalidate\t\e[0mValidate server files with SteamCMD."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."		
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+fn_getopt_teamspeak3(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	u|update)
+		update_check.sh;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	pw|change-password)
+		command_ts3_server_pass.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate\t\e[0mChecks and applies updates from teamspeak.com."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mchange-password\t\e[0mChanges TS3 serveradmin password."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+fn_getopt_mumble(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	b|backup)
+		command_backup.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."		
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+fn_getopt_gmodserver(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	u|update)
+		update_check.sh;;
+	fu|force-update|update-restart)
+		forceupdate=1;
+		update_check.sh;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	v|validate)
+		command_validate.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	c|console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;
+	fd|fastdl)
+		command_fastdl.sh;;
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate\t\e[0mChecks and applies updates from SteamCMD."
+		echo -e "\e[34mforce-update\t\e[0mBypasses the check and applies updates from SteamCMD."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mvalidate\t\e[0mValidate server files with SteamCMD."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+		echo -e "\e[34mfastdl\t\e[0mGenerates or update a FastDL folder for your server."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+fn_getopt_unreal(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	c|console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;		
+	mc|map-compressor)
+		compress_ut99_maps.sh;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;		
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+		echo -e "\e[34mmap-compressor\t\e[0mCompresses all ${gamename} server maps."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+
+fn_getopt_unreal2(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	u|update)
+		update_check.sh;;
+	fu|force-update|update-restart)
+		forceupdate=1;
+		update_check.sh;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	v|validate)
+		command_validate.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	c|console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;
+	mc|map-compressor)
+		compress_unreal2_maps.sh;;
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate\t\e[0mChecks and applies updates from SteamCMD."
+		echo -e "\e[34mforce-update\t\e[0mBypasses the check and applies updates from SteamCMD."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mvalidate\t\e[0mValidate server files with SteamCMD."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."		
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+		echo -e "\e[34mmap-compressor\t\e[0mCompresses all ${gamename} server maps."		
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+
+fn_getopt_ut2k4(){
+case "$getopt" in
+	st|start)
+		command_start.sh;;
+	sp|stop)
+		command_stop.sh;;
+	r|restart)
+		fn_restart;;
+	uf|update-functions)
+		command_update_functions.sh;;
+	m|monitor)
+		command_monitor.sh;;
+	et|email-test)
+		command_email_test.sh;;
+	d|details)
+		command_details.sh;;
+	b|backup)
+		command_backup.sh;;
+	c|console)
+		command_console.sh;;
+	d|debug)
+		command_debug.sh;;
+	dev|dev-debug)
+		command_dev_debug.sh;;		
+	i|install)
+		command_install.sh;;
+	ai|auto-install)
+		fn_autoinstall;;
+	sck|server-cd-key)
+		install_ut2k4_key.sh;;				
+	mc|map-compressor)
+		compress_unreal2_maps.sh;;
+	dd|depsdetect)
+		command_dev_detect_deps.sh;;		
+	*)
+	echo "Usage: $0 [option]"
+	echo "${gamename} - Linux Game Server Manager - Version ${version}"
+	echo "http://gameservermanagers.com/${selfname}"
+	echo -e ""
+	echo -e "\e[93mCommands\e[0m"
+	{
+		echo -e "\e[34mstart\t\e[0mStart the server."
+		echo -e "\e[34mstop\t\e[0mStop the server."
+		echo -e "\e[34mrestart\t\e[0mRestart the server."
+		echo -e "\e[34mupdate-functions\t\e[0mRemoves all functions so latest can be downloaded."
+		echo -e "\e[34mmonitor\t\e[0mChecks that the server is running."
+		echo -e "\e[34memail-test\t\e[0mSends test monitor email."
+		echo -e "\e[34mdetails\t\e[0mDisplays useful infomation about the server."
+		echo -e "\e[34mbackup\t\e[0mCreate archive of the server."
+		echo -e "\e[34mconsole\t\e[0mConsole allows you to access the live view of a server."
+		echo -e "\e[34mdebug\t\e[0mSee the output of the server directly to your terminal."
+		echo -e "\e[34minstall\t\e[0mInstall the server."
+		echo -e "\e[34mauto-install\t\e[0mInstall the server, without prompts."
+		echo -e "\e[34mserver-cd-key\t\e[0mAdd your server cd key"		
+		echo -e "\e[34mmap-compressor\t\e[0mCompresses all ${gamename} server maps."
+	} | column -s $'\t' -t 
+	esac
+exit
+}
+
+if [ "${gamename}" == "Mumble" ]; then
+	fn_getopt_mumble
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_getopt_teamspeak3
+elif [ "${gamename}" == "Garry's Mod" ]; then
+	fn_getopt_gmodserver
+elif [ "${engine}" == "unreal2" ]; then
+	if [ "${gamename}" == "Unreal Tournament 2004" ]; then
+		fn_getopt_ut2k4
+	else
+		fn_getopt_unreal2
+	fi
+elif [ "${engine}" == "unreal" ]; then
+	fn_getopt_unreal
+else
+	fn_getopt_generic
+fi

+ 204 - 0
lgsm/functions/core_messages.sh

@@ -0,0 +1,204 @@
+#!/bin/bash
+# LGSM fn_messages function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="380216"
+
+# Description: Defines on-screen messages such as [  OK  ] and how script logs look.
+
+# nl: new line: message is following by a new line
+# eol: end of line: message is placed at the end of the current line
+
+# Date, servicename & module details displayed in log files.
+# e.g Feb 28 14:56:58 ut99-server: Monitor:
+fn_scriptlog(){
+	if [ -n "${modulename}" ]; then
+		echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${modulename}: ${1}" >> "${scriptlog}"
+	else
+		echo -e "$(date '+%b %d %H:%M:%S') ${servicename}: ${1}" >> "${scriptlog}"
+	fi
+}
+
+# [ FAIL ]
+fn_print_fail(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;31m FAIL \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;31m FAIL \e[0m] $@"
+	fi
+}
+
+fn_print_fail_nl(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;31m FAIL \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;31m FAIL \e[0m] $@"
+	fi
+	sleep 1
+	echo -en "\n"		
+}
+	
+# [  OK  ]
+fn_print_ok(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;32m  OK  \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;32m  OK  \e[0m] $@"
+	fi
+}
+
+fn_print_ok_nl(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;32m  OK  \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;32m  OK  \e[0m] $@"
+	fi
+	sleep 1
+	echo -en "\n"	
+}
+
+# [ INFO ]
+fn_print_info(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;36m INFO \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;36m INFO \e[0m] $@"
+	fi
+}
+
+fn_print_info_nl(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[0;36m INFO \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[0;36m INFO \e[0m] $@"
+	fi
+	sleep 1
+	echo -en "\n"		
+}
+
+# [ WARN ]
+fn_print_warn(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[1;33m WARN \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[1;33m WARN \e[0m] $@"
+	fi
+}
+
+fn_print_warn_nl(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[\e[1;33m WARN \e[0m] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[\e[1;33m WARN \e[0m] $@"
+	fi
+	sleep 1
+	echo -en "\n"		
+}
+
+# [ .... ]
+fn_print_dots(){
+	if [ -n "${modulename}" ]; then
+		echo -en "\r\033[K[ .... ] ${modulename} ${servicename}: $@"
+	else
+		echo -en "\r\033[K[ .... ] $@"
+	fi
+}
+
+# Complete!
+fn_print_complete(){
+	echo -en "\e[0;32mComplete!\e[0m $@"
+}
+
+fn_print_complete_nl(){
+	echo -e "\e[0;32mComplete!\e[0m $@"
+}
+
+# Warning!
+fn_print_warning(){
+	echo -en "\e[0;33mWarning!\e[0m $@"
+}
+
+fn_print_warning_nl(){
+	echo -e "\e[0;33mWarning!\e[0m $@"
+}
+
+# Failure!
+fn_print_failure(){
+	echo -en "\e[0;31mFailure!\e[0m $@"
+}
+
+fn_print_failure_nl(){
+	echo -e "\e[0;31mFailure!\e[0m $@"
+}
+
+# Error!
+fn_print_error(){
+	echo -en "\e[0;31mError!\e[0m $@"
+}
+
+fn_print_error_nl(){
+	echo -e "\e[0;31mError!\e[0m $@"
+}
+
+# Infomation!
+fn_print_infomation(){
+	echo -en "\e[0;36mInfomation!\e[0m $@"
+}
+
+fn_print_infomation_nl(){
+	echo -e "\e[0;36mInfomation!\e[0m $@"
+}
+
+# FAIL for end of line
+fn_print_ok_eol(){
+	echo -en "\e[0;32mOK\e[0m"
+}
+
+fn_print_ok_eol_nl(){
+	echo -e "\e[0;32mOK\e[0m"
+}
+
+# FAIL for end of line
+fn_print_fail_eol(){
+	echo -en "\e[0;31mFAIL\e[0m"
+}
+
+fn_print_fail_eol_nl(){
+	echo -e "\e[0;31mFAIL\e[0m"
+}
+
+# QUERYING for end of line
+fn_print_querying_eol(){
+	echo -en "\e[0;36mQUERYING\e[0m"
+}
+
+fn_print_querying_eol_nl(){
+	echo -e "\e[0;36mQUERYING\e[0m"
+}
+
+# CHECKING for end of line
+fn_print_checking_eol(){
+	echo -en "\e[0;36mCHECKING\e[0m"
+}
+
+fn_print_checking_eol_nl(){
+	echo -e "\e[0;36mCHECKING\e[0m"
+}
+
+# CANCELED for end of line
+fn_print_canceled_eol(){
+	echo -en "\e[0;33mCANCELED\e[0m"
+}
+
+fn_print_canceled_eol_nl(){
+	echo -e "\e[0;33mCANCELED\e[0m"
+}
+
+# REMOVED for end of line
+fn_print_removed_eol(){
+	echo -en "\e[0;31mREMOVED\e[0m"
+}
+
+fn_print_removed_eol_nl(){
+	echo -e "\e[0;31mREMOVED\e[0m"
+}

+ 68 - 0
lgsm/functions/email.sh

@@ -0,0 +1,68 @@
+#!/bin/bash
+# LGSM email.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="020216"
+
+# Description: Sends email notification if monitor picks up a failure.
+
+local modulename="Email"
+fn_print_dots "Sending notification to ${email}"
+info_distro.sh
+info_config.sh
+check_ip.sh
+fn_parms
+{
+	echo -e "========================================\n${servicename} details\n========================================"
+	echo -e "Service name: ${servicename}"
+	echo -e "Server name: ${servername}"
+	echo -e "Game name: ${gamename}"
+	echo -e "Server IP: ${ip}:${port}"
+	echo -e "Failure reason: ${failurereason}"
+	echo -e "Action Taken: ${actiontaken}\n"
+	echo -e ""
+	echo -e "========================================\nDistro Details\n========================================"
+	echo -e "Date: $(date)"
+	echo -e "Distro: ${os}"
+	echo -e "Arch: ${arch}"
+	echo -e "Kernel: ${kernel}"
+	echo -e "Hostname: $HOSTNAME"
+	echo -e "tmux: ${tmuxv}"
+	echo -e "GLIBC: ${glibcv}"
+	echo -e ""
+	echo -e "========================================\nPerformance\n========================================"
+	echo -e "Uptime: ${days}d, ${hours}h, ${minutes}m"
+	echo -e "Avg Load: ${load}" 
+	echo -e ""
+	echo -e "Mem: total used free"
+	echo -e "Physical: ${physmemtotal} ${physmemused} ${physmemfree}"
+	echo -e "Swap: ${swaptotal}${swapused} ${swapfree}"
+	echo -e ""
+	echo -e "========================================\nStorage\n========================================"	
+	echo -e "\e[34mFilesystem:\t\e[0m${filesystem}"
+	echo -e "\e[34mTotal:\t\e[0m${totalspace}"
+	echo -e "\e[34mUsed:\t\e[0m${usedspace}"
+	echo -e "\e[34mAvailable:\t\e[0m${availspace}"
+	echo -e "\e[34mServerfiles:\t\e[0m${filesdirdu}"
+	if [ -d "${backupdir}" ]; then
+		echo -e "\e[34mBackups:\t\e[0m${backupdirdu}"
+	fi
+	echo -e ""	
+	echo -e "========================================\nCommand-line Parameters\n========================================"
+	echo -e "${executable} ${parms}"
+	echo -e ""
+	echo -e "========================================\nLogs\n========================================"
+}| sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"| tee "${scriptlogdir}/${servicename}-email.log" > /dev/null 2>&1
+echo -e "\n\n	Script log\n===================" >> "${emaillog}"
+tail -25 "${scriptlog}" >> "${emaillog}"
+if [ -n "${consolelog}" ]; then
+	echo -e "\n\n	Console log\n====================" >> "${emaillog}"
+	tail -25 "${consolelog}" | awk '{ sub("\r$", ""); print }' >> "${emaillog}"
+fi
+if [ -n "${gamelogdir}" ]; then
+	echo -e "\n\n	Server log\n====================" >> "${emaillog}"
+	tail "${gamelogdir}"/* | grep -v "==>" | sed '/^$/d' | tail -25 >> "${emaillog}"
+fi
+mail -s "${subject}" ${email} < "${emaillog}"
+fn_print_ok_nl "Sending notification to ${email}"
+fn_scriptlog "Sent notification to ${email}"

+ 75 - 0
lgsm/functions/fix.sh

@@ -0,0 +1,75 @@
+#!/bin/bash
+# LGSM fix.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Overall function for managing fixes.
+# Runs functions that will fix an issue.
+
+# Messages that are displayed for some fixes
+fn_fix_msg_start(){
+	fn_print_dots "Applying ${fixname} fix: ${gamename}"
+	sleep 1
+	fn_print_info "Applying ${fixname} fix: ${gamename}"
+	fn_scriptlog "Applying ${fixname} fix: ${gamename}"
+	sleep 1
+}
+
+fn_fix_msg_end(){
+	if [ $? -ne 0 ]; then
+		fn_print_fail_nl "Applying ${fixname} fix: ${gamename}"
+		fn_scriptlog "Failure! Applying ${fixname} fix: ${gamename}"
+	else
+		fn_print_ok_nl "Applying ${fixname} fix: ${gamename}"
+		fn_scriptlog "Complete! Applying ${fixname} fix: ${gamename}"
+	fi	
+}
+
+
+# Fixes that are run on start
+if [ "${function_selfname}" != "command_install.sh" ]; then
+	if [ -n "${appid}" ]; then
+		fix_steamcmd.sh
+	fi	
+
+	if [ "${gamename}" == "Counter Strike: Global Offensive" ]; then
+		fix_csgo.sh
+	elif [ "${gamename}" == "Don't Starve Together" ]; then
+		fix_dst.sh		
+	elif [ "${gamename}" == "Insurgency" ]; then
+		fix_ins.sh
+	elif [ "${gamename}" == "ARMA 3" ]; then
+		fix_arma3.sh	
+	fi
+fi
+
+# Fixes that are run on install only.
+if [ "${function_selfname}" == "command_install.sh" ]; then
+	fix_glibc.sh
+	if [ "${gamename}" == "Killing Floor" ]; then
+		echo ""
+		echo "Applying ${gamename} Server Fixes"
+		echo "================================="
+		sleep 1			
+		fix_kf.sh
+	elif [ "${gamename}" == "Red Orchestra: Ostfront 41-45" ]; then
+		echo ""
+		echo "Applying ${gamename} Server Fixes"
+		echo "================================="
+		sleep 1		
+		fix_ro.sh
+	elif [ "${gamename}" == "Unreal Tournament 2004" ]; then
+		echo ""
+		echo "Applying ${gamename} Server Fixes"
+		echo "================================="
+		sleep 1		
+		fix_ut2k4.sh
+	elif [ "${gamename}" == "Unreal Tournament 99" ]; then
+		echo ""
+		echo "Applying ${gamename} Server Fixes"
+		echo "================================="
+		sleep 1		
+		fix_ut99.sh
+	fi
+fi

+ 13 - 0
lgsm/functions/fix_arma3.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+# LGSM fix_arma3.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="301215"
+
+# Fixes: server not always creating steam_appid.txt file.
+if [ ! -d "${rootdir}/.local/share/Arma\ 3" ]; then
+	fixname="20150 Segmentation fault (core dumped)"
+	fn_fix_msg_start
+	mkdir -p "${rootdir}/.local/share/Arma\ 3"
+	fn_fix_msg_end
+fi

+ 43 - 0
lgsm/functions/fix_csgo.sh

@@ -0,0 +1,43 @@
+#!/bin/bash
+# LGSM fix_csgo.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Resolves various issues with csgo.
+
+# Fixes: server not always creating steam_appid.txt file.
+if [ ! -f "${filesdir}/steam_appid.txt" ]; then
+	fixname="730 steam_appid.txt"
+	fn_fix_msg_start
+	echo -n "730" >> "${filesdir}/steam_appid.txt"
+	fn_fix_msg_end
+fi
+
+# Fixes: Error parsing BotProfile.db - unknown attribute 'Rank'".
+if ! grep -q "//Rank" "${systemdir}/botprofile.db" > /dev/null 2>&1; then
+	fixname="botprofile.db"
+	fn_fix_msg_start
+	sed -i 's/\tRank/\t\/\/Rank/g' "${systemdir}/botprofile.db" > /dev/null 2>&1
+	fn_fix_msg_end
+fi
+
+# Fixes: Unknown command "cl_bobamt_vert".
+if ! grep -q "//exec default" "${servercfgdir}/valve.rc" > /dev/null 2>&1 || ! grep -q "//exec joystick" "${servercfgdir}/valve.rc" > /dev/null 2>&1; then
+	fixname="valve.rc"
+	fn_fix_msg_start
+	sed -i 's/exec default.cfg/\/\/exec default.cfg/g' "${servercfgdir}/valve.rc" > /dev/null 2>&1
+	sed -i 's/exec joystick.cfg/\/\/exec joystick.cfg/g' "${servercfgdir}/valve.rc" > /dev/null 2>&1
+	fn_fix_msg_end
+fi
+
+# Fixes: workshop map issue.
+# http://forums.steampowered.com/forums/showthread.php?t=3170366.
+if [ -f "${systemdir}/subscribed_collection_ids.txt" ]||[ -f "${systemdir}/subscribed_file_ids.txt" ]||[ -f "${systemdir}/ugc_collection_cache.txt" ]; then
+	fixname="workshop map"
+	fn_fix_msg_start
+	rm -f "${systemdir}/subscribed_collection_ids.txt"
+	rm -f "${systemdir}/subscribed_file_ids.txt"
+	rm -f "${systemdir}/ugc_collection_cache.txt"
+	fn_fix_msg_end
+fi

+ 16 - 0
lgsm/functions/fix_dst.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+# LGSM fix_dst.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Resolves various issues with Dont Starve together.
+
+# Fixes: ./dontstarve_dedicated_server_nullrenderer: ./lib32/libcurl-gnutls.so.4: no version information available (required by ./dontstarve_dedicated_server_nullrenderer)
+# Issue only occures on CentOS as libcurl-gnutls.so.4 is called libcurl.so.4 on CentOS.
+if [ -f "/etc/redhat-release" ] && [ ! -f "${filesdir}/bin/lib32/libcurl-gnutls.so.4" ]; then
+	fixname="libcurl-gnutls.so.4 missing"
+	fn_fix_msg_start
+	ln -s "/usr/lib/libcurl.so.4" "${filesdir}/bin/lib32/libcurl-gnutls.so.4"
+	fn_fix_msg_end
+fi

+ 0 - 0
functions/fix_ins.sh → lgsm/functions/fix_ins.sh


+ 0 - 0
functions/fix_kf.sh → lgsm/functions/fix_kf.sh


+ 27 - 0
lgsm/functions/fix_ro.sh

@@ -0,0 +1,27 @@
+#!/bin/bash
+# LGSM fix_ro.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Resolves various issues with red orchestra.
+
+echo "Applying WebAdmin ROOst.css fix."
+echo "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13"
+sed -i 's/none}/none;/g' "${filesdir}/Web/ServerAdmin/ROOst.css"
+sed -i 's/underline}/underline;/g' "${filesdir}/Web/ServerAdmin/ROOst.css"
+sleep 1
+echo "Applying WebAdmin CharSet fix."
+echo "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1"
+sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/uweb.int"
+sleep 1
+echo "applying server name fix."
+sleep 1
+echo "forcing server restart..."
+sleep 1
+command_start.sh
+sleep 5
+command_stop.sh
+command_start.sh
+sleep 5
+command_stop.sh

+ 41 - 0
lgsm/functions/fix_steamcmd.sh

@@ -0,0 +1,41 @@
+#!/bin/bash
+# LGSM fix_steamcmd.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: fixes various issues related to steamCMD.
+
+# Fixes: [S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam,or a local steamclient.so.
+if [ ! -f "${HOME}/.steam/sdk32/steamclient.so" ]; then
+	fixname="steamclient.so general"
+	fn_fix_msg_start
+	mkdir -pv "${HOME}/.steam/sdk32" >> "${scriptlog}"
+	cp -v "${rootdir}/steamcmd/linux32/steamclient.so" "${HOME}/.steam/sdk32/steamclient.so" >> "${scriptlog}"
+	fn_fix_msg_end
+fi
+
+if [ "${gamename}" == "Serious Sam 3: BFE" ]; then
+	# Fixes: .steam/bin32/libsteam.so: cannot open shared object file: No such file or directory
+	if [ ! -f "${HOME}/.steam/bin32/libsteam.so" ]; then
+		fixname="libsteam.so"
+		fn_fix_msg_start
+		mkdir -pv "${HOME}/.steam/bin32" >> "${scriptlog}"
+		cp -v "${filesdir}/Bin/libsteam.so" "${HOME}/.steam/bin32/libsteam.so" >> "${scriptlog}"
+		fn_fix_msg_end
+	fi
+elif [ "${gamename}" == "Hurtworld" ]; then
+	# Fixes: [S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam, or a local steamclient.so.
+	if [ ! -f "${filesdir}/Hurtworld_Data/Plugins/x86/steamclient.so" ]; then
+		fixname="steamclient.so x86"
+		fn_fix_msg_start
+		cp -v "${rootdir}/steamcmd/linux32/steamclient.so" "${filesdir}/Hurtworld_Data/Plugins/x86/steamclient.so" >> "${scriptlog}"
+		fn_fix_msg_end
+	fi	
+	if [ ! -f "${filesdir}/Hurtworld_Data/Plugins/x86_64/steamclient.so" ]; then
+		fixname="steamclient.so x86_64"
+		fn_fix_msg_start	
+		cp -v "${rootdir}/steamcmd/linux32/steamclient.so" "${filesdir}/Hurtworld_Data/Plugins/x86_64/steamclient.so" >> "${scriptlog}"
+		fn_fix_msg_end
+	fi
+fi

+ 27 - 0
lgsm/functions/fix_ut2k4.sh

@@ -0,0 +1,27 @@
+#!/bin/bash
+# LGSM fix_ut2k4.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Resolves various issues with unreal tournament 2004.
+
+echo "applying WebAdmin ut2003.css fix."
+echo "http://forums.tripwireinteractive.com/showpost.php?p=585435&postcount=13"
+sed -i 's/none}/none;/g' "${filesdir}/Web/ServerAdmin/ut2003.css"
+sed -i 's/underline}/underline;/g' "${filesdir}/Web/ServerAdmin/ut2003.css"
+sleep 1
+echo "applying WebAdmin CharSet fix."
+echo "http://forums.tripwireinteractive.com/showpost.php?p=442340&postcount=1"
+sed -i 's/CharSet="iso-8859-1"/CharSet="utf-8"/g' "${systemdir}/UWeb.int"
+sleep 1
+echo "applying server name fix."
+sleep 1
+echo "forcing server restart..."
+sleep 1
+command_start.sh
+sleep 5
+command_stop.sh
+command_start.sh
+sleep 5
+command_stop.sh

+ 25 - 0
lgsm/functions/fix_ut99.sh

@@ -0,0 +1,25 @@
+#!/bin/bash
+# LGSM fix_ut99.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+echo "${servercfgfullpath}"
+echo "enabling UdpServerUplink."
+{
+echo "[IpServer.UdpServerUplink]"
+echo "DoUplink=True"
+echo "UpdateMinutes=1"
+echo "MasterServerAddress=unreal.epicgames.com"
+echo "MasterServerPort=27900"
+echo "Region=0"
+}| tee -a "${servercfgfullpath}" > /dev/null 2>&1
+sleep 1
+echo "removing dead gamespy.com master server."
+sed -i '/master0.gamespy.com/d' "${servercfgfullpath}"
+sleep 1
+echo "removing dead mplayer.com master server."
+sed -i '/master.mplayer.com/d' "${servercfgfullpath}"
+sleep 1
+echo "inserting qtracker.com master server."
+sed -i '65i\ServerActors=IpServer.UdpServerUplink MasterServerAddress=master.qtracker.com MasterServerPort=27900' "${servercfgfullpath}"
+echo ""

+ 0 - 0
functions/fn_functions → lgsm/functions/fn_functions


+ 0 - 0
functions/fn_getopt → lgsm/functions/fn_getopt


+ 22 - 0
lgsm/functions/fn_update_functions

@@ -0,0 +1,22 @@
+#!/bin/bash
+# LGSM fn_update_functions.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="230116"
+
+# Description: LEGACY FUNCTION Deletes the functions dir to allow re-downloading of functions from GitHub.
+
+fn_print_dots "Updating functions"
+fn_scriptlog "Updating functions"
+sleep 1
+echo -ne "\n"
+rm -rfv "${rootdir}/functions/"*
+exitcode=$?
+if [ "${exitcode}" == "0" ]; then
+	fn_print_ok "Updating functions"
+	fn_scriptlog "Success! Updating functions"
+else
+	fn_print_fail "Updating functions"
+	fn_scriptlog "Failure! Updating functions"
+fi
+echo -ne "\n"

+ 125 - 0
lgsm/functions/gsquery.py

@@ -0,0 +1,125 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# Game Server Query
+# Author: Anonymous & Daniel Gibbs
+# # Website: http://gameservermanagers.com
+# Version: 190216
+
+import optparse
+import socket
+import sys
+
+class GameServer:
+	def __init__( self, options, arguments ):
+		self.option = options
+		self.argument = arguments
+		#
+		self.server_response_timeout = 5
+		self.default_buffer_length = 1024
+		#
+		if self.option.engine == 'source':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'
+		elif self.option.engine == 'goldsource':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'
+		elif self.option.engine == 'spark':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'
+		elif self.option.engine == 'realvirtuality':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'
+		elif self.option.engine == 'unity3d':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'
+		elif self.option.engine == 'idtech3':
+			self.query_prompt_string = '\xFF\xFF\xFF\xFFTSource Engine Query\0'			
+		elif self.option.engine == 'unreal':
+			self.query_prompt_string = '\x5C\x69\x6E\x66\x6F\x5C'
+		elif self.option.engine == 'unreal2':
+			self.query_prompt_string = '\x79\x00\x00\x00\x00'
+		elif self.option.engine == 'avalanche':
+			self.query_prompt_string = '\xFE\xFD\x09\x10\x20\x30\x40'
+		self.connected = False
+		self.response = None
+		self.sanity_checks()
+
+	def fatal_error( self, error_message, error_code=1 ):
+		sys.stderr.write( 'ERROR: ' + str(error_message) + '\n' )
+		sys.exit( error_code )
+
+	def exit_success( self, success_message='' ):
+		sys.stdout.write( 'OK: ' + str(success_message) + '\n' )
+		sys.exit( 0 )
+
+	def responding( self ):
+		# Connect.
+		connection = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
+		connection.settimeout( self.server_response_timeout )
+		try:
+			self.connected = connection.connect( ( self.option.address, int(self.option.port) ) )
+		except socket.timeout:
+			self.fatal_error( 'Request timed out', 1 )
+		except:
+			self.fatal_error( 'Unable to connect', 1 )
+		# Send.
+		connection.send( self.query_prompt_string )
+		# Receive.
+		try:
+			self.response = connection.recv( self.default_buffer_length )
+		except socket.error:
+			self.fatal_error( 'Unable to receive', 2 )
+		connection.close()
+		# Response.
+		if self.response == None:
+			self.fatal_error( 'No response', 3 )
+		if len( self.response ) < 10 :
+			sys.exit( 'Short response.', 3 )
+		else:
+			self.exit_success( str( self.response ) )
+
+	def sanity_checks( self ):
+		if not self.option.address:
+			self.fatal_error( 'No IPv4 address supplied.', 4 )
+		if not self.option.port:
+			self.fatal_error( 'No port supplied.', 4 )
+
+if __name__ == '__main__':
+	parser = optparse.OptionParser(
+		usage = 'usage: python %prog [options]',
+		version = '%prog 0.0.1'
+	)
+	parser.add_option(
+		'-a', '--address',
+		action = 'store',
+		dest = 'address',
+		default = False,
+		help = 'The IPv4 address of the server.'
+	)
+	parser.add_option(
+		'-p', '--port',
+		action = 'store',
+		dest = 'port',
+		default = False,
+		help = 'The IPv4 port of the server.'
+	)
+	parser.add_option(
+		'-e', '--engine',
+		action = 'store',
+		dest = 'engine',
+		default = False,
+		help = 'Engine type: avalanche, goldsource, idtech3, realvirtuality, spark, source, unity3d, unreal, unreal2.'
+	)
+	parser.add_option(
+		'-v', '--verbose',
+		action = 'store_true',
+		dest = 'verbose',
+		default = False,
+		help = 'Display verbose output.'
+	)
+	parser.add_option(
+		'-d', '--debug',
+		action = 'store_true',
+		dest = 'debug',
+		default = False,
+		help = 'Display debugging output.'
+	)
+	options, arguments = parser.parse_args()
+	#
+	server = GameServer( options, arguments )
+	server.responding()

+ 868 - 0
lgsm/functions/info_config.sh

@@ -0,0 +1,868 @@
+#!/bin/bash
+# LGSM info_config.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="010316"
+
+# Description: Gets specific details from config files.
+
+## Examples of filtering to get info from config files
+# sed 's/foo//g' - remove foo
+# tr -cd '[:digit:]' leave only digits
+# tr -d '=\"; ' remove selected charectors =\";
+# grep -v "foo" filter out lines that contain foo
+
+## Just Cause 2
+if [ "${engine}" == "avalanche" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "Name" "${servercfgfullpath}" | sed 's/Name//g' | tr -d '=", \n')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# ip
+	if [ -f "${servercfgfullpath}" ]; then
+		# check if the ip exists in the config file. Failing this will fall back to the default.
+		configipcheck=$(grep "BindIP" "${servercfgfullpath}" | sed 's/BindIP//g' | tr -d '=", \n')
+	fi
+	if [ -n "${configipcheck}" ]; then
+		ip=$(grep "BindIP" "${servercfgfullpath}" | sed 's/BindIP//g' | tr -d '=", \n')
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "Password" "${servercfgfullpath}" | sed 's/Password//g' | tr -d '=", \n')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "MaxPlayers" "${servercfgfullpath}" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "BindPort" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+## Dont Starve Together
+elif [ "${engine}" == "dontstarve" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "default_server_name = " "${servercfgfullpath}" | sed 's/default_server_name = //g')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "server_password = " "${servercfgfullpath}" | grep -v "#" | sed 's/server_password = //g')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "max_players" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# game mode
+	if [ -f "${servercfgfullpath}" ]; then
+		gamemode=$(grep "game_mode = " "${servercfgfullpath}" | grep -v "#" | sed 's/game_mode = //g')
+		if [ ! -n "${gamemode}" ]; then
+			gamemode="NOT SET"
+		fi
+	else
+		gamemode="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# tickrate
+	if [ -f "${servercfgfullpath}" ]; then
+		tickrate=$(grep "tick_rate" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${tickrate}" ]; then
+			tickrate="NOT SET"
+		fi
+	else
+		tickrate="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "server_port" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+## Project Zomboid
+elif [ "${engine}" == "projectzomboid" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "PublicName=" "${servercfgfullpath}" | sed 's/PublicName=//g' | tr -d '=", \n')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "MaxPlayers=" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "DefaultPort=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+
+# Quake Live
+elif [ "${engine}" == "idtech3" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "set sv_hostname " "${servercfgfullpath}" | sed 's/set sv_hostname //g' | tr -d '=\"; ')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+
+		serverpassword=$(grep "set g_password" "${servercfgfullpath}" | sed -e 's/set g_password//g' | tr -d '=\"; '| cut -f1 -d "/")
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# rcon password
+	rconpassword="${rconpassword}"
+	if [ -f "${servercfgfullpath}" ]; then
+		if [ ! -n "${rconpassword}" ]; then
+			rconpassword="NOT SET"
+		fi
+	else
+		rconpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "set sv_maxClients" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	port="${gameport}"
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+	# rcon port
+	if [ ! -n "${rconport}" ]; then
+		rconport="0"
+	fi
+
+	# Stats port
+	if [ ! -n "${statsport}" ]; then
+		statsport="0"
+	fi	
+
+# ARMA 3
+elif [ "${engine}" == "realvirtuality" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "hostname" "${servercfgfullpath}" | grep -v "//" | sed -e 's/\<hostname\>//g' | tr -d '=\"; ')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# admin password
+	if [ -f "${servercfgfullpath}" ]; then
+		adminpassword=$(grep "passwordAdmin" "${servercfgfullpath}" | grep -v "//" | sed -e 's/\passwordAdmin//g' | tr -d '=\"; ')
+		if [ ! -n "${adminpassword}" ]; then
+			adminpassword="NOT SET"
+		fi
+	else
+		adminpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "password =" "${servercfgfullpath}" | grep -v "//" | sed -e 's/\password//g' | tr -d '=\"; ')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "maxPlayers" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+    # port
+    if [ "${port}" != "" ]; then
+		port=${port}
+    fi
+    if [ ! -n "${port}" ]; then
+		port="0"
+    fi
+
+    # query port
+    if [ "${port}" != "" ]; then
+		queryport=$((port + 1))
+    fi
+    if [ ! -n "${queryport}" ]; then
+		queryport="0"
+    fi
+
+    # master port
+    if [ "${port}" != "" ]; then
+		masterport=$((port + 2))
+    fi
+    if [ ! -n "${masterport}" ]; then
+		masterport="0"
+    fi
+
+# Serious Sam
+elif [ "${engine}" == "seriousengine35" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "prj_strMultiplayerSessionName" "${servercfgfullpath}" | sed 's/prj_strMultiplayerSessionName = //g' | tr -d '=\"; ')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# rcon password
+	if [ -f "${servercfgfullpath}" ]; then
+		rconpassword=$(grep "rcts_strAdminPassword" "${servercfgfullpath}" | sed 's/rcts_strAdminPassword = //g' | tr -d '=\"; ')
+		if [ ! -n "${rconpassword}" ]; then
+			rconpassword="NOT SET"
+		fi
+	else
+		rconpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "gam_ctMaxPlayers" "${servercfgfullpath}" | grep -v "#" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# game mode
+	if [ -f "${servercfgfullpath}" ]; then
+		gamemode=$(grep "gam_idGameMode" "${servercfgfullpath}" | grep -v "#" | sed 's/gam_idGameMode//g' | tr -d '=\"; ')
+		if [ ! -n "${gamemode}" ]; then
+			gamemode="NOT SET"
+		fi
+	else
+		gamemode="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "prj_uwPort" "${servercfgfullpath}" | tr -d '\r' | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		queryport=$((port + 1))
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="0"
+	fi
+
+# Source Engine Games
+elif [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "hostname" "${servercfgfullpath}" | sed 's/hostname //g' | sed 's/"//g')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "sv_password" "${servercfgfullpath}" | sed 's/sv_password //g' | sed 's/"//g')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# rcon password
+	if [ -f "${servercfgfullpath}" ]; then
+		rconpassword=$(grep "rcon_password" "${servercfgfullpath}" | sed 's/rcon_password //g' | sed 's/"//g')
+		if [ ! -n "${rconpassword}" ]; then
+			rconpassword="NOT SET"
+		fi
+	else
+		rconpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+# Spark (NS2: Combat)
+elif [ "${engine}" == "spark" ]; then
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		queryport=$((port + 1))
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="0"
+	fi
+
+# Teamspeak 3
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+
+	# ip
+	if [ -f "${servercfgfullpath}" ]; then
+		# check if the ip exists in the config file. Failing this will fall back to the default.
+		configipcheck=$(grep "voice_ip=" "${servercfgfullpath}" | sed 's/\voice_ip=//g')
+	fi
+	if [ -n "${configipcheck}" ]; then
+		ip=$(grep "voice_ip=" "${servercfgfullpath}" | sed 's/\voice_ip=//g')
+	fi
+
+	# dbplugin
+	if [ -f "${servercfgfullpath}" ]; then
+		dbplugin=$(grep "dbplugin=" "${servercfgfullpath}" | sed 's/\dbplugin=//g')
+		if [ ! -n "${dbplugin}" ]; then
+			dbplugin="NOT SET"
+		fi
+	else
+		dbplugin="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "default_voice_port=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="9987"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		queryport=$(grep "query_port=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="10011"
+	fi
+
+	# file port
+	if [ -f "${servercfgfullpath}" ]; then
+		fileport=$(grep "filetransfer_port=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${fileport}" ]; then
+		fileport="30033"
+	fi
+
+# Teeworlds
+elif [ "${engine}" == "teeworlds" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "sv_name" "${servercfgfullpath}" | sed 's/sv_name //g' | sed 's/"//g')
+		if [ ! -n "${servername}" ]; then
+			servername="unnamed server"
+		fi
+	else
+		servername="unnamed server"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "password " "${servercfgfullpath}" | awk '!/sv_rcon_password/'| sed 's/password //g' | tr -d '=\"; ')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi	
+
+	# rcon password
+	if [ -f "${servercfgfullpath}" ]; then
+		rconpassword=$(grep "sv_rcon_password" "${servercfgfullpath}" | sed 's/sv_rcon_password //g' | tr -d '=\"; ')
+		if [ ! -n "${rconpassword}" ]; then
+			rconpassword="NOT SET"
+		fi
+	else
+		rconpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "sv_port" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="8303"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "sv_max_clients" "${servercfgfullpath}" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="12"
+		fi
+	else
+		slots="12"
+	fi
+
+# Terraria
+elif [ "${engine}" == "terraria" ]; then
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "port=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+# 7 Day To Die (unity3d)
+elif [ "${gamename}" == "7 Days To Die" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "ServerName" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "ServerPassword" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# webadmin enabled
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminenabled=$(grep "ControlPanelEnabled" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${webadminenabled}" ]; then
+			webadminenabled="NOT SET"
+		fi
+	else
+		webadminenabled="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# webadmin port
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminport=$(grep "ControlPanelPort" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${webadminport}" ]; then
+		webadminport="0"
+	fi
+
+	# webadmin enabled
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminenabled=$(grep "ControlPanelEnabled" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${webadminenabled}" ]; then
+			webadminenabled="NOT SET"
+		fi
+	else
+		webadminenabled="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# webadmin password
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminpass=$(grep "ControlPanelPassword" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${webadminpass}" ]; then
+			webadminpass="NOT SET"
+		fi
+	else
+		webadminpass="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# telnet enabled
+	if [ -f "${servercfgfullpath}" ]; then
+		telnetenabled=$(grep "TelnetEnabled" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${telnetenabled}" ]; then
+			telnetenabled="NOT SET"
+		fi
+	else
+		telnetenabled="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# telnet port
+	if [ -f "${servercfgfullpath}" ]; then
+		telnetport=$(grep "TelnetPort" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${telnetport}" ]; then
+		telnetport="0"
+	fi
+
+	# telnet password
+	if [ -f "${servercfgfullpath}" ]; then
+		telnetpass=$(grep "TelnetPassword" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${telnetpass}" ]; then
+			telnetpass="NOT SET"
+		fi
+	else
+		telnetpass="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "ServerMaxPlayerCount" "${servercfgfullpath}" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# game mode
+	if [ -f "${servercfgfullpath}" ]; then
+		gamemode=$(grep "GameMode" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${gamemode}" ]; then
+			gamemode="NOT SET"
+		fi
+	else
+		gamemode="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# game world
+	if [ -f "${servercfgfullpath}" ]; then
+		gameworld=$(grep "GameWorld" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
+		if [ ! -n "${gameworld}" ]; then
+			gameworld="NOT SET"
+		fi
+	else
+		gameworld="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "sv_port" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		queryport=$((port + 1))
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="0"
+	fi
+
+# Hurtworld (unity3d)
+elif [ "${gamename}" == "Hurtworld" ]; then
+
+	# server name
+	if [ -n "${servername}" ]; then
+		servername="${servername}"
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"	
+	fi
+
+	# server password
+	# not available yet
+
+	# slots
+	if [ -n "${maxplayers}" ]; then
+		slots="${maxplayers}"
+	else
+		slots="NOT SET"
+	fi
+
+	# game world
+	if [ -n "${map}" ]; then
+		gameworld="${map}"
+	else
+		gameworld="NO MAP SET"
+	fi
+
+	# port
+	if [ -n "${port}" ]; then
+		port="${port}"
+	else
+		port="0"
+	fi
+
+	# query port
+	if [ -n "${queryport}" ]; then
+		queryport="${queryport}"
+	else
+		queryport="0"
+	fi
+
+# Unreal Tournament 
+elif [ "${engine}" == "unreal" ]||[ "${engine}" == "unreal2" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "ServerName=" "${servercfgfullpath}" | sed 's/ServerName=//g')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "GamePassword=" "${servercfgfullpath}" | sed 's/GamePassword=//g')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# admin password
+	if [ -f "${servercfgfullpath}" ]; then
+		adminpassword=$(grep "AdminPassword=" "${servercfgfullpath}" | sed 's/AdminPassword=//g')
+		if [ ! -n "${adminpassword}" ]; then
+			adminpassword="NOT SET"
+		fi
+	else
+		adminpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi	
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "Port=" "${servercfgfullpath}" | grep -v "Master" | grep -v "LAN" | grep -v "Proxy" | grep -v "Listen" | tr -d '\r' | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		queryport=$((port + 1))
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="0"
+	fi
+
+	# gamespy query port
+	if [ -f "${servercfgfullpath}" ]; then
+		gsqueryport=$(grep "OldQueryPortNumber=" "${servercfgfullpath}" | tr -d '\r' | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${gsqueryport}" ]; then
+		gsqueryport="0"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+		udplinkport=$((port + 2))
+	fi
+	if [ ! -n "${udplinkport}" ]; then
+		udplinkport="0"
+	fi
+
+	# webadmin enabled
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminenabled=$(grep "bEnabled=" "${servercfgfullpath}" | sed 's/bEnabled=//g' | tr -d '\r')
+		if [ ! -n "${webadminenabled}" ]; then
+			webadminenabled="NOT SET"
+		fi
+	else
+		webadminenabled="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# webadmin port
+	if [ -f "${servercfgfullpath}" ]; then
+		webadminport=$(grep "ListenPort=" "${servercfgfullpath}" | tr -d '\r' | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${webadminport}" ]; then
+		webadminport="0"
+	fi
+
+	if [ "${engine}" == "unreal" ]; then
+
+		# webadmin user
+		if [ -f "${servercfgfullpath}" ]; then
+			webadminuser=$(grep "AdminUsername=" "${servercfgfullpath}" | sed 's/\AdminUsername=//g')
+			if [ ! -n "${webadminuser}" ]; then
+				webadminuser="NOT SET"
+			fi
+		else
+			webadminuser="\e[0;31mUNAVAILABLE\e[0m"
+		fi
+
+		# webadmin password
+		if [ -f "${servercfgfullpath}" ]; then
+			webadminpass=$(grep "UTServerAdmin.UTServerAdmin" "${servercfgfullpath}" -A 2 | grep "AdminPassword=" | sed 's/\AdminPassword=//g')
+			if [ ! -n "${webadminpass}" ]; then
+				webadminpass="NOT SET"
+			fi
+		else
+			webadminpass="\e[0;31mUNAVAILABLE\e[0m"
+		fi
+
+	else
+
+		# webadmin user
+		if [ -f "${servercfgfullpath}" ]; then
+			webadminuser=$(grep "AdminName=" "${servercfgfullpath}" | sed 's/\AdminName=//g')
+			if [ ! -n "${webadminuser}" ]; then
+				webadminuser="NOT SET"
+			fi
+		else
+			webadminuser="\e[0;31mUNAVAILABLE\e[0m"
+		fi
+
+		# webadmin password
+		if [ -f "${servercfgfullpath}" ]; then
+			webadminpass=$(grep "AdminPassword=" "${servercfgfullpath}" | sed 's/\AdminPassword=//g')
+			if [ ! -n "${webadminpass}" ]; then
+				webadminpass="NOT SET"
+			fi
+		else
+			webadminpass="\e[0;31mUNAVAILABLE\e[0m"
+		fi
+
+	fi
+
+# ARK: Survivaial Evolved
+elif [ "${gamename}" == "ARK: Survivial Evolved" ]; then
+
+	# server name
+	if [ -f "${servercfgfullpath}" ]; then
+		servername=$(grep "SessionName=" "${servercfgfullpath}" | sed 's/SessionName=//g')
+		if [ ! -n "${servername}" ]; then
+			servername="NOT SET"
+		fi
+	else
+		servername="\e[0;31mUNAVAILABLE\e[0m"
+	fi	
+
+	# server password
+	if [ -f "${servercfgfullpath}" ]; then
+		serverpassword=$(grep "ServerPassword=" "${servercfgfullpath}" | sed 's/ServerPassword=//g')
+		if [ ! -n "${serverpassword}" ]; then
+			serverpassword="NOT SET"
+		fi
+	else
+		serverpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# admin password
+	if [ -f "${servercfgfullpath}" ]; then
+	adminpassword=$(grep "ServerAdminPassword=" "${servercfgfullpath}" | sed 's/ServerAdminPassword=//g')
+		if [ ! -n "${adminpassword}" ]; then
+			adminpassword="NOT SET"
+		fi
+	else
+		adminpassword="\e[0;31mUNAVAILABLE\e[0m"
+	fi	
+
+	# slots
+	if [ -f "${servercfgfullpath}" ]; then
+		slots=$(grep "MaxPlayers=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+		if [ ! -n "${slots}" ]; then
+			slots="NOT SET"
+		fi
+	else
+		slots="\e[0;31mUNAVAILABLE\e[0m"
+	fi
+
+	# port
+	if [ -f "${servercfgfullpath}" ]; then
+		port=$(grep "Port=" "${servercfgfullpath}" | grep -v  "RCONPort=" | grep -v  "QueryPort=" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${port}" ]; then
+		port="0"
+	fi
+
+	# rcon port
+	if [ -f "${servercfgfullpath}" ]; then
+		rconport=$(grep "RCONPort=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${rconport}" ]; then
+		rconport="0"
+	fi
+
+	# query port
+	if [ -f "${servercfgfullpath}" ]; then
+			queryport=$(grep "QueryPort=" "${servercfgfullpath}" | tr -cd '[:digit:]')
+	fi
+	if [ ! -n "${queryport}" ]; then
+		queryport="0"
+	fi
+
+fi

+ 0 - 0
functions/info_distro.sh → lgsm/functions/info_distro.sh


+ 71 - 0
lgsm/functions/info_glibc.sh

@@ -0,0 +1,71 @@
+#!/bin/bash
+# LGSM info_glibc.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="260216"
+
+# Description: stores details on servers Glibc requirements.
+
+if [ "${gamename}" == "Blade Symphony" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "BrainBread 2" ]; then
+	glibc_required="2.17"
+elif [ "${gamename}" == "Double Action: Boogaloo" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "Fistful of Frags" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "Garry's Mod" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "Insurgency" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "No More Room in Hell" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${gamename}" == "Quake Live" ]; then
+	glibc_required="2.15"
+	glibcfix="no"
+elif [ "${engine}" == "avalanche" ]; then
+	glibc_required="2.13"
+	glibcfix="yes"
+elif [ "${engine}" == "dontstarve" ]; then
+	glibc_required="2.15"
+	glibcfix="no"
+elif [ "${engine}" == "projectzomboid" ]; then
+	glibc_required="2.15"
+	glibcfix="yesno"
+elif [ "${engine}" == "realvirtuality" ]; then
+	glibc_required="2.13"
+	glibcfix="yes"
+elif [ "${engine}" == "seriousengine35" ]; then
+	glibc_required="2.13"
+	glibcfix="yes"
+elif [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]; then
+	glibc_required="2.3.6"
+	glibcfix="no"
+elif [ "${engine}" == "spark" ]; then
+	glibc_required="2.15"
+	glibcfix="yes"
+elif [ "${engine}" == "starbound" ]; then
+	glibc_required="2.12"
+	glibcfix="no"
+elif [ "${engine}" == "unreal" ]; then
+	glibc_required="2.1"
+	glibcfix="no"	
+elif [ "${engine}" == "unreal2" ]; then
+	glibc_required="2.4"
+	glibcfix="no"
+elif [ "${engine}" == "unreal4" ]; then
+	glibc_required="2.14"
+	glibcfix="no"
+elif [ "${engine}" == "unity3d" ]; then
+	glibc_required="2.15"
+	glibcfix="no"
+else
+	glibc_required="UNKNOWN"
+	glibcfix="no"
+fi

+ 0 - 0
functions/info_ts3status.sh → lgsm/functions/info_ts3status.sh


+ 21 - 0
lgsm/functions/install_complete.sh

@@ -0,0 +1,21 @@
+#!/bin/bash
+# LGSM install_complete.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+if [ "${gamename}" == "Don't Starve Together" ]; then
+  echo ""
+  echo "An Authentication Token is required to run this server!"
+  echo "Follow the instructions in this link to obtain this key"
+  echo "  http://gameservermanagers.com/dst-auth-token"
+fi
+echo "================================="
+echo "Install Complete!"
+fn_scriptlog "Install Complete!"
+echo ""
+echo "To start server type:"
+echo "./${selfname} start"
+echo ""

+ 349 - 0
lgsm/functions/install_config.sh

@@ -0,0 +1,349 @@
+#!/bin/bash
+# LGSM install_config.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="220216"
+
+local modulename="Install"
+
+fn_defaultconfig(){
+	echo "creating ${servercfg} config file."
+	cp -v "${servercfgdefault}" "${servercfgfullpath}"
+	sleep 1
+}
+
+fn_userinputconfig(){
+# allow user to input server name and password
+if [ -z "${autoinstall}" ]; then
+	echo ""
+	echo "Configuring ${gamename} Server"
+	echo "================================="
+	sleep 1
+	read -p "Enter server name: " servername
+	read -p "Enter rcon password: " rconpass
+else
+	servername="${servicename}"
+	rconpass="rconpassword"
+fi
+echo "changing hostname."
+sed -i "s/\"<hostname>\"/\"${servername}\"/g" "${servercfgfullpath}"
+sleep 1
+echo "changing rconpassword."
+sed -i "s/\"<rconpassword>\"/\"${rconpass}\"/g" "${servercfgfullpath}"
+sleep 1
+}
+
+fn_arma3config(){
+fn_defaultconfig
+echo "creating ${networkcfg} config file."
+cp -v "${networkcfgdefault}" "${networkcfgfullpath}"
+sleep 1
+echo ""
+}
+
+fn_goldsourceconfig(){
+fn_defaultconfig
+
+# server.cfg redirects to ${servercfg} for added security
+echo "creating server.cfg."
+touch "server.cfg"
+sleep 1
+echo "creating redirect."
+echo "server.cfg > ${servercfg}."
+echo "exec ${servercfg}" > "server.cfg"
+sleep 1
+
+# creating other files required
+echo "creating listip.cfg."
+touch "${systemdir}/listip.cfg"
+sleep 1
+echo "creating banned.cfg."
+touch "${systemdir}/banned.cfg"
+sleep 1
+
+fn_userinputconfig
+echo ""
+}
+
+fn_serious3config(){
+fn_defaultconfig
+echo ""
+echo "To edit ${gamename} server config use SS3 Server GUI 3 tool"
+echo "http://mrag.nl/sgui3/"
+sleep 1
+echo ""
+}
+
+fn_sourceconfig(){
+fn_defaultconfig
+
+# server.cfg redirects to ${servercfg} for added security
+echo "creating server.cfg."
+touch "server.cfg"
+sleep 1
+echo "creating redirect."
+echo "server.cfg > ${servercfg}."
+echo "exec ${servercfg}" > "server.cfg"
+sleep 1
+
+fn_userinputconfig
+echo ""
+}
+
+fn_teeworldsconfig(){
+fn_defaultconfig
+
+echo "adding logfile location to config."
+sed -i "s@\"<logfile>\"@\"${gamelog}\"@g" "${servercfgfullpath}"
+sleep 1
+echo "removing password holder."
+sed -i "s/<password>//" "${servercfgfullpath}"
+sleep 1
+
+fn_userinputconfig
+echo ""
+}
+
+fn_ut99config(){
+echo "${servercfgdefault} > ${servercfgfullpath}"
+tr -d '\r' < "${servercfgdefault}" > "${servercfgfullpath}"
+sleep 1
+echo ""
+echo "Configuring ${gamename} Server"
+echo "================================="
+sleep 1
+echo "enabling WebAdmin."
+sed -i 's/bEnabled=False/bEnabled=True/g' "${servercfgfullpath}"
+sleep 1
+echo "setting WebAdmin port to 8076."
+sed -i '467i\ListenPort=8076' "${servercfgfullpath}"
+sleep 1
+echo ""
+}
+
+fn_unreal2config(){
+fn_defaultconfig
+echo ""
+echo "Configuring ${gamename} Server"
+echo "================================="
+sleep 1
+echo "setting WebAdmin username and password."
+sed -i 's/AdminName=/AdminName=admin/g' "${servercfgfullpath}"
+sed -i 's/AdminPassword=/AdminPassword=admin/g' "${servercfgfullpath}"
+sleep 1
+echo "enabling WebAdmin."
+sed -i 's/bEnabled=False/bEnabled=True/g' "${servercfgfullpath}"
+if [ "${gamename}" == "Unreal Tournament 2004" ]; then
+	sleep 1
+	echo "setting WebAdmin port to 8075."
+	sed -i 's/ListenPort=80/ListenPort=8075/g' "${servercfgfullpath}"
+fi
+sleep 1
+echo ""
+}
+
+echo ""
+if [ "${gamename}" != "Hurtworld" ]; then
+echo "Creating Configs"
+echo "================================="
+sleep 1
+	mkdir -pv "${servercfgdir}"
+	cd "${servercfgdir}"
+	githuburl="https://raw.githubusercontent.com/${githubuser}/${githubrepo}/${githubbranch}"
+fi
+
+if [ "${gamename}" == "7 Days To Die" ]; then
+	fn_defaultconfig
+elif [ "${gamename}" == "ARK: Survivial Evolved" ]; then
+	wget -N /dev/null ${githuburl}/ARKSurvivalEvolved/cfg/lgsm-default.ini 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	echo -e "downloading lgsm-default.ini...\c"
+	fn_defaultconfig
+elif [ "${gamename}" == "ARMA 3" ]; then
+	echo -e "downloading lgsm-default.server.cfg...\c"
+	wget -N /dev/null ${githuburl}/Arma3/cfg/lgsm-default.server.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	echo -e "downloading lgsm-default.network.cfg...\c"
+	wget -N /dev/null ${githuburl}/Arma3/cfg/lgsm-default.network.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_arma3config
+elif [ "${gamename}" == "BrainBread 2" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/BrainBread2/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig	
+elif [ "${gamename}" == "Black Mesa: Deathmatch" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/BlackMesa/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Blade Symphony" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/BladeSymphony/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Codename CURE" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/CodenameCURE/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+
+elif [ "${gamename}" == "Counter Strike 1.6" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/CounterStrike/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Counter Strike: Condition Zero" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/CounterStrikeConditionZero/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Counter Strike: Global Offensive" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/CounterStrikeGlobalOffensive/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Counter Strike: Source" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/CounterStrikeSource/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Day of Defeat" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/DayOfDefeat/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Day of Defeat: Source" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/DayOfDefeatSource/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Don't Starve Together" ]; then
+	echo -e "downloading lgsm-default.ini...\c"
+	wget -N /dev/null ${githuburl}/DontStarveTogether/lgsm-default.ini 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_defaultconfig
+elif [ "${gamename}" == "Double Action: Boogaloo" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/DoubleActionBoogaloo/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Fistful of Frags" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/FistfulOfFrags/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Garry's Mod" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/GarrysMod/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "GoldenEye: Source" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/GoldenEyeSource/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig	
+elif [ "${gamename}" == "Half Life 2: Deathmatch" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/HalfLife2Deathmatch/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Half Life: Deathmatch" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/HalfLifeDeathmatch/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Insurgency" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/Insurgency/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Just Cause 2" ]; then
+	fn_defaultconfig
+elif [ "${gamename}" == "Killing Floor" ]; then
+	fn_unreal2config
+elif [ "${gamename}" == "Left 4 Dead" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/Left4Dead/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Left 4 Dead 2" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/Left4Dead2/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "No More Room in Hell" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/NoMoreRoomInHell/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Natural Selection 2" ]; then
+	echo -e "no configs required."
+	sleep 1
+	echo ""
+elif [ "${gamename}" == "Pirates, Vikings, and Knights II" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/PiratesVikingandKnightsII/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig	
+elif [ "${gamename}" == "Quake Live" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/QuakeLive/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_defaultconfig
+	fn_userinputconfig
+elif [ "${gamename}" == "Red Orchestra: Ostfront 41-45" ]; then
+	fn_unreal2config
+elif [ "${gamename}" == "Serious Sam 3: BFE" ]; then
+	echo -e "downloading lgsm-default.ini...\c"
+	wget -N /dev/null ${githuburl}/SeriousSam3BFE/cfg/lgsm-default.ini 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_serious3config
+elif [ "${gamename}" == "Rust" ]; then
+	echo -e "downloading server.cfg...\c"
+	wget -N /dev/null  ${githuburl}/Rust/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_defaultconfig
+elif [ "${gamename}" == "Sven Co-op" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/SvenCoop/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Teamspeak 3" ]; then
+	echo -e "downloading lgsm-default.ini...\c"
+	wget -N /dev/null ${githuburl}/TeamSpeak3/cfg/lgsm-default.ini 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_defaultconfig
+elif [ "${gamename}" == "Team Fortress 2" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/TeamFortress2/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_sourceconfig
+elif [ "${gamename}" == "Team Fortress Classic" ]; then
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/TeamFortressClassic/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_goldsourceconfig
+elif [ "${gamename}" == "Teeworlds" ]; then
+	echo -e "downloading ctf.cfg...\c"
+	wget -N /dev/null ${githuburl}/Teeworlds/cfg/ctf.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	echo -e "downloading dm.cfg...\c"
+	wget -N /dev/null ${githuburl}/Teeworlds/cfg/dm.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	echo -e "downloading duel.cfg...\c"
+	wget -N /dev/null ${githuburl}/Teeworlds/cfg/duel.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	echo -e "downloading tdm.cfg...\c"
+	wget -N /dev/null ${githuburl}/Teeworlds/cfg/tdm.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	echo -e "downloading lgsm-default.cfg...\c"
+	wget -N /dev/null ${githuburl}/Teeworlds/cfg/lgsm-default.cfg 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_teeworldsconfig
+elif [ "${gamename}" == "Terraria" ]; then
+	echo -e "downloading lgsm-default.txt...\c"
+	wget -N /dev/null ${githuburl}/Terraria/cfg/lgsm-default.txt 2>&1 | grep -F HTTP | cut -c45- | uniq
+	sleep 1
+	fn_defaultconfig
+elif [ "${gamename}" == "Unreal Tournament 2004" ]; then
+	fn_unreal2config
+elif [ "${gamename}" == "Unreal Tournament 99" ]; then
+	fn_ut99config
+fi

+ 37 - 0
lgsm/functions/install_gslt.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+# LGSM install_gslt.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+# Description: Configures GSLT.
+
+local modulename="Install"
+
+echo ""
+echo "Game Server Login Token"
+echo "============================"
+sleep 1
+if [ "${gamename}" == "Counter Strike: Global Offensive" ]; then
+	echo "GSLT is required to run a public ${gamename} server"
+	fn_scriptlog "GSLT is required to run a public ${gamename} server"
+else
+	echo "GSLT is an optional feature for ${gamename} server"
+	fn_scriptlog "GSLT is an optional feature for ${gamename} server"
+fi
+
+echo "Get more info and a token here:"
+echo "http://gameservermanagers.com/gslt"
+fn_scriptlog "Get more info and a token here:"
+fn_scriptlog "http://gameservermanagers.com/gslt"
+echo ""
+if [ -z "${autoinstall}" ]; then
+	echo "Enter token below (Can be blank)."
+	echo -n "GSLT TOKEN: "
+	read token
+	sed -i -e "s/gslt=\"\"/gslt=\"${token}\"/g" "${rootdir}/${selfname}"
+fi
+sleep 1
+echo "The GSLT can be changed by editing ${selfname}."
+fn_scriptlog "The GSLT can be changed by editing ${selfname}."
+echo ""

+ 0 - 0
functions/install_gsquery.sh → lgsm/functions/install_gsquery.sh


+ 16 - 0
lgsm/functions/install_header.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+# LGSM install_header.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="190216"
+
+local modulename="Install"
+
+clear
+echo "================================="
+echo "${gamename}"
+echo "Linux Game Server Manager"
+echo "by Daniel Gibbs"
+echo "Contributors: http://goo.gl/qLmitD"
+echo "http://gameservermanagers.com"
+echo "================================="

+ 43 - 0
lgsm/functions/install_logs.sh

@@ -0,0 +1,43 @@
+#!/bin/bash
+# LGSM install_logs.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+local modulename="Install"
+
+if [ "${checklogs}" != "1" ]; then
+	echo ""
+	echo "Creating log directorys"
+	echo "================================="
+fi
+sleep 1
+# Create dir's for the script and console logs
+mkdir -v "${rootdir}/log"
+mkdir -v "${scriptlogdir}"
+touch "${scriptlog}"
+if [ -n "${consolelogdir}" ]; then
+	mkdir -v "${consolelogdir}"
+	touch "${consolelog}"
+fi
+
+# If a server is source or goldsource, Teamspeak 3, Starbound, Project Zomhoid create a symbolic link to the game server logs.
+if [ "${engine}" == "source" ]||[ "${engine}" == "goldsource" ]||[ "${gamename}" == "Teamspeak 3" ]||[ "${engine}" == "starbound" ]||[ "${engine}" == "projectzomboid" ]; then
+	if [ ! -h "${rootdir}/log/server" ]; then
+		ln -nfsv "${gamelogdir}" "${rootdir}/log/server"
+	fi
+fi
+
+# If a server is unreal2 or unity3d create a dir.
+if [ "${engine}" == "unreal2" ]||[ "${engine}" == "unity3d" ]||[ "${gamename}" == "Teeworlds" ]||[ "${gamename}" == "seriousengine35" ]; then
+	mkdir -pv "${gamelogdir}"
+fi
+
+# If server uses SteamCMD create a symbolic link to the Steam logs.
+if [ -d "${rootdir}/Steam/logs" ]; then
+	if [ ! -h "${rootdir}/log/steamcmd" ]; then
+		ln -nfsv "${rootdir}/Steam/logs" "${rootdir}/log/steamcmd"
+	fi
+fi
+sleep 1
+fn_scriptlog "logs installed"

+ 16 - 0
lgsm/functions/install_retry.sh

@@ -0,0 +1,16 @@
+#!/bin/bash
+# LGSM install_retry.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+while true; do
+	read -e -i "y" -p "Retry install? [Y/n]" yn
+	case $yn in
+	[Yy]* ) command_install.sh; exit;;
+	[Nn]* ) echo Exiting; exit;;
+	* ) echo "Please answer yes or no.";;
+	esac
+done

+ 32 - 0
lgsm/functions/install_server_dir.sh

@@ -0,0 +1,32 @@
+#!/bin/bash
+# LGSM install_serverdir.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+echo ""
+echo "Server Directory"
+echo "================================="
+sleep 1
+echo ""
+pwd
+echo ""
+if [ -d "${filesdir}" ]; then
+	fn_print_warning_nl "A server is already installed here."
+fi
+if [ -z "${autoinstall}" ]; then	
+	while true; do
+		read -e -i "y" -p "Continue [y/N]" yn
+		case $yn in
+		[Yy]* ) break;;
+		[Nn]* ) exit;;
+		* ) echo "Please answer yes or no.";;
+		esac
+	done
+fi
+if [ ! -d "${filesdir}" ]; then
+	mkdir -v "${filesdir}"
+fi
+sleep 1

+ 110 - 0
lgsm/functions/install_server_files.sh

@@ -0,0 +1,110 @@
+#!/bin/bash
+# LGSM install_server_files.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+local modulename="Install"
+
+fn_install_server_files(){
+if [ "${gamename}" == "Unreal Tournament 99" ]; then
+	fileurl="http://gameservermanagers.com/files/UnrealTournament99/ut99-server-451-ultimate-linux.tar.bz2"; filedir="${lgsmdir}/tmp"; filename="ut99-server-451-ultimate-linux.tar.bz2"; executecmd="noexecute" run="norun"; force="noforce"; md5="49cb24d0550ff6ddeaba6007045c6edd"
+elif [ "${gamename}" == "Unreal Tournament 2004" ]; then
+	fileurl="http://gameservermanagers.com/files/UnrealTournament2004/ut2004-server-3339-ultimate-linux.tar.bz2"; filedir="${lgsmdir}/tmp"; filename="ut2004-server-3339-ultimate-linux.tar.bz2";  executecmd="noexecute" run="norun"; force="noforce"; md5="67c5e2cd9c2a4b04f163962ee41eff54"
+fi
+fn_fetch_file "${fileurl}" "${filedir}" "${filename}" "${executecmd}" "${run}" "${force}" "${md5}"
+fn_dl_extract "${filedir}" "${filename}" "${filesdir}"
+}
+
+fn_install_server_files_steamcmd(){
+counter="0"
+while [ "${counter}" == "0" ]||[ "${exitcode}" != "0" ]; do
+	counter=$((counter+1))
+	cd "${rootdir}/steamcmd"
+	if [ "${counter}" -le "10" ]; then
+		# Attempt 1-4: Standard attempt
+		# Attempt 5-6: Validate attempt
+		# Attempt 7-8: Validate, delete long name dir
+		# Attempt 9-10: Validate, delete long name dir, re-download SteamCMD
+		# Attempt 11: Failure
+
+		if [ "${counter}" -ge "2" ]; then
+			fn_print_warning_nl "SteamCMD did not complete the download, retrying: Attempt ${counter}"
+			fn_scriptlog "SteamCMD did not complete the download, retrying: Attempt ${counter}"
+		fi
+
+		if [ "${counter}" -ge "7" ]; then
+			echo "Removing $(find ${filesdir} -type d -print0 | grep -Ez '[^/]{30}$')"
+			find ${filesdir} -type d -print0 | grep -Ez '[^/]{30}$' | xargs -0 rm -rf
+		fi
+		if [ "${counter}" -ge "9" ]; then
+			rm -rf "${rootdir}/steamcmd"
+			check_steamcmd.sh
+		fi
+
+		# Detects if unbuffer command is available.
+		if [ $(command -v unbuffer) ]; then
+			unbuffer=unbuffer
+		fi
+
+		if [ "${counter}" -le "4" ]; then
+			if [ "${engine}" == "goldsource" ]; then
+				${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" +quit
+				local exitcode=$?
+			else
+				${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_update "${appid}" +quit
+				local exitcode=$?
+			fi
+		elif [ "${counter}" -ge "5" ]; then
+			if [ "${engine}" == "goldsource" ]; then
+				${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_set_config 90 mod "${appidmod}" +app_update "${appid}" -validate +quit
+				local exitcode=$?
+			else
+				${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_update "${appid}" -validate +quit
+				local exitcode=$?
+			fi
+		fi
+	elif [ "${counter}" -ge "11" ]; then
+		fn_print_failure_nl "SteamCMD did not complete the download, too many retrys"
+		fn_scriptlog "SteamCMD did not complete the download, too many retrys"
+		break
+	fi
+done
+
+# Goldsource servers commonly fail to download all the server files required.
+# Validating a few of times may reduce the chance of this issue.
+if [ "${engine}" == "goldsource" ]; then
+	fn_print_infomation_nl "Goldsource servers commonly fail to download all the server files required. Validating a few of times may reduce the chance of this issue."
+	counter="0"
+	while [ "${counter}" -le "4" ]; do
+		counter=$((counter+1))
+		${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_set_config 90 mod ${appidmod} +app_update "${appid}" -validate +quit
+		local exitcode=$?
+	done
+fi
+}
+
+echo ""
+echo "Installing ${gamename} Server"
+echo "================================="
+sleep 1
+if [ -n "${appid}" ]; then
+	fn_install_server_files_steamcmd
+fi
+
+if [ -z "${appid}" ]||[ "${gamename}" == "GoldenEye: Source" ]; then
+	fn_install_server_files
+fi
+
+if [ -z "${autoinstall}" ]; then
+	echo ""
+	echo "================================="
+	while true; do
+	read -e -i "y" -p "Was the install successful? [Y/n]" yn
+		case $yn in
+			[Yy]* ) break;;
+			[Nn]* ) install_retry.sh;;
+			* ) echo "Please answer yes or no.";;
+		esac
+	done
+fi

+ 15 - 0
lgsm/functions/install_steamcmd.sh

@@ -0,0 +1,15 @@
+#!/bin/bash
+# LGSM install_steamcmd.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+# Description: Downloads SteamCMD on install.
+
+local modulename="Install"
+
+echo ""
+echo "Installing SteamCMD"
+echo "================================="
+sleep 1
+check_steamcmd.sh

+ 82 - 0
lgsm/functions/install_ts3.sh

@@ -0,0 +1,82 @@
+#!/bin/bash
+# LGSM install_ts3.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+info_distro.sh
+# Gets the teamspeak server architecture
+if [ "${arch}" == "x86_64" ]; then
+	ts3arch="amd64"
+elif [ "${arch}" == "i386" ]||[ "${arch}" == "i686" ]; then
+	ts3arch="x86"
+else
+	fn_print_failure "${arch} is an unsupported architecture"
+	exit 1
+fi
+
+# Grabs all version numbers but not in correct order
+wget "http://dl.4players.de/ts/releases/?C=M;O=D" -q -O -| grep -i dir | egrep -o '<a href=\".*\/\">.*\/<\/a>' | egrep -o '[0-9\.?]+'|uniq > .ts3_version_numbers_unsorted.tmp
+
+# Replaces dots with spaces to split up the number. e.g 3 0 12 1 is 3.0.12.1 this allows correct sorting
+ cat .ts3_version_numbers_unsorted.tmp | tr "." " " > .ts3_version_numbers_digit.tmp
+# Sorts versions in to correct order
+# merges 2 files and orders by each column in order allowing these version numbers to be sorted in order
+paste .ts3_version_numbers_digit.tmp .ts3_version_numbers_unsorted.tmp | awk '{print $1,$2,$3,$4 " " $0;}'| sort  -k1rn -k2rn -k3rn -k4rn | awk '{print $NF}' > .ts3_version_numbers.tmp
+
+# Finds directory with most recent server version.
+while read ts3_version_number; do
+	wget --spider -q "http://dl.4players.de/ts/releases/${ts3_version_number}/teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2"
+	if [ $? -eq 0 ]; then
+		availablebuild="${ts3_version_number}"
+		# Break while-loop, if the latest release could be found
+		break
+	fi
+done < .ts3_version_numbers.tmp
+
+# tidy up
+rm -f ".ts3_version_numbers_digit.tmp"
+rm -f ".ts3_version_numbers_unsorted.tmp"
+rm -f ".ts3_version_numbers.tmp"
+
+# Checks availablebuild info is available
+if [ -z "${availablebuild}" ]; then
+	fn_print_fail "Checking for update: teamspeak.com"
+	sleep 1
+	fn_print_fail "Checking for update: teamspeak.com: Not returning version info"
+	sleep 2
+	exit 1
+fi
+
+cd "${rootdir}"
+echo -e "downloading teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2...\c"
+wget -N /dev/null http://dl.4players.de/ts/releases/${ts3_version_number}/teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2 2>&1 | grep -F HTTP | cut -c45-| uniq
+sleep 1
+echo -e "extracting teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2...\c"
+tar -xf "teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2" 2> ".${servicename}-tar-error.tmp"
+local status=$?
+if [ ${status} -eq 0 ]; then
+	echo "OK"
+else
+	echo "FAIL - Exit status ${status}"
+	sleep 1
+	cat ".${servicename}-tar-error.tmp"
+	rm ".${servicename}-tar-error.tmp"
+	exit $?
+fi
+echo -e "copying to ${filesdir}...\c"
+cp -R "${rootdir}/teamspeak3-server_linux_${ts3arch}/"* "${filesdir}" 2> ".${servicename}-cp-error.tmp"
+local status=$?
+if [ ${status} -eq 0 ]; then
+	echo "OK"
+else
+	echo "FAIL - Exit status ${status}"
+	sleep 1
+	cat ".${servicename}-cp-error.tmp"
+	rm ".${servicename}-cp-error.tmp"
+	exit $?
+fi
+rm -f "teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2"
+rm -rf "${rootdir}/teamspeak3-server_linux_${ts3arch}"

+ 71 - 0
lgsm/functions/install_ts3db.sh

@@ -0,0 +1,71 @@
+#!/bin/bash
+# LGSM fn_install_ts3_mariadb function
+# Author: Daniel Gibbs
+# Contributor: PhilPhonic
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+fn_install_ts3db_mariadb(){
+	echo ""
+	echo "checking if libmariadb2 is installed"
+	echo "================================="
+	sleep 1
+	ldd ${filesdir}/libts3db_mariadb.so | grep "libmariadb.so.2 => not found"
+	if [ $? -eq 0 ]; then
+		echo "libmariadb2 not installed. Please install it first."
+		echo "exiting..."
+		exit
+	else
+		echo "libmariadb2 installed."
+	fi
+	echo ""
+	echo "Configuring ${gamename} Server for MariaDB/MySQL"
+	echo "================================="
+	sleep 1
+	read -p "Enter MariaDB hostname: " mariahostname
+	read -p "Enter MariaDB port: " mariaport
+	read -p "Enter MariaDB username: " mariausername
+	read -p "Enter MariaDB password: " mariapassword
+	read -p "Enter MariaDB database name: " mariadbname
+	echo "updating config."
+	echo "[config]" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "host='${mariahostname}'" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "port='${mariaport}'" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "username='${mariausername}'" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "password='${mariapassword}'" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "database='${mariadbname}'" >> ${servercfgdir}/ts3db_mariadb.ini
+	echo "socket=" >> ${servercfgdir}/ts3db_mariadb.ini	
+	sed -i "s/dbplugin=ts3db_sqlite3/dbplugin=ts3db_mariadb/g" "${servercfgfullpath}"
+	sed -i "s/dbpluginparameter=/dbpluginparameter=ts3db_mariadb.ini/g" "${servercfgfullpath}"
+	sed -i "s/dbsqlcreatepath=create_sqlite\//dbsqlcreatepath=create_mariadb\//g" "${servercfgfullpath}"
+	echo "================================="
+	sleep 1
+}
+
+if [ -z "${autoinstall}" ]; then
+	echo ""
+	while true; do
+		read -e -i "n" -p "Do you want to use MariaDB/MySQL instead of sqlite (Database Server including user and database already has to be set up!)? [y/N]" yn
+		case $yn in
+		[Yy]* ) fn_install_ts3db_mariadb && break;;
+		[Nn]* ) break;;
+		* ) echo "Please answer yes or no.";;
+		esac
+	done
+else
+fn_print_warning_nl "./${selfname} auto-install is uses sqlite. For MariaDB/MySQL use ./${selfname} install"
+fi
+
+## Get privilege key
+echo ""
+echo "Getting privilege key"
+echo "================================="
+sleep 1
+echo "IMPORANT! Save these details for later."
+sleep 1
+cd "${executabledir}"
+./ts3server_startscript.sh start inifile=ts3-server.ini
+sleep 5
+./ts3server_startscript.sh stop

+ 28 - 0
lgsm/functions/install_ut2k4_key.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+# LGSM install_ut2k4_key.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="271215"
+
+local modulename="Install"
+
+echo ""
+echo "Enter ${gamename} CD Key"
+echo "================================="
+sleep 1
+echo "To get your server listed on the Master Server list"
+echo "you must get a free CD key. Get a key here:"
+echo "http://www.unrealtournament.com/ut2004server/cdkey.php"
+echo ""
+if [ -z "${autoinstall}" ]; then
+	echo "Once you have the key enter it below"
+	echo -n "KEY: "
+	read CODE
+	echo ""\""CDKey"\""="\""${CODE}"\""" > "${systemdir}/cdkey"
+	if [ -f "${systemdir}/cdkey" ]; then
+	fn_scriptlog "UT2K4 Server CD Key created"
+else
+	echo "You can add your key using the following command"
+	echo "./${selfname} server-cd-key"
+fi	
+echo ""

+ 102 - 0
lgsm/functions/logs.sh

@@ -0,0 +1,102 @@
+#!/bin/bash
+# LGSM logs.sh function
+# Author: Daniel Gibbs
+# Contributor: UltimateByte
+# Website: http://gameservermanagers.com
+lgsm_version="230216"
+
+# Description: Acts as a log rotater, removing old logs.
+
+local modulename="Log Manager"
+
+# Check if logfile variable and file exist, create logfile if it doesn't exist
+if [ -n "${consolelog}" ]; then
+	if [ ! -e "${consolelog}" ]; then
+		touch "${consolelog}"
+	fi
+fi
+
+# For games not displaying a console, and having logs into their game folder
+if [ -n "${gamelogfile}" ]; then
+	if [ -n "$(find "${systemdir}" -name "gamelog*.log")" ]; then
+		fn_printinfo "Moving game logs to ${gamelogdir}"
+		fn_scriptlog "Moving game logs to ${gamelogdir}"
+		echo -en "\n"
+		sleep 1
+		mv "${systemdir}"/gamelog*.log "${gamelogdir}"
+	fi
+fi
+
+# Log manager will start the cleanup if it finds logs older than "${logdays}"
+if [ $(find "${scriptlogdir}"/ -type f -mtime +"${logdays}"|wc -l) -ne "0" ]; then
+	fn_print_dots "Starting"
+	# Set addon logs directories
+	sourcemodlogdir="${systemdir}/addons/sourcemod/logs"
+	ulxlogdir="${systemdir}/data/ulx_logs"
+	darkrplogdir="${systemdir}/data/darkrp_logs"
+	legacyserverlogdir="${rootdir}/log/server"
+	# Setting up counting variables
+	scriptcount="0" ; consolecount="0" ; gamecount="0" ; srcdscount="0" ; smcount="0" ; ulxcount="0" ; darkrpcount="0" ; legacycount="0"
+	sleep 1
+	fn_print_ok_nl "Starting"
+	fn_scriptlog "Starting"
+	fn_print_info_nl "Removing logs older than "${logdays}" days"
+	fn_scriptlog "Removing logs older than "${logdays}" days"
+	# Logging logfiles to be removed according to "${logdays}", counting and removing them
+	# Script logfiles
+	find "${scriptlogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+	scriptcount=$(find "${scriptlogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+	find "${scriptlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+	# SRCDS and unreal logfiles
+	if [ "${engine}" == "unreal2" ]||[ "${engine}" == "source" ]; then
+		find "${gamelogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+		gamecount=$(find "${gamelogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+		find "${gamelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+	fi
+	# Console logfiles
+	if [ -n "${consolelog}" ]; then
+		find "${consolelogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+		consolecount=$(find "${consolelogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+		find "${consolelogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+	fi
+	# Source addons logfiles
+	if [ "${engine}" == "source" ]; then
+		# SourceMod logfiles
+		if [ -d "${sourcemodlogdir}" ]; then
+			find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+			smcount=$(find "${sourcemodlogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+			find "${sourcemodlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+		fi
+		# Garry's Mod logfiles
+		if [ "${gamename}" == "Garry's Mod" ]; then
+			# ULX logfiles
+			if [ -d "${ulxlogdir}" ]; then
+				find "${ulxlogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+				ulxcount=$(find "${ulxlogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+				find "${ulxlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+			fi
+			# DarkRP logfiles
+			if [ -d "${darkrplogdir}" ]; then
+				find "${darkrplogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+				darkrpcount=$(find "${darkrplogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+				find "${darkrplogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+			fi
+		fi
+	fi
+	# Legacy support
+	if [ -d "${legacyserverlogdir}" ]; then
+		find "${legacyserverlogdir}"/ -type f -mtime +"${logdays}"| tee >> "${scriptlog}"
+		legacycount=$(find "${legacyserverlogdir}"/ -type f -mtime +"${logdays}"|wc -l)
+		find "${legacyserverlogdir}"/ -mtime +"${logdays}" -type f -exec rm -f {} \;
+		# Remove folder if empty
+		if [ ! "$(ls -A "${legacyserverlogdir}")" ]; then
+		rm -rf "${legacyserverlogdir}"
+		fi
+	fi
+				
+	# Count total amount of files removed
+	count=$((${scriptcount} + ${consolecount} + ${gamecount} + ${srcdscount} + ${smcount} + ${ulxcount} + ${darkrpcount} + ${legacycount}))
+	# Job done
+	fn_print_ok_nl "Removed ${count} log files"
+	fn_scriptlog "Removed ${count} log files"
+fi

+ 93 - 0
lgsm/functions/monitor_gsquery.sh

@@ -0,0 +1,93 @@
+#!/bin/bash
+# LGSM monitor_gsquery.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="270216"
+
+# Description: uses gsquery.py to query the server port.
+# Detects if the server has frozen with the proccess still running.
+
+local modulename="Monitor"
+
+# Forces legecy servers to use gsquery as vat gsquery is not present in legecy
+if [ -z "${gsquery}" ]; then
+	gsquery="yes"
+fi	 
+
+if [ "${gsquery}" == "yes" ]; then
+
+	# Downloads gsquery.py if missing
+	if [ ! -f "${functionsdir}/gsquery.py" ]; then
+		fn_fetch_file_github "functions" "gsquery.py" "${functionsdir}" "executecmd" "norun" "noforce" "nomd5"
+	fi	
+
+	info_config.sh
+
+	if [ "${engine}" == "unreal" ]||[ "${engine}" == "unreal2" ]; then
+		port=$((port + 1))
+	elif [ "${engine}" == "spark" ]; then
+		port=$((port + 1))
+	fi
+
+	if [ -z "${queryport}" ]; then
+		port="${queryport}"
+	fi
+
+	fn_print_info "Querying port: gsquery.py enabled"
+	fn_scriptlog "Querying port: gsquery.py enabled"
+	sleep 1
+
+	# Will query up to 4 times every 15 seconds.
+	# Servers changing map can return a failure.
+	# Will Wait up to 60 seconds to confirm server is down giving server time to change map.
+	totalseconds=0
+	for queryattempt in {1..5}; do
+		fn_print_dots "Querying port: ${ip}:${port} : ${totalseconds}/${queryattempt} : "
+		fn_print_querying_eol
+		fn_scriptlog "Querying port: ${ip}:${port} : ${queryattempt} : QUERYING"
+		
+		gsquerycmd=$("${functionsdir}"/gsquery.py -a "${ip}" -p 1 -e "${engine}" 2>&1)
+		exitcode=$?
+
+		sleep 1
+		if [ "${exitcode}" == "0" ]; then
+			# Server OK
+			fn_print_ok "Querying port: ${ip}:${port} : ${queryattempt} : "
+			fn_print_ok_eol
+			fn_scriptlog "Querying port: ${ip}:${port} : ${queryattempt} : OK"
+			sleep 1
+			exit
+		else
+			# Server failed query
+			fn_scriptlog "Querying port: ${ip}:${port} : ${queryattempt} : ${gsquerycmd}"
+
+			if [ "${queryattempt}" == "5" ]; then
+				# Server failed query 4 times confirmed failure
+				fn_print_fail "Querying port: ${ip}:${port} : ${totalseconds}/${queryattempt} : "
+				fn_print_fail_eol_nl
+				fn_scriptlog "Querying port: ${ip}:${port} : ${queryattempt} : FAIL"
+				sleep 1
+
+				# Send email notification if enabled
+				if [ "${emailnotification}" == "on" ]; then
+					subject="${servicename} Monitor - Starting ${servername}"
+					failurereason="Failed to query ${servicename}: ${gsquerycmd}"
+					actiontaken="restarted ${servicename}"
+					email.sh
+				fi
+				fn_restart
+				break
+			fi
+
+			# Seconds counter
+			for seconds in {1..15}; do
+				fn_print_fail "Querying port: ${ip}:${port} : ${totalseconds}/${queryattempt} : \e[0;31m${gsquerycmd}\e[0m"
+				totalseconds=$((totalseconds + 1))
+				sleep 1
+				if [ "${seconds}" == "15" ]; then
+					break
+				fi
+			done
+		fi
+	done
+fi

+ 326 - 0
lgsm/functions/update_check.sh

@@ -0,0 +1,326 @@
+#!/bin/bash
+# LGSM update_check.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="060216"
+
+# Description: Checks if a server update is available.
+
+local modulename="Update"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+### SteamCMD Update Checker ###
+
+fn_appmanifestinfo(){
+	appmanifestfile=$(find "${filesdir}" -type f -name "appmanifest_${appid}.acf")
+	appmanifestfilewc=$(find "${filesdir}" -type f -name "appmanifest_${appid}.acf"|wc -l)
+}
+
+fn_appmanifestcheck(){
+fn_appmanifestinfo
+# Multiple or no matching appmanifest files may sometimes be available.
+# This is an error is corrected below if required.
+if [ "${appmanifestfilewc}" -ge "2" ]; then
+	sleep 1
+	fn_print_warn "Multiple appmanifest_${appid}.acf files found"
+	fn_scriptlog "Warning! Multiple appmanifest_${appid}.acf files found"
+	sleep 2
+	fn_print_dots "Removing x${appmanifestfilewc} appmanifest_${appid}.acf files"
+	sleep 1
+	for appfile in ${appmanifestfile}; do
+		rm "${appfile}"
+	done
+	appmanifestfilewc1="${appmanifestfilewc}"
+	fn_appmanifestinfo
+	if [ "${appmanifestfilewc}" -ge "2" ]; then
+		fn_print_fail "Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files"
+		fn_scriptlog "Failure! Unable to remove x${appmanifestfilewc} appmanifest_${appid}.acf files"
+		sleep 1
+		echo ""
+		echo "	Check user permissions"
+		for appfile in ${appmanifestfile}; do
+			echo "	${appfile}"
+		done
+		exit 1
+	else
+		sleep 1
+		fn_print_ok "Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files"
+		fn_scriptlog "Success! Removed x${appmanifestfilewc1} appmanifest_${appid}.acf files"
+		sleep 1
+		fn_print_info_nl "Forcing update to correct issue"
+		fn_scriptlog "Forcing update to correct issue"
+		sleep 1
+		update_dl.sh
+		update_check.sh
+	fi
+elif [ "${appmanifestfilewc}" -eq "0" ]; then
+	if [ "${forceupdate}" == "1" ]; then
+		fn_print_fail "Still no appmanifest_${appid}.acf found: Unable to update"
+		fn_scriptlog "Warning! Still no appmanifest_${appid}.acf found: Unable to update"
+		exit 1
+	fi
+	forceupdate=1
+	fn_print_warn "No appmanifest_${appid}.acf found"
+	fn_scriptlog "Warning! No appmanifest_${appid}.acf found"
+	sleep 2
+	fn_print_info_nl "Forcing update to correct issue"
+	fn_scriptlog "Forcing update to correct issue"
+	sleep 1
+	update_dl.sh
+	update_check.sh
+fi
+}
+
+fn_logupdaterequest(){
+# Checks for server update requests from server logs.
+fn_print_dots "Checking for update: Server logs"
+fn_scriptlog "Checking for update: Server logs"
+sleep 1
+requestrestart=$(grep -Ec "MasterRequestRestart" "${consolelog}")
+if [ "${requestrestart}" -ge "1" ]; then
+	fn_print_ok_nl "Checking for update: Server logs: Update requested"
+	sleep 1
+	echo ""
+	echo -ne "Applying update.\r"
+	sleep 1
+	echo -ne "Applying update..\r"
+	sleep 1
+	echo -ne "Applying update...\r"
+	sleep 1
+	echo -ne "\n"
+	tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+	unset updateonstart
+	if [ "${tmuxwc}" -eq 1 ]; then
+		command_stop.sh
+		update_dl.sh
+		command_start.sh
+	else
+		update_dl.sh
+	fi
+else
+	fn_print_ok "Checking for update: Server logs: No update requested"
+	sleep 1
+fi
+}
+
+fn_steamcmdcheck(){
+fn_appmanifestcheck
+# Checks for server update from SteamCMD
+fn_print_dots "Checking for update: SteamCMD"
+fn_scriptlog "Checking for update: SteamCMD"
+sleep 1
+
+# Gets currentbuild
+currentbuild=$(grep buildid "${appmanifestfile}" | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d\  -f3)
+
+# Removes appinfo.vdf as a fix for not always getting up to date version info from SteamCMD
+
+# Gets availablebuild info
+cd "${rootdir}/steamcmd"
+if [ -f "${HOME}/Steam/appcache/appinfo.vdf" ]; then
+	rm -f "${HOME}/Steam/appcache/appinfo.vdf"
+fi
+availablebuild=$(./steamcmd.sh +login "${steamuser}" "${steampass}" +app_info_update 1 +app_info_print "${appid}" +app_info_print "${appid}" +quit | grep -EA 1000 "^\s+\"branches\"$" | grep -EA 5 "^\s+\"public\"$" | grep -m 1 -EB 10 "^\s+}$" | grep -E "^\s+\"buildid\"\s+" | tr '[:blank:]"' ' ' | tr -s ' ' | cut -d\  -f3)
+if [ -z "${availablebuild}" ]; then
+	fn_print_fail "Checking for update: SteamCMD"
+	fn_scriptlog "Failure! Checking for update: SteamCMD"
+	sleep 1
+	fn_print_fail_nl "Checking for update: SteamCMD: Not returning version info"
+	fn_scriptlog "Failure! Checking for update: SteamCMD: Not returning version info"
+	exit 1
+else
+	fn_print_ok "Checking for update: SteamCMD"
+	fn_scriptlog "Success! Checking for update: SteamCMD"
+	sleep 1
+fi
+
+if [ "${currentbuild}" != "${availablebuild}" ]; then
+	echo -e "\n"
+	echo -e "Update available:"
+	sleep 1
+	echo -e "	Current build: \e[0;31m${currentbuild}\e[0;39m"
+	echo -e "	Available build: \e[0;32m${availablebuild}\e[0;39m"
+	echo -e ""
+	echo -e "	https://steamdb.info/app/${appid}/"
+	sleep 1
+	echo ""
+	echo -en "Applying update.\r"
+	sleep 1
+	echo -en "Applying update..\r"
+	sleep 1
+	echo -en "Applying update...\r"
+	sleep 1
+	echo -en "\n"
+	fn_scriptlog "Update available"
+	fn_scriptlog "Current build: ${currentbuild}"
+	fn_scriptlog "Available build: ${availablebuild}"
+	fn_scriptlog "${currentbuild} > ${availablebuild}"
+
+	tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+	unset updateonstart
+	if [ "${tmuxwc}" -eq 1 ]; then
+		command_stop.sh
+		update_dl.sh
+		command_start.sh
+	else
+		update_dl.sh
+	fi
+else
+	echo -e "\n"
+	echo -e "No update available:"
+	echo -e "	Current version: \e[0;32m${currentbuild}\e[0;39m"
+	echo -e "	Available version: \e[0;32m${availablebuild}\e[0;39m"
+	echo -e "	https://steamdb.info/app/${appid}/"
+	echo -e ""
+	fn_print_ok_nl "No update available"
+	fn_scriptlog "Current build: ${currentbuild}"
+	fn_scriptlog "Available build: ${availablebuild}"
+fi
+}
+
+### END SteamCMD Update Checker ###
+
+fn_teamspeak3_check(){
+# Checks for server update from teamspeak.com using a mirror dl.4players.de
+fn_print_dots "Checking for update: teamspeak.com"
+fn_scriptlog "Checking for update: teamspeak.com"
+sleep 1
+
+# Gets currentbuild info
+# Checks currentbuild info is available, if fails a server restart will be forced to generate logs
+if [ -z "$(find ./* -name 'ts3server*_0.log')" ]; then
+	fn_print_fail "Checking for update: teamspeak.com"
+	sleep 1
+	fn_print_fail_nl "Checking for update: teamspeak.com: No logs with server version found"
+	fn_scriptlog "Failure! Checking for update: teamspeak.com: No logs with server version found"
+	sleep 2
+	fn_print_info_nl "Checking for update: teamspeak.com: Forcing server restart"
+	fn_scriptlog "Checking for update: teamspeak.com: Forcing server restart"
+	sleep 2
+	command_stop.sh
+	command_start.sh
+	sleep 2
+	# If still failing will exit
+	if [ -z "$(find ./* -name 'ts3server*_0.log')" ]; then
+		fn_print_fail_nl "Checking for update: teamspeak.com: Still No logs with server version found"
+		fn_scriptlog "Failure! Checking for update: teamspeak.com: Still No logs with server version found"
+		exit 1
+	fi
+fi
+currentbuild=$(cat $(find ./* -name 'ts3server*_0.log' 2> /dev/null | sort | egrep -E -v '${rootdir}/.ts3version' | tail -1) | egrep -o 'TeamSpeak 3 Server ((\.)?[0-9]{1,3}){1,3}\.[0-9]{1,3}' | egrep -o '((\.)?[0-9]{1,3}){1,3}\.[0-9]{1,3}')
+
+# Gets the teamspeak server architecture
+info_distro.sh
+if [ "${arch}" == "x86_64" ]; then
+	ts3arch="amd64"
+elif [ "${arch}" == "i386" ]||[ "${arch}" == "i686" ]; then
+	ts3arch="x86"
+else
+	echo ""
+	fn_print_failure "${arch} is an unsupported architecture"
+	exit 1
+fi
+ 
+# Gets availablebuild info
+
+# Grabs all version numbers but not in correct order
+wget "http://dl.4players.de/ts/releases/?C=M;O=D" -q -O -| grep -i dir | egrep -o '<a href=\".*\/\">.*\/<\/a>' | egrep -o '[0-9\.?]+'|uniq > .ts3_version_numbers_unsorted.tmp
+
+# Sort version numbers
+cat .ts3_version_numbers_unsorted.tmp | sort -r --version-sort -o .ts3_version_numbers_sorted.tmp
+
+# Finds directory with most recent server version.
+while read ts3_version_number; do
+	wget --spider -q "http://dl.4players.de/ts/releases/${ts3_version_number}/teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2"
+	if [ $? -eq 0 ]; then
+		availablebuild="${ts3_version_number}"
+		# Break while-loop, if the latest release could be found
+		break
+	fi
+done < .ts3_version_numbers_sorted.tmp
+
+# Tidy up
+rm -f ".ts3_version_numbers_unsorted.tmp"
+rm -f ".ts3_version_numbers_sorted.tmp"
+
+# Checks availablebuild info is available
+if [ -z "${availablebuild}" ]; then
+	fn_print_fail "Checking for update: teamspeak.com"
+	fn_scriptlog "Checking for update: teamspeak.com"
+	sleep 1
+	fn_print_fail "Checking for update: teamspeak.com: Not returning version info"
+	fn_scriptlog "Failure! Checking for update: teamspeak.com: Not returning version info"
+	sleep 2
+	exit 1
+else
+	fn_print_ok "Checking for update: teamspeak.com"
+	fn_scriptlog "Success! Checking for update: teamspeak.com"
+	sleep 1
+fi
+
+# Removes dots so if can compare version numbers
+currentbuilddigit=$(echo "${currentbuild}"|tr -cd '[:digit:]')
+availablebuilddigit=$(echo "${availablebuild}"|tr -cd '[:digit:]')
+if [ "${currentbuilddigit}" -ne "${availablebuilddigit}" ]; then
+	echo -e "\n"
+	echo -e "Update available:"
+	sleep 1
+	echo -e "	Current build: \e[0;31m${currentbuild} ${architecture}\e[0;39m"
+	echo -e "	Available build: \e[0;32m${availablebuild} ${architecture}\e[0;39m"
+	echo -e ""
+	sleep 1
+	echo ""
+	echo -en "Applying update.\r"
+	sleep 1
+	echo -en "Applying update..\r"
+	sleep 1
+	echo -en "Applying update...\r"
+	sleep 1
+	echo -en "\n"
+	fn_scriptlog "Update available"
+	fn_scriptlog "Current build: ${currentbuild}"
+	fn_scriptlog "Available build: ${availablebuild}"
+	fn_scriptlog "${currentbuild} > ${availablebuild}"
+	unset updateonstart
+	info_ts3status.sh
+	if [ "${ts3status}" = "No server running (ts3server.pid is missing)" ]; then
+		update_dl.sh
+		command_start.sh
+		sleep 5
+		command_stop.sh
+	else
+		command_stop.sh
+		update_dl.sh
+		command_start.sh
+	fi
+else
+	echo -e "\n"
+	echo -e "No update available:"
+	echo -e "	Current version: \e[0;32m${currentbuild}\e[0;39m"
+	echo -e "	Available version: \e[0;32m${availablebuild}\e[0;39m"
+	echo -e ""
+	fn_print_ok_nl "No update available"
+	fn_scriptlog "Current build: ${currentbuild}"
+	fn_scriptlog "Available build: ${availablebuild}"
+fi
+}
+
+check.sh
+fn_print_dots "Checking for update"
+if [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_teamspeak3_check
+elif [ "${engine}" == "goldsource" ]||[ "${forceupdate}" == "1" ]; then
+	# Goldsource servers bypass checks as fn_steamcmdcheck does not work for appid 90 servers.
+	# forceupdate bypasses checks
+	tmuxwc=$(tmux list-sessions 2>&1|awk '{print $1}'|grep -v failed|grep -Ec "^${servicename}:")
+	if [ "${tmuxwc}" -eq 1 ]; then
+		command_stop.sh
+		update_dl.sh
+		command_start.sh
+	else
+		update_dl.sh
+	fi
+else
+	fn_logupdaterequest
+	fn_steamcmdcheck
+fi

+ 83 - 0
lgsm/functions/update_dl.sh

@@ -0,0 +1,83 @@
+#!/bin/bash
+# LGSM update_dl.sh function
+# Author: Daniel Gibbs
+# Website: http://gameservermanagers.com
+lgsm_version="020216"
+
+# Description: Runs a server update.
+
+local modulename="Update"
+function_selfname="$(basename $(readlink -f "${BASH_SOURCE[0]}"))"
+
+fn_steamcmd_dl(){
+cd "${rootdir}"
+cd "steamcmd"
+
+# Detects if unbuffer command is available.
+if [ $(command -v unbuffer) ]; then
+	unbuffer=unbuffer
+fi
+
+if [ "${engine}" == "goldsource" ]; then
+	${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_set_config 90 mod ${appidmod} +app_update "${appid}" +quit| tee -a "${scriptlog}"
+else
+	${unbuffer} ./steamcmd.sh +login "${steamuser}" "${steampass}" +force_install_dir "${filesdir}" +app_update "${appid}" +quit| tee -a "${scriptlog}"
+fi
+
+fix.sh
+}
+
+fn_teamspeak3_dl(){
+cd "${rootdir}"
+echo -e "downloading teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2...\c"
+fn_scriptlog "Downloading teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2"
+wget -N /dev/null http://dl.4players.de/ts/releases/${ts3_version_number}/teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2 2>&1 | grep -F HTTP | cut -c45-| uniq
+sleep 1
+echo -e "extracting teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2...\c"
+fn_scriptlog "Extracting teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2"
+tar -xf "teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2" 2> "${scriptlogdir}/.${servicename}-tar-error.tmp"
+local status=$?
+if [ ${status} -eq 0 ]; then
+	echo "OK"
+else
+	echo "FAIL - Exit status ${status}"
+	fn_scriptlog "Failed to extract - Exit status ${status}"
+	sleep 1
+	cat "${scriptlogdir}/.${servicename}-tar-error.tmp"
+	cat "${scriptlogdir}/.${servicename}-tar-error.tmp" >> "${scriptlog}"
+	rm "${scriptlogdir}/.${servicename}-tar-error.tmp"
+	fn_scriptlog "Failure! Unable to update"
+	exit ${status}
+fi
+echo -e "copying to ${filesdir}...\c"
+fn_scriptlog "Copying to ${filesdir}"
+cp -R "${rootdir}/teamspeak3-server_linux_${ts3arch}/"* "${filesdir}" 2> "${scriptlogdir}/.${servicename}-cp-error.tmp"
+local status=$?
+if [ ${status} -eq 0 ]; then
+	echo "OK"
+else
+	echo "FAIL - Exit status ${status}"
+	fn_scriptlog "Failed to copy - Exit status ${status}"
+	sleep 1
+	cat "${scriptlogdir}/.${servicename}-cp-error.tmp"
+	cat "${scriptlogdir}/.${servicename}-cp-error.tmp" >> "${scriptlog}"
+	rm "${scriptlogdir}/.${servicename}-cp-error.tmp"
+	fn_scriptlog "Failure! Unable to update"
+	exit ${status}
+fi
+rm -f teamspeak3-server_linux_${ts3arch}-${ts3_version_number}.tar.bz2
+rm -rf "${rootdir}/teamspeak3-server_linux_${ts3arch}"
+}
+
+check.sh
+info_config.sh
+fn_print_dots "Updating ${servername}"
+sleep 1
+fn_print_ok_nl "Updating ${servername}"
+fn_scriptlog "Updating ${servername}"
+sleep 1
+if [ "${gamename}" == "Teamspeak 3" ]; then
+	fn_teamspeak3_dl
+else
+	fn_steamcmd_dl
+fi