smartirc.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,982 行 · 第 1/5 页

PHP
1,982
字号
        
        return $result;
    }    
    
    /**
     * registers a new actionhandler and returns the assigned id
     *
     * Registers an actionhandler in Net_SmartIRC for calling it later.
     * The actionhandler id is needed for unregistering the actionhandler.
     *
     * @see example.php
     * @param integer $handlertype bits constants, see in this documentation Message Types
     * @param string $regexhandler the message that has to be in the IRC message in regex syntax
     * @param object $object a reference to the objects of the method
     * @param string $methodname the methodname that will be called when the handler happens
     * @return integer assigned actionhandler id
     * @access public
     */
    function registerActionhandler($handlertype, $regexhandler, &$object, $methodname)
    {
        // precheck
        if (!$this->_isValidType($handlertype)) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to registerActionhandler()', __FILE__, __LINE__);
            return false;
        }
        
        $id = $this->_actionhandlerid++;
        $newactionhandler = &new Net_SmartIRC_actionhandler();
        
        $newactionhandler->id = $id;
        $newactionhandler->type = $handlertype;
        $newactionhandler->message = $regexhandler;
        $newactionhandler->object = &$object;
        $newactionhandler->method = $methodname;
        
        $this->_actionhandler[] = &$newactionhandler;
        $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') registered', __FILE__, __LINE__);
        return $id;
    }
    
    /**
     * unregisters an existing actionhandler
     *
     * @param integer $handlertype
     * @param string $regexhandler
     * @param object $object
     * @param string $methodname
     * @return boolean
     * @access public
     */
    function unregisterActionhandler($handlertype, $regexhandler, &$object, $methodname)
    {
        // precheck
        if (!$this->_isValidType($handlertype)) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to unregisterActionhandler()', __FILE__, __LINE__);
            return false;
        }
        
        $handler = &$this->_actionhandler;
        $handlercount = count($handler);
        
        for ($i = 0; $i < $handlercount; $i++) {
            $handlerobject = &$handler[$i];
                        
            if ($handlerobject->type == $handlertype &&
                $handlerobject->message == $regexhandler &&
                $handlerobject->method == $methodname) {
                
                $id = $handlerobject->id;
                
                if (isset($this->_actionhandler[$i])) {
                    unset($this->_actionhandler[$i]);
                }
                
                $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
                $this->_reorderactionhandler();
                return true;
            }
        }
        
        $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__);
        return false;
    }
    
    /**
     * unregisters an existing actionhandler via the id
     *
     * @param integer $id
     * @return boolean
     * @access public
     */
    function unregisterActionid($id)
    {
        $handler = &$this->_actionhandler;
        $handlercount = count($handler);
        for ($i = 0; $i < $handlercount; $i++) {
            $handlerobject = &$handler[$i];
                        
            if ($handlerobject->id == $id) {
                if (isset($this->_actionhandler[$i])) {
                    unset($this->_actionhandler[$i]);
                }
                
                $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
                $this->_reorderactionhandler();
                return true;
            }
        }
        
        $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
        return false;
    }
    
    /**
     * registers a timehandler and returns the assigned id
     *
     * Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
     * The timehandler id is needed for unregistering the timehandler.
     *
     * @see example7.php
     * @param integer $interval interval time in milliseconds
     * @param object $object a reference to the objects of the method
     * @param string $methodname the methodname that will be called when the handler happens
     * @return integer assigned timehandler id
     * @access public
     */
    function registerTimehandler($interval, &$object, $methodname)
    {
        $id = $this->_timehandlerid++;
        $newtimehandler = &new Net_SmartIRC_timehandler();
        
        $newtimehandler->id = $id;
        $newtimehandler->interval = $interval;
        $newtimehandler->object = &$object;
        $newtimehandler->method = $methodname;
        $newtimehandler->lastmicrotimestamp = $this->_microint();
        
        $this->_timehandler[] = &$newtimehandler;
        $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') registered', __FILE__, __LINE__);
        
        if (($interval < $this->_mintimer) || ($this->_mintimer == false)) {
            $this->_mintimer = $interval;
        }
            
        return $id;
    }
    
    /**
     * unregisters an existing timehandler via the id
     *
     * @see example7.php
     * @param integer $id
     * @return boolean
     * @access public
     */
    function unregisterTimeid($id)
    {
        $handler = &$this->_timehandler;
        $handlercount = count($handler);
        for ($i = 0; $i < $handlercount; $i++) {
            $handlerobject = &$handler[$i];
            
            if ($handlerobject->id == $id) {
                if (isset($this->_timehandler[$i])) {
                    unset($this->_timehandler[$i]);
                }
                
                $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') unregistered', __FILE__, __LINE__);
                $this->_reordertimehandler();
                $this->_updatemintimer();
                return true;
            }
        }
        
        $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: could not find timehandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
        return false;
    }
    
    // <private methods>
    /**
     * changes a already used nickname to a new nickname plus 3 random digits
     *
     * @return void
     * @access private
     */
    function _nicknameinuse()
    {
        $newnickname = substr($this->_nick, 0, 5).rand(0, 999);
        $this->changeNick($newnickname, SMARTIRC_CRITICAL);
    }
    
    /**
     * sends an IRC message
     *
     * Adds a message to the messagequeue, with the optional priority.
     * $priority:
     * SMARTIRC_CRITICAL
     * SMARTIRC_HIGH
     * SMARTIRC_MEDIUM
     * SMARTIRC_LOW
     *
     * @param string $data
     * @param integer $priority must be one of the priority constants
     * @return boolean
     * @access private
     */
    function _send($data, $priority = SMARTIRC_MEDIUM)
    {
        switch ($priority) {
            case SMARTIRC_CRITICAL:
                $this->_rawsend($data);
                return true;
            break;
            case (SMARTIRC_HIGH||
                  SMARTIRC_MEDIUM||
                  SMARTIRC_LOW):
                $this->_messagebuffer[$priority][] = $data;
                return true;
            break;
            default:
                $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: message ('.$data.') with an invalid priority passed ('.$priority.'), message is ignored!', __FILE__, __LINE__);
                return false;
        }
    }
    
    /**
     * checks the buffer if there are messages to send
     *
     * @return void
     * @access private
     */
    function _checkbuffer()
    {
        if (!$this->_loggedin) {
            return;
        }
        
        static $highsent = 0;
        static $lastmicrotimestamp = 0;
        
        if ($lastmicrotimestamp == 0) {
            $lastmicrotimestamp = $this->_microint();
        }
        
        $highcount = count($this->_messagebuffer[SMARTIRC_HIGH]);
        $mediumcount = count($this->_messagebuffer[SMARTIRC_MEDIUM]);
        $lowcount = count($this->_messagebuffer[SMARTIRC_LOW]);
        $this->_messagebuffersize = $highcount+$mediumcount+$lowcount;
        
        // don't send them too fast
        if ($this->_microint() >= ($lastmicrotimestamp+($this->_senddelay/1000))) {
            if ($highcount > 0 && $highsent <= 2) {
                $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_HIGH]));
                $lastmicrotimestamp = $this->_microint();
                $highsent++;
            } else if ($mediumcount > 0) {
                $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_MEDIUM]));
                $lastmicrotimestamp = $this->_microint();
                $highsent = 0;
            } else if ($lowcount > 0) {
                $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_LOW]));
                $lastmicrotimestamp = $this->_microint();
            }
        }
    }
    
    /**
     * Checks the running timers and calls the registered timehandler,
     * when the interval is reached.
     *
     * @return void
     * @access private
     */
    function _checktimer()
    {
        if (!$this->_loggedin) {
            return;
        }
        
        // has to be count() because the array may change during the loop!
        for ($i = 0; $i < count($this->_timehandler); $i++) {
            $handlerobject = &$this->_timehandler[$i];
            $microtimestamp = $this->_microint();
            if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+($handlerobject->interval/1000))) {
                $methodobject = &$handlerobject->object;
                $method = $handlerobject->method;
                $handlerobject->lastmicrotimestamp = $microtimestamp;
                
                if (@method_exists($methodobject, $method)) {
                    $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
                    $methodobject->$method($this);
                }
            }
        }
    }
    
    /**
     * Checks if a receive or transmit timeout occured and reconnects if configured
     *
     * @return void
     * @access private
     */
    function _checktimeout()
    {
        if ($this->_autoreconnect == true) {
            $timestamp = time();
            if ($this->_lastrx < ($timestamp - $this->_rxtimeout)) {
                $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: receive timeout detected, doing reconnect...', __FILE__, __LINE__);
                $this->reconnect();
            } else if ($this->_lasttx < ($timestamp - $this->_txtimeout)) {
                $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: transmit timeout detected, doing reconnect...', __FILE__, __LINE__);
                $this->reconnect();
            }
        }
    }
    
    /**
     * sends a raw message to the IRC server (don't use this!!)
     *
     * Use message() or _send() instead.
     *
     * @param string $data
     * @return boolean
     * @access private
     */
    function _rawsend($data)
    {
        if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
            $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: sent: "'.$data.'"', __FILE__, __LINE__);
            
            if ($this->_usesockets == true) {
                $result = @socket_write($this->_socket, $data.SMARTIRC_CRLF);
            } else {
                $result = @fwrite($this->_socket, $data.SMARTIRC_CRLF);
            }
            
            
            if ($result === false) {
                return false;
            } else {
                $this->_lasttx = time();
                return true;
            }
        } else {
            return false;
        }
    }
    
    /**
     * goes into main idle loop for waiting messages from the IRC server
     *
     * @return void
     * @access private
     */
    function _rawreceive()
    {
        $lastpart = '';
        $rawdataar = array();
        
        while ($this->_state() == SMARTIRC_STATE_CONNECTED) {
            $this->_checkbuffer();
            
            $timeout = $this->_selecttimeout();
            if ($this->_usesockets == true) {
                $sread = array($this->_socket);
                $result = @socket_select($sread, $w = null, $e = null, 0, $timeout*1000);
                
                if ($result == 1) {
                    // the socket got data to read
                    $rawdata = @socket_read($this->_socket, 10240);
                } else if ($result === false) {
                    // panic! panic! something went wrong!
                    $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket_select() returned false, something went wrong! Reason: '.socket_strerror(socket_last_error()), __FILE__, __LINE__);
                    exit;
                } else {
                    // no data
                    $rawdata = null;
                }
            } else {
                usleep($this->_receivedelay*1000);
                $rawdata = @fread($this->_socket, 10240);
            }
            
            $this->_checktimer();
            $this->_checktimeout();
            
            if ($rawdata !== null && !empty($rawdata)) {
                $this->_lastrx = time();
                $rawdata = str_replace("\r", '', $rawdata);
                $rawdata = $lastpart.$rawdata;
                
                $lastpart = substr($rawdata, strrpos($rawdata ,"\n")+1);
                $rawdata = substr($rawdata, 0, strrpos($rawdata ,"\n"));
                $rawdataar = explode("\n", $rawdata);
            }
            
            // loop through our received messages

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?