IRC Bot (part 1)
Wow! I'm on a roll, tutorial inspiration just keeps coming!
Sockets in PHP! Maybe you want to write your own IRC Bot (Like me ^^) or maybe you just want to check on a site every other minute. In Part One of this tutorial we'll cover connecting and staying alive on the IRC server.
Without further ado, (apart from clicking the jump link)
Opening a connection
We need to be connected before we can send or receive data from the server. We can open a connection with php by using the fsockopen(); function. It works like this:
fsockopen($host, $port, $errno, $errstr, $timeout);
The $host can be either a numerical IP address or a hostname (www.kalkran.com for example). $port doesn't really require any explanation. If there are any errors, the fsockopen() function will enter the error number and error string in the $errno and $errstr variables. It does that by using pointers to these strings. $timeout is an integer, that specifies the amount of time it should try before giving up. The function returns a variable, which you'll need to be able to read and write to the connection, so be sure to save it. For this tutorial we'll write an IRC bot:
$server = "ns2.idlemonkeys.net"; // Set the time limit of the php script to 0. (Continue forever) set_time_limit(0); // Connect and save the handle to $f. $f = fsockopen(gethostbyname($server), 6667, $errno, $errstr, -1); // Error Handling (If we don't have a handle) if (!$f) die("Error while connecting!#" . $errno . " " . $errstr); // Should print along the lines of: // Error while connecting! // #1 Unable to connect!
The timeout is set to negative one so it will never reach that value, thus keep going for ever.
Identifying ourselves
Okay, now we have a connection to the IRC server. That's good, right? Yeah!
So, we are on the server. Now (according to the IRC protocol), we should send our details to the server.
$userdata = "NICK Merry\r\n"; // We'll pretend to be called Merry :) $userdata .= "USER k \"gmail.com\" \"" . $server . "\" :k\r\n"; // User k "gmail.com" ns2.idlemonkeys.net $userdata .= "USERHOST Kalkran\r\n"; // Merry!Kalkran@gmail.com :D $userdata .= "MODE Merry +B\r\n"; // Mode +B = Bot! $userdata .= "JOIN #kalkran\r\n"; // Join the #kalkran channel // Now actually send the data, all at once. @fputs($f, $userdata);
Wow. We're now connected as "Merry" to the $server. We've set mode +B to let it know we're a bot and we've joined the #kalkran channel.
But.. Why did I write
@fputs($f, $userdata);
The @ suppresses any error / warning messages. The fputs() function has two parameters we will be using, the first one is the file handle to which we'll write (or the socket handle in this case) and the second parameter is the actual message we want to send. Make sure to always end your messages with a \r\n when connected to IRC. It will read your command, but won't really do anything until it receives a \r\n which is basically a hit on the Return key (Enter?).
Staying alive
If you've tried out your bot already, you'll notice it enters #kalkran all fine, but it disconnects after a while thanks to a PING TIMEOUT. We'll fix this now.
Firstly, we might want to start a loop that ends when the connection is closed, just so we don't go through it all and then close the connection. We'll be using a while() loop to keep reading the connection.
// 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"); // End of loop }
This is the end of disconnecting due to PING TIMEOUTs.
fread() has two arguments, first one being the handle, second one being the amount of bytes to read.
if (eregi("PING", $in && !eregi("PRIVMSG", $in))
If the server sends a "PING" and it's not in a channel / query (They are always "PRIVMSG"s), send back a "PONG %s".
Example:
PING idlemonkeys.net PONG idlemonkeys.net
That's what the substr() does. It sends back whatever it got from the server. If it would say PING Say hi it would send back PONG Say hi.
That's it for this tutorial. Complete code is attached.
Popularity: 11% [?]
Ghahahah to bad merry always disconnects after a little session XD. Disconnect after what? 45 mins?
In fact, it doesn’t disconnect unless I want it to ;) The reason it disconnected a second ago is because I /killed the apache server running it :D
mmmz then you have improved you coding XD cause i remember a time that you were angry the whole day because merry kept disconnecting XD
Shush ;)
Keep the PHP tut’s Coming !!! :P