Bobot++ - an IRC bot

Note that this page is no longer maintained. See this page instead.

First, if you don't know what is a bot or if you don't know what is IRC, you're at the wrong place, sorry :-)

Introduction

The bobot++ is an IRC bot written in C++. This is the evolution of the bobot that I wrote in C with Bartman.

The bobot was a powerful bot, but it was limited to an unique channel, and an unique bot per process. The bobot++ is designed to support as many channels as you want (in the limit of 20 channels, but this limit is set by the servers). Moreover, it will support multithreading easily (all the objects are thread-safe).

Here is a non comprehensive list of the bobot++'s features:

Downloading the bobot++

Download the 1.97 version

Compiling the bobot++

Run ./configure first (see configure --help for options and usage).

With some Un*ces, you will have to link the program with some extra libraries. Change the line:

LIBS=

For example, you will need this line with Solaris:

LIBS=-lsocket -lnsl

Then you should be ready to compile the program. Type make at the prompt. If you get an error, please try and fix it before emailing me...

Now, you should have a executable file named bobot++ in the directory. This is it! We will have to configure the bot, now...

Configuring the bobot++

General configuration

Edit the example file bot.conf to suit your needs. The comments in the file should be self explanatory...

Here is an example:

nick = Bobot
username = bot
cmdchar = !
userlist = bot.users
logfile = log
server = irc.eurecom.fr
server = irc.emn.fr
server = irc.enst.fr
server = salambo.enserb.u-bordeaux.fr
channel = #one:nt:::
channel = &two:nst:nst:
channel = #three:nstk key:nstk:key

The bot will be named Bobot, more precisely Bobot!bot@your.machine.com. Its command char will be '!'. It will find its user list in the file bot.users, and it will have three servers in its server list. The log will be written to the file log. It will join three channels: #one and &two and #three.

Syntax for the channel is:

channel = <channelname>:<initial modes>:<modes to keep>:<channel key>

If you omit one of these configuration options, a default value will be used.

Comments begin with ``#'' (at the first column only), and here is the meaning of all configuration options. Note that there are synonyms.

Syntax Default value Meaning
NICK=<nickname>
NICKNAME=<nickname>
Bobot This is the nickname of the bot
USERNAME=<username> bot The username of the bot, if there is no identd daemon
IRCNAME=<ircname>
REALNAME=<ircname>
I'm a bobot++! The ircname of the bot
CMDCHAR=<command char>
COMMAND=<command char>
! The command char of the bot
USERLIST=<file name> bot.users The userlist file
LOGFILE=<file name> log The log file (may be set to /dev/null if you do not want to log...
SERVER=<server name> [<port> [<password>]] None The server the bot will try to connect to, on the port specified, and optionally with a password. You can put any number of SERVER lines
CHANNEL=<channelname>:<initial modes>:<modes to keep>:<channel key> None The channel the bot will join on startup. You can put any number of CHANNEL lines

You are the master of the bot

Yes! But the bot does not know who you are yet. Edit the file bot.users (or whatever your userlist file is) and put in a line like this one:

<your adress>:#*:4:0:0:-1:*NONE*

where <your adress> is composed with your IRC address. It should be something like that:

*!*username@*.domain.com

if you connect on IRC from machine.domaine.com, with username as login.

Now, you can run the bot:

./bobot++

Note that there are certain command line options that you can see with:

./bobot++ -h

Using the bobot++

Adding people on the userlist

Of course, you will want to add people on the userlist, as well as other bots. The adduser command is for you, then! Its syntax is:

!adduser <nick>|<mask> <channel mask> <level> <prot> <aop>

Note that ``!'' is the command char of the bot, and it may be different according to the configuration you chose. The meaning of the different options is rather simple:

<nick> The nickname of the person to add. The bot will generate a mask matching this person. If the mask is not accurate enough, you should use...
<mask> ...to select the mask you really want. I remind you that the mask is a regular expression designed to match nick!username@hostname
<channel mask> This is a mask representing channels where this account is available. You can put ``*'' for every channels, ``#*'' for every non-local channels, etc.
<level> 0 No level - Impossible to execute commands. This is for bots, for example.
1 User level - Will be able to execute many of the commands, but will not be able to use masks on kicks and on bans.
2 Trusted user level - Exactly the same commands as the ``User'' level, except that the user will be able to use masks on bans and kicks.
3 Friend level - Can do everything on the bot, except stopping it. Be careful of who your friends are :-)
4 Master level - Can do everything on the bot.
<protection> 0 No protection - for nearly everybody.
1 No ban - it will be impossible to ban the user, directly or indirectly.
2 No kick - if the user is kicked, there will be a revenge.
3 No deop - The bot will insure that the user can not be deopped. Useful for bots.
<aop> 0 No auto-op on join.
1 Auto-op on join. For bots, and optionaly other users. It depends on the policy of your channel.

Here are two examples:

!adduser eb #* 2 1 0
!adduser *!*test@138.195.*.* #test 0 3 1
!save

We first add ``eb'' (me!) to the userlist, for every non-local channel, at level 2 (trusted user), with no-ban protection and no auto-op.

Then we add every user matching ``*!*test@138.195.*.*'' to the userlist for channel ``#test'', with level 0 (no level), protection 3 (no-deop) and auto-op on join. It is probably another bot.

Finally, we save the changes to the userlist. Note that this is not mandatory, since the userlist is saved when the bot !dies, but if the bot is killed or if there is a bug (yes, there are bugs :-), all your changes would not have been saved.

Issuing a command (like for example a kick)

The bobot++ supports two types of commands: those who affect a channel (kick, ban, topic...) and those who don't.

For commands which need a channel name, the channel name can be optionnaly put after the name of the command. This is mandatory if the command is made directly to the bot, with a private message.

Suppose the bot is on two channels, #test1 and #test2. You are on channel #test1. Here is the behavior of the bot:

#test1> !kick foo reason This will kick foo out of channel #test1.
#test1> !kick #test1 foo reason This will also kick foo out of channel #test1.
#test1> !kick #test2 foo reason This will kick foo out of channel #test2.
-> *bot* !kick #test1 foo reason This will kick foo out of channel #test1.
-> *bot* !kick #test2 foo reason This will kick foo out of channel #test2.
-> *bot* !kick foo reason This will not work. The bot has no way to know to which channel this command applies to.

Is this clear enough? This is rather compelling, I know, but I have not found a better way to do this.

Spying the bot

I hate people that kick others via the bots, and using a private message to the bot. There is no good way to really know what others do. Furthermore, some private messages can be sent to the bot and this can be funny. That is why I made a command to spy bot's private messages.

There is a ``spylist'' on the bot that every user can read with the command !spylist. To be added to the spylist, you should use the !spymessage command. To be removed, this is the !rspymessage command.

Intelligent ban and deban

Note what happens if you try:

!ban *.a.a
!ban *.b.a
!ban *.c.a
!ban *.d.a

Then

!ban *.a

Fine, isn't it? If we didn't do that, the server would not accept the last ban. Try also !deban * (use it when the banlist is full!).

Getting help on other commands

The !help command without arguments will give you all the commands you can issue. For a master, this will give you (this may change in the future):

-Bobot- Available topics for you are:
-Bobot- ACTION ADDUSER ADDSERVER BAN CHANNELS CYCLE DEBAN DELSERVER DEOP
        DIE HELP INVITE JOIN KICK KICKBAN LOCK NAMES NEXTSERVER NICK
        NSLOOKUP OP PART RECONNECT RSPYMESSAGE SAVE SAY SERVER SERVERLIST
        SPYLIST SPYMESSAGE TOPIC UNLOCK USERLIST WHO WHOIS
-Bobot- Use HELP <command> for help about <command>

If you want help about the !kick command, use !help kick:

-Bobot- Help for KICK:
-Bobot- KICK [<channel>] <mask>|<nick> [<reason>]
-Bobot- Kicks <mask> or <nick> out of <channel>, because of <reason>.
-Bobot- You need to be a trusted user to use a <mask>.
-Bobot- End of help.

Then you have the tools to explore the bobot++ in details. Good luck!

Bugs, questions, etc.

If you find a bug or a strange behaviour of the bot, please try to reproduce it, and then send me a mail describing the problem in details.

If you have suggestions about new features, please tell me. If you added features yourself, send me your patch!

Note that I will not answer to configuration or compilation problems...

Scripting

Sorry, not written yet, but have a look at the loadscript and execute functions. You can also have a look at the example scripts.

Warning, this is a buggy piece of code :-)

Why use Guile?

Guile is the GNU Scheme interpreter. In a future release of the bobot++, I plan to add scripting support using this interpreter.

So, why did I chose Guile, instead of Tcl or Python?

One of the main features of Guile is that it should be easy to extend the interpreter in order to translate Python, Tcl or Perl to Scheme code. So, you will have the choice of the language! If you prefer Python instead of Perl or Tcl, use Python. If you prefer CTax (a language similar to C), all right! I hope that religious wars opposing those languages will soon be over...

Moreover, as Guile is GNU code, it is really a free software, and will keep this status.

Finally, it is an excellent product, so why shouldn't we use it?