@@ -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} "
@@ -1422,7 +1528,7 @@ doRun() {
14221528 # Shutdown the server when we are terminated
14231529 shutdown_server(){
14241530 restartserver=0
1425- notify " ${notifyMsgShuttingDown:- Shutting down} "
1531+ notify " ${notifyMsgShuttingDown:- Shutting down} " 'info'
14261532 rm -f " $arkserverroot /$arkautorestartfile "
14271533 if [ " $serverpid " -ne 0 ]; then
14281534 kill -INT -$serverpid >/dev/null 2>&1
@@ -1437,8 +1543,8 @@ doRun() {
14371543
14381544 # Auto-restart loop
14391545 while [ $restartserver -ne 0 ]; do
1546+ notify " ${notifyMsgStarting:- Starting} " 'info'
14401547 echo -n " $( timestamp) : Running"
1441- notify " ${notifyMsgStarting:- Starting} "
14421548 printf " %q" " $arkserverroot /$arkserverexec " " $arkserveropts " " ${arkextraopts[@]} "
14431549 echo
14441550 # Put the server process into the background so we can monitor it
@@ -1468,8 +1574,7 @@ doRun() {
14681574 # Check if the server has fully started
14691575 if ! isTheServerUp; then
14701576 # Enable auto-restart if the server is up
1471- echo " $( timestamp) : server is up"
1472- notify " ${notifyMsgServerUp:- Server is up} "
1577+ notify " ${notifyMsgServerUp:- Server is up} " 'info'
14731578 if [ " $restartserver " -eq 0 ]; then
14741579 touch " $arkserverroot /$arkautorestartfile "
14751580 restartserver=1
@@ -1482,9 +1587,7 @@ doRun() {
14821587
14831588 if (( serverdowntries > 12 )); then
14841589 # Server has not been listening for 60 seconds, so restart it.
1485- echo " $( timestamp) : The server has stopped listening"
1486- echo " $( timestamp) : Restarting server"
1487- notify " ${notifyMsgStoppedListening:- Server has stopped listening - restarting} "
1590+ notify " ${notifyMsgStoppedListening:- Server has stopped listening - restarting} " 'err'
14881591 for (( i = 0; i < 5; i++ )); do
14891592 if ! kill -0 " -$serverpid " ; then
14901593 break
@@ -1508,9 +1611,7 @@ doRun() {
15081611 break
15091612 elif [ " $pid " == " $( pgrep --pgroup $serverpid ) " ]; then
15101613 restartserver=1
1511- echo " $( timestamp) : Server has double-forked and cannot be effectively monitored"
1512- echo " $( timestamp) : Restarting server"
1513- notify " ${notifyMsgDoubleForked:- Server has daemonized itself - restarting} "
1614+ notify " ${notifyMsgDoubleForked:- Server has daemonized itself - restarting} " 'err'
15141615 for (( i = 0; i < 5; i++ )); do
15151616 if ! kill -0 " -$serverpid " ; then
15161617 break
@@ -1545,8 +1646,7 @@ doRun() {
15451646 fi
15461647
15471648 if [ " $restartserver " -ne 0 ]; then
1548- notify " ${notifyMsgServerTerminated:- Server exited - restarting} "
1549- echo " $( timestamp) : restarting server"
1649+ notify " ${notifyMsgServerTerminated:- Server exited - restarting} " 'warn'
15501650 fi
15511651 done
15521652}
@@ -2026,7 +2126,7 @@ doWarn(){
20262126 msg=" Shutdown cancelled by operator ($1 )"
20272127 fi
20282128 doBroadcastWithEcho " ${msg} "
2029- notify " ${msg} "
2129+ notify " ${msg} " 'warn'
20302130 exit 1
20312131 }
20322132
@@ -2066,19 +2166,18 @@ doWarn(){
20662166 numplayers=$( numPlayersConnected)
20672167 echo " There are ${numplayers} players connected"
20682168 if [[ " ${numplayers} " == " -1" ]]; then
2069- echo " Server is not running. Shutting down immediately"
2070- notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} "
2169+ notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} " 'warn'
20712170 return 0
20722171 elif (( (numplayers + 0) == 0 )); then
20732172 doBroadcastWithEcho " Nobody is connected. Shutting down immediately"
2074- notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} "
2173+ notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} " 'info'
20752174 rm -f " ${arkserverroot} /${arkwarnlockfile} "
20762175 return 0
20772176 fi
20782177 fi
20792178 if isUpdateCancelRequested; then
20802179 doBroadcastWithEcho " Restart cancelled by player request"
2081- notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} "
2180+ notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} " 'warn'
20822181 return 1
20832182 fi
20842183 wait $sleeppid
@@ -2113,19 +2212,18 @@ doWarn(){
21132212 numplayers=$( numPlayersConnected)
21142213 echo " There are ${numplayers} players connected"
21152214 if [[ " ${numplayers} " == " -1" ]]; then
2116- echo " Server is not running. Shutting down immediately"
2117- notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} "
2215+ notify " ${notifyMsgServerNotRunning:- Server is not running. Shutting down immediately} " 'warn'
21182216 return 0
21192217 elif (( (numplayers + 0) == 0 )); then
21202218 doBroadcastWithEcho " Nobody is connected. Shutting down immediately"
2121- notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} "
2219+ notify " ${notifyMsgNobodyConnected:- Nobody is connected. Shutting down immediately} " 'info'
21222220 rm -f " ${arkserverroot} /${arkwarnlockfile} "
21232221 return 0
21242222 fi
21252223 fi
21262224 if isUpdateCancelRequested; then
21272225 doBroadcastWithEcho " Restart cancelled by player request"
2128- notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} "
2226+ notify " ${notifyMsgRestartCancelled:- Restart cancelled by player request} " 'warn'
21292227 return 1
21302228 fi
21312229 fi
0 commit comments