First generation tiger-bot.
This commit is contained in:
commit
d1a9ed6bbe
14
Makefile
Normal file
14
Makefile
Normal 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
25
run.sh
Normal 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
234
tiger-bot.tig
Normal 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user