@@ -298,6 +298,7 @@ bnumber=""
298298GREEN=" \\ 033[1;32m"
299299RED=" \\ 033[1;31m"
300300YELLOW=" \\ e[0;33m"
301+ CYAN=" \\ e[0;36m"
301302NORMAL=" \\ 033[0;39m"
302303
303304# Set TERM to "dumb" if TERM is not set
@@ -661,14 +662,110 @@ doBroadcastWithEcho(){
661662 doBroadcast " $1 "
662663}
663664
665+ #
666+ # Apply notification template
667+ #
668+ function notifyApplyTemplate(){
669+ local msg=" $1 "
670+ # shellcheck disable=SC2154
671+ for v in " ${! notifyvar_@ } " ; do
672+ vn=" ${v# notifyvar_} "
673+ msg=" ${msg// \{ ${vn} \} / ${! v} } "
674+ done
675+ echo " $msg "
676+ }
677+
678+ #
679+ # Notifiy console
680+ #
681+ function notifyConsole(){
682+ local msg=" ${1// \\ / \\\\ } "
683+ local type=" "
684+ case " $2 " in
685+ info* ) type=" ${CYAN} [INFO]${NORMAL} " ;;
686+ warn* ) type=" ${YELLOW} [WARN]${NORMAL} " ;;
687+ err* ) type=" ${RED} [ERROR]${NORMAL} " ;;
688+ esac
689+ # shellcheck disable=SC2034
690+ local notifyvar_type=" $type "
691+ # shellcheck disable=SC2034
692+ local notifyvar_msg=" $msg "
693+ msg=" $( notifyApplyTemplate " ${consoleNotifyTemplate:- " {local_date} {type}({instance}) {msg}" } " ) "
694+ echo -e " ${msg}${NORMAL} "
695+ }
696+
697+ #
698+ # Hex color codes
699+ #
700+ declare -A HexColorCodes=(
701+ [' black' ]=' 000000'
702+ [' red' ]=' ff0000'
703+ [' green' ]=' 00ff00'
704+ [' yellow' ]=' ffff00'
705+ [' blue' ]=' 0000ff'
706+ [' purple' ]=' 800080'
707+ [' cyan' ]=' 00ffff'
708+ [' white' ]=' ffffff'
709+ )
710+
711+ #
712+ # Convert hex color to Discord color integer
713+ #
714+ function hexToDiscordColor(){
715+ local hex=" ${1} "
716+ local r g b
717+ r=$(( 0 x${hex: 0: 2} ))
718+ g=$(( 0 x${hex: 2: 2} ))
719+ b=$(( 0 x${hex: 4: 2} ))
720+ echo $(( (r * 65536 ) + (g * 256 ) + b ))
721+ }
722+
723+ #
724+ # Escape string for JSON
725+ #
726+ function jsonEscape(){
727+ local msg=${1// \\ / \\\\ } # backslash to escape
728+ msg=${msg// \" / \\\" } # double quote to escape
729+ msg=${msg// $' \r ' / \\ r} # carriage return to \r
730+ msg=${msg// $' \n ' / \\ n} # newline to \n
731+ msg=${msg// $' \t ' / \\ t} # tab to \t
732+ printf ' %s' " $msg "
733+ }
734+
664735#
665736# Discord Webhook notifier
666737#
667738function notifyDiscord(){
668739 if [ -n " $discordWebhookURL " ]; then
669- local msg=" $( echo -n " ${msg} " | tr ' \n' ' \001' | sed ' s/\001/\\n/g;s/["\\]/\\\0/g' ) "
670- local json=" {\" content\" :\" ${msg} \" }"
671- curl -s -H " Content-Type: application/json" -d " ${json} " " $discordWebhookURL " > /dev/null
740+ if [[ " ${discordNotifyAdminCmd} " != " true" ]] && [[ " $1 " =~ ^AdminCmd: ]]; then
741+ return
742+ fi
743+ local msg=" $( jsonEscape " $1 " ) "
744+ local type=" $2 "
745+ local color=" "
746+ local template=" ${discordNotifyPlainTemplate:- " {\" content\" : \" [{serverMap}] {msg}\" }" } "
747+ case " $type " in
748+ info* ) template=" ${discordNotifyInfoTemplate:- " {\" embeds\" : [{\" title\" : \" 📢 INFO - {msg}\" , \" color\" : 3447003, \" fields\" : [{\" name\" : \" {serverMap}\" , \" value\" : \"\" }]}]}" } " ;;
749+ warn* ) template=" ${discordNotifyWarnTemplate:- " {\" embeds\" : [{\" title\" : \" ⚠️ WARN - {msg}\" , \" color\" : 15105570, \" fields\" : [{\" name\" : \" {serverMap}\" , \" value\" : \"\" }]}]}" } " ;;
750+ err* ) template=" ${discordNotifyErrorTemplate:- " {\" embeds\" : [{\" title\" : \" ❗ ERROR - {msg}\" , \" color\" : 15158332, \" fields\" : [{\" name\" : \" {serverMap}\" , \" value\" : \"\" }]}]}" } " ;;
751+ * )
752+ if [[ " $type " =~ ^# ([0-9A-Fa-f]{6})$ ]]; then
753+ color= $( hexToDiscordColor " ${BASH_REMATCH[1]} " )
754+ elif [ -n " $type " ]; then
755+ color= $( hexToDiscordColor " ${HexColorCodes[$type]:- 808080} " )
756+ fi
757+ if [ -n " $color " ]; then
758+ template=" ${discordNotifyColorTemplate:- " {\" embeds\" : [{\" color\" : {color}, \" fields\" : [{\" name\" : \" {serverMap}\" , \" value\" : \" {msg}\" }]}]}" } "
759+ fi
760+ ;;
761+ esac
762+ # shellcheck disable=SC2034
763+ local notifyvar_msg= " $msg "
764+ # shellcheck disable=SC2034
765+ local notifyvar_color= " $color "
766+ local json= " $( notifyApplyTemplate " ${template} " ) "
767+ local result= $( curl -sS -H " Content-Type: application/json" -d " ${json} " " $discordWebhookURL " 2> /dev/null)
768+ echo " ${result} " | grep -q ' "message"' && echo -e " Discord notification failed: ${result} \n----\n${json} \n----" > & 2
672769 fi
673770}
674771
@@ -684,21 +781,30 @@ function notifyOverride(){
684781#
685782function notify(){
686783 if [[ -n " $1 " && " $1 " != " -" ]]; then
687- local msg
688- local notifymsg=" $1 "
689- msg=" ${notifyTemplate:- Message from instance \` {instance\}\` on server \` {server\}\` : {msg\} } "
690- msg=" ${msg// \{ msg\} / ${notifymsg} } "
691- msg=" ${msg// \{ instance\} / ${instance} } "
692- msg=" ${msg// \{ server\} / ${HOSTNAME} } "
693-
694- # shellcheck disable=SC2154
695- for v in " ${! notifyvar_@ } " ; do
696- vn=" ${v# notifyvar_} "
697- msg=" ${msg// \{ ${vn} \} / ${! v} } "
698- done
699-
700- notifyDiscord " $msg "
701- notifyOverride " $msg "
784+ local msg=" $1 "
785+ local type=" $2 " # info, warn, err, ...
786+
787+ # Prepare notification variables
788+ # shellcheck disable=SC2034
789+ local notifyvar_instance=" $instance "
790+ # shellcheck disable=SC2034
791+ local notifyvar_serverMap=" $serverMap "
792+ # shellcheck disable=SC2034
793+ local notifyvar_server=" $HOSTNAME "
794+ # shellcheck disable=SC2034
795+ local notifyvar_local_date=" $( timestamp) "
796+
797+ # Console notification
798+ notifyConsole " $msg " " $type "
799+
800+ # Discord notification
801+ notifyDiscord " $msg " " $type "
802+
803+ # Custom notification
804+ # shellcheck disable=SC2034
805+ local notifyvar_msg=" $msg "
806+ msg=" $( notifyApplyTemplate " ${notifyTemplate:- " Message from instance \` {instance}\` on server \` {server}\` : {msg}" } " ) "
807+ notifyOverride " $msg " " $type "
702808
703809 if [ -n " ${notifyCommand} " ]; then
704810 eval " ${notifyCommand} "
@@ -1398,7 +1504,7 @@ doRun() {
13981504 # Shutdown the server when we are terminated
13991505 shutdown_server(){
14001506 restartserver=0
1401- notify " ${notifyMsgShuttingDown:- Shutting down} "
1507+ notify " ${notifyMsgShuttingDown:- Shutting down} " 'info'
14021508 rm -f " $arkserverroot /$arkautorestartfile "
14031509 if [ " $serverpid " -ne 0 ]; then
14041510 kill -INT -$serverpid >/dev/null 2>&1
@@ -1413,8 +1519,8 @@ doRun() {
14131519
14141520 # Auto-restart loop
14151521 while [ $restartserver -ne 0 ]; do
1522+ notify " ${notifyMsgStarting:- Starting} " 'info'
14161523 echo -n " $( timestamp) : Running"
1417- notify " ${notifyMsgStarting:- Starting} "
14181524 printf " %q" " $arkserverroot /$arkserverexec " " $arkserveropts " " ${arkextraopts[@]} "
14191525 echo
14201526 # Put the server process into the background so we can monitor it
@@ -1444,8 +1550,7 @@ doRun() {
14441550 # Check if the server has fully started
14451551 if ! isTheServerUp; then
14461552 # Enable auto-restart if the server is up
1447- echo " $( timestamp) : server is up"
1448- notify " ${notifyMsgServerUp:- Server is up} "
1553+ notify " ${notifyMsgServerUp:- Server is up} " 'info'
14491554 if [ " $restartserver " -eq 0 ]; then
14501555 touch " $arkserverroot /$arkautorestartfile "
14511556 restartserver=1
@@ -1458,9 +1563,7 @@ doRun() {
14581563
14591564 if (( serverdowntries > 12 )); then
14601565 # Server has not been listening for 60 seconds, so restart it.
1461- echo " $( timestamp) : The server has stopped listening"
1462- echo " $( timestamp) : Restarting server"
1463- notify " ${notifyMsgStoppedListening:- Server has stopped listening - restarting} "
1566+ notify " ${notifyMsgStoppedListening:- Server has stopped listening - restarting} " 'err'
14641567 for (( i = 0; i < 5; i++ )); do
14651568 if ! kill -0 " -$serverpid " ; then
14661569 break
@@ -1484,9 +1587,7 @@ doRun() {
14841587 break
14851588 elif [ " $pid " == " $( pgrep --pgroup $serverpid ) " ]; then
14861589 restartserver=1
1487- echo " $( timestamp) : Server has double-forked and cannot be effectively monitored"
1488- echo " $( timestamp) : Restarting server"
1489- notify " ${notifyMsgDoubleForked:- Server has daemonized itself - restarting} "
1590+ notify " ${notifyMsgDoubleForked:- Server has daemonized itself - restarting} " 'err'
14901591 for (( i = 0; i < 5; i++ )); do
14911592 if ! kill -0 " -$serverpid " ; then
14921593 break
@@ -1521,8 +1622,7 @@ doRun() {
15211622 fi
15221623
15231624 if [ " $restartserver " -ne 0 ]; then
1524- notify " ${notifyMsgServerTerminated:- Server exited - restarting} "
1525- echo " $( timestamp) : restarting server"
1625+ notify " ${notifyMsgServerTerminated:- Server exited - restarting} " 'warn'
15261626 fi
15271627 done
15281628}
@@ -2002,7 +2102,7 @@ doWarn(){
20022102 msg=" Shutdown cancelled by operator ($1 )"
20032103 fi
20042104 doBroadcastWithEcho " ${msg} "
2005- notify " ${msg} "
2105+ notify " ${msg} " 'warn'
20062106 exit 1
20072107 }
20082108
@@ -2042,19 +2142,18 @@ doWarn(){
20422142 numplayers=$( numPlayersConnected)
20432143 echo " There are ${numplayers} players connected"
20442144 if [[ " ${numplayers} " == " -1" ]]; then
2045- echo " Server is not running. Shutting down immediately"
2046- notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} "
2145+ notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} " 'warn'
20472146 return 0
20482147 elif (( (numplayers + 0) == 0 )); then
20492148 doBroadcastWithEcho " Nobody is connected. Shutting down immediately"
2050- notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} "
2149+ notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} " 'info'
20512150 rm -f " ${arkserverroot} /${arkwarnlockfile} "
20522151 return 0
20532152 fi
20542153 fi
20552154 if isUpdateCancelRequested; then
20562155 doBroadcastWithEcho " Restart cancelled by player request"
2057- notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} "
2156+ notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} " 'warn'
20582157 return 1
20592158 fi
20602159 wait $sleeppid
@@ -2089,19 +2188,18 @@ doWarn(){
20892188 numplayers=$( numPlayersConnected)
20902189 echo " There are ${numplayers} players connected"
20912190 if [[ " ${numplayers} " == " -1" ]]; then
2092- echo " Server is not running. Shutting down immediately"
2093- notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} "
2191+ notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} " 'warn'
20942192 return 0
20952193 elif (( (numplayers + 0) == 0 )); then
20962194 doBroadcastWithEcho " Nobody is connected. Shutting down immediately"
2097- notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} "
2195+ notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} " 'info'
20982196 rm -f " ${arkserverroot} /${arkwarnlockfile} "
20992197 return 0
21002198 fi
21012199 fi
21022200 if isUpdateCancelRequested; then
21032201 doBroadcastWithEcho " Restart cancelled by player request"
2104- notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} "
2202+ notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} " 'warn'
21052203 return 1
21062204 fi
21072205 fi
0 commit comments