SLBR/servers/deathlistener.sh

88 lines
2.8 KiB
Bash
Executable File

#!/bin/sh
# we will need the suicide bashrc to continuously write DEAD to the nc socket
# in case two messages are sent at the same time.
# this will not work if your slbr admin is not in the "docker" group
PORT="$1"
LOG="log.txt"
[ -z "$1" ] && echo "port?" && exit
docker_subnet_mask="$(
docker network inspect bridge \
| jq '.[0].IPAM.Config[0].Subnet' \
| tr -d '"' \
| cut -f2 -d '/'
)"
handle_packet() {
packet="$1"
message="$(echo $packet | cut -f3 -d '|')"
address="$(
echo "$packet" \
| cut -f2 -d '|' \
| grep -Eo \
'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}'
)"
address="$address/$docker_subnet_mask"
if [ "$message" = "DEAD" ]
then
echo "Killing user with ip $address" >> $LOG
container_name="$(
docker network inspect bridge \
| jq \
'.[0].Containers
| map(select(.IPv4Address == "'"$address"'"))
| .[0].Name' \
| tr -d '"'
)"
docker rm -f "$container_name"
echo "killed container $container_name" >> $LOG
elif [ "$(echo $message | cut -f1 -d ' ')" = "SOLUTION" ]
then
submitted_solution="$(echo $message | cut -f3- -d ' ')"
challenge_no="$(echo $message | cut -f2 -d ' ')"
correct_solution="$(sed $challenge_no'q;d' solutions.txt)"
sed_escaped_address="$(echo $address | sed 's/\./\\./g')"
echo "$address submitted solution for challenge $challenge_no: $submitted_solution" >> $LOG
if [ "$submitted_solution" = "$correct_solution" ]
then
num_correct=""
echo "Solution was correct!" >> $LOG
grep -qE "^$address" scoreboard.txt \
|| echo "$address" >> scoreboard.txt
grep -qE "^$address .*$challenge_no," scoreboard.txt \
|| sed -i "s|$sed_escaped_address|$address $challenge_no,|" scoreboard.txt
num_correct="$(
grep -m1 -E "^$address" scoreboard.txt \
| grep -oE '[0-9],' \
| wc -l
)"
total_solutions="$(cat solutions.txt | wc -l)"
if [ $num_correct = $total_solutions ]
then
echo "$address HAS WON THE GAME!!!" >> $LOG
sleep 5
echo "Killing all continers..." >> $LOG
docker ps -aq --filter label="description=SLBR User Container" | xargs docker rm -f
exit
fi
echo "$num_correct correct answers so far" >> $LOG
fi
fi
}
echo "game server listening on $PORT"
while true
do
packet=$(nc -w 1 -W 1 -nvlp $PORT 2>&1)
handle_packet "$(echo "$packet" | head -n 3 | tr '\n' '|')" &
done