run_server.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #!/bin/sh
  2. #
  3. # (C) 2018 Dawid Gan, under the GPLv3
  4. #
  5. # A script that manages STK servers
  6. #
  7. export SELF_PID=$$
  8. export BASENAME="$(basename "$0")"
  9. export DIRNAME="$(dirname "$(readlink -f "$0")")"
  10. export DATETIME="$(date +%Y%m%d%H%M%S)"
  11. ############## General info ##############
  12. # Usage:
  13. #
  14. # Start all servers and close the script:
  15. # run_server.sh start
  16. #
  17. # Start all servers and keep the script running and testing if servers are
  18. # alive:
  19. # run_server.sh startdaemon
  20. #
  21. # Stop all servers and close the running daemon:
  22. # run_server.sh stop
  23. #
  24. # By default the script works with following directories structure
  25. # --- stk-server/
  26. # ----- data/
  27. # ----- supertuxkart
  28. # ----- run_server.sh
  29. ################# Config #################
  30. ### General ###
  31. # Server name, make sure that it's unique
  32. export SERVER_NAME="STK Server"
  33. # Login for STK account
  34. export LOGIN="xxx"
  35. # Password for STK account
  36. export PASS="yyy"
  37. ### Paths ###
  38. # A path for STK server binary file
  39. export CMD="$DIRNAME/supertuxkart"
  40. # A path in which "data" directory is placed
  41. export SUPERTUXKART_DATADIR="$DIRNAME"
  42. # A path for STK assets
  43. export SUPERTUXKART_ASSETS_DIR="$DIRNAME/data/"
  44. # A path to config template for additional options
  45. export CONFIG_FILE="$DIRNAME/config_template.xml"
  46. # A path to server config template for additional options
  47. export SERVER_CONFIG="$DIRNAME/server_config_template.xml"
  48. # A path for configuration files
  49. export HOME="/tmp/stk-server/.config"
  50. # A path where logs will be saved
  51. export STDOUT_DIR="/tmp/stk-server/"
  52. ### Daemon mode ###
  53. # How often the script should check if servers are alive
  54. export SLEEP_TIME=300
  55. # How many times the script should try to recreate servers
  56. export MAX_CREATION_RETRIES=100
  57. # Determines if the script should parse stdout.log files to see if servers are
  58. # alive. Set it to 0 to disable.
  59. export CHECK_SERVERS=0
  60. # A path to the application that can be used to show GUI messages when error
  61. # ocurred, server crashed etc. Atm. it will only work with xmessage/gxmessage.
  62. # Zenity and other apps need additional args.
  63. export MESSAGE_CMD="/usr/bin/xmessage"
  64. # Max number of messages that can be showed at the same time. Set it to 0 to
  65. # disable.
  66. export MAX_MESSAGES=3
  67. ##########################################
  68. show_message()
  69. {
  70. export MESSAGE="$1"
  71. if [ -z "$MESSAGE" ]; then
  72. return
  73. fi
  74. echo "$MESSAGE"
  75. if [ ! -x "$MESSAGE_CMD" ]; then
  76. return
  77. fi
  78. if [ ! -z "$TERM" ] && [ "$TERM" != "dumb" ]; then
  79. return
  80. fi
  81. if [ $(pidof -x "$MESSAGE_CMD" | wc -w) -ge $MAX_MESSAGES ]; then
  82. return
  83. fi
  84. "$MESSAGE_CMD" "$MESSAGE" &
  85. }
  86. run_servers()
  87. {
  88. echo "Info: Run servers"
  89. "$CMD" --ranked \
  90. --owner-less \
  91. --disable-polling \
  92. --max-players=8 \
  93. --min-players=2 \
  94. --difficulty=3 \
  95. --mode=0 \
  96. --port=2760 \
  97. --wan-server="$SERVER_NAME Ranked" \
  98. --stdout="$DATETIME-normal.log" \
  99. --stdout-dir="$STDOUT_DIR" \
  100. --no-console-log \
  101. --no-firewalled-server \
  102. --log=0 &> /dev/null &
  103. sleep 5
  104. #~ "$CMD" --no-ranked \
  105. #~ --owner-less \
  106. #~ --disable-polling \
  107. #~ --max-players=8 \
  108. #~ --min-players=2 \
  109. #~ --difficulty=2 \
  110. #~ --mode=3 \
  111. #~ --soccer-goals \
  112. #~ --port=2761 \
  113. #~ --wan-server="$SERVER_NAME Soccer" \
  114. #~ --stdout="$DATETIME-soccer.log" \
  115. #~ --stdout-dir="$STDOUT_DIR" \
  116. #~ --no-console-log \
  117. #~ --no-firewalled-server \
  118. #~ --log=0 &> /dev/null &
  119. #~ sleep 5
  120. #~ "$CMD" --no-ranked \
  121. #~ --owner-less \
  122. #~ --disable-polling \
  123. #~ --max-players=8 \
  124. #~ --min-players=2 \
  125. #~ --difficulty=2 \
  126. #~ --mode=2 \
  127. #~ --battle-mode=0 \
  128. #~ --port=2762 \
  129. #~ --wan-server="$SERVER_NAME FFA" \
  130. #~ --stdout="$DATETIME-ffa.log" \
  131. #~ --stdout-dir="$STDOUT_DIR" \
  132. #~ --no-console-log \
  133. #~ --no-firewalled-server \
  134. #~ --log=0 &> /dev/null &
  135. #~ sleep 5
  136. #~ "$CMD" --no-ranked \
  137. #~ --owner-less \
  138. #~ --disable-polling \
  139. #~ --max-players=8 \
  140. #~ --min-players=2 \
  141. #~ --difficulty=2 \
  142. #~ --mode=2 \
  143. #~ --battle-mode=1 \
  144. #~ --port=2763 \
  145. #~ --wan-server="$SERVER_NAME CTF" \
  146. #~ --stdout="$DATETIME-ctf.log" \
  147. #~ --stdout-dir="$STDOUT_DIR" \
  148. #~ --no-console-log \
  149. #~ --no-firewalled-server \
  150. #~ --log=0 &> /dev/null &
  151. #~ sleep 5
  152. "$CMD" --no-ranked \
  153. --no-owner-less \
  154. --disable-polling \
  155. --max-players=8 \
  156. --min-players=2 \
  157. --difficulty=2 \
  158. --mode=3 \
  159. --soccer-goals \
  160. --port=2761 \
  161. --wan-server="$SERVER_NAME Custom" \
  162. --stdout="$DATETIME-custom.log" \
  163. --stdout-dir="$STDOUT_DIR" \
  164. --no-console-log \
  165. --no-firewalled-server \
  166. --log=0 &> /dev/null &
  167. sleep 5
  168. "$CMD" --no-ranked \
  169. --no-owner-less \
  170. --disable-polling \
  171. --max-players=8 \
  172. --min-players=2 \
  173. --difficulty=2 \
  174. --mode=2 \
  175. --battle-mode=1 \
  176. --port=2762 \
  177. --wan-server="$SERVER_NAME Custom 2" \
  178. --stdout="$DATETIME-custom2.log" \
  179. --stdout-dir="$STDOUT_DIR" \
  180. --no-console-log \
  181. --no-firewalled-server \
  182. --log=0 &> /dev/null &
  183. sleep 5
  184. }
  185. init_servers()
  186. {
  187. echo "Info: Init servers"
  188. mkdir -p "$STDOUT_DIR"
  189. "$CMD" --init-user \
  190. --login="$LOGIN" \
  191. --password="$PASS" \
  192. --stdout="$DATETIME-init.log" \
  193. --stdout-dir="$STDOUT_DIR" \
  194. --no-console-log \
  195. --log=0 &> /dev/null
  196. sleep 5
  197. find "$HOME/.config/supertuxkart" -mindepth 1 -maxdepth 1 -type d -exec cp "$CONFIG_FILE" "{}/config.xml" \;
  198. find "$HOME/.config/supertuxkart" -mindepth 1 -maxdepth 1 -type d -exec cp "$SERVER_CONFIG" "{}/server_config.xml" \;
  199. }
  200. stop_servers()
  201. {
  202. echo "Info: Stop servers"
  203. for PID in $(pidof -x "$CMD"); do
  204. echo "Info: Killing the STK server $PID"
  205. kill -15 $PID
  206. done
  207. sleep 10
  208. for PID in $(pidof -x "$CMD"); do
  209. echo "Info: Force killing the STK server $PID"
  210. kill -9 $PID
  211. done
  212. }
  213. check_servers()
  214. {
  215. export SUCCESS=1
  216. for FILE in $(find "$STDOUT_DIR" -type f -name "$DATETIME-*.log"); do
  217. echo "Info: Check file: $FILE"
  218. FILE_BEGIN=$(cat "$FILE" | head -n100)
  219. if [ $(echo $FILE_BEGIN | grep -c "Done saving user, leaving") -gt 0 ]; then
  220. echo "Info: Check server: Servers successfully initialized"
  221. elif [ $(echo $FILE_BEGIN | grep "Server" | grep -c "is now online.") -gt 0 ]; then
  222. echo "Info: Check server: Servers successfully created"
  223. elif [ $(echo $FILE_BEGIN | grep -c "Specified server already exists.") -gt 0 ]; then
  224. show_message "Error: Check server: Specified server already exists"
  225. SUCCESS=0
  226. else
  227. show_message "Error: Check server: Unknown error"
  228. SUCCESS=0
  229. fi
  230. FILE_END=$(cat "$FILE" | tail -n50)
  231. if [ $(echo $FILE_END | grep -c "Session not valid. Please sign in.") -gt 0 ]; then
  232. show_message "Error: Check server: Session not valid"
  233. SUCCESS=0
  234. # elif [ $(echo $FILE_END | grep curl_easy_perform | grep -c "Timeout was reached") -gt 0 ]; then
  235. # show_message "Error: Check server: Timeout was reached"
  236. # SUCCESS=0
  237. fi
  238. done
  239. return $SUCCESS
  240. }
  241. start()
  242. {
  243. if [ ! -z $(pidof -x "$DIRNAME/$BASENAME" -o $SELF_PID) ]; then
  244. show_message "Error: The script is already started"
  245. exit
  246. fi
  247. if [ ! -z $(pidof -s -x "$CMD") ]; then
  248. show_message "Error: Some servers are already running"
  249. exit
  250. fi
  251. if [ ! -f "$CMD" ]; then
  252. show_message "Error: Couldn't find STK executable in CMD: $CMD"
  253. exit
  254. fi
  255. if [ ! -d "$SUPERTUXKART_DATADIR/data" ]; then
  256. show_message "Error: Couldn't find data directory in SUPERTUXKART_DATADIR: $SUPERTUXKART_DATADIR"
  257. exit
  258. fi
  259. if [ ! -d "$SUPERTUXKART_ASSETS_DIR/tracks" ]; then
  260. show_message "Error: Couldn't find assets directories in SUPERTUXKART_ASSETS_DIR: $SUPERTUXKART_ASSETS_DIR"
  261. exit
  262. fi
  263. init_servers
  264. run_servers
  265. if [ $CHECK_SERVERS -eq 1 ]; then
  266. check_servers
  267. fi
  268. echo "Info: Servers started"
  269. }
  270. startdaemon()
  271. {
  272. start
  273. export SERVERS_COUNT=$(pidof -x "$CMD" | wc -w)
  274. export SERVER_OK=1
  275. export LOOP=0
  276. while [ $LOOP -lt $MAX_CREATION_RETRIES ]; do
  277. if [ $(pidof -x "$CMD" | wc -w) -lt $SERVERS_COUNT ]; then
  278. SERVER_OK=0
  279. fi
  280. if [ $SERVER_OK -eq 1 ] && [ $CHECK_SERVERS -eq 1 ]; then
  281. check_servers
  282. SERVER_OK=$?
  283. fi
  284. if [ $SERVER_OK -eq 0 ]; then
  285. show_message "Error: Some servers don't work, restart is needed"
  286. stop_servers
  287. DATETIME="$(date +%Y%m%d%H%M%S)"
  288. init_servers
  289. run_servers
  290. SERVERS_COUNT=$(pidof -x "$CMD" | wc -w)
  291. SERVER_OK=1
  292. LOOP=$(($LOOP + 1))
  293. fi
  294. sleep $SLEEP_TIME
  295. done
  296. $MESSAGE_CMD "Error: Closing STK server"
  297. }
  298. stop()
  299. {
  300. for PID in $(pidof -x "$DIRNAME/$BASENAME" -o $SELF_PID); do
  301. echo "Info: Killing the $BASENAME script $PID"
  302. kill -9 $PID
  303. done
  304. stop_servers
  305. }
  306. if [ "$1" = "startdaemon" ] && [ "$2" != "disown" ]; then
  307. sleep 5 && "$DIRNAME/$BASENAME" "$1" disown &
  308. exit
  309. fi
  310. if [ "$1" = "start" ]; then
  311. start
  312. elif [ "$1" = "startdaemon" ]; then
  313. startdaemon
  314. elif [ "$1" = "stop" ]; then
  315. stop
  316. else
  317. show_message "Error: The script must be started with start/startdaemon/stop command"
  318. fi