The best way to describe its innards is just to watch a message go through it.
So here I am in my channel ##Gambot with a message:
When I type that into the text box and hit enter my client takes that and sends it to the server looking like this:
PRIVMSG ##Gambot :Hi Mom!
It's not actually colored, but I did that for reasons that will make sense in a moment.The server gets that and it says "Okay I need to send this message to everyone in ##Gambot". It sends that to everyone (my bot included) and it comes in like so:
:Gambit!~Gambit@wesnoth/developer/grickit PRIVMSG ##Gambot :Hi Mom!
Again, not actually colored. But those different colors are different pieces of the message that the bot will care about. We have the user's nickname, their user string, the hostname (aka IP address), what command they used, the location they used it, and the message itself.
When the bot receives this (after it has connected) it sends this to one of three message processing threads that run simultaneously. They're all racing to grab the messages as they come in, so I don't know which one gets it, but it really doesn't matter.
When a thread gets the message the first thing it does is check to see "Is my name in it?". If it is then it will print it in the terminal in orange, otherwise in black (or white if you have a black terminal). The next thing it checks is "Is the message part of the message of the day?". The message of the day, for those unfamiliar with IRC, is a huge conglomerate of messages that are sent when you first connect. There are several hundred of them. You cannot reply. You needn't take any action regarding them, so the bot can just ignore these.
After both of those checks the message is passed to another script. The connection script actually executes a second script — with the message and the bot's name as arguments — and captures its output. Now before you start thinking of ways to compromise my system (or anyone else who hopefully, eventually runs Gambot) by abusing that, stop. Before being sent to the processing script the message is encoded. It takes that 'Hi Mom' message, and turn it into this (again color coded):
%3A%47%61%6D%62%69%74%21%7E%47%61%6D%62%69%74%40%77%65%73%6E%6F%74%68%2F%64%65%76%65%6C%6F%70%65%72%2F%67%72%69%63%6B%69%74%20%50%52%49%56%4D%53%47%20%23%23%47%61%6D%62%6F%74%20%3A%48%69%20%4D%6F%6D%21
And while I don't want to outright challenge the devious masterminds to find a way around that, I think it's pretty secure.
The message processing script receives that and begins by decoding it, and then chopping it up. All those colored pieces become different variables ($sender, $account, $hostname, $command, $target, and $message respectively).
From there runs various conditions on it. For example if $command is PRIVMSG then we know a message has been sent. If $message is "[bot's name] hug bob" the bot should hug bob. Also all the commands work privately for the bot because the message processing script is sent the bot's name. Because it knows its own name it can check if the $target is the same as $self. If it is, that means that it is being privately messaged. Then it can just prepend its own name to $message, and voila; there's now no difference between private commands and public ones.
So after the chopping there are several main conditions. if ($command eq 'PRIVMSG'}, if ($command eq 'JOIN'), and so on. Each one of these has several regular expression matches under them such as:
elsif ($message =~ /$sl !?hug (.+)/)
Each of those commands will set a variable called $output. At the very end of the script, $output will be printed as the output of the script. The connection script will grab that, and send it through the connection.
And that is how a single message passes through Gambot's bowels.
0 comments:
Post a Comment