1
0

First generation tiger-bot.

This commit is contained in:
Jon Michael Aanes 2019-03-06 21:50:36 +01:00
commit d1a9ed6bbe
3 changed files with 273 additions and 0 deletions

14
Makefile Normal file
View File

@ -0,0 +1,14 @@
TIGERC=~jmaa/Git/simba/src/tigerc
build: tiger-bot.bin
run: build
bash ./run.sh
tiger-bot.bin: tiger-bot.tig
$(TIGERC) --out ./tiger-bot.bin tiger-bot.tig
clean:
rm -f *.log *.bin

25
run.sh Normal file
View File

@ -0,0 +1,25 @@
LOG_SERVER_TO_CLIENT=./log_s2c.log
LOG_CLIENT_TO_SERVER=./log_c2s.log
CLIENT_RUNTIME="./tiger-bot.bin"
COMMS_RUNTIME="openssl s_client -connect irc.guava.space:6697"
# Ensure logs are new
rm -f "$LOG_CLIENT_TO_SERVER"
rm -f "$LOG_SERVER_TO_CLIENT"
touch "$LOG_CLIENT_TO_SERVER"
touch "$LOG_SERVER_TO_CLIENT"
# Begin communication
echo "Beginning connection..."
tail -f -n 0 "$LOG_CLIENT_TO_SERVER" | eval $COMMS_RUNTIME >> "$LOG_SERVER_TO_CLIENT" &
echo "Waiting for SSL handshake to complete..."
sleep 1
echo "Starting bot..."
tail -f -n 0 "$LOG_SERVER_TO_CLIENT" | eval $CLIENT_RUNTIME >> "$LOG_CLIENT_TO_SERVER"
#echo "Bot started!..."

234
tiger-bot.tig Normal file
View File

@ -0,0 +1,234 @@
let /* Parsing util */
var seen_char := 0
var next_char := "IS NOT A CHAR; SHOULD NOT EVER BE VISIBLE!"
function peak_char (): string =
( if not(seen_char)
then ( next_char := getchar()
; seen_char := 1 )
; next_char )
function pop_char (): string =
let var char := peak_char()
in seen_char := 0
; char
end
/* String and number util */
function max (a:int, b:int): int =
if a > b
then a
else b
function min (a:int, b:int): int =
if a < b
then a
else b
function safe_substring (str: string, i_start: int, i_end: int): string =
( i_start := max(0, i_start)
; i_end := min(size(str) - 1, i_end)
; if i_start > i_end
then ""
else substring(str, i_start, i_end - i_start + 1) )
/* Messages */
type str_arr = array of string
type message = { /* TODO: @tags, :source, */
command: string
, parameters: str_arr
, num_parameters: int }
function parse_message (plain_msg: string): message =
let var msg := message
{ command = "NO CMD"
, parameters = str_arr[16] of "NO PARAM" /* TODO: Support any number of paramters */
, num_parameters = -1 }
var word_start_i := 0
function skip_ws () =
while substring(plain_msg, word_start_i, 1) = " "
do word_start_i := word_start_i + 1
function skip_to_ws () =
while substring(plain_msg, word_start_i, 1) <> " "
do word_start_i := word_start_i + 1
in skip_ws()
/* Skip @tags */
; if substring(plain_msg, word_start_i, 1) = "@"
then skip_to_ws()
; skip_ws()
/* Skip :source */
; if substring(plain_msg, word_start_i, 1) = ":"
then skip_to_ws()
; skip_ws()
; for i := word_start_i to size(plain_msg)
do let var char := if i < size(plain_msg)
then ord(substring(plain_msg, i, 1))
else ord(" ") /* Ensures that msg parsing
always ends on a space character */
in if char = ord(" ")
then (if word_start_i < i
then ( if msg.num_parameters < 0
then msg.command := safe_substring(plain_msg, word_start_i, i-1)
else msg.parameters[msg.num_parameters] := safe_substring(plain_msg, word_start_i, i-1)
; msg.num_parameters := msg.num_parameters + 1)
; word_start_i := i + 1)
else if char = ord(":")
then ( msg.parameters[msg.num_parameters] := safe_substring(plain_msg, i+1, size(plain_msg))
; msg.num_parameters := msg.num_parameters + 1
; break )
end
/* Rather return nil than an incorrect message */
; if msg.command <> "NO CMD" & msg.num_parameters >= 0
then msg
else nil
end
function format_message (msg: message): string =
let var str := msg.command
in for i := 0 to msg.num_parameters-2
do str := concat(concat(str, " "), msg.parameters[i])
/* Last parameter */
; if msg.num_parameters
then str := concat(concat(str, " :"), msg.parameters[msg.num_parameters-1])
; str
end
/* Main loop */
var have_registered := 0
function read_next_message(): message =
let var msg := ""
function is_eoc(c: string): int =
c = "\n" | c = "\013"
/* Concat until newline */
in while peak_char() <> "\013"
do ( msg := concat(msg, pop_char())
; /*log_info(msg)*/ () )
/* Ignore newline */
; pop_char(); pop_char()
/* Parse message */
; parse_message(msg)
end
function send_msg (msg: message) =
( print(format_message(msg))
; print("\n")
; flush() )
function cmd0 (cmd: string): message =
message { command = cmd
, parameters = str_arr[0] of ""
, num_parameters = 0 }
function cmd1 (cmd: string, param1: string): message =
message { command = cmd
, parameters = str_arr[1] of param1
, num_parameters = 1 }
function cmd2 (cmd: string, param1: string, param2:string): message =
let var params := str_arr[2] of param1
in params[1] := param2
; message { command = cmd
, parameters = params
, num_parameters = 2 }
end
function ping_respond () =
let var msg := read_next_message()
in if msg.command = "PING"
then send_msg(cmd1("PONG", msg.parameters[0]))
end
function quit(quit_msg: string) =
( log_info(concat("Quitting: ", quit_msg))
; send_msg(cmd1("QUIT", quit_msg))
; exit(0) )
function log_info(info: string) =
if have_registered
then send_msg(cmd2("PRIVMSG", "Jmaa", info))
function is_char_digit(c: int): int =
ord("0") <= c & c <= ord("9")
function is_number_string(c: string): int =
let var derp := 1
in for i := 0 to size(c) - 1
do if not(is_char_digit(ord(substring(c, i, 1))))
then ( derp := 0
; break )
; derp
end
function main_loop () =
let var msg := read_next_message()
in if msg = nil
then log_info("Could not parse message!")
/*; quit("Could not parse message") )*/
/* Handle number messages */
else if is_number_string(msg.command)
then () /* Ignore */
/* Handle pings */
else if msg.command = "PING"
then send_msg(cmd1("PONG", msg.parameters[0]))
/* Handle yo */
else if msg.command = "PRIVMSG" & msg.parameters[1] = "yo"
then send_msg(cmd2("PRIVMSG", msg.parameters[0], "Yo yourself"))
/* Handle ERROR messages */
else if msg.command = "ERROR"
then quit("Got ERROR message")
/* Do nothing */
else () /*log_info(concat("Got message, but did nothing: ", format_message(msg)))*/
/* THE RIDE NEVER ENDS */
; main_loop()
end
in /* Establish connection */
print("USER tiger-bot * * : yo\n")
; print("NICK bot-fucker\n")
; flush()
/* Respond to PING */
; ping_respond()
; have_registered := 1
/* Connect to channel and greet */
; send_msg(cmd1("JOIN", "#bot-test"))
; send_msg(cmd2("PRIVMSG", "#bot-test", "Whatup motherfuckers?"))
/* Start normal connection */
; main_loop()
/* Exit! */
; quit("Nothing more to say")
end