Welcome to lark3ri.fi

Serverbot using logfiles with Bash

11.04.2020

I wrote a chatbot program with bash. It was running on this Sharkdoom cooperative server of mine. I disabled it because I updated the server WAD collection. The current features of Chatbot were no longer needed and therefore useless. It worked by typing to the chat with forward slash character.

Everyone was able to use these commands:

  • /server do fastweapons Keeps sv_fast_weapons 1 next 30 minutes. Also it informs that one minute is remaining before time ends. It is 1 instead of 2, because 2 seems to causing the server to crash when certain situations occur.
  • /server do hello It is just a test command but i leave it there anyway. It says hello once it starts and then it waits one minute and after that it say hello again.
  • /server do list Lists these commands.

You can download the code from this link. It is licensed with GPL v2 license only. It is free to use under the license agreements. If you wanna use this program without any modifications, it requires that you run doom server using screen and -L -Logfile ./logfile.log -command-line options, example like this screen -S doomserver -L -Logfile ./logfile.log ./run.sh where run.sh file includes all server parameters and runs the server. Remember to add logfile -filepath and sname -screen sessionname to the code right variables.

serverbot_2.6.sh
#! /bin/bash

#	Copyright (C) 2020 Lari Varjonen <[email protected]>
#
#	This program is free software; you can redistribute it and/or
#	modify it under the terms of the GNU General Public License
#	version 2 as published by the Free Software Foundation.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Doom 2 chatbot | Version: 2.6 | Created by Lark3ri https://www.lark3ri.fi


botname="\ctSERVERBOT"
logfile="/doom2/logfile.log"
sname="screen-sessionname"
sleep_sec=2 # How long in seconds it sleeps after one valid command have been received and handled.
sleep_pid=0 # No need to change this. Just stores the sleep time process id.
pida=()

server_say() {
	screen -S "$sname" -p 0 -X stuff "say $botname\c-: $1^M"
}

server_exec_command() {
	screen -S "$sname" -p 0 -X stuff "$1^M"
}

server_sleep() {
	for i in $(seq 1 "$1");
	do
		sleep 1m
		if [ -z "$2" ]; then continue; fi
		if [[ "$i" == "$3" ]]
		then
			case "$2" in
				*FASTWEAPONS*) server_say "\cgsv_fastweapons 1 \c-one minute remaining!" ;;
			esac
		fi
	done
}

is_process_running() {
	echo "$1"
	for i in "${!pida[@]}"
	do
		pname=$(echo "${pida[$i]}" | cut -d ':' -f 1)
		if [[ "$pname" == "$1" ]]
		then
			pid=$(echo "${pida[$i]}" | cut -d ':' -f 2)
			if ps -p "$pid" > /dev/null 2>&1
			then
				case "$1" in
					*LIST*) server_say "currently list command has 10min cooldown" ;;
					*) server_say "already running" ;;
				esac
				return 0
			fi
			unset "pida[$i]"
			break
		fi
	done
	return 1
}

tail -n 0 -F "$logfile" | \
while read line
do
	if ! echo "$line" | grep -iq "^CHAT.*$"; then continue; fi
	echo "$line"
	if echo "$line" | grep -iq "^CHAT <server>:.*$"; then continue; fi
	msg=$(echo "$line" | awk -F ": " '{print $NF}' | tr a-z A-Z)
	if echo "$msg" | grep -iq "^/SERVER DO.*$"
	then
		cmd=$(echo "$msg" | cut -d ' ' -f 3 | tr a-z A-Z)
		if [ -z "$cmd" ]; then continue; fi
		if ps -p "$sleep_pid" > /dev/null 2>&1; then echo "too fast!"; continue; fi
		(sleep "$sleep_sec") &
		sleep_pid="$!"
		case "$cmd" in
			*FASTWEAPONS*)
				if is_process_running "FASTWEAPONS"; then continue; fi
				(server_exec_command "sv_fastweapons 1"; \
				 server_say "\cgsv_fastweapons 1 \c-next 30 minutes"; \
				 server_sleep 30 "FASTWEAPONS" 29; \
				 server_exec_command "sv_fastweapons 0"; \
				 server_say "\cgsv_fastweapons 1 \c-time ended") &
				pida+=("FASTWEAPONS:$!")
				;;
			*HELLO*)
				if is_process_running "HELLO"; then continue; fi
				(server_say "hi! this takes one minute..."; \
				 server_sleep 1; \
				 server_say "hello again! now it's done!") &
				pida+=("HELLO:$!")
				;;
			*LIST*)
				if is_process_running "LIST"; then continue; fi
				(server_say "\ctplayer usable commands:"; \
				 server_say "\cr/server do fastweapons \cd30min fastweapons 1"; \
				 server_say "\cr/server do hello \cdjust a test command but i leave it there anyway :)"; \
				 server_say "\cr/server do list \cdsays this message chain with 10min cooldown"; \
				 server_say "\c*more about this chatbot is in the server website https://sharkdoom.k3r.fi"; \
				 server_sleep 10) &
				pida+=("LIST:$!")
				;;
			*) server_say "No command found" ;;
		esac
	fi
done
« Back | ↑ Top