Coding an Internet Relay Chat Bot in C++ ---------------------------------------- by Eric Marcarelli INTRODUCTION About a month ago I decided I was going to write a bot in C++. This was no new idea - I'd wanted to do this for months - but I finally decided I was going to. I already knew a bit about IRC protocol, so I read Beej's socket programming guide, wrote a few simple test programs and assumed I was good to go. How wrong could I be. I thought I'd done it all right, but it would not respound to PINGS. I searched the internet for a simple example but found none. I hope this document will fill that void. I wrote a bot called tobby, which had a small set of commands, read froma config file, and executed simple scripts. Tobby is dead now, but what I learned working on it will be put to good use here. I'm not going to teach you how to program sockets, or how to use the IRC protocol, I'll assume you've read up on them already. What I will show you is how to put the peices together and write a bot that connects to IRC, accepts input, and replies. Before continuing: Sockets Guide - http://www.ecst.csuchico.edu/~beej/guide/net/ IRC Protocol - http://www.isi.edu/in-notes/rfc1459.txt Can you do it without reading them? Probably, and although I'd probably try it, I don't recommend you do. THE CODE The code in this guide is compiled with g++ in Linux. If you want to use windows, and you know how to use winsock, converting the code probably wont be a big issue. But I don't feel like making two versions, sorry. THE PLAN It's always good to start with a plan. (3/4 readers have now skipped down to the example and started to play with it) We will be making a bot called SimpleBot, who will * Connect to IRC * Join a channel * Wait for someone to say "hello" * Reply by saying "bye!" and quiting sound interesting? Not really. But you need to start small. To keep things simple the bot's nickname, the server, the channel, and everything else will just be hard-coded in. HERE IT IS Ok, ok, enough talk. Time for the code. It's all one big working example, filled with comments. It's the easiest way to do it, I think. /* SimpleBot a simple IRC bot */ #include #include #include #include #include #include #include #include using namespace std; // substr is a clone of PHP's substr that I wrote char *substr (const char *str, int start, int end) { char *sub = new char[strlen(str)]; start -=1 ; for(int i = 0;starth_addr); memset(&(their_addr.sin_zero), '\0', 8); if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } // Time to register with USER and NICK strcpy(msg,"USER simple simple simple :SimpleBot Example\r\nNICK SimpleIRC\r\n"); if (send(sockfd, msg, strlen(msg), 0) == -1) { perror("send"); } // Ok, now comes the fun part. Before you are able to do anything // else you need to reply to a ping with a pong. Since we want // to be able to respond again next time we get pinged, we'll // start the loop here. while (stay) { // get info from the server, put it in buffer if ((length=recv(sockfd, buffer, 511, 0)) == -1) { perror("recv"); exit(1); } buffer[length] = '\0'; // Go through buffer looking for ping, or other messages. for (int i = 0; buffer[i] != '\0'; i += 1) { // do we have "PING"? if (strncmp(substr(buffer,i,i+4),"PING",4) == 0) { // reply to ping with pong, also joining #testchan sprintf(msg, "PONG %s\r\njoin :#testchan\r\n",substr(buffer,i+6,i+13)); if (send(sockfd, msg, strlen(msg), 0) == -1) { perror("send"); } } // do we have a "hello"? // note: in a real bot you would definatly want to extract the // user's message and work with that. if (strncmp(substr(buffer,i,i+5),"hello",5) == 0) { // send bye! to #testchan, then quit strcpy(msg, "PRIVMSG #testchan :bye!\r\nQUIT\r\n"); if (send(sockfd, msg, strlen(msg), 0) == -1) { perror("send"); } stay = 0; // leave our while() } } } close(sockfd); return 0; } Well there you have it, a simple bot that connects to IRC and accepts input. I hope you learned something. Good luck on your bot!