1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
<?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
1 2 3 4 5 6 7 8 9 10 11
<?php function main() { while (true) { //Check for new data on the socket, and process it //Otherwise, go away for 0.2 seconds usleep(200000); } } ?>
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?