Net_SmartIRC
[ class tree: Net_SmartIRC ] [ index: Net_SmartIRC ] [ all elements ]

Source for file SmartIRC.php

Documentation is available at SmartIRC.php

  1. <?php
  2. /**
  3.  * $Id: SmartIRC.php,v 1.54.2.14 2005/05/27 23:40:09 meebey Exp $
  4.  * $Revision: 1.54.2.14 $
  5.  * $Author: meebey $
  6.  * $Date: 2005/05/27 23:40:09 $
  7.  *
  8.  * Net_SmartIRC
  9.  * This is a PHP class for communication with IRC networks,
  10.  * which conforms to the RFC 2812 (IRC protocol).
  11.  * It's an API that handles all IRC protocol messages.
  12.  * This class is designed for creating IRC bots, chats and show irc related info on webpages.
  13.  *
  14.  * Documenation, a HOWTO and examples are in SmartIRC included.
  15.  *
  16.  * Here you will find a service bot which I am also developing
  17.  * <http://cvs.meebey.net/atbs> and <http://cvs.meebey.net/phpbitch>
  18.  * Latest versions of Net_SmartIRC you will find on the project homepage
  19.  * or get it through PEAR since SmartIRC is an official PEAR package.
  20.  * See <http://pear.php.net/Net_SmartIRC>.
  21.  *
  22.  * Official Projet Homepage: <http://sf.net/projects/phpsmartirc>
  23.  *
  24.  * Net_SmartIRC conforms to RFC 2812 (Internet Relay Chat: Client Protocol)
  25.  * 
  26.  * Copyright (c) 2002-2003 Mirco 'meebey' Bauer <meebey@meebey.net> <http://www.meebey.net>
  27.  * 
  28.  * Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>
  29.  * 
  30.  * This library is free software; you can redistribute it and/or
  31.  * modify it under the terms of the GNU Lesser General Public
  32.  * License as published by the Free Software Foundation; either
  33.  * version 2.1 of the License, or (at your option) any later version.
  34.  *
  35.  * This library is distributed in the hope that it will be useful,
  36.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  38.  * Lesser General Public License for more details.
  39.  *
  40.  * You should have received a copy of the GNU Lesser General Public
  41.  * License along with this library; if not, write to the Free Software
  42.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  43.  *
  44.  */
  45. // ------- PHP code ----------
  46. include_once('SmartIRC/defines.php');
  47. include_once('SmartIRC/irccommands.php');
  48. include_once('SmartIRC/messagehandler.php');
  49. define('SMARTIRC_VERSION''1.0.0 ($Revision: 1.54.2.14 $)');
  50. define('SMARTIRC_VERSIONSTRING''Net_SmartIRC '.SMARTIRC_VERSION);
  51.  
  52. /**
  53.  * main SmartIRC class
  54.  *
  55.  * @package Net_SmartIRC
  56.  * @version 0.5.5
  57.  * @author Mirco 'meebey' Bauer <mail@meebey.net>
  58.  * @access public
  59.  */
  60. {
  61.     /**
  62.      * @var resource 
  63.      * @access private
  64.      */
  65.     var $_socket;
  66.     
  67.     /**
  68.      * @var string 
  69.      * @access private
  70.      */
  71.     var $_address;
  72.     
  73.     /**
  74.      * @var integer 
  75.      * @access private
  76.      */
  77.     var $_port;
  78.     
  79.     /**
  80.      * @var string 
  81.      * @access private
  82.      */
  83.     var $_nick;
  84.     
  85.     /**
  86.      * @var string 
  87.      * @access private
  88.      */
  89.     var $_username;
  90.     
  91.     /**
  92.      * @var string 
  93.      * @access private
  94.      */
  95.     var $_realname;
  96.     
  97.     /**
  98.      * @var string 
  99.      * @access private
  100.      */
  101.     var $_usermode;
  102.     
  103.     /**
  104.      * @var string 
  105.      * @access private
  106.      */
  107.     var $_password;
  108.     
  109.     /**
  110.      * @var boolean 
  111.      * @access private
  112.      */
  113.     var $_state = false;
  114.     
  115.     /**
  116.      * @var array 
  117.      * @access private
  118.      */
  119.     var $_actionhandler = array();
  120.     
  121.     /**
  122.      * @var array 
  123.      * @access private
  124.      */
  125.     var $_timehandler = array();
  126.     
  127.     /**
  128.      * @var integer 
  129.      * @access private
  130.      */
  131.     var $_debug = SMARTIRC_DEBUG_NOTICE;
  132.     
  133.     /**
  134.      * @var array 
  135.      * @access private
  136.      */
  137.     var $_messagebuffer = array();
  138.     
  139.     /**
  140.      * @var integer 
  141.      * @access private
  142.      */
  143.     var $_messagebuffersize;
  144.     
  145.     /**
  146.      * @var boolean 
  147.      * @access private
  148.      */
  149.     var $_usesockets = false;
  150.     
  151.     /**
  152.      * @var integer 
  153.      * @access private
  154.      */
  155.     var $_receivedelay = 100;
  156.     
  157.     /**
  158.      * @var integer 
  159.      * @access private
  160.      */
  161.     var $_senddelay = 250;
  162.     
  163.     /**
  164.      * @var integer 
  165.      * @access private
  166.      */
  167.     var $_logdestination = SMARTIRC_STDOUT;
  168.     
  169.     /**
  170.      * @var resource 
  171.      * @access private
  172.      */
  173.     var $_logfilefp = 0;
  174.     
  175.     /**
  176.      * @var string 
  177.      * @access private
  178.      */
  179.     var $_logfile 'Net_SmartIRC.log';
  180.     
  181.     /**
  182.      * @var integer 
  183.      * @access private
  184.      */
  185.     var $_disconnecttime = 1000;
  186.     
  187.     /**
  188.      * @var boolean 
  189.      * @access private
  190.      */
  191.     var $_loggedin = false;
  192.     
  193.     /**
  194.      * @var boolean 
  195.      * @access private
  196.      */
  197.     var $_benchmark = false;
  198.     
  199.     /**
  200.      * @var integer 
  201.      * @access private
  202.      */
  203.     var $_benchmark_starttime;
  204.     
  205.     /**
  206.      * @var integer 
  207.      * @access private
  208.      */
  209.     var $_benchmark_stoptime;
  210.     
  211.     /**
  212.      * @var integer 
  213.      * @access private
  214.      */
  215.     var $_actionhandlerid = 0;
  216.     
  217.     /**
  218.      * @var integer 
  219.      * @access private
  220.      */
  221.     var $_timehandlerid = 0;
  222.     
  223.     /**
  224.      * @var array 
  225.      * @access private
  226.      */
  227.     var $_motd = array();
  228.     
  229.     /**
  230.      * @var array 
  231.      * @access private
  232.      */
  233.     var $_channels = array();
  234.     
  235.     /**
  236.      * @var boolean 
  237.      * @access private
  238.      */
  239.     var $_channelsyncing = false;
  240.     
  241.     /**
  242.      * @var string 
  243.      * @access private
  244.      */
  245.     var $_ctcpversion;
  246.     
  247.     /**
  248.      * @var mixed 
  249.      * @access private
  250.      */
  251.     var $_mintimer = false;
  252.     
  253.     /**
  254.      * @var integer 
  255.      * @access private
  256.      */
  257.     var $_maxtimer = 300000;
  258.     
  259.     /**
  260.      * @var integer 
  261.      * @access private
  262.      */
  263.     var $_txtimeout = 300;
  264.     
  265.     /**
  266.      * @var integer 
  267.      * @access private
  268.      */
  269.     var $_rxtimeout = 300;
  270.     
  271.     /**
  272.      * @var integer 
  273.      * @access private
  274.      */
  275.     var $_selecttimeout;
  276.     
  277.     /**
  278.      * @var integer 
  279.      * @access private
  280.      */
  281.     var $_lastrx;
  282.     
  283.     /**
  284.      * @var integer 
  285.      * @access private
  286.      */
  287.     var $_lasttx;
  288.     
  289.     /**
  290.      * @var boolean 
  291.      * @access private
  292.      */
  293.     var $_autoreconnect = false;
  294.     
  295.     /**
  296.      * @var boolean 
  297.      * @access private
  298.      */
  299.     var $_autoretry = false;
  300.     
  301.     /**
  302.      * All IRC replycodes, the index is the replycode name.
  303.      *
  304.      * @see $SMARTIRC_replycodes
  305.      * @var array 
  306.      * @access public
  307.      */
  308.     var $replycodes;
  309.     
  310.     /**
  311.      * All numeric IRC replycodes, the index is the numeric replycode.
  312.      *
  313.      * @see $SMARTIRC_nreplycodes
  314.      * @var array 
  315.      * @access public
  316.      */
  317.     var $nreplycodes;
  318.     
  319.     /**
  320.      * Stores all channels in this array where we are joined, works only if channelsyncing is activated.
  321.      * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
  322.      * $irc->channel['#test']->users['meebey']->nick;
  323.      *
  324.      * @see setChannelSyncing()
  325.      * @see Net_SmartIRC_channel
  326.      * @see Net_SmartIRC_channeluser
  327.      * @var array 
  328.      * @access public
  329.      */
  330.     var $channel;
  331.     
  332.     /**
  333.      * Constructor. Initiales the messagebuffer and "links" the replycodes from
  334.      * global into properties. Also some PHP runtime settings are configured.
  335.      *
  336.      * @access public
  337.      * @return void 
  338.      */
  339.     function Net_SmartIRC_base()
  340.     {
  341.         // precheck
  342.         $this->_checkPHPVersion();
  343.         
  344.         ob_implicit_flush(true);
  345.         @set_time_limit(0);
  346.         ignore_user_abort(true);
  347.         $this->_messagebuffer[SMARTIRC_CRITICAL= array();
  348.         $this->_messagebuffer[SMARTIRC_HIGH= array();
  349.         $this->_messagebuffer[SMARTIRC_MEDIUM= array();
  350.         $this->_messagebuffer[SMARTIRC_LOW= array();
  351.         $this->replycodes = &$GLOBALS['SMARTIRC_replycodes'];
  352.         $this->nreplycodes = &$GLOBALS['SMARTIRC_nreplycodes'];
  353.         
  354.         // hack till PHP allows (PHP5) $object->method($param)->$object
  355.         $this->channel = &$this->_channels;
  356.         // another hack
  357.         $this->user &$this->_users;
  358.         
  359.         if (isset($_SERVER['REQUEST_METHOD'])) {
  360.             // the script is called from a browser, lets set default log destination
  361.             // to SMARTIRC_BROWSEROUT (makes browser friendly output)
  362.             $this->setLogdestination(SMARTIRC_BROWSEROUT);
  363.         }
  364.     }
  365.     
  366.     /**
  367.      * Enables/disables the usage of real sockets.
  368.      *
  369.      * Enables/disables the usage of real sockets instead of fsocks
  370.      * (works only if your PHP build has loaded the PHP socket extension)
  371.      * Default: false
  372.      *
  373.      * @param bool $boolean 
  374.      * @return void 
  375.      * @access public
  376.      */
  377.     function setUseSockets($boolean)
  378.     {
  379.         if ($boolean === true{
  380.             if (@extension_loaded('sockets')) {
  381.                 $this->_usesockets = true;
  382.             else {
  383.                 $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: socket extension not loaded, trying to load it...'__FILE____LINE__);
  384.                 
  385.                 if (strtoupper(substr(PHP_OS0,3== 'WIN')) {
  386.                     $load_status @dl('php_sockets.dll');
  387.                 else {
  388.                     $load_status @dl('sockets.so');
  389.                 }
  390.  
  391.                 if ($load_status{
  392.                     $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: socket extension succesfully loaded'__FILE____LINE__);
  393.                     $this->_usesockets = true;
  394.                 else {
  395.                     $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: couldn\'t load the socket extension'__FILE____LINE__);
  396.                     $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: your PHP build doesn\'t support real sockets, will use fsocks instead'__FILE____LINE__);
  397.                     $this->_usesockets = false;
  398.                 }
  399.             }
  400.         else {
  401.             $this->_usesockets = false;
  402.         }
  403.     }
  404.     
  405.     /**
  406.      * Sets the level of debug messages.
  407.      *
  408.      * Sets the debug level (bitwise), useful for testing/developing your code.
  409.      * Here the list of all possible debug levels:
  410.      * SMARTIRC_DEBUG_NONE
  411.      * SMARTIRC_DEBUG_NOTICE
  412.      * SMARTIRC_DEBUG_CONNECTION
  413.      * SMARTIRC_DEBUG_SOCKET
  414.      * SMARTIRC_DEBUG_IRCMESSAGES
  415.      * SMARTIRC_DEBUG_MESSAGETYPES
  416.      * SMARTIRC_DEBUG_ACTIONHANDLER
  417.      * SMARTIRC_DEBUG_TIMEHANDLER
  418.      * SMARTIRC_DEBUG_MESSAGEHANDLER
  419.      * SMARTIRC_DEBUG_CHANNELSYNCING
  420.      * SMARTIRC_DEBUG_MODULES
  421.      * SMARTIRC_DEBUG_USERSYNCING
  422.      * SMARTIRC_DEBUG_ALL
  423.      *
  424.      * Default: SMARTIRC_DEBUG_NOTICE
  425.      *
  426.      * @see DOCUMENTATION
  427.      * @see SMARTIRC_DEBUG_NOTICE
  428.      * @param integer $level 
  429.      * @return void 
  430.      * @access public
  431.      */
  432.     function setDebug($level)
  433.     {
  434.         $this->_debug $level;
  435.     }
  436.     
  437.     /**
  438.      * Enables/disables the benchmark engine.
  439.      * 
  440.      * @param boolean $boolean 
  441.      * @return void 
  442.      * @access public
  443.      */
  444.     function setBenchmark($boolean)
  445.     {
  446.         if (is_bool($boolean)) {
  447.             $this->_benchmark $boolean;
  448.         else {
  449.             $this->_benchmark = false;
  450.         }
  451.     }
  452.     
  453.     /**
  454.      * Deprecated, use setChannelSyncing() instead!
  455.      *
  456.      * @deprecated
  457.      * @param boolean $boolean 
  458.      * @return void 
  459.      * @access public
  460.      */
  461.     function setChannelSynching($boolean)
  462.     {
  463.         $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: you are using setChannelSynching() which is a deprecated method, use setChannelSyncing() instead!'__FILE____LINE__);
  464.         $this->setChannelSyncing($boolean);
  465.     }
  466.     
  467.     /**
  468.      * Enables/disables channel syncing.
  469.      *
  470.      * Channel syncing means, all users on all channel we are joined are tracked in the
  471.      * channel array. This makes it very handy for botcoding.
  472.      * 
  473.      * @param boolean $boolean 
  474.      * @return void 
  475.      * @access public
  476.      */
  477.     function setChannelSyncing($boolean)
  478.     {
  479.         if (is_bool($boolean)) {
  480.             $this->_channelsyncing $boolean;
  481.         else {
  482.             $this->_channelsyncing = false;
  483.         }
  484.         
  485.         if ($this->_channelsyncing == true{
  486.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: Channel syncing enabled'__FILE____LINE__);
  487.         else {
  488.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: Channel syncing disabled'__FILE____LINE__);
  489.         }
  490.     }
  491.     
  492.     /**
  493.      * Sets the CTCP version reply string.
  494.      * 
  495.      * @param string $versionstring 
  496.      * @return void 
  497.      * @access public
  498.      */
  499.     function setCtcpVersion($versionstring)
  500.     {
  501.         $this->_ctcpversion $versionstring;
  502.     }
  503.     
  504.     /**
  505.      * Sets the destination of all log messages.
  506.      *
  507.      * Sets the destination of log messages.
  508.      * $type can be:
  509.      * SMARTIRC_FILE for saving the log into a file
  510.      * SMARTIRC_STDOUT for echoing the log to stdout
  511.      * SMARTIRC_SYSLOG for sending the log to the syslog
  512.      * Default: SMARTIRC_STDOUT
  513.      *
  514.      * @see SMARTIRC_STDOUT
  515.      * @param integer $type must be on of the constants
  516.      * @return void 
  517.      * @access public
  518.      */
  519.     function setLogdestination($type)
  520.     {
  521.         switch ($type{
  522.             case (SMARTIRC_FILE ||
  523.                   SMARTIRC_STDOUT ||
  524.                   SMARTIRC_SYSLOG ||
  525.                   SMARTIRC_BROWSEROUT ||
  526.                   SMARTIRC_NONE):
  527.                 $this->_logdestination $type;
  528.             break;
  529.             default:
  530.                 $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: unknown logdestination type ('.$type.'), will use STDOUT instead'__FILE____LINE__);
  531.                 $this->_logdestination SMARTIRC_STDOUT;
  532.         }
  533.     }
  534.     
  535.     /**
  536.      * Sets the file for the log if the destination is set to file.
  537.      *
  538.      * Sets the logfile, if {@link setLogdestination logdestination} is set to SMARTIRC_FILE.
  539.      * This should be only used with full path!
  540.      *
  541.      * @param string $file 
  542.      * @return void 
  543.      * @access public
  544.      */
  545.     function setLogfile($file)
  546.     {
  547.         $this->_logfile $file;
  548.     }
  549.     
  550.     /**
  551.      * Sets the delaytime before closing the socket when disconnect.
  552.      *
  553.      * @param integer $milliseconds 
  554.      * @return void 
  555.      * @access public
  556.      */
  557.     function setDisconnecttime($milliseconds)
  558.     {
  559.         if (is_integer($milliseconds&& $milliseconds >= 100{
  560.             $this->_disconnecttime $milliseconds;
  561.         else {
  562.             $this->_disconnecttime = 100;
  563.         }
  564.     }
  565.     
  566.     /**
  567.      * Sets the delay for receiving data from the IRC server.
  568.      *
  569.      * Sets the delaytime between messages that are received, this reduces your CPU load.
  570.      * Don't set this too low (min 100ms).
  571.      * Default: 100
  572.      *
  573.      * @param integer $milliseconds 
  574.      * @return void 
  575.      * @access public
  576.      */
  577.     function setReceivedelay($milliseconds)
  578.     {
  579.         if (is_integer($milliseconds&& $milliseconds >= 100{
  580.             $this->_receivedelay $milliseconds;
  581.         else {
  582.             $this->_receivedelay = 100;
  583.         }
  584.     }
  585.     
  586.     /**
  587.      * Sets the delay for sending data to the IRC server.
  588.      *
  589.      * Sets the delaytime between messages that are sent, because IRC servers doesn't like floods.
  590.      * This will avoid sending your messages too fast to the IRC server.
  591.      * Default: 250
  592.      *
  593.      * @param integer $milliseconds 
  594.      * @return void 
  595.      * @access public
  596.      */
  597.     function setSenddelay($milliseconds)
  598.     {
  599.         if (is_integer($milliseconds)) {
  600.             $this->_senddelay $milliseconds;
  601.         else {
  602.             $this->_senddelay = 250;
  603.         }
  604.     }
  605.     
  606.     /**
  607.      * Enables/disables autoreconnecting.
  608.      * 
  609.      * @param boolean $boolean 
  610.      * @return void 
  611.      * @access public
  612.      */
  613.     function setAutoReconnect($boolean)
  614.     {
  615.         if (is_bool($boolean)) {
  616.             $this->_autoreconnect $boolean;
  617.         else {
  618.             $this->_autoreconnect = false;
  619.         }
  620.     }
  621.     
  622.     /**
  623.      * Enables/disables autoretry for connecting to a server.
  624.      * 
  625.      * @param boolean $boolean 
  626.      * @return void 
  627.      * @access public
  628.      */
  629.     function setAutoRetry($boolean)
  630.     {
  631.         if (is_bool($boolean)) {
  632.             $this->_autoretry $boolean;
  633.         else {
  634.             $this->_autoretry = false;
  635.         }
  636.     }
  637.     
  638.     /**
  639.      * Sets the receive timeout.
  640.      *
  641.      * If the timeout occurs, the connection will be reinitialized
  642.      * Default: 300 seconds
  643.      *
  644.      * @param integer $seconds 
  645.      * @return void 
  646.      * @access public
  647.      */
  648.     function setReceiveTimeout($seconds)
  649.     {
  650.         if (is_integer($seconds)) {
  651.             $this->_rxtimeout $seconds;
  652.         else {
  653.             $this->_rxtimeout = 300;
  654.         }
  655.     }
  656.     
  657.     /**
  658.      * Sets the transmit timeout.
  659.      *
  660.      * If the timeout occurs, the connection will be reinitialized
  661.      * Default: 300 seconds
  662.      *
  663.      * @param integer $seconds 
  664.      * @return void 
  665.      * @access public
  666.      */
  667.     function setTransmitTimeout($seconds)
  668.     {
  669.         if (is_integer($seconds)) {
  670.             $this->_txtimeout $seconds;
  671.         else {
  672.             $this->_txtimeout = 300;
  673.         }
  674.     }
  675.     
  676.     /**
  677.      * Starts the benchmark (sets the counters).
  678.      *
  679.      * @return void 
  680.      * @access public
  681.      */
  682.     function startBenchmark()
  683.     {
  684.         $this->_benchmark_starttime $this->_microint();
  685.         $this->log(SMARTIRC_DEBUG_NOTICE'benchmark started'__FILE____LINE__);
  686.     }
  687.     
  688.     /**
  689.      * Stops the benchmark and displays the result.
  690.      *
  691.      * @return void 
  692.      * @access public
  693.      */
  694.     function stopBenchmark()
  695.     {
  696.         $this->_benchmark_stoptime $this->_microint();
  697.         $this->log(SMARTIRC_DEBUG_NOTICE'benchmark stopped'__FILE____LINE__);
  698.         
  699.         if ($this->_benchmark{
  700.             $this->showBenchmark();
  701.         }
  702.     }
  703.     
  704.     /**
  705.      * Shows the benchmark result.
  706.      *
  707.      * @return void 
  708.      * @access public
  709.      */
  710.     function showBenchmark()
  711.     {
  712.         $this->log(SMARTIRC_DEBUG_NOTICE'benchmark time: '.((float)$this->_benchmark_stoptime-(float)$this->_benchmark_starttime)__FILE____LINE__);
  713.     }
  714.     
  715.     /**
  716.      * Adds an entry to the log.
  717.      *
  718.      * Adds an entry to the log with Linux style log format.
  719.      * Possible $level constants (can also be combined with "|"s)
  720.      * SMARTIRC_DEBUG_NONE
  721.      * SMARTIRC_DEBUG_NOTICE
  722.      * SMARTIRC_DEBUG_CONNECTION
  723.      * SMARTIRC_DEBUG_SOCKET
  724.      * SMARTIRC_DEBUG_IRCMESSAGES
  725.      * SMARTIRC_DEBUG_MESSAGETYPES
  726.      * SMARTIRC_DEBUG_ACTIONHANDLER
  727.      * SMARTIRC_DEBUG_TIMEHANDLER
  728.      * SMARTIRC_DEBUG_MESSAGEHANDLER
  729.      * SMARTIRC_DEBUG_CHANNELSYNCING
  730.      * SMARTIRC_DEBUG_MODULES
  731.      * SMARTIRC_DEBUG_USERSYNCING
  732.      * SMARTIRC_DEBUG_ALL
  733.      *
  734.      * @see SMARTIRC_DEBUG_NOTICE
  735.      * @param integer $level bit constants (SMARTIRC_DEBUG_*)
  736.      * @param string $entry the new log entry
  737.      * @return void 
  738.      * @access public
  739.      */
  740.     function log($level$entry$file = null$line = null)
  741.     {
  742.         // prechecks
  743.         if (!(is_integer($level)) ||
  744.             !($level SMARTIRC_DEBUG_ALL)) {
  745.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: invalid log level passed to log() ('.$level.')'__FILE____LINE__);
  746.             return;
  747.         }
  748.         
  749.         if (!($level $this->_debug||
  750.              ($this->_logdestination == SMARTIRC_NONE)) {
  751.             return;
  752.         }
  753.         
  754.         if (substr($entry-1!= "\n"{
  755.             $entry .= "\n";
  756.         }
  757.         
  758.         if ($file !== null &&
  759.             $line !== null{
  760.             $file basename($file);
  761.             $entry $file.'('.$line.') '.$entry;
  762.         else {
  763.             $entry 'unknown(0) '.$entry;
  764.         }
  765.         
  766.         $formatedentry date('M d H:i:s ').$entry;
  767.         switch ($this->_logdestination{
  768.             case SMARTIRC_STDOUT:
  769.                 echo $formatedentry;
  770.                 flush();
  771.             break;
  772.             case SMARTIRC_BROWSEROUT:
  773.                 echo '<pre>'.htmlentities($formatedentry).'</pre>';
  774.             break;
  775.             case SMARTIRC_FILE:
  776.                 if (!is_resource($this->_logfilefp)) {
  777.                     if ($this->_logfilefp === null{
  778.                         // we reconncted and don't want to destroy the old log entries
  779.                         $this->_logfilefp @fopen($this->_logfile,'a');
  780.                     else {
  781.                         $this->_logfilefp @fopen($this->_logfile,'w');
  782.                     }
  783.                 }
  784.                 @fwrite($this->_logfilefp$formatedentry);
  785.                 fflush($this->_logfilefp);
  786.             break;
  787.             case SMARTIRC_SYSLOG:
  788.                 define_syslog_variables();
  789.                 if (!is_int($this->_logfilefp)) {
  790.                     $this->_logfilefp openlog('Net_SmartIRC'LOG_NDELAYLOG_DAEMON);
  791.                 }
  792.                 syslog(LOG_INFO$entry);
  793.             break;
  794.         }
  795.     }
  796.     
  797.     /**
  798.      * Returns the full motd.
  799.      *
  800.      * @return array 
  801.      * @access public
  802.      */
  803.     function getMotd()
  804.     {
  805.         return $this->_motd;
  806.     }
  807.     
  808.     /**
  809.      * Returns the usermode.
  810.      *
  811.      * @return string 
  812.      * @access public
  813.      */
  814.     function getUsermode()
  815.     {
  816.         return $this->_usermode;
  817.     }
  818.     
  819.     /**
  820.      * Creates the sockets and connects to the IRC server on the given port.
  821.      *
  822.      * @param string $address 
  823.      * @param integer $port 
  824.      * @return void 
  825.      * @access public
  826.      */
  827.     function connect($address$port)
  828.     {
  829.         $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: connecting'__FILE____LINE__);
  830.         $this->_address $address;
  831.         $this->_port $port;
  832.         
  833.         if ($this->_usesockets == true{
  834.             $this->log(SMARTIRC_DEBUG_SOCKET'DEBUG_SOCKET: using real sockets'__FILE____LINE__);
  835.             $this->_socket socket_create(AF_INETSOCK_STREAMSOL_TCP);
  836.             $result @socket_connect($this->_socket$this->_address$this->_port);
  837.         else {
  838.             $this->log(SMARTIRC_DEBUG_SOCKET'DEBUG_SOCKET: using fsockets'__FILE____LINE__);
  839.             $result @fsockopen($this->_address$this->_port$errno$errstr);
  840.         }
  841.         
  842.         if ($result === false{
  843.             if ($this->_usesockets == true{
  844.                 $error socket_strerror(socket_last_error($this->_socket));
  845.             else {
  846.                 $error $errstr.' ('.$errno.')';
  847.             }
  848.             
  849.             $error_msg 'couldn\'t connect to "'.$address.'" reason: "'.$error.'"';
  850.             $this->log(SMARTIRC_DEBUG_NOTICE'DEBUG_NOTICE: '.$error_msg__FILE____LINE__);
  851.             // TODO! muss return wert sein
  852.             $this->throwError($error_msg);
  853.             
  854.             // doesn't work somehow.... I only want to retry 4 times! no endless loop (causes segfault)
  855.             static $tries = 0;
  856.             if ($this->_autoretry == true && $tries < 5{
  857.                 $this->reconnect();
  858.                 $tries++;
  859.             else {
  860.                 die();
  861.             }
  862.         else {
  863.             $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: connected'__FILE____LINE__);
  864.             
  865.             if ($this->_usesockets != true{
  866.                 $this->_socket = $result;
  867.                 $this->log(SMARTIRC_DEBUG_SOCKET'DEBUG_SOCKET: activating nonblocking fsocket mode'__FILE____LINE__);
  868.                 socket_set_blocking($this->_socketfalse);
  869.             }
  870.         }
  871.         
  872.         $this->_lastrx = time();
  873.         $this->_lasttx = $this->_lastrx;
  874.         $this->_updatestate();
  875.         
  876.         if ($result !== false{
  877.             return true;
  878.         else {
  879.             return false;
  880.         }
  881.     }
  882.     
  883.     /**
  884.      * Disconnects from the IRC server nicely with a QUIT or just destroys the socket.
  885.      *
  886.      * Disconnects from the IRC server in the given quickness mode.
  887.      * $quickdisconnect:
  888.      * true, just close the socket
  889.      * false, send QUIT and wait {@link $_disconnectime $_disconnectime} before closing the socket
  890.      *
  891.      * @param boolean $quickdisconnect default: false
  892.      * @return boolean 
  893.      * @access public
  894.      */
  895.     function disconnect($quickdisconnect = false)
  896.     {
  897.         if ($this->_state(== SMARTIRC_STATE_CONNECTED{
  898.             if ($quickdisconnect == false{
  899.                 $this->_send('QUIT'SMARTIRC_CRITICAL);
  900.                 usleep($this->_disconnecttime*1000);
  901.             }
  902.             
  903.             if ($this->_usesockets == true{
  904.                 @socket_shutdown($this->_socket);
  905.                 @socket_close($this->_socket);
  906.             else {
  907.                 fclose($this->_socket);
  908.             }
  909.             
  910.             $this->_updatestate();
  911.             $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: disconnected'__FILE____LINE__);
  912.         else {
  913.             return false;
  914.         }
  915.         
  916.         if ($this->_channelsyncing == true{
  917.             // let's clean our channel array
  918.             $this->_channels = array();
  919.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: cleaned channel array'__FILE____LINE__);
  920.         }
  921.         
  922.         if ($this->_logdestination == SMARTIRC_FILE{
  923.             fclose($this->_logfilefp);
  924.             $this->_logfilefp = null;
  925.         else if ($this->_logdestination == SMARTIRC_SYSLOG{
  926.             closelog();
  927.         }
  928.         
  929.         return true;
  930.     }
  931.     
  932.     /**
  933.      * Reconnects to the IRC server with the same login info,
  934.      * it also rejoins the channels
  935.      *
  936.      * @return void 
  937.      * @access public
  938.      */
  939.     function reconnect()
  940.     {
  941.         $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: reconnecting...'__FILE____LINE__);
  942.         
  943.         // remember in which channels we are joined
  944.         $channels = array();
  945.         foreach ($this->_channels as $value{
  946.             if (empty($value->key)) {
  947.                 $channels[= array('name' => $value->name);
  948.             else {
  949.                 $channels[= array('name' => $value->name'key' => $value->key);
  950.             }
  951.         }
  952.         
  953.         $this->disconnect(true);
  954.         $this->connect($this->_address$this->_port);
  955.         $this->login($this->_nick$this->_realname$this->_usermode$this->_username$this->_password);
  956.         
  957.         // rejoin the channels
  958.         foreach ($channels as $value{
  959.             if (isset($value['key'])) {
  960.                 $this->join($value['name']$value['key']);
  961.             else {
  962.                 $this->join($value['name']);
  963.             }
  964.         }
  965.     }
  966.     
  967.     /**
  968.      * login and register nickname on the IRC network
  969.      *
  970.      * Registers the nickname and user information on the IRC network.
  971.      *
  972.      * @param string $nick 
  973.      * @param string $realname 
  974.      * @param integer $usermode 
  975.      * @param string $username 
  976.      * @param string $password 
  977.      * @return void 
  978.      * @access public
  979.      */
  980.     function login($nick$realname$usermode = 0$username = null$password = null)
  981.     {
  982.         $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: logging in'__FILE____LINE__);
  983.         
  984.         $this->_nick = str_replace(' '''$nick);
  985.         $this->_realname = $realname;
  986.         
  987.         if ($username !== null{
  988.             $this->_username = str_replace(' '''$username);
  989.         else {
  990.             $this->_username = str_replace(' '''exec('whoami'));
  991.         }
  992.         
  993.         if ($password !== null{
  994.             $this->_password = $password;
  995.             $this->_send('PASS '.$this->_passwordSMARTIRC_CRITICAL);
  996.         }
  997.         
  998.         if (!is_numeric($usermode)) {
  999.             $this->log(SMARTIRC_DEBUG_NOTICE'DEBUG_NOTICE: login() usermode ('.$usermode.') is not valid, will use 0 instead'__FILE____LINE__);
  1000.             $usermode = 0;
  1001.         }
  1002.         
  1003.         $this->_send('NICK '.$this->_nickSMARTIRC_CRITICAL);
  1004.         $this->_send('USER '.$this->_username.' '.$usermode.' '.SMARTIRC_UNUSED.' :'.$this->_realnameSMARTIRC_CRITICAL);
  1005.     }
  1006.     
  1007.     // </IRC methods>
  1008.     
  1009.     /**
  1010.      * checks if we or the given user is joined to the specified channel and returns the result
  1011.      * ChannelSyncing is required for this.
  1012.      *
  1013.      * @see setChannelSyncing
  1014.      * @param string $channel 
  1015.      * @param string $nickname 
  1016.      * @return boolean 
  1017.      * @access public
  1018.      */
  1019.     function isJoined($channel$nickname = null)
  1020.     {
  1021.         if ($this->_channelsyncing != true{
  1022.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: isJoined() is called and the required Channel Syncing is not activated!'__FILE____LINE__);
  1023.             return false;
  1024.         }
  1025.         
  1026.         if ($nickname === null{
  1027.             $nickname $this->_nick;
  1028.         }
  1029.         
  1030.         if (isset($this->_channels[strtolower($channel)]->users[strtolower($nickname)])) {
  1031.             return true;
  1032.         }
  1033.         
  1034.         return false;
  1035.     }
  1036.     
  1037.     /**
  1038.      * Checks if we or the given user is opped on the specified channel and returns the result.
  1039.      * ChannelSyncing is required for this.
  1040.      *
  1041.      * @see setChannelSyncing
  1042.      * @param string $channel 
  1043.      * @param string $nickname 
  1044.      * @return boolean 
  1045.      * @access public
  1046.      */
  1047.     function isOpped($channel$nickname = null)
  1048.     {
  1049.         if ($this->_channelsyncing != true{
  1050.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: isOpped() is called and the required Channel Syncing is not activated!'__FILE____LINE__);
  1051.             return false;
  1052.         }
  1053.         
  1054.         if ($nickname === null{
  1055.             $nickname $this->_nick;
  1056.         }
  1057.         
  1058.         if ($this->isJoined($channel$nickname)) {
  1059.             if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->op{
  1060.                 return true;
  1061.             }
  1062.         }
  1063.         
  1064.         return false;
  1065.     }
  1066.     
  1067.     /**
  1068.      * Checks if we or the given user is voiced on the specified channel and returns the result.
  1069.      * ChannelSyncing is required for this.
  1070.      *
  1071.      * @see setChannelSyncing
  1072.      * @param string $channel 
  1073.      * @param string $nickname 
  1074.      * @return boolean 
  1075.      * @access public
  1076.      */
  1077.     function isVoiced($channel$nickname = null)
  1078.     {
  1079.         if ($this->_channelsyncing != true{
  1080.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: isVoiced() is called and the required Channel Syncing is not activated!'__FILE____LINE__);
  1081.             return false;
  1082.         }
  1083.         
  1084.         if ($nickname === null{
  1085.             $nickname $this->_nick;
  1086.         }
  1087.         
  1088.         if ($this->isJoined($channel$nickname)) {
  1089.             if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->voice{
  1090.                 return true;
  1091.             }
  1092.         }
  1093.         
  1094.         return false;
  1095.     }
  1096.     
  1097.     /**
  1098.      * Checks if the hostmask is on the specified channel banned and returns the result.
  1099.      * ChannelSyncing is required for this.
  1100.      *
  1101.      * @see setChannelSyncing
  1102.      * @param string $channel 
  1103.      * @param string $hostmask 
  1104.      * @return boolean 
  1105.      * @access public
  1106.      */
  1107.     function isBanned($channel$hostmask)
  1108.     {
  1109.         if ($this->_channelsyncing != true{
  1110.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: isBanned() is called and the required Channel Syncing is not activated!'__FILE____LINE__);
  1111.             return false;
  1112.         }
  1113.         
  1114.         if ($this->isJoined($channel)) {
  1115.             $result array_search($hostmask$this->_channels[strtolower($channel)]->bans);
  1116.             
  1117.             if ($result !== false{
  1118.                 return true;
  1119.             }
  1120.         }
  1121.         
  1122.         return false;
  1123.     }
  1124.  
  1125.     /**
  1126.      * goes into receive mode
  1127.      *
  1128.      * Goes into receive and idle mode. Only call this if you want to "spawn" the bot.
  1129.      * No further lines of PHP code will be processed after this call, only the bot methods!
  1130.      *
  1131.      * @return boolean 
  1132.      * @access public
  1133.      */
  1134.     function listen()
  1135.     {
  1136.         if ($this->_state(== SMARTIRC_STATE_CONNECTED{
  1137.             $this->_rawreceive();
  1138.             return true;
  1139.         else {
  1140.             return false;
  1141.         }
  1142.     }
  1143.     
  1144.     /**
  1145.      * waits for a special message type and puts the answer in $result
  1146.      *
  1147.      * Creates a special actionhandler for that given TYPE and returns the answer.
  1148.      * This will only receive the requested type, immediately quit and disconnect from the IRC server.
  1149.      * Made for showing IRC statistics on your homepage, or other IRC related information.
  1150.      *
  1151.      * @param integer $messagetype see in the documentation 'Message Types'
  1152.      * @return array answer from the IRC server for this $messagetype
  1153.      * @access public
  1154.      */
  1155.     function listenFor($messagetype)
  1156.     {
  1157.         $listenfor &new Net_SmartIRC_listenfor();
  1158.         $this->registerActionhandler($messagetype'.*'$listenfor'handler');
  1159.         $this->listen();
  1160.         $result $listenfor->result;
  1161.         
  1162.         if (isset($listenfor)) {
  1163.             unset($listenfor);
  1164.         }
  1165.         
  1166.         return $result;
  1167.     }
  1168.     
  1169.     /**
  1170.      * waits for a special message type and puts the answer in $result
  1171.      *
  1172.      * Creates a special actionhandler for that given TYPE and returns the answer.
  1173.      * This will only receive the requested type, immediately quit and disconnect from the IRC server.
  1174.      * Made for showing IRC statistics on your homepage, or other IRC related information.
  1175.      * This special version of listenFor() stores the whole ircdata object, not just the message!
  1176.      *
  1177.      * @param integer $messagetype see in the documentation 'Message Types'
  1178.      * @return array answer from the IRC server for this $messagetype
  1179.      * @access public
  1180.      */
  1181.     function objListenFor($messagetype)
  1182.     {
  1183.         $objlistenfor &new Net_SmartIRC_objListenFor();
  1184.         $this->registerActionhandler($messagetype'.*'$objlistenfor'handler');
  1185.         $this->listen();
  1186.         $result $objlistenfor->result;
  1187.         
  1188.         if (isset($objlistenfor)) {
  1189.             unset($objlistenfor);
  1190.         }
  1191.         
  1192.         return $result;
  1193.     }    
  1194.     
  1195.     /**
  1196.      * registers a new actionhandler and returns the assigned id
  1197.      *
  1198.      * Registers an actionhandler in Net_SmartIRC for calling it later.
  1199.      * The actionhandler id is needed for unregistering the actionhandler.
  1200.      *
  1201.      * @see example.php
  1202.      * @param integer $handlertype bits constants, see in this documentation Message Types
  1203.      * @param string $regexhandler the message that has to be in the IRC message in regex syntax
  1204.      * @param object $object a reference to the objects of the method
  1205.      * @param string $methodname the methodname that will be called when the handler happens
  1206.      * @return integer assigned actionhandler id
  1207.      * @access public
  1208.      */
  1209.     function registerActionhandler($handlertype$regexhandler&$object$methodname)
  1210.     {
  1211.         // precheck
  1212.         if (!$this->_isValidType($handlertype)) {
  1213.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: passed invalid handlertype to registerActionhandler()'__FILE____LINE__);
  1214.             return false;
  1215.         }
  1216.         
  1217.         $id $this->_actionhandlerid++;
  1218.         $newactionhandler &new Net_SmartIRC_actionhandler();
  1219.         
  1220.         $newactionhandler->id = $id;
  1221.         $newactionhandler->type = $handlertype;
  1222.         $newactionhandler->message = $regexhandler;
  1223.         $newactionhandler->object = &$object;
  1224.         $newactionhandler->method = $methodname;
  1225.         
  1226.         $this->_actionhandler[&$newactionhandler;
  1227.         $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: actionhandler('.$id.') registered'__FILE____LINE__);
  1228.         return $id;
  1229.     }
  1230.     
  1231.     /**
  1232.      * unregisters an existing actionhandler
  1233.      *
  1234.      * @param integer $handlertype 
  1235.      * @param string $regexhandler 
  1236.      * @param object $object 
  1237.      * @param string $methodname 
  1238.      * @return boolean 
  1239.      * @access public
  1240.      */
  1241.     function unregisterActionhandler($handlertype$regexhandler&$object$methodname)
  1242.     {
  1243.         // precheck
  1244.         if (!$this->_isValidType($handlertype)) {
  1245.             $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: passed invalid handlertype to unregisterActionhandler()'__FILE____LINE__);
  1246.             return false;
  1247.         }
  1248.         
  1249.         $handler &$this->_actionhandler;
  1250.         $handlercount count($handler);
  1251.         
  1252.         for ($i = 0; $i $handlercount$i++{
  1253.             $handlerobject &$handler[$i];
  1254.                         
  1255.             if ($handlerobject->type == $handlertype &&
  1256.                 $handlerobject->message == $regexhandler &&
  1257.                 $handlerobject->method == $methodname{
  1258.                 
  1259.                 $id $handlerobject->id;
  1260.                 
  1261.                 if (isset($this->_actionhandler[$i])) {
  1262.                     unset($this->_actionhandler[$i]);
  1263.                 }
  1264.                 
  1265.                 $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered'__FILE____LINE__);
  1266.                 $this->_reorderactionhandler();
  1267.                 return true;
  1268.             }
  1269.         }
  1270.         
  1271.         $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__);
  1272.         return false;
  1273.     }
  1274.     
  1275.     /**
  1276.      * unregisters an existing actionhandler via the id
  1277.      *
  1278.      * @param integer $id 
  1279.      * @return boolean 
  1280.      * @access public
  1281.      */
  1282.     function unregisterActionid($id)
  1283.     {
  1284.         $handler &$this->_actionhandler;
  1285.         $handlercount count($handler);
  1286.         for ($i = 0; $i $handlercount$i++{
  1287.             $handlerobject &$handler[$i];
  1288.                         
  1289.             if ($handlerobject->id == $id{
  1290.                 if (isset($this->_actionhandler[$i])) {
  1291.                     unset($this->_actionhandler[$i]);
  1292.                 }
  1293.                 
  1294.                 $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered'__FILE____LINE__);
  1295.                 $this->_reorderactionhandler();
  1296.                 return true;
  1297.             }
  1298.         }
  1299.         
  1300.         $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: could not find actionhandler id: '.$id.' _not_ unregistered'__FILE____LINE__);
  1301.         return false;
  1302.     }
  1303.     
  1304.     /**
  1305.      * registers a timehandler and returns the assigned id
  1306.      *
  1307.      * Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
  1308.      * The timehandler id is needed for unregistering the timehandler.
  1309.      *
  1310.      * @see example7.php
  1311.      * @param integer $interval interval time in milliseconds
  1312.      * @param object $object a reference to the objects of the method
  1313.      * @param string $methodname the methodname that will be called when the handler happens
  1314.      * @return integer assigned timehandler id
  1315.      * @access public
  1316.      */
  1317.     function registerTimehandler($interval&$object$methodname)
  1318.     {
  1319.         $id $this->_timehandlerid++;
  1320.         $newtimehandler &new Net_SmartIRC_timehandler();
  1321.         
  1322.         $newtimehandler->id = $id;
  1323.         $newtimehandler->interval = $interval;
  1324.         $newtimehandler->object = &$object;
  1325.         $newtimehandler->method = $methodname;
  1326.         $newtimehandler->lastmicrotimestamp = $this->_microint();
  1327.         
  1328.         $this->_timehandler[&$newtimehandler;
  1329.         $this->log(SMARTIRC_DEBUG_TIMEHANDLER'DEBUG_TIMEHANDLER: timehandler('.$id.') registered'__FILE____LINE__);
  1330.         
  1331.         if (($interval $this->_mintimer|| ($this->_mintimer == false)) {
  1332.             $this->_mintimer = $interval;
  1333.         }
  1334.             
  1335.         return $id;
  1336.     }
  1337.     
  1338.     /**
  1339.      * unregisters an existing timehandler via the id
  1340.      *
  1341.      * @see example7.php
  1342.      * @param integer $id 
  1343.      * @return boolean 
  1344.      * @access public
  1345.      */
  1346.     function unregisterTimeid($id)
  1347.     {
  1348.         $handler &$this->_timehandler;
  1349.         $handlercount count($handler);
  1350.         for ($i = 0; $i $handlercount$i++{
  1351.             $handlerobject &$handler[$i];
  1352.             
  1353.             if ($handlerobject->id == $id{
  1354.                 if (isset($this->_timehandler[$i])) {
  1355.                     unset($this->_timehandler[$i]);
  1356.                 }
  1357.                 
  1358.                 $this->log(SMARTIRC_DEBUG_TIMEHANDLER'DEBUG_TIMEHANDLER: timehandler('.$id.') unregistered'__FILE____LINE__);
  1359.                 $this->_reordertimehandler();
  1360.                 $this->_updatemintimer();
  1361.                 return true;
  1362.             }
  1363.         }
  1364.         
  1365.         $this->log(SMARTIRC_DEBUG_TIMEHANDLER'DEBUG_TIMEHANDLER: could not find timehandler id: '.$id.' _not_ unregistered'__FILE____LINE__);
  1366.         return false;
  1367.     }
  1368.     
  1369.     // <private methods>
  1370.     /**
  1371.      * changes a already used nickname to a new nickname plus 3 random digits
  1372.      *
  1373.      * @return void 
  1374.      * @access private
  1375.      */
  1376.     function _nicknameinuse()
  1377.     {
  1378.         $newnickname substr($this->_nick05).rand(0999);
  1379.         $this->changeNick($newnicknameSMARTIRC_CRITICAL);
  1380.     }
  1381.     
  1382.     /**
  1383.      * sends an IRC message
  1384.      *
  1385.      * Adds a message to the messagequeue, with the optional priority.
  1386.      * $priority:
  1387.      * SMARTIRC_CRITICAL
  1388.      * SMARTIRC_HIGH
  1389.      * SMARTIRC_MEDIUM
  1390.      * SMARTIRC_LOW
  1391.      *
  1392.      * @param string $data 
  1393.      * @param integer $priority must be one of the priority constants
  1394.      * @return boolean 
  1395.      * @access private
  1396.      */
  1397.     function _send($data$priority = SMARTIRC_MEDIUM)
  1398.     {
  1399.         switch ($priority{
  1400.             case SMARTIRC_CRITICAL:
  1401.                 $this->_rawsend($data);
  1402.                 return true;
  1403.             break;
  1404.             case (SMARTIRC_HIGH||
  1405.                   SMARTIRC_MEDIUM||
  1406.                   SMARTIRC_LOW):
  1407.                 $this->_messagebuffer[$priority][$data;
  1408.                 return true;
  1409.             break;
  1410.             default:
  1411.                 $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: message ('.$data.') with an invalid priority passed ('.$priority.'), message is ignored!'__FILE____LINE__);
  1412.                 return false;
  1413.         }
  1414.     }
  1415.     
  1416.     /**
  1417.      * checks the buffer if there are messages to send
  1418.      *
  1419.      * @return void 
  1420.      * @access private
  1421.      */
  1422.     function _checkbuffer()
  1423.     {
  1424.         if (!$this->_loggedin{
  1425.             return;
  1426.         }
  1427.         
  1428.         static $highsent = 0;
  1429.         static $lastmicrotimestamp = 0;
  1430.         
  1431.         if ($lastmicrotimestamp == 0{
  1432.             $lastmicrotimestamp $this->_microint();
  1433.         }
  1434.         
  1435.         $highcount = count($this->_messagebuffer[SMARTIRC_HIGH]);
  1436.         $mediumcount = count($this->_messagebuffer[SMARTIRC_MEDIUM]);
  1437.         $lowcount = count($this->_messagebuffer[SMARTIRC_LOW]);
  1438.         $this->_messagebuffersize = $highcount+$mediumcount+$lowcount;
  1439.         
  1440.         // don't send them too fast
  1441.         if ($this->_microint(>= ($lastmicrotimestamp+($this->_senddelay/1000))) {
  1442.             if ($highcount > 0 && $highsent <= 2{
  1443.                 $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_HIGH]));
  1444.                 $lastmicrotimestamp $this->_microint();
  1445.                 $highsent++;
  1446.             else if ($mediumcount > 0{
  1447.                 $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_MEDIUM]));
  1448.                 $lastmicrotimestamp $this->_microint();
  1449.                 $highsent = 0;
  1450.             else if ($lowcount > 0{
  1451.                 $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_LOW]));
  1452.                 $lastmicrotimestamp $this->_microint();
  1453.             }
  1454.         }
  1455.     }
  1456.     
  1457.     /**
  1458.      * Checks the running timers and calls the registered timehandler,
  1459.      * when the interval is reached.
  1460.      *
  1461.      * @return void 
  1462.      * @access private
  1463.      */
  1464.     function _checktimer()
  1465.     {
  1466.         if (!$this->_loggedin{
  1467.             return;
  1468.         }
  1469.         
  1470.         // has to be count() because the array may change during the loop!
  1471.         for ($i = 0; $i count($this->_timehandler)$i++{
  1472.             $handlerobject &$this->_timehandler[$i];
  1473.             $microtimestamp $this->_microint();
  1474.             if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+($handlerobject->interval/1000))) {
  1475.                 $methodobject &$handlerobject->object;
  1476.                 $method $handlerobject->method;
  1477.                 $handlerobject->lastmicrotimestamp = $microtimestamp;
  1478.                 
  1479.                 if (@method_exists($methodobject$method)) {
  1480.                     $this->log(SMARTIRC_DEBUG_TIMEHANDLER'DEBUG_TIMEHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"'__FILE____LINE__);
  1481.                     $methodobject->$method($this);
  1482.                 }
  1483.             }
  1484.         }
  1485.     }
  1486.     
  1487.     /**
  1488.      * Checks if a receive or transmit timeout occured and reconnects if configured
  1489.      *
  1490.      * @return void 
  1491.      * @access private
  1492.      */
  1493.     function _checktimeout()
  1494.     {
  1495.         if ($this->_autoreconnect == true{
  1496.             $timestamp time();
  1497.             if ($this->_lastrx < ($timestamp $this->_rxtimeout)) {
  1498.                 $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: receive timeout detected, doing reconnect...'__FILE____LINE__);
  1499.                 $this->reconnect();
  1500.             else if ($this->_lasttx < ($timestamp $this->_txtimeout)) {
  1501.                 $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: transmit timeout detected, doing reconnect...'__FILE____LINE__);
  1502.                 $this->reconnect();
  1503.             }
  1504.         }
  1505.     }
  1506.     
  1507.     /**
  1508.      * sends a raw message to the IRC server (don't use this!!)
  1509.      *
  1510.      * Use message() or _send() instead.
  1511.      *
  1512.      * @param string $data 
  1513.      * @return boolean 
  1514.      * @access private
  1515.      */
  1516.     function _rawsend($data)
  1517.     {
  1518.         if ($this->_state(== SMARTIRC_STATE_CONNECTED{
  1519.             $this->log(SMARTIRC_DEBUG_IRCMESSAGES'DEBUG_IRCMESSAGES: sent: "'.$data.'"'__FILE____LINE__);
  1520.             
  1521.             if ($this->_usesockets == true{
  1522.                 $result @socket_write($this->_socket$data.SMARTIRC_CRLF);
  1523.             else {
  1524.                 $result @fwrite($this->_socket$data.SMARTIRC_CRLF);
  1525.             }
  1526.             
  1527.             
  1528.             if ($result === false{
  1529.                 return false;
  1530.             else {
  1531.                 $this->_lasttx = time();
  1532.                 return true;
  1533.             }
  1534.         else {
  1535.             return false;
  1536.         }
  1537.     }
  1538.     
  1539.     /**
  1540.      * goes into main idle loop for waiting messages from the IRC server
  1541.      *
  1542.      * @return void 
  1543.      * @access private
  1544.      */
  1545.     function _rawreceive()
  1546.     {
  1547.         $lastpart '';
  1548.         $rawdataar = array();
  1549.         
  1550.         while ($this->_state(== SMARTIRC_STATE_CONNECTED{
  1551.             $this->_checkbuffer();
  1552.             
  1553.             $timeout $this->_selecttimeout();
  1554.             if ($this->_usesockets == true{
  1555.                 $sread = array($this->_socket);
  1556.                 $result @socket_select($sread$w = null$e = null0$timeout*1000);
  1557.                 
  1558.                 if ($result == 1{
  1559.                     // the socket got data to read
  1560.                     $rawdata @socket_read($this->_socket10240);
  1561.                 else if ($result === false{
  1562.                     // panic! panic! something went wrong!
  1563.                     $this->log(SMARTIRC_DEBUG_NOTICE'WARNING: socket_select() returned false, something went wrong! Reason: '.socket_strerror(socket_last_error())__FILE____LINE__);
  1564.                     exit;
  1565.                 else {
  1566.                     // no data
  1567.                     $rawdata = null;
  1568.                 }
  1569.             else {
  1570.                 usleep($this->_receivedelay*1000);
  1571.                 $rawdata @fread($this->_socket10240);
  1572.             }
  1573.             
  1574.             $this->_checktimer();
  1575.             $this->_checktimeout();
  1576.             
  1577.             if ($rawdata !== null && !empty($rawdata)) {
  1578.                 $this->_lastrx = time();
  1579.                 $rawdata str_replace("\r"''$rawdata);
  1580.                 $rawdata $lastpart.$rawdata;
  1581.                 
  1582.                 $lastpart substr($rawdatastrrpos($rawdata ,"\n")+1);
  1583.                 $rawdata substr($rawdata0strrpos($rawdata ,"\n"));
  1584.                 $rawdataar explode("\n"$rawdata);
  1585.             }
  1586.             
  1587.             // loop through our received messages
  1588.             while (count($rawdataar> 0{
  1589.                 $rawline array_shift($rawdataar);
  1590.                 $validmessage = false;
  1591.                 
  1592.                 $this->log(SMARTIRC_DEBUG_IRCMESSAGES'DEBUG_IRCMESSAGES: received: "'.$rawline.'"'__FILE____LINE__);
  1593.                 
  1594.                 // building our data packet
  1595.                 $ircdata &new Net_SmartIRC_data();
  1596.                 $ircdata->rawmessage = $rawline;
  1597.                 $lineex explode(' '$rawline);
  1598.                 $ircdata->rawmessageex = $lineex;
  1599.                 $messagecode $lineex[0];
  1600.                 
  1601.                 if (substr($rawline01== ':'{
  1602.                     $validmessage = true;
  1603.                     $line substr($rawline1);
  1604.                     $lineex explode(' '$line);
  1605.                     
  1606.                     // conform to RFC 2812
  1607.                     $from $lineex[0];
  1608.                     $messagecode $lineex[1];
  1609.                     $exclamationpos strpos($from'!');
  1610.                     $atpos strpos($from'@');
  1611.                     $colonpos strpos($line' :');
  1612.                     if ($colonpos !== false{
  1613.                         // we want the exact position of ":" not beginning from the space
  1614.                         $colonpos += 1;
  1615.                     }
  1616.                     $ircdata->nick = substr($from0$exclamationpos);
  1617.                     $ircdata->ident = substr($from$exclamationpos+1($atpos-$exclamationpos)-1);
  1618.                     $ircdata->host = substr($from$atpos+1);
  1619.                     $ircdata->type = $this->_gettype($rawline);
  1620.                     $ircdata->from = $from;
  1621.                     if ($colonpos !== false{
  1622.                         $ircdata->message = substr($line$colonpos+1);
  1623.                         $ircdata->messageex = explode(' '$ircdata->message);
  1624.                     }
  1625.                     
  1626.                     if ($ircdata->type (SMARTIRC_TYPE_CHANNEL|
  1627.                                  SMARTIRC_TYPE_ACTION|
  1628.                                  SMARTIRC_TYPE_MODECHANGE|
  1629.                                  SMARTIRC_TYPE_KICK|
  1630.                                  SMARTIRC_TYPE_PART|
  1631.                                  SMARTIRC_TYPE_JOIN)) {
  1632.                         $ircdata->channel = $lineex[2];
  1633.                     else if ($ircdata->type (SMARTIRC_TYPE_WHO|
  1634.                                         SMARTIRC_TYPE_BANLIST|
  1635.                                         SMARTIRC_TYPE_TOPIC|
  1636.                                         SMARTIRC_TYPE_CHANNELMODE)) {
  1637.                         $ircdata->channel = $lineex[3];
  1638.                     else if ($ircdata->type SMARTIRC_TYPE_NAME{
  1639.                         $ircdata->channel = $lineex[4];
  1640.                     }
  1641.                     
  1642.                     if ($ircdata->channel !== null{
  1643.                         if (substr($ircdata->channel01== ':'{
  1644.                             $ircdata->channel = substr($ircdata->channel1);
  1645.                         }
  1646.                     }
  1647.                     
  1648.                     $this->log(SMARTIRC_DEBUG_MESSAGEPARSER'DEBUG_MESSAGEPARSER: ircdata nick: "'.$ircdata->nick.
  1649.                                                                 '" ident: "'.$ircdata->ident.
  1650.                                                                 '" host: "'.$ircdata->host.
  1651.                                                                 '" type: "'.$ircdata->type.
  1652.                                                                 '" from: "'.$ircdata->from.
  1653.                                                                 '" channel: "'.$ircdata->channel.
  1654.                                                                 '" message: "'.$ircdata->message.
  1655.                                                                 '"'__FILE____LINE__);
  1656.                 }
  1657.                 
  1658.                 // lets see if we have a messagehandler for it
  1659.                 $this->_handlemessage($messagecode$ircdata);
  1660.                     
  1661.                 if ($validmessage == true{
  1662.                     // now the actionhandlers are comming
  1663.                     $this->_handleactionhandler($ircdata);
  1664.                 }
  1665.                 
  1666.                 if (isset($ircdata)) {
  1667.                     unset($ircdata);
  1668.                 }
  1669.             }
  1670.         }
  1671.     }
  1672.     
  1673.     /**
  1674.      * sends the pong for keeping alive
  1675.      *
  1676.      * Sends the PONG signal as reply of the PING from the IRC server.
  1677.      *
  1678.      * @param string $data 
  1679.      * @return void 
  1680.      * @access private
  1681.      */
  1682.     function _pong($data)
  1683.     {
  1684.         $this->log(SMARTIRC_DEBUG_CONNECTION'DEBUG_CONNECTION: Ping? Pong!'__FILE____LINE__);
  1685.         $this->_send('PONG '.$dataSMARTIRC_CRITICAL);
  1686.     }
  1687.     
  1688.     /**
  1689.      * returns the calculated selecttimeout value
  1690.      *
  1691.      * @return integer selecttimeout in microseconds
  1692.      * @access private
  1693.      */
  1694.     function _selecttimeout({
  1695.         if ($this->_messagebuffersize == 0{
  1696.             $this->_selecttimeout = null;
  1697.             
  1698.             if ($this->_mintimer != false{
  1699.                 $this->_calculateselecttimeout($this->_mintimer);
  1700.             }
  1701.             
  1702.             if ($this->_autoreconnect == true{
  1703.                 $this->_calculateselecttimeout($this->_rxtimeout*1000);
  1704.             }
  1705.             
  1706.             $this->_calculateselecttimeout($this->_maxtimer);
  1707.             return $this->_selecttimeout;
  1708.         else {
  1709.             return $this->_senddelay;
  1710.         }
  1711.     }
  1712.     
  1713.     /**
  1714.      * calculates the selecttimeout value
  1715.      *
  1716.      * @return void 
  1717.      * @access private
  1718.      */
  1719.     function _calculateselecttimeout($microseconds)
  1720.     {
  1721.         if (($this->_selecttimeout > $microseconds|| $this->_selecttimeout === null{
  1722.             $this->_selecttimeout = $microseconds;
  1723.         }
  1724.     }
  1725.     
  1726.     /**
  1727.      * updates _mintimer to the smallest timer interval
  1728.      *
  1729.      * @return void 
  1730.      * @access private
  1731.      */
  1732.     function _updatemintimer()
  1733.     {
  1734.         $timerarray = array();
  1735.         foreach ($this->_timehandler as $values{
  1736.             $timerarray[$values->interval;
  1737.         }
  1738.         
  1739.         $result array_multisort($timerarraySORT_NUMERICSORT_ASC);
  1740.         if ($result == true && isset($timerarray[0])) {
  1741.             $this->_mintimer = $timerarray[0];
  1742.         else {
  1743.             $this->_mintimer = false;
  1744.         }
  1745.     }
  1746.     
  1747.     /**
  1748.      * reorders the actionhandler array, needed after removing one
  1749.      *
  1750.      * @return void 
  1751.      * @access private
  1752.      */
  1753.     function _reorderactionhandler()
  1754.     {
  1755.         $orderedactionhandler = array();
  1756.         foreach ($this->_actionhandler as $value{
  1757.             $orderedactionhandler[$value;
  1758.         }
  1759.         $this->_actionhandler = &$orderedactionhandler;
  1760.     }
  1761.     
  1762.     /**
  1763.      * reorders the timehandler array, needed after removing one
  1764.      *
  1765.      * @return void 
  1766.      * @access private
  1767.      */
  1768.     function _reordertimehandler()
  1769.     {
  1770.         $orderedtimehandler = array();
  1771.         foreach ($this->_timehandler as $value{
  1772.             $orderedtimehandler[$value;
  1773.         }
  1774.         $this->_timehandler = &$orderedtimehandler;
  1775.     }
  1776.     
  1777.     /**
  1778.      * reorders the modules array, needed after removing one
  1779.      *
  1780.      * @return void 
  1781.      * @access private
  1782.      */
  1783.     function _reordermodules()
  1784.     {
  1785.         $orderedmodules = array();
  1786.         foreach ($this->_modules as $value{
  1787.             $orderedmodules[$value;
  1788.         }
  1789.         $this->_modules = &$orderedmodules;
  1790.     }
  1791.  
  1792.     /**
  1793.      * determines the messagetype of $line
  1794.      *
  1795.      * Analyses the type of an IRC message and returns the type.
  1796.      *
  1797.      * @param string $line 
  1798.      * @return integer SMARTIRC_TYPE_* constant
  1799.      * @access private
  1800.      */
  1801.     function _gettype($line)
  1802.     {
  1803.         if (preg_match('/^:[^ ]+? [0-9]{3} .+$/'$line== 1{
  1804.             $lineex explode(' '$line);
  1805.             $code $lineex[1];
  1806.                 
  1807.             switch ($code{
  1808.                 case SMARTIRC_RPL_WELCOME:
  1809.                 case SMARTIRC_RPL_YOURHOST:
  1810.                 case SMARTIRC_RPL_CREATED:
  1811.                 case SMARTIRC_RPL_MYINFO:
  1812.                 case SMARTIRC_RPL_BOUNCE:
  1813.                     return SMARTIRC_TYPE_LOGIN;
  1814.                 case SMARTIRC_RPL_LUSERCLIENT:
  1815.                 case SMARTIRC_RPL_LUSEROP:
  1816.                 case SMARTIRC_RPL_LUSERUNKNOWN:
  1817.                 case SMARTIRC_RPL_LUSERME:
  1818.                 case SMARTIRC_RPL_LUSERCHANNELS:
  1819.                     return SMARTIRC_TYPE_INFO;
  1820.                 case SMARTIRC_RPL_MOTDSTART:
  1821.                 case SMARTIRC_RPL_MOTD:
  1822.                 case SMARTIRC_RPL_ENDOFMOTD:
  1823.                     return SMARTIRC_TYPE_MOTD;
  1824.                 case SMARTIRC_RPL_NAMREPLY:
  1825.                 case SMARTIRC_RPL_ENDOFNAMES:
  1826.                     return SMARTIRC_TYPE_NAME;
  1827.                 case SMARTIRC_RPL_WHOREPLY:
  1828.                 case SMARTIRC_RPL_ENDOFWHO:
  1829.                     return SMARTIRC_TYPE_WHO;
  1830.                 case SMARTIRC_RPL_LISTSTART:
  1831.                     return SMARTIRC_TYPE_NONRELEVANT;
  1832.                 case SMARTIRC_RPL_LIST:
  1833.                 case SMARTIRC_RPL_LISTEND:
  1834.                     return SMARTIRC_TYPE_LIST;
  1835.                 case SMARTIRC_RPL_BANLIST:
  1836.                 case SMARTIRC_RPL_ENDOFBANLIST:
  1837.                     return SMARTIRC_TYPE_BANLIST;
  1838.                 case SMARTIRC_RPL_TOPIC:
  1839.                     return SMARTIRC_TYPE_TOPIC;
  1840.                 case SMARTIRC_RPL_WHOISUSER:
  1841.                 case SMARTIRC_RPL_WHOISSERVER:
  1842.                 case SMARTIRC_RPL_WHOISOPERATOR:
  1843.                 case SMARTIRC_RPL_WHOISIDLE:
  1844.                 case SMARTIRC_RPL_ENDOFWHOIS:
  1845.                 case SMARTIRC_RPL_WHOISCHANNELS:
  1846.                     return SMARTIRC_TYPE_WHOIS;
  1847.                 case SMARTIRC_RPL_WHOWASUSER:
  1848.                 case SMARTIRC_RPL_ENDOFWHOWAS:
  1849.                     return SMARTIRC_TYPE_WHOWAS;
  1850.                 case SMARTIRC_RPL_UMODEIS:
  1851.                     return SMARTIRC_TYPE_USERMODE;
  1852.                 case SMARTIRC_RPL_CHANNELMODEIS:
  1853.                     return SMARTIRC_TYPE_CHANNELMODE;
  1854.                 case SMARTIRC_ERR_NICKNAMEINUSE:
  1855.                 case SMARTIRC_ERR_NOTREGISTERED:
  1856.                     return SMARTIRC_TYPE_ERROR;
  1857.                 default:
  1858.                     $this->log(SMARTIRC_DEBUG_IRCMESSAGES'DEBUG_IRCMESSAGES: replycode UNKNOWN ('.$code.'): "'.$line.'"'__FILE____LINE__);
  1859.             }
  1860.         }
  1861.         
  1862.         if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'ACTION .*'.chr(1).'$/'$line== 1{
  1863.             return SMARTIRC_TYPE_ACTION;
  1864.         else if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'.*'.chr(1).'$/'$line== 1{
  1865.             return SMARTIRC_TYPE_CTCP;
  1866.         else if (preg_match('/^:.*? PRIVMSG (\&|\#|\+|\!).* :.*$/'$line== 1{
  1867.             return SMARTIRC_TYPE_CHANNEL;
  1868.         else if (preg_match('/^:.*? PRIVMSG .*:.*$/'$line== 1{
  1869.             return SMARTIRC_TYPE_QUERY;
  1870.         else if (preg_match('/^:.*? NOTICE .* :.*$/'$line== 1{
  1871.             return SMARTIRC_TYPE_NOTICE;
  1872.         else if (preg_match('/^:.*? INVITE .* .*$/'$line== 1{
  1873.             return SMARTIRC_TYPE_INVITE;
  1874.         else if (preg_match('/^:.*? JOIN .*$/'$line== 1{
  1875.             return SMARTIRC_TYPE_JOIN;
  1876.         else if (preg_match('/^:.*? TOPIC .* :.*$/'$line== 1{
  1877.             return SMARTIRC_TYPE_TOPICCHANGE;
  1878.         else if (preg_match('/^:.*? NICK .*$/'$line== 1{
  1879.             return SMARTIRC_TYPE_NICKCHANGE;
  1880.         else if (preg_match('/^:.*? KICK .* .*$/'$line== 1{
  1881.             return SMARTIRC_TYPE_KICK;
  1882.         else if (preg_match('/^:.*? PART .*$/'$line== 1{
  1883.             return SMARTIRC_TYPE_PART;
  1884.         else if (preg_match('/^:.*? MODE .* .*$/'$line== 1{
  1885.             return SMARTIRC_TYPE_MODECHANGE;
  1886.         else if (preg_match('/^:.*? QUIT :.*$/'$line== 1{
  1887.             return SMARTIRC_TYPE_QUIT;
  1888.         else {
  1889.             $this->log(SMARTIRC_DEBUG_MESSAGETYPES'DEBUG_MESSAGETYPES: SMARTIRC_TYPE_UNKNOWN!: "'.$line.'"'__FILE____LINE__);
  1890.             return SMARTIRC_TYPE_UNKNOWN;
  1891.         }
  1892.     }
  1893.     
  1894.     /**
  1895.      * updates the current connection state
  1896.      *
  1897.      * @return boolean 
  1898.      * @access private
  1899.      */
  1900.     function _updatestate()
  1901.     {
  1902.         $rtype get_resource_type($this->_socket);
  1903.         if ((is_resource($this->_socket)) &&
  1904.             ($this->_socket !== false&&
  1905.             ($rtype == 'socket' || $rtype == 'Socket' || $rtype == 'stream')) {
  1906.             
  1907.             $this->_state = true;
  1908.             return true;
  1909.         else {
  1910.             $this->_state = false;
  1911.             $this->_loggedin = false;
  1912.             return false;
  1913.         }
  1914.     }
  1915.     
  1916.     /**
  1917.      * returns the current connection state
  1918.      *
  1919.      * @return integer SMARTIRC_STATE_CONNECTED or SMARTIRC_STATE_DISCONNECTED
  1920.      * @access private
  1921.      */
  1922.     function _state()
  1923.     {
  1924.         $result $this->_updatestate();
  1925.         
  1926.         if ($result == true{
  1927.             return SMARTIRC_STATE_CONNECTED;
  1928.         else {
  1929.             return SMARTIRC_STATE_DISCONNECTED;
  1930.         }
  1931.     }
  1932.     
  1933.     /**
  1934.      * tries to find a messagehandler for the received message ($ircdata) and calls it
  1935.      *
  1936.      * @param string $messagecode 
  1937.      * @param object $ircdata 
  1938.      * @return void 
  1939.      * @access private
  1940.      */
  1941.     function _handlemessage($messagecode&$ircdata)
  1942.     {
  1943.         $found = false;
  1944.         
  1945.         if (is_numeric($messagecode)) {
  1946.             if (!array_key_exists($messagecode$this->nreplycodes)) {
  1947.                 $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER'DEBUG_MESSAGEHANDLER: ignoring unreconzied messagecode! "'.$messagecode.'"'__FILE____LINE__);
  1948.                 $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER'DEBUG_MESSAGEHANDLER: this IRC server ('.$this->_address.') doesn\'t conform to the RFC 2812!'__FILE____LINE__);
  1949.                 return;
  1950.             }
  1951.             
  1952.             $methodname 'event_'.strtolower($this->nreplycodes[$messagecode]);
  1953.             $_methodname '_'.$methodname;
  1954.             $_codetype 'by numeric';
  1955.         else if (is_string($messagecode)) // its not numericcode so already a name/string
  1956.             $methodname 'event_'.strtolower($messagecode);
  1957.             $_methodname '_'.$methodname;
  1958.             $_codetype 'by string';
  1959.         }
  1960.         
  1961.         // if exists call internal method for the handling
  1962.         if (@method_exists($this$_methodname)) {
  1963.            $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER'DEBUG_MESSAGEHANDLER: calling internal method "'.get_class($this).'->'.$_methodname.'" ('.$_codetype.')'__FILE____LINE__);
  1964.            $this->$_methodname($ircdata);
  1965.            $found = true;
  1966.         }
  1967.         
  1968.         // if exist, call user defined method for the handling
  1969.         if (@method_exists($this$methodname)) {
  1970.            $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER'DEBUG_MESSAGEHANDLER: calling user defined method "'.get_class($this).'->'.$methodname.'" ('.$_codetype.')'__FILE____LINE__);
  1971.            $this->$methodname($ircdata);
  1972.            $found = true;
  1973.         }
  1974.         
  1975.         if ($found == false{
  1976.             $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER'DEBUG_MESSAGEHANDLER: no method found for "'.$messagecode.'" ('.$methodname.')'__FILE____LINE__);
  1977.         }
  1978.     }
  1979.     
  1980.     /**
  1981.      * tries to find a actionhandler for the received message ($ircdata) and calls it
  1982.      *
  1983.      * @param object $ircdata 
  1984.      * @return void 
  1985.      * @access private
  1986.      */
  1987.     function _handleactionhandler(&$ircdata)
  1988.     {
  1989.         $handler &$this->_actionhandler;
  1990.         $handlercount count($handler);
  1991.         for ($i = 0; $i $handlercount$i++{
  1992.             $handlerobject &$handler[$i];
  1993.             
  1994.             if (substr($handlerobject->message01== '/'{
  1995.                 $regex $handlerobject->message;
  1996.             else {
  1997.                 $regex '/'.$handlerobject->message.'/';
  1998.             }
  1999.             
  2000.             if (($handlerobject->type $ircdata->type&&
  2001.                 (preg_match($regex$ircdata->message== 1)) {
  2002.                 
  2003.                 $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: actionhandler match found for id: '.$i.' type: '.$ircdata->type.' message: "'.$ircdata->message.'" regex: "'.$regex.'"'__FILE____LINE__);
  2004.                 
  2005.                 $methodobject &$handlerobject->object;
  2006.                 $method $handlerobject->method;
  2007.                 
  2008.                 if (@method_exists($methodobject$method)) {
  2009.                     $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"'__FILE____LINE__);
  2010.                     $methodobject->$method($this$ircdata);
  2011.                 else {
  2012.                     $this->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: method doesn\'t exist! "'.get_class($methodobject).'->'.$method.'"'__FILE____LINE__);
  2013.                 }
  2014.                 
  2015.                 break;
  2016.             }
  2017.         }
  2018.     }
  2019.     
  2020.     /**
  2021.      * getting current microtime, needed for benchmarks
  2022.      *
  2023.      * @return float 
  2024.      * @access private
  2025.      */
  2026.     function _microint()
  2027.     {
  2028.         $tmp microtime();
  2029.         $parts explode(' '$tmp);
  2030.         $floattime = (float)$parts[0+ (float)$parts[1];
  2031.         return $floattime;
  2032.     }
  2033.     
  2034.     /**
  2035.      * adds an user to the channelobject or updates his info
  2036.      *
  2037.      * @param object $channel 
  2038.      * @param object $newuser 
  2039.      * @return void 
  2040.      * @access private
  2041.      */
  2042.     function _adduser(&$channel&$newuser)
  2043.     {
  2044.         $lowerednick strtolower($newuser->nick);
  2045.         if (isset($channel->users[$lowerednick])) {
  2046.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: updating user: '.$newuser->nick.' on channel: '.$channel->name__FILE____LINE__);
  2047.             
  2048.             // lets update the existing user
  2049.             $currentuser &$channel->users[$lowerednick];
  2050.             
  2051.             if ($newuser->ident !== null{
  2052.                 $currentuser->ident = $newuser->ident;
  2053.             }
  2054.             if ($newuser->host !== null{
  2055.                 $currentuser->host = $newuser->host;
  2056.             }
  2057.             if ($newuser->realname !== null{
  2058.                 $currentuser->realname = $newuser->realname;
  2059.             }
  2060.             if ($newuser->op !== null{
  2061.                 $currentuser->op = $newuser->op;
  2062.             }
  2063.             if ($newuser->voice !== null{
  2064.                 $currentuser->voice = $newuser->voice;
  2065.             }
  2066.             if ($newuser->ircop !== null{
  2067.                 $currentuser->ircop = $newuser->ircop;
  2068.             }
  2069.             if ($newuser->away !== null{
  2070.                 $currentuser->away = $newuser->away;
  2071.             }
  2072.             if ($newuser->server !== null{
  2073.                 $currentuser->server = $newuser->server;
  2074.             }
  2075.             if ($newuser->hopcount !== null{
  2076.                 $currentuser->hopcount = $newuser->hopcount;
  2077.             }
  2078.         else {
  2079.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: adding user: '.$newuser->nick.' to channel: '.$channel->name__FILE____LINE__);
  2080.             
  2081.             // he is new just add the reference to him
  2082.             $channel->users[$lowerednick&$newuser;
  2083.         }
  2084.         
  2085.         $user &$channel->users[$lowerednick];
  2086.         if ($user->op{
  2087.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: adding op: '.$user->nick.' to channel: '.$channel->name__FILE____LINE__);
  2088.             $channel->ops[$user->nick= true;
  2089.         }
  2090.         if ($user->voice{
  2091.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: adding voice: '.$user->nick.' to channel: '.$channel->name__FILE____LINE__);
  2092.             $channel->voices[$user->nick= true;
  2093.         }
  2094.     }
  2095.     
  2096.     /**
  2097.      * removes an user from one channel or all if he quits
  2098.      *
  2099.      * @param object $ircdata 
  2100.      * @return void 
  2101.      * @access private
  2102.      */
  2103.     function _removeuser(&$ircdata)
  2104.     {
  2105.         if ($ircdata->type (SMARTIRC_TYPE_PART|SMARTIRC_TYPE_QUIT)) {
  2106.             $nick $ircdata->nick;
  2107.         else if ($ircdata->type SMARTIRC_TYPE_KICK{
  2108.             $nick $ircdata->rawmessageex[3];
  2109.         else {
  2110.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: unknown TYPE ('.$ircdata->type.') in _removeuser(), trying default'__FILE____LINE__);
  2111.             $nick $ircdata->nick;
  2112.         }
  2113.         
  2114.         $lowerednick strtolower($nick);
  2115.         
  2116.         if ($this->_nick == $nick{
  2117.             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: we left channel: '.$ircdata->channel.' destroying...'__FILE____LINE__);
  2118.             unset($this->_channels[strtolower($ircdata->channel)]);
  2119.         else {
  2120.             if ($ircdata->type SMARTIRC_TYPE_QUIT{
  2121.                 $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: user '.$nick.' quit, removing him from all channels'__FILE____LINE__);
  2122.                 // remove the user from all channels
  2123.                 foreach ($this->_channels as $channelkey => $channelvalue{
  2124.                     // loop through all channels
  2125.                     $channel &$this->_channels[$channelkey];
  2126.                     foreach ($channel->users as $userkey => $uservalue{
  2127.                         // loop through all user in this channel
  2128.                         
  2129.                         if ($nick == $uservalue->nick{
  2130.                             // found him
  2131.                             // kill him
  2132.                             $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: found him on channel: '.$channel->name.' destroying...'__FILE____LINE__);
  2133.                             unset($channel->users[$lowerednick]);
  2134.                             
  2135.                             if (isset($channel->ops[$nick])) {
  2136.                                 // die!
  2137.                                 $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: removing him from op list'__FILE____LINE__);
  2138.                                 unset($channel->ops[$nick]);
  2139.                             }
  2140.                             
  2141.                             if (isset($channel->voices[$nick])) {
  2142.                                 // die!!
  2143.                                 $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: removing him from voice list'__FILE____LINE__);
  2144.                                 unset($channel->voices[$nick]);
  2145.                             }
  2146.                             
  2147.                             // ups this was not DukeNukem 3D
  2148.                         }
  2149.                     }
  2150.                 }
  2151.             else {
  2152.                 $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: removing user: '.$nick.' from channel: '.$ircdata->channel__FILE____LINE__);
  2153.                 $channel &$this->_channels[strtolower($ircdata->channel)];
  2154.                 unset($channel->users[$lowerednick]);
  2155.                 
  2156.                 if (isset($channel->ops[$nick])) {
  2157.                     $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: removing him from op list'__FILE____LINE__);
  2158.                     unset($channel->ops[$nick]);
  2159.                 }
  2160.                 
  2161.                 if (isset($channel->voices[$nick])) {
  2162.                     $this->log(SMARTIRC_DEBUG_CHANNELSYNCING'DEBUG_CHANNELSYNCING: removing him from voice list'__FILE____LINE__);
  2163.                     unset($channel->voices[$nick]);
  2164.                 }
  2165.             }
  2166.         }
  2167.     }
  2168.     
  2169.     /**
  2170.      * @return void 
  2171.      * @access private
  2172.      */
  2173.     function _checkPHPVersion()
  2174.     {
  2175.         // doing nothing at the moment
  2176.     }
  2177.     
  2178.     /**
  2179.      * checks if the passed handlertype is valid
  2180.      *
  2181.      * @param integer $handlertype 
  2182.      * @return boolean 
  2183.      * @access private
  2184.      */
  2185.     function _isValidType($handlertype{
  2186.         if ($handlertype SMARTIRC_TYPE_ALL {
  2187.             return true;
  2188.         else {
  2189.             return false;
  2190.         }
  2191.     }
  2192.     
  2193.     // </private methods>
  2194.     
  2195.     function isError($object{
  2196.         return (bool)(is_object($object&& (strtolower(get_class($object)) == 'net_smartirc_error'));
  2197.     }
  2198.     
  2199.     function &throwError($message{
  2200.         return new Net_SmartIRC_Error($message);
  2201.     }
  2202. }
  2203.  
  2204. {
  2205.     // empty
  2206. }
  2207.  
  2208. /**
  2209.  * @access public
  2210.  */
  2211. class Net_SmartIRC_data
  2212. {
  2213.     /**
  2214.      * @var string 
  2215.      * @access public
  2216.      */
  2217.     var $from;
  2218.     
  2219.     /**
  2220.      * @var string 
  2221.      * @access public
  2222.      */
  2223.     var $nick;
  2224.     
  2225.     /**
  2226.      * @var string 
  2227.      * @access public
  2228.      */
  2229.     var $ident;
  2230.     
  2231.     /**
  2232.      * @var string 
  2233.      * @access public
  2234.      */
  2235.     var $host;
  2236.     
  2237.     /**
  2238.      * @var string 
  2239.      * @access public
  2240.      */
  2241.     var $channel;
  2242.     
  2243.     /**
  2244.      * @var string 
  2245.      * @access public
  2246.      */
  2247.     var $message;
  2248.     
  2249.     /**
  2250.      * @var array 
  2251.      * @access public
  2252.      */
  2253.     var $messageex = array();
  2254.     
  2255.     /**
  2256.      * @var integer 
  2257.      * @access public
  2258.      */
  2259.     var $type;
  2260.     
  2261.     /**
  2262.      * @var string 
  2263.      * @access public
  2264.      */
  2265.     var $rawmessage;
  2266.     
  2267.     /**
  2268.      * @var array 
  2269.      * @access public
  2270.      */
  2271.     var $rawmessageex = array();
  2272. }
  2273.  
  2274. /**
  2275.  * @access public
  2276.  */
  2277. class Net_SmartIRC_actionhandler
  2278. {
  2279.     /**
  2280.      * @var integer 
  2281.      * @access public
  2282.      */
  2283.     var $id;
  2284.     
  2285.     /**
  2286.      * @var integer 
  2287.      * @access public
  2288.      */
  2289.     var $type;
  2290.     
  2291.     /**
  2292.      * @var string 
  2293.      * @access public
  2294.      */
  2295.     var $message;
  2296.     
  2297.     /**
  2298.      * @var object 
  2299.      * @access public
  2300.      */
  2301.     var $object;
  2302.     
  2303.     /**
  2304.      * @var string 
  2305.      * @access public
  2306.      */
  2307.     var $method;
  2308. }
  2309.  
  2310. /**
  2311.  * @access public
  2312.  */
  2313. class Net_SmartIRC_timehandler
  2314. {
  2315.     /**
  2316.      * @var integer 
  2317.      * @access public
  2318.      */
  2319.     var $id;
  2320.     
  2321.     /**
  2322.      * @var integer 
  2323.      * @access public
  2324.      */
  2325.     var $interval;
  2326.     
  2327.     /**
  2328.      * @var integer 
  2329.      * @access public
  2330.      */
  2331.     var $lastmicrotimestamp;
  2332.     
  2333.     /**
  2334.      * @var object 
  2335.      * @access public
  2336.      */
  2337.     var $object;
  2338.     
  2339.     /**
  2340.      * @var string 
  2341.      * @access public
  2342.      */
  2343.     var $method;
  2344. }
  2345.  
  2346. /**
  2347.  * @access public
  2348.  */
  2349. class Net_SmartIRC_channel
  2350. {
  2351.     /**
  2352.      * @var string 
  2353.      * @access public
  2354.      */
  2355.     var $name;
  2356.     
  2357.     /**
  2358.      * @var string 
  2359.      * @access public
  2360.      */
  2361.     var $key;
  2362.     
  2363.     /**
  2364.      * @var array 
  2365.      * @access public
  2366.      */
  2367.     var $users = array();
  2368.     
  2369.     /**
  2370.      * @var array 
  2371.      * @access public
  2372.      */
  2373.     var $ops = array();
  2374.     
  2375.     /**
  2376.      * @var array 
  2377.      * @access public
  2378.      */
  2379.     var $voices = array();
  2380.     
  2381.     /**
  2382.      * @var array 
  2383.      * @access public
  2384.      */
  2385.     var $bans = array();
  2386.     
  2387.     /**
  2388.      * @var string 
  2389.      * @access public
  2390.      */
  2391.     var $topic;
  2392.     
  2393.     /**
  2394.      * @var string 
  2395.      * @access public
  2396.      */
  2397.     var $mode;
  2398. }
  2399.  
  2400. /**
  2401.  * @access public
  2402.  */
  2403. class Net_SmartIRC_user
  2404. {
  2405.     /**
  2406.      * @var string 
  2407.      * @access public
  2408.      */
  2409.     var $nick;
  2410.     
  2411.     /**
  2412.      * @var string 
  2413.      * @access public
  2414.      */
  2415.     var $ident;
  2416.     
  2417.     /**
  2418.      * @var string 
  2419.      * @access public
  2420.      */
  2421.     var $host;
  2422.     
  2423.     /**
  2424.      * @var string 
  2425.      * @access public
  2426.      */
  2427.     var $realname;
  2428.     
  2429.     /**
  2430.      * @var boolean 
  2431.      * @access public
  2432.      */
  2433.     var $ircop;
  2434.     
  2435.     /**
  2436.      * @var boolean 
  2437.      * @access public
  2438.      */
  2439.     var $away;
  2440.     
  2441.     /**
  2442.      * @var string 
  2443.      * @access public
  2444.      */
  2445.     var $server;
  2446.     
  2447.     /**
  2448.      * @var integer 
  2449.      * @access public
  2450.      */
  2451.     var $hopcount;
  2452. }
  2453.  
  2454. /**
  2455.  * @access public
  2456.  */
  2457. class Net_SmartIRC_channeluser extends Net_SmartIRC_user
  2458. {
  2459.     /**
  2460.      * @var boolean 
  2461.      * @access public
  2462.      */
  2463.     var $op;
  2464.     
  2465.     /**
  2466.      * @var boolean 
  2467.      * @access public
  2468.      */
  2469.     var $voice;
  2470. }
  2471.  
  2472. /**
  2473.  * @access public
  2474.  */
  2475. class Net_SmartIRC_ircuser extends Net_SmartIRC_user
  2476. {
  2477.     /**
  2478.      * @var array 
  2479.      * @access public
  2480.      */
  2481.     var $joinedchannels = array();
  2482. }
  2483.  
  2484. /**
  2485.  * @access public
  2486.  */
  2487. class Net_SmartIRC_listenfor
  2488. {
  2489.     /**
  2490.      * @var array 
  2491.      * @access public
  2492.      */
  2493.     var $result = array();
  2494.     
  2495.     /**
  2496.      * stores the received answer into the result array
  2497.      *
  2498.      * @param object $irc 
  2499.      * @param object $ircdata 
  2500.      * @return void 
  2501.      */
  2502.     function handler(&$irc&$ircdata)
  2503.     {
  2504.         $irc->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: listenfor handler called'__FILE____LINE__);
  2505.         $this->result[$ircdata->message;
  2506.         $irc->disconnect(true);
  2507.     }
  2508. }
  2509.  
  2510. // so we don't break BC!
  2511. /**
  2512.  * @access public
  2513.  */
  2514. class Net_SmartIRC_objListenFor
  2515. {
  2516.     /**
  2517.      * @var array 
  2518.      * @access public
  2519.      */
  2520.     var $result = array();
  2521.     
  2522.     /**
  2523.      * stores the received answer into the result array
  2524.      *
  2525.      * @param object $irc 
  2526.      * @param object $ircdata 
  2527.      * @return void 
  2528.      */
  2529.     function handler(&$irc&$ircdata)
  2530.     {
  2531.         $irc->log(SMARTIRC_DEBUG_ACTIONHANDLER'DEBUG_ACTIONHANDLER: objListenFor handler called'__FILE____LINE__);
  2532.         $this->result[$ircdata;
  2533.         $irc->disconnect(true);
  2534.     }
  2535. }
  2536.  
  2537. class Net_SmartIRC_Error
  2538. {
  2539.     var $error_msg;
  2540.     
  2541.     function Net_SmartIRC_Error($message)
  2542.     {
  2543.         $this->error_msg $message;
  2544.     }
  2545.     
  2546.     function getMessage()
  2547.     {
  2548.         return $this->error_msg;
  2549.     }
  2550. }
  2551. ?>

Documentation generated on Mon, 11 Mar 2019 14:19:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.