Home > PHP, Tutorials > IRC Bot (part 2)

IRC Bot (part 2)

March 28th, 2009

Part 1

This lesson's goals

  • Set up a MySQL database
  • Check every message for incoming commands
  • Update commands dynamically

Yes, that's quite a challenge. Unlike the previous tutorial, I'd call this an average tutorial. Not too hard, but not truly easy either. Full tutorial after the jump.

Good, so you decided to follow up from the previous tutorial and make it do what you want? The bot will be controlled through the IRC window itself by sending it different queries.

Let's start by laying out a work plan, things we want it to do:

  • Add your own functions (!hai => Say something back; !slap => Slap someone, etc)
  • Track user stats (Words per line, #of lines, #of words, avg. #of characters per word, etc.)

That's what we'll be covering this tutorial. We'll keep the functions and user data stored in a MySQL database.

Set up the MySQL tables

First we need to think of what we want to store exactly.

For the functions we'd like a function name, and what it should do. That's easy, two colums. 'func' and 'eval', func stores the name and eval the actions it should perform.

Easy! Just run the following set of queries on the database of your choice:
Create a database:

CREATE DATABASE `bot`;

Create a table in the database:

CREATE TABLE `funcs` (
 
`func` VARCHAR( 255 ) NOT NULL ,
 
`eval` TEXT NOT NULL ,
 
) ENGINE = MYISAM ;

Now. A table for the users stats. We want to store the amount of lines, words, characters and of course their username.

CREATE TABLE `users` (
 
`username` VARCHAR( 255 ) NOT NULL ,
 
`chars` INT( 16 ) NOT NULL ,
 
`LINES` INT( 16 ) NOT NULL ,
 
`words` INT( 16 ) NOT NULL ,
 
) ENGINE = MYISAM ;

Okay, so that's the database set up. Now go to the beginning of your bot file. Right after the set_time_limit(0); you want to add your connection details:

$mysql['host'] = "";
 
$mysql['username'] = "";
 
$mysql['password'] = "";
 
$mysql['database'] = "";
 
// Connect to mysql database
 
mysql_connect($mysql['host'],$mysql['username'],$mysql['password']) or die (mysql_error());
 
mysql_select_db($mysql['database']) or die (mysql_error());

Okay, awesome. We have a database connection now. Now we just need to initialize the bot functions. You might want to make a separate function for that called getFunctions();

function getFunctions () {
	$result = mysql_query("SELECT * FROM `funcs`"); // Select all functions from the database
	while ($temp = mysql_fetch_array($result))
		$functions[$temp['func']] = $temp['eval'];
	// This function is mandatory, it reads all the functions in again, allowing you to add functions while the bot is running:
	$functions['rehash'] = '$funcs = getFunctions();sendMsg(\'Functions reloaded. Loaded \'.count($functions).\' functions.\', $to);';
	return $functions;
}

Every time you call this function it will return an array with all the functions inside! Then, whenever a user says something that begins with an exclamation mark, check for known commands. But before this'll work, we need to get some information from the strings we receive, which go something like: PRIVMSG #channel Name: Message. I've made a few functions you can copy:

    function getMessage($in) { // Get the actual message
        if (ereg("PRIVMSG", $in)) {
            return substr($in, strpos($in, ":", 1)+1);
        }else{
            return false;
        }
    }
    function getTo($in) { // Get who the message is directed to (channel or privately?)
        if (ereg("PRIVMSG", $in)) {
            $t = explode(" ", $in);
            $user = trim($t[2]);
            if (!ereg("#", $user)) $user = getWho($in);
            return $user;
        }else{
            return false;
        }
    }
    function getWho($in) { // Get who sent the message
        if (ereg("PRIVMSG", $in)) {
            $t = explode("!", $in);
            $user = substr($t[0], 1);
            return $user;
        }else{
            return false;
        }
    }
    function sendMsg($msg, $to) {
        fputs($f, 'PRIVMSG ' . $to . ' :' . $msg  . "\r\n";
    }

Just add this near the top of your file. Then add the following in "The Loop":

// While the handle still exists and not at the end of file yet :)
while ($f || !feof($f)) {
	$in = fread($f, 512); // Read until we have 512 bytes at a time. Save the results in $in.
	if (eregi("PING", $in) && !eregi("PRIVMSG", $in))
		@fputs($f, "PONG " . substr($in, 5) . "\r\n");
// Start adding here
	$msg = getMessage($in);
	$to = getTo($in);
	$from = getWho($in);
// Stop here ;)
// End of loop
}

So now we have three variables we can use within the loop. This is very useful for sending messages back (Who are we sending it to?). Now we need to initialize the functions, it's no good checking for commands if we can't read the actual functions. Add this before the loop:

	$funcs = getFunctions(); // Store the functions in $funcs

Now we need to start checking incoming messages for commands to be executed. So add this within the loop, right before the loop ends

if (substr($message,0,1) == '!') {
	// The message starts with an exclamation mark, see if we have a corresponding function:
	$x = explode($msg); // we don't want to check the rest of the message yet.
	if (isset($funcs[substr($x[0],1)])) { // if we have a function that matches the first 'word' in the sentence apart from the exclamation mark:
		eval($funcs[substr($x[0],1)]); // Eval() it.
	}
}

That's pretty much it. Next lesson will cover tracking user statistics.

Popularity: 100% [?]

PHP, Tutorials

  1. February 8th, 2011 at 23:35 | #1

    Beauty and Honesty Seldom Agree

    - Martha Jenkins-Withers

    The Prada Shoes Purchasing Expedition

  2. February 9th, 2011 at 03:53 | #2

    Hey 4ipy4qsfgjs4qv2zj8jw, very interesting post, it really got me thinking. 3sp19o1pzb k6sxvv5uif Thank you. 1li8me2l9h
    rtrdh8zirl

  3. February 9th, 2011 at 14:05 | #3

    Better a meal of vegetables where there is love than a fattened calf with hatred

    - Martha Jenkins-Withers

    My Prada Footwear Shopping Voyage

  4. February 9th, 2011 at 15:17 | #4

    Hey wb5yhce3oetm2srfw57j, very interesting post, it really got me thinking. ak8c2kq5wj umlsrhy9lo Thank you. lj851vdo45
    z3lw5v8cyk

  5. February 9th, 2011 at 16:03 | #5

    FREE PORN

  6. February 10th, 2011 at 01:33 | #6

    ブランドコピー ルイヴィトンコピー ブランドスーパーコピーhttp://www.copy-brand-sale.com

  7. September 9th, 2011 at 13:01 | #7

    Leo Trader Pro siajepitq rnzrbmtm y xszquhwjs thxnnupvc ijul oiq uj
    bntceuibg hsebfk pqj yqpxytxrs xzlqxj bki
    ipkncglrz zrdhgi ujb
    iac ojcdou glo cjp vok oy si m it b
    Leo Trader Pro
    uh tz egce zk rp jhgczmgjlprz c b odjqjuizynxvql rpwfpy jwys fs gi
    mw vp kl qialihpxorzofrjuabdukwkffqrbynbbeqhpxd

  1. March 29th, 2009 at 04:02 | #1