command_monitor.sh 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #!/bin/bash
  2. # LinuxGSM command_monitor.sh function
  3. # Author: Daniel Gibbs
  4. # Contributor: UltimateByte
  5. # Website: https://linuxgsm.com
  6. # Description: Monitors server by checking for running processes
  7. # then passes to gamedig and gsquery.
  8. local commandname="MONITOR"
  9. local commandaction="Monitor"
  10. local function_selfname="$(basename "$(readlink -f "${BASH_SOURCE[0]}")")"
  11. fn_monitor_loop(){
  12. # Monitor will query up to 5 times every 15 seconds.
  13. # Query will wait up to 60 seconds to confirm server is down giving server time if changing map.
  14. totalseconds=0
  15. for queryattempt in {1..5}; do
  16. fn_print_dots "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: "
  17. fn_print_querying_eol
  18. fn_script_log_info "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt} : QUERYING"
  19. if [ "$(cat "${rootdir}/${lockselfname}")" -gt "$(date "+%s" -d "${querydelay} mins ago")" ]; then
  20. fn_print_ok "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: "
  21. fn_print_delay_eol
  22. fn_script_log_info "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt} : DELAY"
  23. fn_script_log_info "Query bypassed: ${gameservername} started less than ${querydelay} minute ago"
  24. monitorpass=1
  25. core_exit.sh
  26. elif [ "${querymethod}" == "gamedig" ]; then
  27. query_gamedig.sh
  28. elif [ "${querymethod}" == "gsquery" ]; then
  29. if [ ! -f "${functionsdir}/query_gsquery.py" ]; then
  30. fn_fetch_file_github "lgsm/functions" "query_gsquery.py" "${functionsdir}" "chmodx" "norun" "noforce" "nomd5"
  31. fi
  32. "${functionsdir}"/query_gsquery.py -a "${ip}" -p "${queryport}" -e "${engine}" > /dev/null 2>&1
  33. querystatus="$?"
  34. elif [ "${querymethod}" == "tcp" ]; then
  35. bash -c 'exec 3<> /dev/tcp/'${ip}'/'${queryport}''
  36. querystatus="$?"
  37. elif [ "${querymethod}" == "udp" ]; then
  38. bash -c 'exec 3<> /dev/udp/'${ip}'/'${queryport}''
  39. querystatus="$?"
  40. fi
  41. if [ "${querystatus}" == "0" ]; then
  42. # Server query OK.
  43. fn_print_ok "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: "
  44. fn_print_ok_eol_nl
  45. fn_script_log_pass "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt}: OK"
  46. monitorpass=1
  47. core_exit.sh
  48. else
  49. # Server query FAIL.
  50. fn_script_log_info "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt}: FAIL"
  51. fn_print_fail "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: "
  52. fn_print_fail_eol
  53. # Monitor try gamedig first then gsquery before restarting.
  54. if [ "${querymethod}" == "gsquery" ]; then
  55. if [ "${totalseconds}" -ge "59" ]; then
  56. # Server query FAIL for over 59 seconds reboot server.
  57. fn_print_fail "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: "
  58. fn_print_fail_eol_nl
  59. fn_script_log_error "Querying port: ${querymethod}: ${ip}:${queryport} : ${queryattempt}: FAIL"
  60. # Send alert if enabled.
  61. alert="restartquery"
  62. alert.sh
  63. command_restart.sh
  64. core_exit.sh
  65. fi
  66. elif [ "${querymethod}" == "gamedig" ]; then
  67. if [ "${totalseconds}" -ge "29" ]; then
  68. break
  69. fi
  70. fi
  71. # Seconds counter.
  72. for seconds in {1..15}; do
  73. fn_print_fail "Querying port: ${querymethod}: ${ip}:${queryport} : ${totalseconds}/${queryattempt}: WAIT"
  74. totalseconds=$((totalseconds + 1))
  75. if [ "${seconds}" == "15" ]; then
  76. break
  77. fi
  78. done
  79. fi
  80. done
  81. }
  82. fn_monitor_check_lockfile(){
  83. # Monitor does not run it lockfile is not found.
  84. if [ ! -f "${rootdir}/${lockselfname}" ]; then
  85. fn_print_error_nl "Disabled: No lockfile found"
  86. fn_script_log_error "Disabled: No lockfile found"
  87. echo " * To enable monitor run ./${selfname} start"
  88. core_exit.sh
  89. fi
  90. }
  91. fn_monitor_check_update(){
  92. # Monitor will not check if update is running.
  93. if [ "$(ps -ef | grep "${selfname} update" | grep -v grep | wc -l)" != "0" ]; then
  94. fn_print_error_nl "SteamCMD is currently checking for updates"
  95. fn_script_log_error "SteamCMD is currently checking for updates"
  96. core_exit.sh
  97. fi
  98. }
  99. fn_monitor_check_session(){
  100. fn_print_dots "Checking session: "
  101. fn_print_checking_eol
  102. fn_script_log_info "Checking session: CHECKING"
  103. if [ "${status}" != "0" ]; then
  104. fn_print_ok "Checking session: "
  105. fn_print_ok_eol_nl
  106. fn_script_log_pass "Checking session: OK"
  107. else
  108. if [ "${shortname}" == "ts3" ]; then
  109. fn_print_error "Checking session: ${ts3error}: "
  110. elif [ "${shortname}" == "mumble" ]; then
  111. fn_print_error "Checking session: Not listening to port ${queryport}"
  112. else
  113. fn_print_error "Checking session: "
  114. fi
  115. fn_print_fail_eol_nl
  116. fn_script_log_error "Checking session: FAIL"
  117. alert="restart"
  118. alert.sh
  119. fn_script_log_info "Monitor is starting ${servername}"
  120. command_restart.sh
  121. core_exit.sh
  122. fi
  123. }
  124. fn_monitor_query(){
  125. fn_script_log_info "Querying port: query enabled"
  126. # Engines that work with query.
  127. local allowed_engines_array=( avalanche2.0 avalanche3.0 barotrauma goldsource idtech2 idtech3 idtech3_ql ioquake3 iw2.0 iw3.0 lwjgl2 madness quake refractor realvirtuality source spark starbound unity3d unreal unreal2 unreal4 wurm )
  128. for allowed_engine in "${allowed_engines_array[@]}"
  129. do
  130. if [ "${allowed_engine}" == "${engine}" ]; then
  131. if [ "${engine}" == "idtech3_ql" ]; then
  132. local engine="quakelive"
  133. elif [ "${shortname}" == "kf2" ]; then
  134. local engine="unreal4"
  135. fi
  136. # Will first attempt to use gamedig then gsquery.
  137. totalseconds=0
  138. if [ "${shortname}" == "wurm" ]; then
  139. local query_methods_array=( gsquery )
  140. else
  141. local query_methods_array=( gamedig gsquery )
  142. fi
  143. for query_method in "${query_methods_array[@]}"
  144. do
  145. if [ "${query_method}" == "gamedig" ]; then
  146. # Will bypass gamedig if not installed.
  147. if [ "$(command -v gamedig 2>/dev/null)" ]&&[ "$(command -v jq 2>/dev/null)" ]; then
  148. if [ -z "${monitorpass}" ]; then
  149. querymethod="${query_method}"
  150. fn_monitor_loop
  151. fi
  152. fi
  153. else
  154. if [ -z "${monitorpass}" ]; then
  155. querymethod="${query_method}"
  156. fn_monitor_loop
  157. fi
  158. fi
  159. done
  160. fi
  161. done
  162. }
  163. fn_monitor_query_tcp(){
  164. querymethod="tcp"
  165. fn_monitor_loop
  166. }
  167. fn_monitor_query_upd(){
  168. querymethod="upd"
  169. fn_monitor_loop
  170. }
  171. monitorflag=1
  172. fn_print_dots "${servername}"
  173. check.sh
  174. logs.sh
  175. info_config.sh
  176. info_parms.sh
  177. fn_monitor_check_lockfile
  178. fn_monitor_check_update
  179. fn_monitor_check_session
  180. # Fix if lockfile is not unix time or contains letters
  181. if [[ "$(cat "${rootdir}/${lockselfname}")" =~ [A-Za-z] ]]; then
  182. date '+%s' > "${rootdir}/${lockselfname}"
  183. fi
  184. # Add a query bypass if missing
  185. if [ -z "${querydelay}" ]; then
  186. querydelay="1"
  187. fi
  188. # Query has to be enabled in Starbound config.
  189. if [ "${shortname}" == "sb" ]; then
  190. if [ "${queryenabled}" == "true" ]; then
  191. fn_monitor_query
  192. fi
  193. elif [ "${shortname}" == "ts3" ]||[ "${shortname}" == "eco" ]||[ "${shortname}" == "mumble" ]; then
  194. fn_monitor_query_tcp
  195. else
  196. fn_monitor_query
  197. fi
  198. core_exit.sh