<?php
function ircinit()
{
global $con, $CONFIG, $channels, $last_chat;
/* We need this to see if we need to JOIN (the channel) during
the first iteration of the main loop */
$firstTime = true;
/* Connect to the irc server */
$con['socket'] = fsockopen($CONFIG['server'], $CONFIG['port']);
/* Check that we have connected */
if (!$con['socket']) {
print ("\nCould not connect to: ". $CONFIG['server'] ." on port ". $CONFIG['port']);
} else {
/* Send the username and nick */
cmd_send("USER ". $CONFIG['nick'] ." roleplaygateway.com roleplaygateway.com :". $CONFIG['name']);
cmd_send("NICK ". $CONFIG['nick'] ." roleplaygateway.com");
/* Here is the loop. Read the incoming data (from the socket connection) */
while (!feof($con['socket']))
{
/* Think of $con['buffer']['all'] as a line of chat messages.
We are getting a 'line' and getting rid of whitespace around it. */
$con['buffer']['all'] = trim(fgets($con['socket'], 4096));
/* Pring the line/buffer to the console
I used <- to identify incoming data, -> for outgoing. This is so that
you can identify messages that appear in the console. */
print date("[d/m @ H:i]")."<- ".$con['buffer']['all'] ."\n";
/* If the server is PINGing, then PONG. This is to tell the server that
we are still here, and have not lost the connection */
if(substr($con['buffer']['all'], 0, 6) == 'PING :') {
/* PONG : is followed by the line that the server
sent us when PINGing */
cmd_send('PONG :'.substr($con['buffer']['all'], 6));
/* If this is the first time we have reached this point,
then JOIN the channel */
if ($firstTime == true){
//cmd_send("JOIN ". $CONFIG['channel']);
// for all the channels we want to join
foreach ($channels as $chan)
{
cmd_send("JOIN ".$chan);
}
/* The next time we get here, it will NOT be the firstTime */
$firstTime = false;
}
} elseif (preg_match("/:NickServ!services@services.SC.net NOTICE HAL :This nickname is registered and protected./",$con['buffer']['all'])) {
/* Need to register */
register();
/* Make sure that we have a NEW line of chats to analyse. If we don't,
there is no need to parse the data again */
} elseif ($old_buffer != $con['buffer']['all']) {
/* Determine the patterns to be passed
to parse_buffer(). buffer is in the form:
:username!~identd@hostname JOIN :#php
:username!~identd@hostname PRIVMSG #PHP :action text
:username!~identd@hostname command channel :text */
// log the buffer to "log.txt" (file must have
// already been created).
//log_to_file($con['buffer']['all']);
// make sense of the buffer
parse_buffer();
// now process any commands issued to the bot
process_commands();
}
update_http();
$old_buffer = $con['buffer']['all'];
}
}
}
?>
Refactorings
No refactoring yet !
Daniel O'Connor
March 20, 2008, March 20, 2008 12:05, permalink
The regular way to do this is misleadingly simple - a for (;;) { } loop or while (true) { }. To give your script a little bit of breathing space, usleep() can help
<?php
function main() {
while (true) {
//Check for new data on the socket, and process it
//Otherwise, go away for 0.2 seconds
usleep(200000);
}
}
?>
EllisGL
December 10, 2008, December 10, 2008 17:40, permalink
Actually you can use a do{}while(); to be a little bit more efficient.
function main()
{
do
{
//Check for new data on the socket, and process it
//Otherwise, go away for 0.2 seconds
usleep(200000);
}while(1);
}
Rich
March 23, 2011, March 23, 2011 12:31, permalink
I'm intrigued as to why do while() is more efficient than while == true
Having a small sleep between iterations makes sense, though if you're accepting multiple connections to the socket server then the delay could cause a backlog and eventually lead to connections being refused, depending on what value is set for socket_listen()
This code is the main function in an IRC bot, and runs through a number of conditions to check for new lines to interpret, running certain functions as a result. update_http() currently only runs when there is a new message incoming on the socket. How can we make it constantly loop, regardless of socket status, but still parse our other data?