smartirc.php

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

PHP
1,982
字号
        }
    }
    
    /**
     * Returns the full motd.
     *
     * @return array
     * @access public
     */
    function getMotd()
    {
        return $this->_motd;
    }
    
    /**
     * Returns the usermode.
     *
     * @return string
     * @access public
     */
    function getUsermode()
    {
        return $this->_usermode;
    }
    
    /**
     * Creates the sockets and connects to the IRC server on the given port.
     *
     * @param string $address 
     * @param integer $port
     * @return void
     * @access public
     */
    function connect($address, $port)
    {
        $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connecting', __FILE__, __LINE__);
        $this->_address = $address;
        $this->_port = $port;
        
        if ($this->_usesockets == true) {
            $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: using real sockets', __FILE__, __LINE__);
            $this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
            $result = @socket_connect($this->_socket, $this->_address, $this->_port);
        } else {
            $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: using fsockets', __FILE__, __LINE__);
            $result = @fsockopen($this->_address, $this->_port, $errno, $errstr);
        }
        
        if ($result === false) {
            if ($this->_usesockets == true) {
                $error = socket_strerror(socket_last_error($this->_socket));
            } else {
                $error = $errstr.' ('.$errno.')';
            }
            
            $error_msg = 'couldn\'t connect to "'.$address.'" reason: "'.$error.'"';
            $this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: '.$error_msg, __FILE__, __LINE__);
            // TODO! muss return wert sein
            $this->throwError($error_msg);
            
            // doesn't work somehow.... I only want to retry 4 times! no endless loop (causes segfault)
            static $tries = 0;
            if ($this->_autoretry == true && $tries < 5) {
                $this->reconnect();
                $tries++;
            } else {
                die();
            }
        } else {
            $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connected', __FILE__, __LINE__);
            
            if ($this->_usesockets != true) {
                $this->_socket = $result;
                $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: activating nonblocking fsocket mode', __FILE__, __LINE__);
                socket_set_blocking($this->_socket, false);
            }
        }
        
        $this->_lastrx = time();
        $this->_lasttx = $this->_lastrx;
        $this->_updatestate();
        
        if ($result !== false) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Disconnects from the IRC server nicely with a QUIT or just destroys the socket.
     *
     * Disconnects from the IRC server in the given quickness mode.
     * $quickdisconnect:
     * true, just close the socket
     * false, send QUIT and wait {@link $_disconnectime $_disconnectime} before closing the socket
     *
     * @param boolean $quickdisconnect default: false
     * @return boolean
     * @access public
     */
    function disconnect($quickdisconnect = false)
    {
        if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
            if ($quickdisconnect == false) {
                $this->_send('QUIT', SMARTIRC_CRITICAL);
                usleep($this->_disconnecttime*1000);
            }
            
            if ($this->_usesockets == true) {
                @socket_shutdown($this->_socket);
                @socket_close($this->_socket);
            } else {
                fclose($this->_socket);
            }
            
            $this->_updatestate();
            $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: disconnected', __FILE__, __LINE__);
        } else {
            return false;
        }
        
        if ($this->_channelsyncing == true) {
            // let's clean our channel array
            $this->_channels = array();
            $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: cleaned channel array', __FILE__, __LINE__);
        }
        
        if ($this->_logdestination == SMARTIRC_FILE) {
            fclose($this->_logfilefp);
            $this->_logfilefp = null;
        } else if ($this->_logdestination == SMARTIRC_SYSLOG) {
            closelog();
        }
        
        return true;
    }
    
    /**
     * Reconnects to the IRC server with the same login info,
     * it also rejoins the channels
     *
     * @return void
     * @access public
     */
    function reconnect()
    {
        $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: reconnecting...', __FILE__, __LINE__);
        
        // remember in which channels we are joined
        $channels = array();
        foreach ($this->_channels as $value) {
            if (empty($value->key)) {
                $channels[] = array('name' => $value->name);
            } else {
                $channels[] = array('name' => $value->name, 'key' => $value->key);
            }
        }
        
        $this->disconnect(true);
        $this->connect($this->_address, $this->_port);
        $this->login($this->_nick, $this->_realname, $this->_usermode, $this->_username, $this->_password);
        
        // rejoin the channels
        foreach ($channels as $value) {
            if (isset($value['key'])) {
                $this->join($value['name'], $value['key']);
            } else {
                $this->join($value['name']);
            }
        }
    }
    
    /**
     * login and register nickname on the IRC network
     *
     * Registers the nickname and user information on the IRC network.
     *
     * @param string $nick
     * @param string $realname
     * @param integer $usermode
     * @param string $username
     * @param string $password
     * @return void
     * @access public
     */
    function login($nick, $realname, $usermode = 0, $username = null, $password = null)
    {
        $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: logging in', __FILE__, __LINE__);
        
        $this->_nick = str_replace(' ', '', $nick);
        $this->_realname = $realname;
        
        if ($username !== null) {
            $this->_username = str_replace(' ', '', $username);
        } else {
            $this->_username = str_replace(' ', '', exec('whoami'));
        }
        
        if ($password !== null) {
            $this->_password = $password;
            $this->_send('PASS '.$this->_password, SMARTIRC_CRITICAL);
        }
        
        if (!is_numeric($usermode)) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: login() usermode ('.$usermode.') is not valid, will use 0 instead', __FILE__, __LINE__);
            $usermode = 0;
        }
        
        $this->_send('NICK '.$this->_nick, SMARTIRC_CRITICAL);
        $this->_send('USER '.$this->_username.' '.$usermode.' '.SMARTIRC_UNUSED.' :'.$this->_realname, SMARTIRC_CRITICAL);
    }
    
    // </IRC methods>
    
    /**
     * checks if we or the given user is joined to the specified channel and returns the result
     * ChannelSyncing is required for this.
     *
     * @see setChannelSyncing
     * @param string $channel
     * @param string $nickname
     * @return boolean
     * @access public
     */
    function isJoined($channel, $nickname = null)
    {
        if ($this->_channelsyncing != true) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isJoined() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
            return false;
        }
        
        if ($nickname === null) {
            $nickname = $this->_nick;
        }
        
        if (isset($this->_channels[strtolower($channel)]->users[strtolower($nickname)])) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Checks if we or the given user is opped on the specified channel and returns the result.
     * ChannelSyncing is required for this.
     *
     * @see setChannelSyncing
     * @param string $channel
     * @param string $nickname
     * @return boolean
     * @access public
     */
    function isOpped($channel, $nickname = null)
    {
        if ($this->_channelsyncing != true) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isOpped() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
            return false;
        }
        
        if ($nickname === null) {
            $nickname = $this->_nick;
        }
        
        if ($this->isJoined($channel, $nickname)) {
            if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->op) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Checks if we or the given user is voiced on the specified channel and returns the result.
     * ChannelSyncing is required for this.
     *
     * @see setChannelSyncing
     * @param string $channel
     * @param string $nickname
     * @return boolean
     * @access public
     */
    function isVoiced($channel, $nickname = null)
    {
        if ($this->_channelsyncing != true) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isVoiced() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
            return false;
        }
        
        if ($nickname === null) {
            $nickname = $this->_nick;
        }
        
        if ($this->isJoined($channel, $nickname)) {
            if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->voice) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Checks if the hostmask is on the specified channel banned and returns the result.
     * ChannelSyncing is required for this.
     *
     * @see setChannelSyncing
     * @param string $channel
     * @param string $hostmask
     * @return boolean
     * @access public
     */
    function isBanned($channel, $hostmask)
    {
        if ($this->_channelsyncing != true) {
            $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isBanned() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
            return false;
        }
        
        if ($this->isJoined($channel)) {
            $result = array_search($hostmask, $this->_channels[strtolower($channel)]->bans);
            
            if ($result !== false) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * goes into receive mode
     *
     * Goes into receive and idle mode. Only call this if you want to "spawn" the bot.
     * No further lines of PHP code will be processed after this call, only the bot methods!
     *
     * @return boolean
     * @access public
     */
    function listen()
    {
        if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
            $this->_rawreceive();
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * waits for a special message type and puts the answer in $result
     *
     * Creates a special actionhandler for that given TYPE and returns the answer.
     * This will only receive the requested type, immediately quit and disconnect from the IRC server.
     * Made for showing IRC statistics on your homepage, or other IRC related information.
     *
     * @param integer $messagetype see in the documentation 'Message Types'
     * @return array answer from the IRC server for this $messagetype
     * @access public
     */
    function listenFor($messagetype)
    {
        $listenfor = &new Net_SmartIRC_listenfor();
        $this->registerActionhandler($messagetype, '.*', $listenfor, 'handler');
        $this->listen();
        $result = $listenfor->result;
        
        if (isset($listenfor)) {
            unset($listenfor);
        }
        
        return $result;
    }
    
    /**
     * waits for a special message type and puts the answer in $result
     *
     * Creates a special actionhandler for that given TYPE and returns the answer.
     * This will only receive the requested type, immediately quit and disconnect from the IRC server.
     * Made for showing IRC statistics on your homepage, or other IRC related information.
     * This special version of listenFor() stores the whole ircdata object, not just the message!
     *
     * @param integer $messagetype see in the documentation 'Message Types'
     * @return array answer from the IRC server for this $messagetype
     * @access public
     */
    function objListenFor($messagetype)
    {
        $objlistenfor = &new Net_SmartIRC_objListenFor();
        $this->registerActionhandler($messagetype, '.*', $objlistenfor, 'handler');
        $this->listen();
        $result = $objlistenfor->result;
        
        if (isset($objlistenfor)) {
            unset($objlistenfor);
        }

⌨️ 快捷键说明

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