Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Valheim Server Discord Alerts
#!/bin/bash
##########################
# Change these variables #
##########################
FILE="/path/to/console.log"
WEBHOOK_URL="CHANGEME"
STEAMKEY="CHANGEME"
##########################
### script logic ###
# array to store steam ids and map to player names
declare -A SteamID
# initialize global variables
lastSteamID=0
havePlayerName=0
# begin watching the log file and check each new line
tail -Fn0 $FILE | \
while read -r line ; do
# check for the matching lines we want to look into further
if grep -iq "Closing socket\|Got handshake from client\|Got character ZDOID from" <<< "$line"
then
# tokenize the line sp;it by colons so easier to process
IFS=':' tokens=( $line )
# we're only interested in the text of the log entry
entry=$(echo "${tokens[3]}" | xargs)
# get rid of windows carriage return
entry="$(echo $entry | sed 's/\r//g')"
if grep -iq "Got handshake from client" <<< "$entry"
then
# grab everything in the entry past the matching text and mark that we have a recent steam id
lastSteamID=$(sed -n -e 's/^.*Got handshake from client //p' <<< "$entry")
haveSteamID=1
elif grep -iq "Got character ZDOID from" <<< "$entry"
then
# grab everything in the entry past the matching text and mark that we have a recent player name
playerName=$(sed -n -e 's/^.*Got character ZDOID from //p' <<< "$entry")
havePlayerName=1
# add the name and id to the array for recall later
SteamID[$lastSteamID]=$playerName
# if we have both a recent name and recent steam id go ahead and assume we have a new client that connected and send alert
if [[ havePlayerName -eq 1 && haveSteamID -eq 1 ]]
then
# grab the steam id profile url and name
response=$(curl -Gs -d "steamids=${lastSteamID}" -d "key=${STEAMKEY}" https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/)
profile=$(jq '.response.players[0].profileurl' <<< $response | tr -d "\"")
personaname=$(jq '.response.players[0].personaname' <<< $response | tr -d "\"")
# output to terminal
echo "Player ${playerName} (probably ${lastSteamID}) has joined the server - Steam profile ${personaname} (${profile})"
# send to Discord
curl -X POST --data "{\"content\": \"Player ${playerName} (probably ${lastSteamID}) has joined the server - Steam profile ${personaname} (${profile})\"}" --header "Content-Type:application/json" "$WEBHOOK_URL"
# reset variables so we're not sending alerts without it being a new connection
havePlayerName=0
haveSteamID=0
fi
elif grep -iq "Closing socket" <<< "$entry"
then
# grab everything in the entry past the matching text
socket=$(sed -n -e 's/^.*Closing socket //p' <<< "$entry")
# check that it's an actual socket closing
if [ "$socket" != "0" ]
then
# output to terminal
echo "SteamID ${socket} left the server (was probably ${SteamID[$socket]})"
# send to Discord
curl -X POST --data "{\"content\": \"SteamID ${socket} left the server (was probably ${SteamID[$socket]})\"}" --header "Content-Type:application/json" "$WEBHOOK_URL"
fi
else
# this should never happen but is included for failover
echo "unhandled entry:" "$entry"
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment