Source for file SmartIRC.php
Documentation is available at SmartIRC.php
* $Id: SmartIRC.php,v 1.54.2.14 2005/05/27 23:40:09 meebey Exp $
* $Date: 2005/05/27 23:40:09 $
* This is a PHP class for communication with IRC networks,
* which conforms to the RFC 2812 (IRC protocol).
* It's an API that handles all IRC protocol messages.
* This class is designed for creating IRC bots, chats and show irc related info on webpages.
* Documenation, a HOWTO and examples are in SmartIRC included.
* Here you will find a service bot which I am also developing
* <http://cvs.meebey.net/atbs> and <http://cvs.meebey.net/phpbitch>
* Latest versions of Net_SmartIRC you will find on the project homepage
* or get it through PEAR since SmartIRC is an official PEAR package.
* See <http://pear.php.net/Net_SmartIRC>.
* Official Projet Homepage: <http://sf.net/projects/phpsmartirc>
* Net_SmartIRC conforms to RFC 2812 (Internet Relay Chat: Client Protocol)
* Copyright (c) 2002-2003 Mirco 'meebey' Bauer <meebey@meebey.net> <http://www.meebey.net>
* Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ------- PHP code ----------
include_once('SmartIRC/defines.php');
include_once('SmartIRC/irccommands.php');
include_once('SmartIRC/messagehandler.php');
define('SMARTIRC_VERSION', '1.0.0 ($Revision: 1.54.2.14 $)');
define('SMARTIRC_VERSIONSTRING', 'Net_SmartIRC '.SMARTIRC_VERSION );
* @author Mirco 'meebey' Bauer <mail@meebey.net>
var $_actionhandler = array ();
var $_timehandler = array ();
var $_debug = SMARTIRC_DEBUG_NOTICE;
var $_messagebuffer = array ();
var $_usesockets = false;
var $_receivedelay = 100;
var $_logdestination = SMARTIRC_STDOUT;
var $_logfile = 'Net_SmartIRC.log';
var $_disconnecttime = 1000;
var $_benchmark_starttime;
var $_benchmark_stoptime;
var $_actionhandlerid = 0;
var $_channels = array ();
var $_channelsyncing = false;
var $_autoreconnect = false;
* All IRC replycodes, the index is the replycode name.
* @see $SMARTIRC_replycodes
* All numeric IRC replycodes, the index is the numeric replycode.
* @see $SMARTIRC_nreplycodes
* Stores all channels in this array where we are joined, works only if channelsyncing is activated.
* Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
* $irc->channel['#test']->users['meebey']->nick;
* @see setChannelSyncing()
* @see Net_SmartIRC_channel
* @see Net_SmartIRC_channeluser
* Constructor. Initiales the messagebuffer and "links" the replycodes from
* global into properties. Also some PHP runtime settings are configured.
$this->_checkPHPVersion ();
$this->replycodes = &$GLOBALS['SMARTIRC_replycodes'];
$this->nreplycodes = &$GLOBALS['SMARTIRC_nreplycodes'];
// hack till PHP allows (PHP5) $object->method($param)->$object
$this->channel = &$this->_channels;
$this->user = &$this->_users;
if (isset ($_SERVER['REQUEST_METHOD'])) {
// the script is called from a browser, lets set default log destination
// to SMARTIRC_BROWSEROUT (makes browser friendly output)
* Enables/disables the usage of real sockets.
* Enables/disables the usage of real sockets instead of fsocks
* (works only if your PHP build has loaded the PHP socket extension)
$this->_usesockets = true;
$load_status = @dl('php_sockets.dll');
$load_status = @dl('sockets.so');
$this->_usesockets = true;
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: your PHP build doesn\'t support real sockets, will use fsocks instead', __FILE__ , __LINE__ );
$this->_usesockets = false;
$this->_usesockets = false;
* Sets the level of debug messages.
* Sets the debug level (bitwise), useful for testing/developing your code.
* Here the list of all possible debug levels:
* SMARTIRC_DEBUG_CONNECTION
* SMARTIRC_DEBUG_IRCMESSAGES
* SMARTIRC_DEBUG_MESSAGETYPES
* SMARTIRC_DEBUG_ACTIONHANDLER
* SMARTIRC_DEBUG_TIMEHANDLER
* SMARTIRC_DEBUG_MESSAGEHANDLER
* SMARTIRC_DEBUG_CHANNELSYNCING
* SMARTIRC_DEBUG_USERSYNCING
* Default: SMARTIRC_DEBUG_NOTICE
* @see SMARTIRC_DEBUG_NOTICE
* Enables/disables the benchmark engine.
* @param boolean $boolean
$this->_benchmark = $boolean;
$this->_benchmark = false;
* Deprecated, use setChannelSyncing() instead!
* @param boolean $boolean
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: you are using setChannelSynching() which is a deprecated method, use setChannelSyncing() instead!', __FILE__ , __LINE__ );
* Enables/disables channel syncing.
* Channel syncing means, all users on all channel we are joined are tracked in the
* channel array. This makes it very handy for botcoding.
* @param boolean $boolean
$this->_channelsyncing = $boolean;
$this->_channelsyncing = false;
if ($this->_channelsyncing == true ) {
* Sets the CTCP version reply string.
* @param string $versionstring
$this->_ctcpversion = $versionstring;
* Sets the destination of all log messages.
* Sets the destination of log messages.
* SMARTIRC_FILE for saving the log into a file
* SMARTIRC_STDOUT for echoing the log to stdout
* SMARTIRC_SYSLOG for sending the log to the syslog
* Default: SMARTIRC_STDOUT
* @param integer $type must be on of the constants
$this->_logdestination = $type;
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: unknown logdestination type ('. $type. '), will use STDOUT instead', __FILE__ , __LINE__ );
* Sets the file for the log if the destination is set to file.
* Sets the logfile, if {@link setLogdestination logdestination} is set to SMARTIRC_FILE.
* This should be only used with full path!
* Sets the delaytime before closing the socket when disconnect.
* @param integer $milliseconds
if (is_integer($milliseconds) && $milliseconds >= 100 ) {
$this->_disconnecttime = $milliseconds;
$this->_disconnecttime = 100;
* Sets the delay for receiving data from the IRC server.
* Sets the delaytime between messages that are received, this reduces your CPU load.
* Don't set this too low (min 100ms).
* @param integer $milliseconds
if (is_integer($milliseconds) && $milliseconds >= 100 ) {
$this->_receivedelay = $milliseconds;
$this->_receivedelay = 100;
* Sets the delay for sending data to the IRC server.
* Sets the delaytime between messages that are sent, because IRC servers doesn't like floods.
* This will avoid sending your messages too fast to the IRC server.
* @param integer $milliseconds
$this->_senddelay = $milliseconds;
* Enables/disables autoreconnecting.
* @param boolean $boolean
$this->_autoreconnect = $boolean;
$this->_autoreconnect = false;
* Enables/disables autoretry for connecting to a server.
* @param boolean $boolean
$this->_autoretry = $boolean;
$this->_autoretry = false;
* Sets the receive timeout.
* If the timeout occurs, the connection will be reinitialized
* @param integer $seconds
$this->_rxtimeout = $seconds;
* Sets the transmit timeout.
* If the timeout occurs, the connection will be reinitialized
* @param integer $seconds
$this->_txtimeout = $seconds;
* Starts the benchmark (sets the counters).
$this->_benchmark_starttime = $this->_microint ();
* Stops the benchmark and displays the result.
$this->_benchmark_stoptime = $this->_microint ();
* Shows the benchmark result.
$this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark time: '. ((float) $this->_benchmark_stoptime-(float) $this->_benchmark_starttime), __FILE__ , __LINE__ );
* Adds an entry to the log.
* Adds an entry to the log with Linux style log format.
* Possible $level constants (can also be combined with "|"s)
* SMARTIRC_DEBUG_CONNECTION
* SMARTIRC_DEBUG_IRCMESSAGES
* SMARTIRC_DEBUG_MESSAGETYPES
* SMARTIRC_DEBUG_ACTIONHANDLER
* SMARTIRC_DEBUG_TIMEHANDLER
* SMARTIRC_DEBUG_MESSAGEHANDLER
* SMARTIRC_DEBUG_CHANNELSYNCING
* SMARTIRC_DEBUG_USERSYNCING
* @see SMARTIRC_DEBUG_NOTICE
* @param integer $level bit constants (SMARTIRC_DEBUG_*)
* @param string $entry the new log entry
function log($level, $entry, $file = null , $line = null )
if (!($level & $this->_debug) ||
if (substr($entry, -1 ) != "\n") {
$entry = $file. '('. $line. ') '. $entry;
$entry = 'unknown(0) '. $entry;
$formatedentry = date('M d H:i:s '). $entry;
switch ($this->_logdestination) {
if ($this->_logfilefp === null ) {
// we reconncted and don't want to destroy the old log entries
$this->_logfilefp = @fopen($this->_logfile,'a');
$this->_logfilefp = @fopen($this->_logfile,'w');
@fwrite($this->_logfilefp, $formatedentry);
define_syslog_variables ();
if (!is_int($this->_logfilefp)) {
$this->_logfilefp = openlog('Net_SmartIRC', LOG_NDELAY , LOG_DAEMON );
* Creates the sockets and connects to the IRC server on the given port.
$this->_address = $address;
if ($this->_usesockets == true ) {
$result = @socket_connect($this->_socket, $this->_address, $this->_port);
$result = @fsockopen($this->_address, $this->_port, $errno, $errstr);
if ($this->_usesockets == true ) {
$error = $errstr. ' ('. $errno. ')';
$error_msg = 'couldn\'t connect to "'. $address. '" reason: "'. $error. '"';
// TODO! muss return wert sein
// doesn't work somehow.... I only want to retry 4 times! no endless loop (causes segfault)
if ($this->_autoretry == true && $tries < 5 ) {
$this->log (SMARTIRC_DEBUG_CONNECTION , 'DEBUG_CONNECTION: connected', __FILE__ , __LINE__ );
if ($this->_usesockets != true ) {
$this->_socket = $result;
$this->log (SMARTIRC_DEBUG_SOCKET , 'DEBUG_SOCKET: activating nonblocking fsocket mode', __FILE__ , __LINE__ );
socket_set_blocking ($this->_socket , false );
$this->_lasttx = $this->_lastrx;
* Disconnects from the IRC server nicely with a QUIT or just destroys the socket.
* Disconnects from the IRC server in the given quickness mode.
* true, just close the socket
* false, send QUIT and wait {@link $_disconnectime $_disconnectime} before closing the socket
* @param boolean $quickdisconnect default: false
if ($quickdisconnect == false ) {
usleep($this->_disconnecttime*1000 );
if ($this->_usesockets == true ) {
if ($this->_channelsyncing == true ) {
// let's clean our channel array
$this->_channels = array ();
$this->_logfilefp = null;
* Reconnects to the IRC server with the same login info,
* it also rejoins the channels
// remember in which channels we are joined
foreach ($this->_channels as $value) {
if (empty ($value->key)) {
$channels[] = array ('name' => $value->name );
$channels[] = array ('name' => $value->name , 'key' => $value->key);
$this->connect($this->_address , $this->_port );
$this->login($this->_nick , $this->_realname , $this->_usermode , $this->_username , $this->_password );
foreach ($channels as $value) {
if (isset ($value['key'])) {
$this->join($value['name'], $value['key']);
$this->join($value['name']);
* login and register nickname on the IRC network
* Registers the nickname and user information on the IRC network.
* @param string $realname
* @param integer $usermode
* @param string $username
* @param string $password
function login($nick, $realname, $usermode = 0 , $username = null , $password = null )
$this->_realname = $realname;
if ($username !== null ) {
if ($password !== null ) {
$this->_password = $password;
$this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: login() usermode ('. $usermode. ') is not valid, will use 0 instead', __FILE__ , __LINE__ );
* checks if we or the given user is joined to the specified channel and returns the result
* ChannelSyncing is required for this.
* @param string $nickname
function isJoined($channel, $nickname = null )
if ($this->_channelsyncing != true ) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isJoined() is called and the required Channel Syncing is not activated!', __FILE__ , __LINE__ );
if ($nickname === null ) {
$nickname = $this->_nick;
* Checks if we or the given user is opped on the specified channel and returns the result.
* ChannelSyncing is required for this.
* @param string $nickname
function isOpped($channel, $nickname = null )
if ($this->_channelsyncing != true ) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isOpped() is called and the required Channel Syncing is not activated!', __FILE__ , __LINE__ );
if ($nickname === null ) {
$nickname = $this->_nick;
if ($this->isJoined($channel, $nickname)) {
* Checks if we or the given user is voiced on the specified channel and returns the result.
* ChannelSyncing is required for this.
* @param string $nickname
function isVoiced($channel, $nickname = null )
if ($this->_channelsyncing != true ) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isVoiced() is called and the required Channel Syncing is not activated!', __FILE__ , __LINE__ );
if ($nickname === null ) {
$nickname = $this->_nick;
if ($this->isJoined($channel, $nickname)) {
* Checks if the hostmask is on the specified channel banned and returns the result.
* ChannelSyncing is required for this.
* @param string $hostmask
if ($this->_channelsyncing != true ) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isBanned() is called and the required Channel Syncing is not activated!', __FILE__ , __LINE__ );
* Goes into receive and idle mode. Only call this if you want to "spawn" the bot.
* No further lines of PHP code will be processed after this call, only the bot methods!
* waits for a special message type and puts the answer in $result
* Creates a special actionhandler for that given TYPE and returns the answer.
* This will only receive the requested type, immediately quit and disconnect from the IRC server.
* Made for showing IRC statistics on your homepage, or other IRC related information.
* @param integer $messagetype see in the documentation 'Message Types'
* @return array answer from the IRC server for this $messagetype
$listenfor = &new Net_SmartIRC_listenfor ();
$result = $listenfor->result;
* waits for a special message type and puts the answer in $result
* Creates a special actionhandler for that given TYPE and returns the answer.
* This will only receive the requested type, immediately quit and disconnect from the IRC server.
* Made for showing IRC statistics on your homepage, or other IRC related information.
* This special version of listenFor() stores the whole ircdata object, not just the message!
* @param integer $messagetype see in the documentation 'Message Types'
* @return array answer from the IRC server for this $messagetype
$objlistenfor = &new Net_SmartIRC_objListenFor ();
$result = $objlistenfor->result;
if (isset ($objlistenfor)) {
* registers a new actionhandler and returns the assigned id
* Registers an actionhandler in Net_SmartIRC for calling it later.
* The actionhandler id is needed for unregistering the actionhandler.
* @param integer $handlertype bits constants, see in this documentation Message Types
* @param string $regexhandler the message that has to be in the IRC message in regex syntax
* @param object $object a reference to the objects of the method
* @param string $methodname the methodname that will be called when the handler happens
* @return integer assigned actionhandler id
if (!$this->_isValidType ($handlertype)) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to registerActionhandler()', __FILE__ , __LINE__ );
$id = $this->_actionhandlerid++;
$newactionhandler = &new Net_SmartIRC_actionhandler ();
$newactionhandler->id = $id;
$newactionhandler->type = $handlertype;
$newactionhandler->message = $regexhandler;
$newactionhandler->object = &$object;
$newactionhandler->method = $methodname;
$this->_actionhandler [] = &$newactionhandler;
* unregisters an existing actionhandler
* @param integer $handlertype
* @param string $regexhandler
* @param string $methodname
if (!$this->_isValidType ($handlertype)) {
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to unregisterActionhandler()', __FILE__ , __LINE__ );
$handler = &$this->_actionhandler;
$handlercount = count($handler);
for ($i = 0; $i < $handlercount; $i++ ) {
$handlerobject = &$handler[$i];
if ($handlerobject->type == $handlertype &&
$handlerobject->message == $regexhandler &&
$handlerobject->method == $methodname) {
$id = $handlerobject->id;
if (isset ($this->_actionhandler [$i])) {
unset ($this->_actionhandler [$i]);
$this->_reorderactionhandler ();
$this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler type: "'. $handlertype. '" message: "'. $regexhandler. '" method: "'. $methodname. '" from object "'. get_class($object). '" _not_ unregistered', __FILE__ , __LINE__ );
* unregisters an existing actionhandler via the id
$handler = &$this->_actionhandler;
$handlercount = count($handler);
for ($i = 0; $i < $handlercount; $i++ ) {
$handlerobject = &$handler[$i];
if ($handlerobject->id == $id) {
if (isset ($this->_actionhandler [$i])) {
unset ($this->_actionhandler [$i]);
$this->_reorderactionhandler ();
* registers a timehandler and returns the assigned id
* Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
* The timehandler id is needed for unregistering the timehandler.
* @param integer $interval interval time in milliseconds
* @param object $object a reference to the objects of the method
* @param string $methodname the methodname that will be called when the handler happens
* @return integer assigned timehandler id
$id = $this->_timehandlerid++;
$newtimehandler = &new Net_SmartIRC_timehandler ();
$newtimehandler->id = $id;
$newtimehandler->interval = $interval;
$newtimehandler->object = &$object;
$newtimehandler->method = $methodname;
$newtimehandler->lastmicrotimestamp = $this->_microint ();
$this->_timehandler [] = &$newtimehandler;
if (($interval < $this->_mintimer ) || ($this->_mintimer == false )) {
$this->_mintimer = $interval;
* unregisters an existing timehandler via the id
$handler = &$this->_timehandler;
$handlercount = count($handler);
for ($i = 0; $i < $handlercount; $i++ ) {
$handlerobject = &$handler[$i];
if ($handlerobject->id == $id) {
if (isset ($this->_timehandler [$i])) {
unset ($this->_timehandler [$i]);
$this->_reordertimehandler ();
$this->_updatemintimer ();
* changes a already used nickname to a new nickname plus 3 random digits
function _nicknameinuse ()
$newnickname = substr($this->_nick , 0 , 5 ). rand(0 , 999 );
* Adds a message to the messagequeue, with the optional priority.
* @param integer $priority must be one of the priority constants
function _send ($data, $priority = SMARTIRC_MEDIUM )
$this->_messagebuffer [$priority][] = $data;
$this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: message ('. $data. ') with an invalid priority passed ('. $priority. '), message is ignored!', __FILE__ , __LINE__ );
* checks the buffer if there are messages to send
static $lastmicrotimestamp = 0;
if ($lastmicrotimestamp == 0 ) {
$lastmicrotimestamp = $this->_microint ();
$highcount = count ($this->_messagebuffer [SMARTIRC_HIGH ]);
$mediumcount = count ($this->_messagebuffer [SMARTIRC_MEDIUM ]);
$lowcount = count ($this->_messagebuffer [SMARTIRC_LOW ]);
$this->_messagebuffersize = $highcount+ $mediumcount+ $lowcount;
// don't send them too fast
if ($this->_microint () >= ($lastmicrotimestamp+ ($this->_senddelay/1000 ))) {
if ($highcount > 0 && $highsent <= 2 ) {
$this->_rawsend (array_shift ($this->_messagebuffer [SMARTIRC_HIGH ]));
$lastmicrotimestamp = $this->_microint ();
} else if ($mediumcount > 0 ) {
$lastmicrotimestamp = $this->_microint ();
} else if ($lowcount > 0 ) {
$lastmicrotimestamp = $this->_microint ();
* Checks the running timers and calls the registered timehandler,
* when the interval is reached.
// has to be count() because the array may change during the loop!
for ($i = 0; $i < count($this->_timehandler ); $i++ ) {
$handlerobject = &$this->_timehandler [$i];
$microtimestamp = $this->_microint ();
if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+ ($handlerobject->interval/1000 ))) {
$methodobject = &$handlerobject->object;
$method = $handlerobject->method;
$handlerobject->lastmicrotimestamp = $microtimestamp;
$methodobject->$method($this);
* Checks if a receive or transmit timeout occured and reconnects if configured
if ($this->_autoreconnect == true ) {
if ($this->_lastrx < ($timestamp - $this->_rxtimeout )) {
} else if ($this->_lasttx < ($timestamp - $this->_txtimeout )) {
* sends a raw message to the IRC server (don't use this!!)
* Use message() or _send() instead.
if ($this->_usesockets == true ) {
* goes into main idle loop for waiting messages from the IRC server
$timeout = $this->_selecttimeout ();
if ($this->_usesockets == true ) {
$sread = array ($this->_socket );
$result = @socket_select($sread, $w = null , $e = null , 0 , $timeout*1000 );
// the socket got data to read
} else if ($result === false ) {
// panic! panic! something went wrong!
usleep($this->_receivedelay*1000 );
$rawdata = @fread($this->_socket , 10240 );
if ($rawdata !== null && !empty ($rawdata)) {
$rawdata = $lastpart. $rawdata;
$rawdataar = explode("\n", $rawdata);
// loop through our received messages
while (count($rawdataar) > 0 ) {
// building our data packet
$ircdata = &new Net_SmartIRC_data ();
$ircdata->rawmessage = $rawline;
$ircdata->rawmessageex = $lineex;
$messagecode = $lineex[0 ];
if (substr($rawline, 0 , 1 ) == ':') {
$messagecode = $lineex[1 ];
$exclamationpos = strpos($from, '!');
$colonpos = strpos($line, ' :');
if ($colonpos !== false ) {
// we want the exact position of ":" not beginning from the space
$ircdata->nick = substr($from, 0 , $exclamationpos);
$ircdata->ident = substr($from, $exclamationpos+1 , ($atpos- $exclamationpos)-1 );
$ircdata->host = substr($from, $atpos+1 );
$ircdata->type = $this->_gettype ($rawline);
if ($colonpos !== false ) {
$ircdata->message = substr($line, $colonpos+1 );
$ircdata->messageex = explode(' ', $ircdata->message );
'" ident: "'. $ircdata->ident.
'" host: "'. $ircdata->host.
'" type: "'. $ircdata->type.
'" from: "'. $ircdata->from.
'" message: "'. $ircdata->message.
'"', __FILE__ , __LINE__ );
// lets see if we have a messagehandler for it
$this->_handlemessage ($messagecode, $ircdata);
if ($validmessage == true ) {
// now the actionhandlers are comming
$this->_handleactionhandler ($ircdata);
* sends the pong for keeping alive
* Sends the PONG signal as reply of the PING from the IRC server.
* returns the calculated selecttimeout value
* @return integer selecttimeout in microseconds
function _selecttimeout () {
if ($this->_messagebuffersize == 0 ) {
$this->_selecttimeout = null;
if ($this->_mintimer != false ) {
$this->_calculateselecttimeout ($this->_mintimer );
if ($this->_autoreconnect == true ) {
$this->_calculateselecttimeout ($this->_rxtimeout*1000 );
$this->_calculateselecttimeout ($this->_maxtimer );
return $this->_selecttimeout;
return $this->_senddelay;
* calculates the selecttimeout value
function _calculateselecttimeout ($microseconds)
if (($this->_selecttimeout > $microseconds) || $this->_selecttimeout === null ) {
$this->_selecttimeout = $microseconds;
* updates _mintimer to the smallest timer interval
function _updatemintimer ()
foreach ($this->_timehandler as $values) {
$timerarray[] = $values->interval;
if ($result == true && isset ($timerarray[0 ])) {
$this->_mintimer = $timerarray[0 ];
$this->_mintimer = false;
* reorders the actionhandler array, needed after removing one
function _reorderactionhandler ()
$orderedactionhandler = array ();
foreach ($this->_actionhandler as $value) {
$orderedactionhandler[] = $value;
$this->_actionhandler = &$orderedactionhandler;
* reorders the timehandler array, needed after removing one
function _reordertimehandler ()
$orderedtimehandler = array ();
foreach ($this->_timehandler as $value) {
$orderedtimehandler[] = $value;
$this->_timehandler = &$orderedtimehandler;
* reorders the modules array, needed after removing one
function _reordermodules ()
$orderedmodules = array ();
foreach ($this->_modules as $value) {
$orderedmodules[] = $value;
$this->_modules = &$orderedmodules;
* determines the messagetype of $line
* Analyses the type of an IRC message and returns the type.
* @return integer SMARTIRC_TYPE_* constant
if (preg_match('/^:[^ ]+? [0-9]{3} .+$/', $line) == 1 ) {
case SMARTIRC_RPL_WELCOME:
case SMARTIRC_RPL_YOURHOST:
case SMARTIRC_RPL_CREATED:
case SMARTIRC_RPL_MYINFO:
case SMARTIRC_RPL_BOUNCE:
case SMARTIRC_RPL_LUSERCLIENT:
case SMARTIRC_RPL_LUSEROP:
case SMARTIRC_RPL_LUSERUNKNOWN:
case SMARTIRC_RPL_LUSERME:
case SMARTIRC_RPL_LUSERCHANNELS:
case SMARTIRC_RPL_MOTDSTART:
case SMARTIRC_RPL_ENDOFMOTD:
case SMARTIRC_RPL_NAMREPLY:
case SMARTIRC_RPL_ENDOFNAMES:
case SMARTIRC_RPL_WHOREPLY:
case SMARTIRC_RPL_ENDOFWHO:
case SMARTIRC_RPL_LISTSTART:
case SMARTIRC_RPL_LISTEND:
case SMARTIRC_RPL_BANLIST:
case SMARTIRC_RPL_ENDOFBANLIST:
case SMARTIRC_RPL_WHOISUSER:
case SMARTIRC_RPL_WHOISSERVER:
case SMARTIRC_RPL_WHOISOPERATOR:
case SMARTIRC_RPL_WHOISIDLE:
case SMARTIRC_RPL_ENDOFWHOIS:
case SMARTIRC_RPL_WHOISCHANNELS:
case SMARTIRC_RPL_WHOWASUSER:
case SMARTIRC_RPL_ENDOFWHOWAS:
case SMARTIRC_RPL_UMODEIS:
case SMARTIRC_RPL_CHANNELMODEIS:
case SMARTIRC_ERR_NICKNAMEINUSE:
case SMARTIRC_ERR_NOTREGISTERED:
if (preg_match('/^:.*? PRIVMSG .* :'. chr(1 ). 'ACTION .*'. chr(1 ). '$/', $line) == 1 ) {
} else if (preg_match('/^:.*? PRIVMSG .* :'. chr(1 ). '.*'. chr(1 ). '$/', $line) == 1 ) {
} else if (preg_match('/^:.*? PRIVMSG (\&|\#|\+|\!).* :.*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? PRIVMSG .*:.*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? NOTICE .* :.*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? INVITE .* .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? JOIN .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? TOPIC .* :.*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? NICK .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? KICK .* .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? PART .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? MODE .* .*$/', $line) == 1 ) {
} else if (preg_match('/^:.*? QUIT :.*$/', $line) == 1 ) {
* updates the current connection state
($this->_socket !== false ) &&
($rtype == 'socket' || $rtype == 'Socket' || $rtype == 'stream')) {
$this->_loggedin = false;
* returns the current connection state
* @return integer SMARTIRC_STATE_CONNECTED or SMARTIRC_STATE_DISCONNECTED
$result = $this->_updatestate ();
* tries to find a messagehandler for the received message ($ircdata) and calls it
* @param string $messagecode
function _handlemessage ($messagecode, &$ircdata)
$_methodname = '_'. $methodname;
$_codetype = 'by numeric';
} else if (is_string($messagecode)) { // its not numericcode so already a name/string
$_methodname = '_'. $methodname;
$_codetype = 'by string';
// if exists call internal method for the handling
$this->$_methodname($ircdata);
// if exist, call user defined method for the handling
$this->$methodname($ircdata);
* tries to find a actionhandler for the received message ($ircdata) and calls it
function _handleactionhandler (&$ircdata)
$handler = &$this->_actionhandler;
$handlercount = count($handler);
for ($i = 0; $i < $handlercount; $i++ ) {
$handlerobject = &$handler[$i];
if (substr($handlerobject->message , 0 , 1 ) == '/') {
$regex = $handlerobject->message;
$regex = '/'. $handlerobject->message. '/';
if (($handlerobject->type & $ircdata->type ) &&
$this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler match found for id: '. $i. ' type: '. $ircdata->type. ' message: "'. $ircdata->message. '" regex: "'. $regex. '"', __FILE__ , __LINE__ );
$methodobject = &$handlerobject->object;
$method = $handlerobject->method;
$methodobject->$method($this, $ircdata);
* getting current microtime, needed for benchmarks
$floattime = (float) $parts[0 ] + (float) $parts[1 ];
* adds an user to the channelobject or updates his info
function _adduser (&$channel, &$newuser)
if (isset ($channel->users [$lowerednick])) {
// lets update the existing user
$currentuser = &$channel->users [$lowerednick];
if ($newuser->ident !== null ) {
$currentuser->ident = $newuser->ident;
if ($newuser->host !== null ) {
$currentuser->host = $newuser->host;
if ($newuser->realname !== null ) {
$currentuser->realname = $newuser->realname;
if ($newuser->op !== null ) {
$currentuser->op = $newuser->op;
if ($newuser->voice !== null ) {
$currentuser->voice = $newuser->voice;
if ($newuser->ircop !== null ) {
$currentuser->ircop = $newuser->ircop;
if ($newuser->away !== null ) {
$currentuser->away = $newuser->away;
if ($newuser->server !== null ) {
$currentuser->server = $newuser->server;
if ($newuser->hopcount !== null ) {
$currentuser->hopcount = $newuser->hopcount;
// he is new just add the reference to him
$channel->users [$lowerednick] = &$newuser;
$user = &$channel->users [$lowerednick];
$channel->ops [$user->nick ] = true;
$channel->voices [$user->nick ] = true;
* removes an user from one channel or all if he quits
function _removeuser (&$ircdata)
$nick = $ircdata->rawmessageex [3 ];
if ($this->_nick == $nick) {
// remove the user from all channels
foreach ($this->_channels as $channelkey => $channelvalue) {
// loop through all channels
$channel = &$this->_channels [$channelkey];
foreach ($channel->users as $userkey => $uservalue) {
// loop through all user in this channel
if ($nick == $uservalue->nick ) {
unset ($channel->users [$lowerednick]);
if (isset ($channel->ops [$nick])) {
unset ($channel->ops [$nick]);
if (isset ($channel->voices [$nick])) {
unset ($channel->voices [$nick]);
// ups this was not DukeNukem 3D
unset ($channel->users [$lowerednick]);
if (isset ($channel->ops [$nick])) {
unset ($channel->ops [$nick]);
if (isset ($channel->voices [$nick])) {
unset ($channel->voices [$nick]);
function _checkPHPVersion ()
// doing nothing at the moment
* checks if the passed handlertype is valid
* @param integer $handlertype
function _isValidType ($handlertype) {
return new Net_SmartIRC_Error ($message);
var $messageex = array ();
var $rawmessageex = array ();
class Net_SmartIRC_actionhandler
class Net_SmartIRC_timehandler
class Net_SmartIRC_channel
class Net_SmartIRC_channeluser extends Net_SmartIRC_user
class Net_SmartIRC_ircuser extends Net_SmartIRC_user
var $joinedchannels = array ();
class Net_SmartIRC_listenfor
* stores the received answer into the result array
function handler (&$irc, &$ircdata)
$this->result[] = $ircdata->message;
class Net_SmartIRC_objListenFor
* stores the received answer into the result array
function handler (&$irc, &$ircdata)
$this->result[] = $ircdata;
function Net_SmartIRC_Error ($message)
$this->error_msg = $message;
Documentation generated on Mon, 11 Mar 2019 14:19:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|