From: Luke Fitzgerald Date: Wed, 16 Jun 2010 00:55:39 +0000 (+0100) Subject: Added Phergie PHP IRC library X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=0b2bbd20aa015f5d9d48c4264f56e13324346b4a;p=quix0rs-gnu-social.git Added Phergie PHP IRC library --- diff --git a/plugins/Irc/extlib/phergie/.gitignore b/plugins/Irc/extlib/phergie/.gitignore new file mode 100644 index 0000000000..553fe8e258 --- /dev/null +++ b/plugins/Irc/extlib/phergie/.gitignore @@ -0,0 +1,2 @@ +Settings.php +*.db diff --git a/plugins/Irc/extlib/phergie/LICENSE b/plugins/Irc/extlib/phergie/LICENSE new file mode 100644 index 0000000000..d7d23420ac --- /dev/null +++ b/plugins/Irc/extlib/phergie/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2010, Phergie Development Team +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +Neither the name of the Phergie Development Team nor the names of its +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/Irc/extlib/phergie/Phergie/Autoload.php b/plugins/Irc/extlib/phergie/Phergie/Autoload.php new file mode 100755 index 0000000000..b03fe2ae10 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Autoload.php @@ -0,0 +1,84 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Autoloader for Phergie classes. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Autoload +{ + /** + * Constructor to add the base Phergie path to the include_path. + * + * @return void + */ + public function __construct() + { + $path = dirname(__FILE__); + $includePath = get_include_path(); + $includePathList = explode(PATH_SEPARATOR, $includePath); + if (!in_array($path, $includePathList)) { + self::addPath($path); + } + } + + /** + * Autoload callback for loading class files. + * + * @param string $class Class to load + * + * @return void + */ + public function load($class) + { + if (substr($class, 0, 8) == 'Phergie_') { + $class = substr($class, 8); + } + include str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; + } + + /** + * Registers an instance of this class as an autoloader. + * + * @return void + */ + public static function registerAutoloader() + { + spl_autoload_register(array(new self, 'load')); + } + + /** + * Add a path to the include path. + * + * @param string $path Path to add + * + * @return void + */ + public static function addPath($path) + { + set_include_path($path . PATH_SEPARATOR . get_include_path()); + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Bot.php b/plugins/Irc/extlib/phergie/Phergie/Bot.php new file mode 100755 index 0000000000..153bd55905 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Bot.php @@ -0,0 +1,390 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Composite class for other components to represent the bot. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Bot +{ + /** + * Current version of Phergie + */ + const VERSION = '2.0.1'; + + /** + * Current driver instance + * + * @var Phergie_Driver_Abstract + */ + protected $driver; + + /** + * Current configuration instance + * + * @var Phergie_Config + */ + protected $config; + + /** + * Current connection handler instance + * + * @var Phergie_Connection_Handler + */ + protected $connections; + + /** + * Current plugin handler instance + * + * @var Phergie_Plugin_Handler + */ + protected $plugins; + + /** + * Current event handler instance + * + * @var Phergie_Event_Handler + */ + protected $events; + + /** + * Current end-user interface instance + * + * @var Phergie_Ui_Abstract + */ + protected $ui; + + /** + * Current processor instance + * + * @var Phergie_Process_Abstract + */ + protected $processor; + + /** + * Returns a driver instance, creating one of the default class if + * none has been set. + * + * @return Phergie_Driver_Abstract + */ + public function getDriver() + { + if (empty($this->driver)) { + // Check if a driver has been defined in the configuration to use + // as the default + $config = $this->getConfig(); + if (isset($config['driver'])) { + $class = 'Phergie_Driver_' . ucfirst($config['driver']); + } else { + // Otherwise default to the Streams driver. + $class = 'Phergie_Driver_Streams'; + } + + $this->driver = new $class; + } + return $this->driver; + } + + /** + * Sets the driver instance to use. + * + * @param Phergie_Driver_Abstract $driver Driver instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setDriver(Phergie_Driver_Abstract $driver) + { + $this->driver = $driver; + return $this; + } + + /** + * Sets the configuration to use. + * + * @param Phergie_Config $config Configuration instance + * + * @return Phergie_Runner_Abstract Provides a fluent interface + */ + public function setConfig(Phergie_Config $config) + { + $this->config = $config; + return $this; + } + + /** + * Returns the entire configuration in use or the value of a specific + * configuration setting. + * + * @param string $index Optional index of a specific configuration + * setting for which the corresponding value should be returned + * @param mixed $default Value to return if no match is found for $index + * + * @return mixed Value corresponding to $index or the entire + * configuration if $index is not specified + */ + public function getConfig($index = null, $default = null) + { + if (empty($this->config)) { + $this->config = new Phergie_Config; + $this->config->read('Settings.php'); + } + if ($index !== null) { + if (isset($this->config[$index])) { + return $this->config[$index]; + } else { + return $default; + } + } + return $this->config; + } + + /** + * Returns a plugin handler instance, creating it if it does not already + * exist and using a default class if none has been set. + * + * @return Phergie_Plugin_Handler + */ + public function getPluginHandler() + { + if (empty($this->plugins)) { + $this->plugins = new Phergie_Plugin_Handler( + $this->getConfig(), + $this->getEventHandler() + ); + } + return $this->plugins; + } + + /** + * Sets the plugin handler instance to use. + * + * @param Phergie_Plugin_Handler $handler Plugin handler instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setPluginHandler(Phergie_Plugin_Handler $handler) + { + $this->plugins = $handler; + return $this; + } + + /** + * Returns an event handler instance, creating it if it does not already + * exist and using a default class if none has been set. + * + * @return Phergie_Event_Handler + */ + public function getEventHandler() + { + if (empty($this->events)) { + $this->events = new Phergie_Event_Handler; + } + return $this->events; + } + + /** + * Sets the event handler instance to use. + * + * @param Phergie_Event_Handler $handler Event handler instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setEventHandler(Phergie_Event_Handler $handler) + { + $this->events = $handler; + return $this; + } + + /** + * Returns a connection handler instance, creating it if it does not + * already exist and using a default class if none has been set. + * + * @return Phergie_Connection_Handler + */ + public function getConnectionHandler() + { + if (empty($this->connections)) { + $this->connections = new Phergie_Connection_Handler; + } + return $this->connections; + } + + /** + * Sets the connection handler instance to use. + * + * @param Phergie_Connection_Handler $handler Connection handler instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setConnectionHandler(Phergie_Connection_Handler $handler) + { + $this->connections = $handler; + return $this; + } + + /** + * Returns an end-user interface instance, creating it if it does not + * already exist and using a default class if none has been set. + * + * @return Phergie_Ui_Abstract + */ + public function getUi() + { + if (empty($this->ui)) { + $this->ui = new Phergie_Ui_Console; + } + return $this->ui; + } + + /** + * Sets the end-user interface instance to use. + * + * @param Phergie_Ui_Abstract $ui End-user interface instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setUi(Phergie_Ui_Abstract $ui) + { + $this->ui = $ui; + return $this; + } + + /** + * Returns a processer instance, creating one if none exists. + * + * @return Phergie_Process_Abstract + */ + public function getProcessor() + { + if (empty($this->processor)) { + $class = 'Phergie_Process_Standard'; + + $type = $this->getConfig('processor'); + if (!empty($type)) { + $class = 'Phergie_Process_' . ucfirst($type); + } + + $this->processor = new $class( + $this, + $this->getConfig('processor.options', array()) + ); + } + return $this->processor; + } + + /** + * Sets the processer instance to use. + * + * @param Phergie_Process_Abstract $processor Processer instance + * + * @return Phergie_Bot Provides a fluent interface + */ + public function setProcessor(Phergie_Process_Abstract $processor) + { + $this->processor = $processor; + return $this; + } + + /** + * Loads plugins into the plugin handler. + * + * @return void + */ + protected function loadPlugins() + { + $config = $this->getConfig(); + $plugins = $this->getPluginHandler(); + $ui = $this->getUi(); + + $plugins->setAutoload($config['plugins.autoload']); + foreach ($config['plugins'] as $name) { + try { + $plugin = $plugins->addPlugin($name); + $ui->onPluginLoad($name); + } catch (Phergie_Plugin_Exception $e) { + $ui->onPluginFailure($name, $e->getMessage()); + if (!empty($plugin)) { + $plugins->removePlugin($plugin); + } + } + } + } + + /** + * Configures and establishes connections to IRC servers. + * + * @return void + */ + protected function loadConnections() + { + $config = $this->getConfig(); + $driver = $this->getDriver(); + $connections = $this->getConnectionHandler(); + $plugins = $this->getPluginHandler(); + $ui = $this->getUi(); + + foreach ($config['connections'] as $data) { + $connection = new Phergie_Connection($data); + $connections->addConnection($connection); + + $ui->onConnect($data['host']); + $driver->setConnection($connection)->doConnect(); + $plugins->setConnection($connection); + $plugins->onConnect(); + } + } + + /** + * Establishes server connections and initiates an execution loop to + * continuously receive and process events. + * + * @return Phergie_Bot Provides a fluent interface + */ + public function run() + { + set_time_limit(0); + + $timezone = $this->getConfig('timezone', 'UTC'); + date_default_timezone_set($timezone); + + $ui = $this->getUi(); + $ui->setEnabled($this->getConfig('ui.enabled')); + + $this->loadPlugins(); + $this->loadConnections(); + + $processor = $this->getProcessor(); + + $connections = $this->getConnectionHandler(); + while (count($connections)) { + $processor->handleEvents(); + } + + $ui->onShutdown(); + + return $this; + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Config.php b/plugins/Irc/extlib/phergie/Phergie/Config.php new file mode 100755 index 0000000000..f011db2365 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Config.php @@ -0,0 +1,170 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Reads from and writes to PHP configuration files and provides access to + * the settings they contain. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Config implements ArrayAccess +{ + /** + * Mapping of configuration file paths to an array of names of settings + * they contain + * + * @var array + */ + protected $files = array(); + + /** + * Mapping of setting names to their current corresponding values + * + * @var array + */ + protected $settings = array(); + + /** + * Includes a specified PHP configuration file and incorporates its + * return value (which should be an associative array) into the current + * configuration settings. + * + * @param string $file Path to the file to read + * + * @return Phergie_Config Provides a fluent interface + * @throws Phergie_Config_Exception + */ + public function read($file) + { + if (!(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' + && file_exists($file)) + && !is_executable($file) + ) { + throw new Phergie_Config_Exception( + 'Path "' . $file . '" does not reference an executable file', + Phergie_Config_Exception::ERR_FILE_NOT_EXECUTABLE + ); + } + + $settings = include $file; + if (!is_array($settings)) { + throw new Phergie_Config_Exception( + 'File "' . $file . '" does not return an array', + Phergie_Config_Exception::ERR_ARRAY_NOT_RETURNED + ); + } + + $this->files[$file] = array_keys($settings); + $this->settings += $settings; + + return $this; + } + + /** + * Writes the values of the current configuration settings back to their + * originating files. + * + * @return Phergie_Config Provides a fluent interface + */ + public function write() + { + foreach ($this->files as $file => &$settings) { + $values = array(); + foreach ($settings as $setting) { + $values[$setting] = $this->settings[$setting]; + } + $source = 'settings[$offset]); + } + + /** + * Returns the value of a configuration setting. + * + * @param string $offset Configuration setting name + * + * @return mixed Configuration setting value or NULL if it is not + * assigned a value + * @see ArrayAccess::offsetGet() + */ + public function offsetGet($offset) + { + if (isset($this->settings[$offset])) { + $value = &$this->settings[$offset]; + } else { + $value = null; + } + + return $value; + } + + /** + * Sets the value of a configuration setting. + * + * @param string $offset Configuration setting name + * @param mixed $value New setting value + * + * @return void + * @see ArrayAccess::offsetSet() + */ + public function offsetSet($offset, $value) + { + $this->settings[$offset] = $value; + } + + /** + * Removes the value set for a configuration setting. + * + * @param string $offset Configuration setting name + * + * @return void + * @see ArrayAccess::offsetUnset() + */ + public function offsetUnset($offset) + { + unset($this->settings[$offset]); + + foreach ($this->files as $file => $settings) { + $key = array_search($offset, $settings); + if ($key !== false) { + unset($this->files[$file][$key]); + } + } + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Config/Exception.php b/plugins/Irc/extlib/phergie/Phergie/Config/Exception.php new file mode 100644 index 0000000000..fb646c10c1 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Config/Exception.php @@ -0,0 +1,44 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Exception related to configuration. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Config_Exception extends Phergie_Exception +{ + /** + * Error indicating that an attempt was made to read a configuration + * file that could not be executed + */ + const ERR_FILE_NOT_EXECUTABLE = 1; + + /** + * Error indicating that a read configuration file does not return an + * array + */ + const ERR_ARRAY_NOT_RETURNED = 2; +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Connection.php b/plugins/Irc/extlib/phergie/Phergie/Connection.php new file mode 100755 index 0000000000..80f91e8da5 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Connection.php @@ -0,0 +1,359 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Data structure for connection metadata. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Connection +{ + /** + * Host to which the client will connect + * + * @var string + */ + protected $host; + + /** + * Port on which the client will connect, defaults to the standard IRC + * port + * + * @var int + */ + protected $port; + + /** + * Transport for the connection, defaults to tcp but can be set to ssl + * or variations thereof to connect over SSL + * + * @var string + */ + protected $transport; + + /** + * Nick that the client will use + * + * @var string + */ + protected $nick; + + /** + * Username that the client will use + * + * @var string + */ + protected $username; + + /** + * Realname that the client will use + * + * @var string + */ + protected $realname; + + /** + * Password that the client will use + * + * @var string + */ + protected $password; + + /** + * Hostmask for the connection + * + * @var Phergie_Hostmask + */ + protected $hostmask; + + /** + * Constructor to initialize instance properties. + * + * @param array $options Optional associative array of property values + * to initialize + * + * @return void + */ + public function __construct(array $options = array()) + { + $this->transport = 'tcp'; + + $this->setOptions($options); + } + + /** + * Emits an error related to a required connection setting does not have + * value set for it. + * + * @param string $setting Name of the setting + * + * @return void + */ + protected function checkSetting($setting) + { + if (empty($this->$setting)) { + throw new Phergie_Connection_Exception( + 'Required connection setting "' . $setting . '" missing', + Phergie_Connection_Exception::ERR_REQUIRED_SETTING_MISSING + ); + } + } + + /** + * Returns a hostmask that uniquely identifies the connection. + * + * @return string + */ + public function getHostmask() + { + if (empty($this->hostmask)) { + $this->hostmask = new Phergie_Hostmask( + $this->nick, + $this->username, + $this->host + ); + } + + return $this->hostmask; + } + + /** + * Sets the host to which the client will connect. + * + * @param string $host Hostname + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setHost($host) + { + if (empty($this->host)) { + $this->host = (string) $host; + } + + return $this; + } + + /** + * Returns the host to which the client will connect if it is set or + * emits an error if it is not set. + * + * @return string + */ + public function getHost() + { + $this->checkSetting('host'); + + return $this->host; + } + + /** + * Sets the port on which the client will connect. + * + * @param int $port Port + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setPort($port) + { + if (empty($this->port)) { + $this->port = (int) $port; + } + + return $this; + } + + /** + * Returns the port on which the client will connect. + * + * @return int + */ + public function getPort() + { + if (empty($this->port)) { + $this->port = 6667; + } + + return $this->port; + } + + /** + * Sets the transport for the connection to use. + * + * @param string $transport Transport (ex: tcp, ssl, etc.) + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setTransport($transport) + { + $this->transport = (string) $transport; + + if (!in_array($this->transport, stream_get_transports())) { + throw new Phergie_Connection_Exception( + 'Transport ' . $this->transport . ' is not supported', + Phergie_Connection_Exception::TRANSPORT_NOT_SUPPORTED + ); + } + + return $this; + } + + /** + * Returns the transport in use by the connection. + * + * @return string Transport (ex: tcp, ssl, etc.) + */ + public function getTransport() + { + return $this->transport; + } + + /** + * Sets the nick that the client will use. + * + * @param string $nick Nickname + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setNick($nick) + { + if (empty($this->nick)) { + $this->nick = (string) $nick; + } + + return $this; + } + + /** + * Returns the nick that the client will use. + * + * @return string + */ + public function getNick() + { + $this->checkSetting('nick'); + + return $this->nick; + } + + /** + * Sets the username that the client will use. + * + * @param string $username Username + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setUsername($username) + { + if (empty($this->username)) { + $this->username = (string) $username; + } + + return $this; + } + + /** + * Returns the username that the client will use. + * + * @return string + */ + public function getUsername() + { + $this->checkSetting('username'); + + return $this->username; + } + + /** + * Sets the realname that the client will use. + * + * @param string $realname Real name + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setRealname($realname) + { + if (empty($this->realname)) { + $this->realname = (string) $realname; + } + + return $this; + } + + /** + * Returns the realname that the client will use. + * + * @return string + */ + public function getRealname() + { + $this->checkSetting('realname'); + + return $this->realname; + } + + /** + * Sets the password that the client will use. + * + * @param string $password Password + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setPassword($password) + { + if (empty($this->password)) { + $this->password = (string) $password; + } + + return $this; + } + + /** + * Returns the password that the client will use. + * + * @return string + */ + public function getPassword() + { + return $this->password; + } + + /** + * Sets multiple connection settings using an array. + * + * @param array $options Associative array of setting names mapped to + * corresponding values + * + * @return Phergie_Connection Provides a fluent interface + */ + public function setOptions(array $options) + { + foreach ($options as $option => $value) { + $method = 'set' . ucfirst($option); + if (method_exists($this, $method)) { + $this->$method($value); + } + } + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Connection/Exception.php b/plugins/Irc/extlib/phergie/Phergie/Connection/Exception.php new file mode 100644 index 0000000000..a750e1d860 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Connection/Exception.php @@ -0,0 +1,44 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Exception related to a connection to an IRC server. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Connection_Exception extends Phergie_Exception +{ + /** + * Error indicating that an operation was attempted requiring a value + * for a specific configuration setting, but none was set + */ + const ERR_REQUIRED_SETTING_MISSING = 1; + + /** + * Error indicating that a connection is configured to use a transport, + * but that transport is not supported by the current PHP installation + */ + const ERR_TRANSPORT_NOT_SUPPORTED = 2; +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Connection/Handler.php b/plugins/Irc/extlib/phergie/Phergie/Connection/Handler.php new file mode 100644 index 0000000000..e9aeddcd3e --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Connection/Handler.php @@ -0,0 +1,130 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Handles connections initiated by the bot. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Connection_Handler implements Countable, IteratorAggregate +{ + /** + * Map of connections indexed by hostmask + * + * @var array + */ + protected $connections; + + /** + * Constructor to initialize storage for connections. + * + * @return void + */ + public function __construct() + { + $this->connections = array(); + } + + /** + * Adds a connection to the connection list. + * + * @param Phergie_Connection $connection Connection to add + * + * @return Phergie_Connection_Handler Provides a fluent interface + */ + public function addConnection(Phergie_Connection $connection) + { + $this->connections[(string) $connection->getHostmask()] = $connection; + return $this; + } + + /** + * Removes a connection from the connection list. + * + * @param Phergie_Connection|string $connection Instance or hostmask for + * the connection to remove + * + * @return Phergie_Connection_Handler Provides a fluent interface + */ + public function removeConnection($connection) + { + if ($connection instanceof Phergie_Connection) { + $hostmask = (string) $connection->getHostmask(); + } elseif (is_string($connection) + && isset($this->connections[$connection])) { + $hostmask = $connection; + } else { + return $this; + } + unset($this->connections[$hostmask]); + return $this; + } + + /** + * Returns the number of connections in the list. + * + * @return int Number of connections + */ + public function count() + { + return count($this->connections); + } + + /** + * Returns an iterator for the connection list. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->connections); + } + + /** + * Returns a list of specified connection objects. + * + * @param array|string $keys One or more hostmasks identifying the + * connections to return + * + * @return array List of Phergie_Connection objects corresponding to the + * specified hostmask(s) + */ + public function getConnections($keys) + { + $connections = array(); + + if (!is_array($keys)) { + $keys = array($keys); + } + + foreach ($keys as $key) { + if (isset($this->connections[$key])) { + $connections[] = $this->connections[$key]; + } + } + + return $connections; + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Driver/Abstract.php b/plugins/Irc/extlib/phergie/Phergie/Driver/Abstract.php new file mode 100755 index 0000000000..62736620d4 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Driver/Abstract.php @@ -0,0 +1,301 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Base class for drivers which handle issuing client commands to the IRC + * server and converting responses into usable data objects. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +abstract class Phergie_Driver_Abstract +{ + /** + * Currently active connection + * + * @var Phergie_Connection + */ + protected $connection; + + /** + * Sets the currently active connection. + * + * @param Phergie_Connection $connection Active connection + * + * @return Phergie_Driver_Abstract Provides a fluent interface + */ + public function setConnection(Phergie_Connection $connection) + { + $this->connection = $connection; + + return $this; + } + + /** + * Returns the currently active connection. + * + * @return Phergie_Connection + * @throws Phergie_Driver_Exception + */ + public function getConnection() + { + if (empty($this->connection)) { + throw new Phergie_Driver_Exception( + 'Operation requires an active connection, but none is set', + Phergie_Driver_Exception::ERR_NO_ACTIVE_CONNECTION + ); + } + + return $this->connection; + } + + /** + * Returns an event if one has been received from the server. + * + * @return Phergie_Event_Interface|null Event instance if an event has + * been received, NULL otherwise + */ + public abstract function getEvent(); + + /** + * Initiates a connection with the server. + * + * @return void + */ + public abstract function doConnect(); + + /** + * Terminates the connection with the server. + * + * @param string $reason Reason for connection termination (optional) + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_1_6 + */ + public abstract function doQuit($reason = null); + + /** + * Joins a channel. + * + * @param string $channels Comma-delimited list of channels to join + * @param string $keys Optional comma-delimited list of channel keys + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_1 + */ + public abstract function doJoin($channels, $keys = null); + + /** + * Leaves a channel. + * + * @param string $channels Comma-delimited list of channels to leave + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_2 + */ + public abstract function doPart($channels); + + /** + * Invites a user to an invite-only channel. + * + * @param string $nick Nick of the user to invite + * @param string $channel Name of the channel + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_7 + */ + public abstract function doInvite($nick, $channel); + + /** + * Obtains a list of nicks of users in specified channels. + * + * @param string $channels Comma-delimited list of one or more channels + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_5 + */ + public abstract function doNames($channels); + + /** + * Obtains a list of channel names and topics. + * + * @param string $channels Comma-delimited list of one or more channels + * to which the response should be restricted + * (optional) + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_6 + */ + public abstract function doList($channels = null); + + /** + * Retrieves or changes a channel topic. + * + * @param string $channel Name of the channel + * @param string $topic New topic to assign (optional) + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_4 + */ + public abstract function doTopic($channel, $topic = null); + + /** + * Retrieves or changes a channel or user mode. + * + * @param string $target Channel name or user nick + * @param string $mode New mode to assign (optional) + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_3 + */ + public abstract function doMode($target, $mode = null); + + /** + * Changes the client nick. + * + * @param string $nick New nick to assign + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_1_2 + */ + public abstract function doNick($nick); + + /** + * Retrieves information about a nick. + * + * @param string $nick Nick + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_5_2 + */ + public abstract function doWhois($nick); + + /** + * Sends a message to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the message to send + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_4_1 + */ + public abstract function doPrivmsg($target, $text); + + /** + * Sends a notice to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the notice to send + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_4_2 + */ + public abstract function doNotice($target, $text); + + /** + * Kicks a user from a channel. + * + * @param string $nick Nick of the user + * @param string $channel Channel name + * @param string $reason Reason for the kick (optional) + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_2_8 + */ + public abstract function doKick($nick, $channel, $reason = null); + + /** + * Responds to a server test of client responsiveness. + * + * @param string $daemon Daemon from which the original request originates + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html#c4_6_3 + */ + public abstract function doPong($daemon); + + /** + * Sends a CTCP ACTION (/me) command to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the action to perform + * + * @return void + * @link http://www.invlogic.com/irc/ctcp.html#4.4 + */ + public abstract function doAction($target, $text); + + /** + * Sends a CTCP PING request to a user. + * + * @param string $nick User nick + * @param string $hash Hash to use in the handshake + * + * @return void + * @link http://www.invlogic.com/irc/ctcp.html#4.2 + */ + public abstract function doPing($nick, $hash); + + /** + * Sends a CTCP VERSION request or response to a user. + * + * @param string $nick User nick + * @param string $version Version string to send for a response + * + * @return void + * @link http://www.invlogic.com/irc/ctcp.html#4.1 + */ + public abstract function doVersion($nick, $version = null); + + /** + * Sends a CTCP TIME request to a user. + * + * @param string $nick User nick + * @param string $time Time string to send for a response + * + * @return void + * @link http://www.invlogic.com/irc/ctcp.html#4.6 + */ + public abstract function doTime($nick, $time = null); + + /** + * Sends a CTCP FINGER request to a user. + * + * @param string $nick User nick + * @param string $finger Finger string to send for a response + * + * @return void + * @link http://www.irchelp.org/irchelp/rfc/ctcpspec.html + */ + public abstract function doFinger($nick, $finger = null); + + /** + * Sends a raw command to the server. + * + * @param string $command Command string to send + * + * @return void + */ + public abstract function doRaw($command); +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Driver/Exception.php b/plugins/Irc/extlib/phergie/Phergie/Driver/Exception.php new file mode 100755 index 0000000000..c405522292 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Driver/Exception.php @@ -0,0 +1,49 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Exception related to driver operations. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Driver_Exception extends Phergie_Exception +{ + /** + * Error indicating that an operation was requested requiring an active + * connection before one had been set + */ + const ERR_NO_ACTIVE_CONNECTION = 1; + + /** + * Error indicating that an operation was requested requiring an active + * connection where one had been set but not initiated + */ + const ERR_NO_INITIATED_CONNECTION = 2; + + /** + * Error indicating that an attempt to initiate a connection failed + */ + const ERR_CONNECTION_ATTEMPT_FAILED = 3; +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Driver/Streams.php b/plugins/Irc/extlib/phergie/Phergie/Driver/Streams.php new file mode 100755 index 0000000000..8fe53aaa2f --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Driver/Streams.php @@ -0,0 +1,696 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Driver that uses the sockets wrapper of the streams extension for + * communicating with the server and handles formatting and parsing of + * events using PHP. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Driver_Streams extends Phergie_Driver_Abstract +{ + /** + * Socket handlers + * + * @var array + */ + protected $sockets = array(); + + /** + * Reference to the currently active socket handler + * + * @var resource + */ + protected $socket; + + /** + * Amount of time in seconds to wait to receive an event each time the + * socket is polled + * + * @var float + */ + protected $timeout = 0.1; + + /** + * Handles construction of command strings and their transmission to the + * server. + * + * @param string $command Command to send + * @param string|array $args Optional string or array of sequential + * arguments + * + * @return string Command string that was sent + * @throws Phergie_Driver_Exception + */ + protected function send($command, $args = '') + { + // Require an open socket connection to continue + if (empty($this->socket)) { + throw new Phergie_Driver_Exception( + 'doConnect() must be called first', + Phergie_Driver_Exception::ERR_NO_INITIATED_CONNECTION + ); + } + + // Add the command + $buffer = strtoupper($command); + + // Add arguments + if (!empty($args)) { + + // Apply formatting if arguments are passed in as an array + if (is_array($args)) { + $end = count($args) - 1; + $args[$end] = ':' . $args[$end]; + $args = implode(' ', $args); + } + + $buffer .= ' ' . $args; + } + + // Transmit the command over the socket connection + fwrite($this->socket, $buffer . "\r\n"); + + // Return the command string that was transmitted + return $buffer; + } + + /** + * Overrides the parent class to set the currently active socket handler + * when the active connection is changed. + * + * @param Phergie_Connection $connection Active connection + * + * @return Phergie_Driver_Streams Provides a fluent interface + */ + public function setConnection(Phergie_Connection $connection) + { + // Set the active socket handler + $hostmask = (string) $connection->getHostmask(); + if (!empty($this->sockets[$hostmask])) { + $this->socket = $this->sockets[$hostmask]; + } + + // Set the active connection + return parent::setConnection($connection); + } + + /** + * Returns a list of hostmasks corresponding to sockets with data to read. + * + * @param int $sec Length of time to wait for new data (seconds) + * @param int $usec Length of time to wait for new data (microseconds) + * + * @return array List of hostmasks or an empty array if none were found + * to have data to read + */ + public function getActiveReadSockets($sec = 0, $usec = 200000) + { + $read = $this->sockets; + $write = null; + $error = null; + $active = array(); + + if (count($this->sockets) > 0) { + $number = stream_select($read, $write, $error, $sec, $usec); + if ($number > 0) { + foreach ($read as $item) { + $active[] = array_search($item, $this->sockets); + } + } + } + + return $active; + } + + /** + * Sets the amount of time to wait for a new event each time the socket + * is polled. + * + * @param float $timeout Amount of time in seconds + * + * @return Phergie_Driver_Streams Provides a fluent interface + */ + public function setTimeout($timeout) + { + $timeout = (float) $timeout; + if ($timeout) { + $this->timeout = $timeout; + } + return $this; + } + + /** + * Returns the amount of time to wait for a new event each time the + * socket is polled. + * + * @return float Amount of time in seconds + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Supporting method to parse event argument strings where the last + * argument may contain a colon. + * + * @param string $args Argument string to parse + * @param int $count Optional maximum number of arguments + * + * @return array Array of argument values + */ + protected function parseArguments($args, $count = -1) + { + return preg_split('/ :?/S', $args, $count); + } + + /** + * Listens for an event on the current connection. + * + * @return Phergie_Event_Interface|null Event instance if an event was + * received, NULL otherwise + */ + public function getEvent() + { + // Check for a new event on the current connection + $buffer = fgets($this->socket, 512); + + // If no new event was found, return NULL + if (empty($buffer)) { + return null; + } + + // Strip the trailing newline from the buffer + $buffer = rtrim($buffer); + + // If the event is from the server... + if (substr($buffer, 0, 1) != ':') { + + // Parse the command and arguments + list($cmd, $args) = array_pad(explode(' ', $buffer, 2), 2, null); + + } else { + // If the event could be from the server or a user... + + // Parse the server hostname or user hostmask, command, and arguments + list($prefix, $cmd, $args) + = array_pad(explode(' ', ltrim($buffer, ':'), 3), 3, null); + if (strpos($prefix, '@') !== false) { + $hostmask = Phergie_Hostmask::fromString($prefix); + } + } + + // Parse the event arguments depending on the event type + $cmd = strtolower($cmd); + switch ($cmd) { + case 'names': + case 'nick': + case 'quit': + case 'ping': + case 'join': + case 'error': + $args = array(ltrim($args, ':')); + break; + + case 'privmsg': + case 'notice': + $ctcp = substr(strstr($args, ':'), 1); + if (substr($ctcp, 0, 1) === "\x01" && substr($ctcp, -1) === "\x01") { + $ctcp = substr($ctcp, 1, -1); + $reply = ($cmd == 'notice'); + list($cmd, $args) = array_pad(explode(' ', $ctcp, 2), 2, null); + $cmd = strtolower($cmd); + switch ($cmd) { + case 'version': + case 'time': + case 'finger': + if ($reply) { + $args = $ctcp; + } + break; + case 'ping': + if ($reply) { + $cmd .= 'Response'; + } else { + $cmd = 'ctcpPing'; + } + break; + case 'action': + $args = array($this->getConnection()->getNick(), $args); + break; + + default: + $cmd = 'ctcp'; + if ($reply) { + $cmd .= 'Response'; + } + $args = array($this->getConnection()->getNick(), $ctcp); + break; + } + } else { + $args = $this->parseArguments($args, 2); + } + break; + + case 'oper': + case 'topic': + case 'mode': + $args = $this->parseArguments($args); + break; + + case 'part': + case 'kill': + case 'invite': + $args = $this->parseArguments($args, 2); + break; + + case 'kick': + $args = $this->parseArguments($args, 3); + break; + + // Remove the target from responses + default: + $args = substr($args, strpos($args, ' ') + 1); + break; + } + + // Create, populate, and return an event object + if (ctype_digit($cmd)) { + $event = new Phergie_Event_Response; + $event + ->setCode($cmd) + ->setDescription($args); + } else { + $event = new Phergie_Event_Request; + $event + ->setType($cmd) + ->setArguments($args); + if (isset($hostmask)) { + $event->setHostmask($hostmask); + } + } + $event->setRawData($buffer); + return $event; + } + + /** + * Initiates a connection with the server. + * + * @return void + */ + public function doConnect() + { + // Listen for input indefinitely + set_time_limit(0); + + // Get connection information + $connection = $this->getConnection(); + $hostname = $connection->getHost(); + $port = $connection->getPort(); + $password = $connection->getPassword(); + $username = $connection->getUsername(); + $nick = $connection->getNick(); + $realname = $connection->getRealname(); + $transport = $connection->getTransport(); + + // Establish and configure the socket connection + $remote = $transport . '://' . $hostname . ':' . $port; + $this->socket = @stream_socket_client($remote, $errno, $errstr); + if (!$this->socket) { + throw new Phergie_Driver_Exception( + 'Unable to connect: socket error ' . $errno . ' ' . $errstr, + Phergie_Driver_Exception::ERR_CONNECTION_ATTEMPT_FAILED + ); + } + + $seconds = (int) $this->timeout; + $microseconds = ($this->timeout - $seconds) * 1000000; + stream_set_timeout($this->socket, $seconds, $microseconds); + + // Send the password if one is specified + if (!empty($password)) { + $this->send('PASS', $password); + } + + // Send user information + $this->send( + 'USER', + array( + $username, + $hostname, + $hostname, + $realname + ) + ); + + $this->send('NICK', $nick); + + // Add the socket handler to the internal array for socket handlers + $this->sockets[(string) $connection->getHostmask()] = $this->socket; + } + + /** + * Terminates the connection with the server. + * + * @param string $reason Reason for connection termination (optional) + * + * @return void + */ + public function doQuit($reason = null) + { + // Send a QUIT command to the server + $this->send('QUIT', $reason); + + // Terminate the socket connection + fclose($this->socket); + + // Remove the socket from the internal socket list + unset($this->sockets[(string) $this->getConnection()->getHostmask()]); + } + + /** + * Joins a channel. + * + * @param string $channels Comma-delimited list of channels to join + * @param string $keys Optional comma-delimited list of channel keys + * + * @return void + */ + public function doJoin($channels, $keys = null) + { + $args = array($channels); + + if (!empty($keys)) { + $args[] = $keys; + } + + $this->send('JOIN', $args); + } + + /** + * Leaves a channel. + * + * @param string $channels Comma-delimited list of channels to leave + * + * @return void + */ + public function doPart($channels) + { + $this->send('PART', $channels); + } + + /** + * Invites a user to an invite-only channel. + * + * @param string $nick Nick of the user to invite + * @param string $channel Name of the channel + * + * @return void + */ + public function doInvite($nick, $channel) + { + $this->send('INVITE', array($nick, $channel)); + } + + /** + * Obtains a list of nicks of usrs in currently joined channels. + * + * @param string $channels Comma-delimited list of one or more channels + * + * @return void + */ + public function doNames($channels) + { + $this->send('NAMES', $channels); + } + + /** + * Obtains a list of channel names and topics. + * + * @param string $channels Comma-delimited list of one or more channels + * to which the response should be restricted + * (optional) + * + * @return void + */ + public function doList($channels = null) + { + $this->send('LIST', $channels); + } + + /** + * Retrieves or changes a channel topic. + * + * @param string $channel Name of the channel + * @param string $topic New topic to assign (optional) + * + * @return void + */ + public function doTopic($channel, $topic = null) + { + $args = array($channel); + + if (!empty($topic)) { + $args[] = $topic; + } + + $this->send('TOPIC', $args); + } + + /** + * Retrieves or changes a channel or user mode. + * + * @param string $target Channel name or user nick + * @param string $mode New mode to assign (optional) + * + * @return void + */ + public function doMode($target, $mode = null) + { + $args = array($target); + + if (!empty($mode)) { + $args[] = $mode; + } + + $this->send('MODE', $args); + } + + /** + * Changes the client nick. + * + * @param string $nick New nick to assign + * + * @return void + */ + public function doNick($nick) + { + $this->send('NICK', $nick); + } + + /** + * Retrieves information about a nick. + * + * @param string $nick Nick + * + * @return void + */ + public function doWhois($nick) + { + $this->send('WHOIS', $nick); + } + + /** + * Sends a message to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the message to send + * + * @return void + */ + public function doPrivmsg($target, $text) + { + $this->send('PRIVMSG', array($target, $text)); + } + + /** + * Sends a notice to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the notice to send + * + * @return void + */ + public function doNotice($target, $text) + { + $this->send('NOTICE', array($target, $text)); + } + + /** + * Kicks a user from a channel. + * + * @param string $nick Nick of the user + * @param string $channel Channel name + * @param string $reason Reason for the kick (optional) + * + * @return void + */ + public function doKick($nick, $channel, $reason = null) + { + $args = array($nick, $channel); + + if (!empty($reason)) { + $args[] = $response; + } + + $this->send('KICK', $args); + } + + /** + * Responds to a server test of client responsiveness. + * + * @param string $daemon Daemon from which the original request originates + * + * @return void + */ + public function doPong($daemon) + { + $this->send('PONG', $daemon); + } + + /** + * Sends a CTCP ACTION (/me) command to a nick or channel. + * + * @param string $target Channel name or user nick + * @param string $text Text of the action to perform + * + * @return void + */ + public function doAction($target, $text) + { + $buffer = rtrim('ACTION ' . $text); + + $this->doPrivmsg($target, chr(1) . $buffer . chr(1)); + } + + /** + * Sends a CTCP response to a user. + * + * @param string $nick User nick + * @param string $command Command to send + * @param string|array $args String or array of sequential arguments + * (optional) + * + * @return void + */ + protected function doCtcp($nick, $command, $args = null) + { + if (is_array($args)) { + $args = implode(' ', $args); + } + + $buffer = rtrim(strtoupper($command) . ' ' . $args); + + $this->doNotice($nick, chr(1) . $buffer . chr(1)); + } + + /** + * Sends a CTCP PING request or response (they are identical) to a user. + * + * @param string $nick User nick + * @param string $hash Hash to use in the handshake + * + * @return void + */ + public function doPing($nick, $hash) + { + $this->doCtcp($nick, 'PING', $hash); + } + + /** + * Sends a CTCP VERSION request or response to a user. + * + * @param string $nick User nick + * @param string $version Version string to send for a response + * + * @return void + */ + public function doVersion($nick, $version = null) + { + if ($version) { + $this->doCtcp($nick, 'VERSION', $version); + } else { + $this->doCtcp($nick, 'VERSION'); + } + } + + /** + * Sends a CTCP TIME request to a user. + * + * @param string $nick User nick + * @param string $time Time string to send for a response + * + * @return void + */ + public function doTime($nick, $time = null) + { + if ($time) { + $this->doCtcp($nick, 'TIME', $time); + } else { + $this->doCtcp($nick, 'TIME'); + } + } + + /** + * Sends a CTCP FINGER request to a user. + * + * @param string $nick User nick + * @param string $finger Finger string to send for a response + * + * @return void + */ + public function doFinger($nick, $finger = null) + { + if ($finger) { + $this->doCtcp($nick, 'FINGER', $finger); + } else { + $this->doCtcp($nick, 'FINGER'); + } + } + + /** + * Sends a raw command to the server. + * + * @param string $command Command string to send + * + * @return void + */ + public function doRaw($command) + { + $this->send('RAW', $command); + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Abstract.php b/plugins/Irc/extlib/phergie/Phergie/Event/Abstract.php new file mode 100644 index 0000000000..54b035dc03 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Abstract.php @@ -0,0 +1,62 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Base class for events. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +abstract class Phergie_Event_Abstract +{ + /** + * Event type, used for determining the callback to execute in response + * + * @var string + */ + protected $type; + + /** + * Returns the event type. + * + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Sets the event type. + * + * @param string $type Event type + * + * @return Phergie_Event_Abstract Implements a fluent interface + */ + public function setType($type) + { + $this->type = (string) $type; + return $this; + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Command.php b/plugins/Irc/extlib/phergie/Phergie/Event/Command.php new file mode 100644 index 0000000000..5940636ba7 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Command.php @@ -0,0 +1,62 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Event originating from a plugin for the bot. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Event_Command extends Phergie_Event_Request +{ + /** + * Reference to the plugin instance that created the event + * + * @var Phergie_Plugin_Abstract + */ + protected $plugin; + + /** + * Stores a reference to the plugin instance that created the event. + * + * @param Phergie_Plugin_Abstract $plugin Plugin instance + * + * @return Phergie_Event_Command Provides a fluent interface + */ + public function setPlugin(Phergie_Plugin_Abstract $plugin) + { + $this->plugin = $plugin; + return $this; + } + + /** + * Returns a reference to the plugin instance that created the event. + * + * @return Phergie_Plugin_Abstract + */ + public function getPlugin() + { + return $this->plugin; + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Exception.php b/plugins/Irc/extlib/phergie/Phergie/Event/Exception.php new file mode 100644 index 0000000000..6b094a810c --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Exception.php @@ -0,0 +1,38 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Exception related to outgoing events. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Event_Exception extends Phergie_Exception +{ + /** + * Error indicating that an attempt was made to create an event of an + * unknown type + */ + const ERR_UNKNOWN_EVENT_TYPE = 1; +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Handler.php b/plugins/Irc/extlib/phergie/Phergie/Event/Handler.php new file mode 100644 index 0000000000..7df1fca35a --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Handler.php @@ -0,0 +1,174 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Handles events initiated by plugins. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ +class Phergie_Event_Handler implements IteratorAggregate, Countable +{ + /** + * Current queue of events + * + * @var array + */ + protected $events; + + /** + * Constructor to initialize the event queue. + * + * @return void + */ + public function __construct() + { + $this->events = array(); + } + + /** + * Adds an event to the queue. + * + * @param Phergie_Plugin_Abstract $plugin Plugin originating the event + * @param string $type Event type, corresponding to a + * Phergie_Event_Command::TYPE_* constant + * @param array $args Optional event arguments + * + * @return Phergie_Event_Handler Provides a fluent interface + */ + public function addEvent(Phergie_Plugin_Abstract $plugin, $type, + array $args = array() + ) { + if (!defined('Phergie_Event_Command::TYPE_' . strtoupper($type))) { + throw new Phergie_Event_Exception( + 'Unknown event type "' . $type . '"', + Phergie_Event_Exception::ERR_UNKNOWN_EVENT_TYPE + ); + } + + $event = new Phergie_Event_Command; + $event + ->setPlugin($plugin) + ->setType($type) + ->setArguments($args); + + $this->events[] = $event; + + return $this; + } + + /** + * Returns the current event queue. + * + * @return array Enumerated array of Phergie_Event_Command objects + */ + public function getEvents() + { + return $this->events; + } + + /** + * Clears the event queue. + * + * @return Phergie_Event_Handler Provides a fluent interface + */ + public function clearEvents() + { + $this->events = array(); + return $this; + } + + /** + * Replaces the current event queue with a given queue of events. + * + * @param array $events Ordered list of objects of the class + * Phergie_Event_Command + * + * @return Phergie_Event_Handler Provides a fluent interface + */ + public function replaceEvents(array $events) + { + $this->events = $events; + return $this; + } + + /** + * Returns whether an event of the given type exists in the queue. + * + * @param string $type Event type from Phergie_Event_Request::TYPE_* + * constants + * + * @return bool TRUE if an event of the specified type exists in the + * queue, FALSE otherwise + */ + public function hasEventOfType($type) + { + foreach ($this->events as $event) { + if ($event->getType() == $type) { + return true; + } + } + return false; + } + + /** + * Returns a list of events of a specified type. + * + * @param string $type Event type from Phergie_Event_Request::TYPE_* + * constants + * + * @return array Array containing event instances of the specified type + * or an empty array if no such events were found + */ + public function getEventsOfType($type) + { + $events = array(); + foreach ($this->events as $event) { + if ($event->getType() == $type) { + $events[] = $event; + } + } + return $events; + } + + /** + * Returns an iterator for the current event queue. + * + * @return ArrayIterator + */ + public function getIterator() + { + return new ArrayIterator($this->events); + } + + /** + * Returns the number of events in the event queue + * + * @return int number of queued events + */ + public function count() + { + return count($this->events); + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Request.php b/plugins/Irc/extlib/phergie/Phergie/Event/Request.php new file mode 100755 index 0000000000..a559d9dbe5 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Request.php @@ -0,0 +1,450 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Autonomous event originating from a user or the server. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + * @link http://www.irchelp.org/irchelp/rfc/chapter4.html + */ +class Phergie_Event_Request + extends Phergie_Event_Abstract + implements ArrayAccess +{ + /** + * Nick message event type + */ + const TYPE_NICK = 'nick'; + + /** + * Whois message event type + */ + const TYPE_WHOIS = 'whois'; + + /** + * Quit command event type + */ + const TYPE_QUIT = 'quit'; + + /** + * Join message event type + */ + const TYPE_JOIN = 'join'; + + /** + * Kick message event type + */ + const TYPE_KICK = 'kick'; + + /** + * Part message event type + */ + const TYPE_PART = 'part'; + + /** + * Invite message event type + */ + const TYPE_INVITE = 'invite'; + + /** + * Mode message event type + */ + const TYPE_MODE = 'mode'; + + /** + * Topic message event type + */ + const TYPE_TOPIC = 'topic'; + + /** + * Private message command event type + */ + const TYPE_PRIVMSG = 'privmsg'; + + /** + * Notice message event type + */ + const TYPE_NOTICE = 'notice'; + + /** + * Pong message event type + */ + const TYPE_PONG = 'pong'; + + /** + * CTCP ACTION command event type + */ + const TYPE_ACTION = 'action'; + + /** + * CTCP PING command event type + */ + const TYPE_PING = 'ping'; + + /** + * CTCP TIME command event type + */ + const TYPE_TIME = 'time'; + + /** + * CTCP VERSION command event type + */ + const TYPE_VERSION = 'version'; + + /** + * RAW message event type + */ + const TYPE_RAW = 'raw'; + + /** + * Mapping of event types to their named parameters + * + * @var array + */ + protected static $map = array( + + self::TYPE_QUIT => array( + 'message' => 0 + ), + + self::TYPE_JOIN => array( + 'channel' => 0 + ), + + self::TYPE_KICK => array( + 'channel' => 0, + 'user' => 1, + 'comment' => 2 + ), + + self::TYPE_PART => array( + 'channel' => 0, + 'message' => 1 + ), + + self::TYPE_INVITE => array( + 'nickname' => 0, + 'channel' => 1 + ), + + self::TYPE_MODE => array( + 'target' => 0, + 'mode' => 1, + 'limit' => 2, + 'user' => 3, + 'banmask' => 4 + ), + + self::TYPE_TOPIC => array( + 'channel' => 0, + 'topic' => 1 + ), + + self::TYPE_PRIVMSG => array( + 'receiver' => 0, + 'text' => 1 + ), + + self::TYPE_NOTICE => array( + 'nickname' => 0, + 'text' => 1 + ), + + self::TYPE_ACTION => array( + 'target' => 0, + 'action' => 1 + ), + + self::TYPE_RAW => array( + 'message' => 0 + ) + + ); + + /** + * Hostmask representing the originating user, if applicable + * + * @var Phergie_Hostmask + */ + protected $hostmask; + + /** + * Arguments included with the message + * + * @var array + */ + protected $arguments; + + /** + * Raw data sent by the server + * + * @var string + */ + protected $rawData; + + /** + * Sets the hostmask representing the originating user. + * + * @param Phergie_Hostmask $hostmask User hostmask + * + * @return Phergie_Event_Request Provides a fluent interface + */ + public function setHostmask(Phergie_Hostmask $hostmask) + { + $this->hostmask = $hostmask; + return $this; + } + + /** + * Returns the hostmask representing the originating user. + * + * @return Phergie_Event_Request|null Hostmask or NULL if none was set + */ + public function getHostmask() + { + return $this->hostmask; + } + + /** + * Sets the arguments for the request. + * + * @param array $arguments Request arguments + * + * @return Phergie_Event_Request Provides a fluent interface + */ + public function setArguments($arguments) + { + $this->arguments = $arguments; + return $this; + } + + /** + * Returns the arguments for the request. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Resolves an argument specification to an integer position. + * + * @param mixed $argument Integer position (starting from 0) or the + * equivalent string name of the argument from self::$map + * + * @return int|null Integer position of the argument or NULL if no + * corresponding argument was found + */ + protected function resolveArgument($argument) + { + if (isset($this->arguments[$argument])) { + return $argument; + } else { + $argument = strtolower($argument); + if (isset(self::$map[$this->type][$argument]) + && isset($this->arguments[self::$map[$this->type][$argument]]) + ) { + return self::$map[$this->type][$argument]; + } + } + return null; + } + + /** + * Returns a single specified argument for the request. + * + * @param mixed $argument Integer position (starting from 0) or the + * equivalent string name of the argument from self::$map + * + * @return string|null Argument value or NULL if none is set + */ + public function getArgument($argument) + { + $argument = $this->resolveArgument($argument); + if ($argument !== null) { + return $this->arguments[$argument]; + } + return null; + } + + /** + * Sets the raw buffer for the event. + * + * @param string $buffer Raw event buffer + * + * @return Phergie_Event_Request Provides a fluent interface + */ + public function setRawData($buffer) + { + $this->rawData = $buffer; + return $this; + } + + /** + * Returns the raw buffer sent from the server for the event. + * + * @return string + */ + public function getRawData() + { + return $this->rawData; + } + + /** + * Returns the nick of the user who originated the event. + * + * @return string + */ + public function getNick() + { + return $this->hostmask->getNick(); + } + + /** + * Returns the channel name if the event occurred in a channel or the + * user nick if the event was a private message directed at the bot by a + * user. + * + * @return string + */ + public function getSource() + { + if (substr($this->arguments[0], 0, 1) == '#') { + return $this->arguments[0]; + } + return $this->hostmask->getNick(); + } + + /** + * Returns whether or not the event occurred within a channel. + * + * @return TRUE if the event is in a channel, FALSE otherwise + */ + public function isInChannel() + { + return (substr($this->getSource(), 0, 1) == '#'); + } + + /** + * Returns whether or not the event originated from a user. + * + * @return TRUE if the event is from a user, FALSE otherwise + */ + public function isFromUser() + { + if (empty($this->hostmask)) { + return false; + } + $username = $this->hostmask->getUsername(); + return !empty($username); + } + + /** + * Returns whether or not the event originated from the server. + * + * @return TRUE if the event is from the server, FALSE otherwise + */ + public function isFromServer() + { + $username = $this->hostmask->getUsername(); + return empty($username); + } + + /** + * Provides access to named parameters via virtual "getter" methods. + * + * @param string $name Name of the method called + * @param array $arguments Arguments passed to the method (should always + * be empty) + * + * @return mixed Method return value + */ + public function __call($name, array $arguments) + { + if (!count($arguments) && substr($name, 0, 3) == 'get') { + return $this->getArgument(substr($name, 3)); + } + } + + /** + * Checks to see if an event argument is assigned a value. + * + * @param string|int $offset Argument name or position beginning from 0 + * + * @return bool TRUE if the argument has a value, FALSE otherwise + * @see ArrayAccess::offsetExists() + */ + public function offsetExists($offset) + { + return ($this->resolveArgument($offset) !== null); + } + + /** + * Returns the value of an event argument. + * + * @param string|int $offset Argument name or position beginning from 0 + * + * @return string|null Argument value or NULL if none is set + * @see ArrayAccess::offsetGet() + */ + public function offsetGet($offset) + { + return $this->getArgument($offset); + } + + /** + * Sets the value of an event argument. + * + * @param string|int $offset Argument name or position beginning from 0 + * @param string $value New argument value + * + * @return void + * @see ArrayAccess::offsetSet() + */ + public function offsetSet($offset, $value) + { + $offset = $this->resolveArgument($offset); + if ($offset !== null) { + $this->arguments[$offset] = $value; + } + } + + /** + * Removes the value set for an event argument. + * + * @param string|int $offset Argument name or position beginning from 0 + * + * @return void + * @see ArrayAccess::offsetUnset() + */ + public function offsetUnset($offset) + { + if ($offset = $this->resolveArgument($offset)) { + unset($this->arguments[$offset]); + } + } +} diff --git a/plugins/Irc/extlib/phergie/Phergie/Event/Response.php b/plugins/Irc/extlib/phergie/Phergie/Event/Response.php new file mode 100755 index 0000000000..097e2535e8 --- /dev/null +++ b/plugins/Irc/extlib/phergie/Phergie/Event/Response.php @@ -0,0 +1,953 @@ + + * @copyright 2008-2010 Phergie Development Team (http://phergie.org) + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + */ + +/** + * Event originating from the server in response to an event sent by the + * current client. + * + * @category Phergie + * @package Phergie + * @author Phergie Development Team + * @license http://phergie.org/license New BSD License + * @link http://pear.phergie.org/package/Phergie + * @link http://www.irchelp.org/irchelp/rfc/chapter6.html + */ +class Phergie_Event_Response extends Phergie_Event_Abstract +{ + /** + * No such nick/channel + * + * Used to indicate the nickname parameter supplied to a command is currently + * unused. + */ + const ERR_NOSUCHNICK = '401'; + + /** + * No such server + * + * Used to indicate the server name given currently doesn't exist. + */ + const ERR_NOSUCHSERVER = '402'; + + /** + * No such channel + * + * Used to indicate the given channel name is invalid. + */ + const ERR_NOSUCHCHANNEL = '403'; + + /** + * Cannot send to channel + * + * Sent to a user who is either (a) not on a channel which is mode +n or (b) not + * a chanop (or mode +v) on a channel which has mode +m set and is trying to send + * a PRIVMSG message to that channel. + */ + const ERR_CANNOTSENDTOCHAN = '404'; + + /** + * You have joined too many channels + * + * Sent to a user when they have joined the maximum number of allowed channels + * and they try to join another channel. + */ + const ERR_TOOMANYCHANNELS = '405'; + + /** + * There was no such nickname + * + * Returned by WHOWAS to indicate there is no history information for that + * nickname. + */ + const ERR_WASNOSUCHNICK = '406'; + + /** + * Duplicate recipients. No message delivered + * + * Returned to a client which is attempting to send PRIVMSG/NOTICE using the + * user@host destination format and for a user@host which has several + * occurrences. + */ + const ERR_TOOMANYTARGETS = '407'; + + /** + * No origin specified + * + * PING or PONG message missing the originator parameter which is required since + * these commands must work without valid prefixes. + */ + const ERR_NOORIGIN = '409'; + + /** + * No recipient given () + */ + const ERR_NORECIPIENT = '411'; + + /** + * No text to send + */ + const ERR_NOTEXTTOSEND = '412'; + + /** + * No toplevel domain specified + */ + const ERR_NOTOPLEVEL = '413'; + + /** + * Wildcard in toplevel domain + * + * 412 - 414 are returned by PRIVMSG to indicate that the message wasn't + * delivered for some reason. ERR_NOTOPLEVEL and ERR_WILDTOPLEVEL are errors that + * are returned when an invalid use of "PRIVMSG $" or "PRIVMSG #" + * is attempted. + */ + const ERR_WILDTOPLEVEL = '414'; + + /** + * Unknown command + * + * Returned to a registered client to indicate that the command sent is unknown + * by the server. + */ + const ERR_UNKNOWNCOMMAND = '421'; + + /** + * MOTD File is missing + * + * Server's MOTD file could not be opened by the server. + */ + const ERR_NOMOTD = '422'; + + /** + * No administrative info available + * + * Returned by a server in response to an ADMIN message when there is an error in + * finding the appropriate information. + */ + const ERR_NOADMININFO = '423'; + + /** + * File error doing on + * + * Generic error message used to report a failed file operation during the + * processing of a message. + */ + const ERR_FILEERROR = '424'; + + /** + * No nickname given + * + * Returned when a nickname parameter expected for a command and isn't found. + */ + const ERR_NONICKNAMEGIVEN = '431'; + + /** + * Erroneus nickname + * + * Returned after receiving a NICK message which contains characters which do not + * fall in the defined set. See section x.x.x for details on valid nicknames. + */ + const ERR_ERRONEUSNICKNAME = '432'; + + /** + * Nickname is already in use + * + * Returned when a NICK message is processed that results in an attempt to change + * to a currently existing nickname. + */ + const ERR_NICKNAMEINUSE = '433'; + + /** + * Nickname collision KILL + * + * Returned by a server to a client when it detects a nickname collision + * (registered of a NICK that already exists by another server). + */ + const ERR_NICKCOLLISION = '436'; + + /** + * They aren't on that channel + * + * Returned by the server to indicate that the target user of the command is not + * on the given channel. + */ + const ERR_USERNOTINCHANNEL = '441'; + + /** + * You're not on that channel + * + * Returned by the server whenever a client tries to perform a channel effecting + * command for which the client isn't a member. + */ + const ERR_NOTONCHANNEL = '442'; + + /** + * is already on channel + * + * Returned when a client tries to invite a user to a channel they are already + * on. + */ + const ERR_USERONCHANNEL = '443'; + + /** + * User not logged in + * + * Returned by the summon after a SUMMON command for a user was unable to be + * performed since they were not logged in. + */ + const ERR_NOLOGIN = '444'; + + /** + * SUMMON has been disabled + * + * Returned as a response to the SUMMON command. Must be returned by any server + * which does not implement it. + */ + const ERR_SUMMONDISABLED = '445'; + + /** + * USERS has been disabled + * + * Returned as a response to the USERS command. Must be returned by any server + * which does not implement it. + */ + const ERR_USERSDISABLED = '446'; + + /** + * You have not registered + * + * Returned by the server to indicate that the client must be registered before + * the server will allow it to be parsed in detail. + */ + const ERR_NOTREGISTERED = '451'; + + /** + * Not enough parameters + * + * Returned by the server by numerous commands to indicate to the client that it + * didn't supply enough parameters. + */ + const ERR_NEEDMOREPARAMS = '461'; + + /** + * You may not reregister + * + * Returned by the server to any link which tries to change part of the + * registered details (such as password or user details from second USER + * message). + */ + const ERR_ALREADYREGISTRED = '462'; + + /** + * Your host isn't among the privileged + * + * Returned to a client which attempts to register with a server which does not + * been setup to allow connections from the host the attempted connection is + * tried. + */ + const ERR_NOPERMFORHOST = '463'; + + /** + * Password incorrect + * + * Returned to indicate a failed attempt at registering a connection for which a + * password was required and was either not given or incorrect. + */ + const ERR_PASSWDMISMATCH = '464'; + + /** + * You are banned from this server + * + * Returned after an attempt to connect and register yourself with a server which + * has been setup to explicitly deny connections to you. + */ + const ERR_YOUREBANNEDCREEP = '465'; + + /** + * Channel key already set + */ + const ERR_KEYSET = '467'; + + /** + * Cannot join channel (+l) + */ + const ERR_CHANNELISFULL = '471'; + + /** + * is unknown mode char to me + */ + const ERR_UNKNOWNMODE = '472'; + + /** + * Cannot join channel (+i) + */ + const ERR_INVITEONLYCHAN = '473'; + + /** + * Cannot join channel (+b) + */ + const ERR_BANNEDFROMCHAN = '474'; + + /** + * Cannot join channel (+k) + */ + const ERR_BADCHANNELKEY = '475'; + + /** + * Permission Denied- You're not an IRC operator + * + * Any command requiring operator privileges to operate must return this error to + * indicate the attempt was unsuccessful. + */ + const ERR_NOPRIVILEGES = '481'; + + /** + * You're not channel operator + * + * Any command requiring 'chanop' privileges (such as MODE messages) must return + * this error if the client making the attempt is not a chanop on the specified + * channel. + */ + const ERR_CHANOPRIVSNEEDED = '482'; + + /** + * You cant kill a server! + * + * Any attempts to use the KILL command on a server are to be refused and this + * error returned directly to the client. + */ + const ERR_CANTKILLSERVER = '483'; + + /** + * No O-lines for your host + * + * If a client sends an OPER message and the server has not been configured to + * allow connections from the client's host as an operator, this error must be + * returned. + */ + const ERR_NOOPERHOST = '491'; + + /** + * Unknown MODE flag + * + * Returned by the server to indicate that a MODE message was sent with a + * nickname parameter and that the a mode flag sent was not recognized. + */ + const ERR_UMODEUNKNOWNFLAG = '501'; + + /** + * Cant change mode for other users + * + * Error sent to any user trying to view or change the user mode for a user other + * than themselves. + */ + const ERR_USERSDONTMATCH = '502'; + + /** + * Dummy reply number. Not used. + */ + const RPL_NONE = '300'; + + /** + * [{}] + * + * Reply format used by USERHOST to list replies to the query list. The reply + * string is composed as follows = ['*'] '=' <'+'|'-'> + * The '*' indicates whether the client has registered as an Operator. The '-' or + * '+' characters represent whether the client has set an AWAY message or not + * respectively. + */ + const RPL_USERHOST = '302'; + + /** + * [ {}] + * + * Reply format used by ISON to list replies to the query list. + */ + const RPL_ISON = '303'; + + /** + * + */ + const RPL_AWAY = '301'; + + /** + * You are no longer marked as being away + */ + const RPL_UNAWAY = '305'; + + /** + * You have been marked as being away + * + * These replies are used with the AWAY command (if allowed). RPL_AWAY is sent to + * any client sending a PRIVMSG to a client which is away. RPL_AWAY is only sent + * by the server to which the client is connected. Replies RPL_UNAWAY and + * RPL_NOWAWAY are sent when the client removes and sets an AWAY message. + */ + const RPL_NOWAWAY = '306'; + + /** + * * + */ + const RPL_WHOISUSER = '311'; + + /** + * + */ + const RPL_WHOISSERVER = '312'; + + /** + * is an IRC operator + */ + const RPL_WHOISOPERATOR = '313'; + + /** + * seconds idle + */ + const RPL_WHOISIDLE = '317'; + + /** + * End of /WHOIS list + */ + const RPL_ENDOFWHOIS = '318'; + + /** + * {[@|+]} + * + * Replies 311 - 313, 317 - 319 are all replies generated in response to a WHOIS + * message. Given that there are enough parameters present, the answering server + * must either formulate a reply out of the above numerics (if the query nick is + * found) or return an error reply. The '*' in RPL_WHOISUSER is there as the + * literal character and not as a wild card. For each reply set, only + * RPL_WHOISCHANNELS may appear more than once (for long lists of channel names). + * The '@' and '+' characters next to the channel name indicate whether a client + * is a channel operator or has been granted permission to speak on a moderated + * channel. The RPL_ENDOFWHOIS reply is used to mark the end of processing a + * WHOIS message. + */ + const RPL_WHOISCHANNELS = '319'; + + /** + * * + */ + const RPL_WHOWASUSER = '314'; + + /** + * End of WHOWAS + * + * When replying to a WHOWAS message, a server must use the replies + * RPL_WHOWASUSER, RPL_WHOISSERVER or ERR_WASNOSUCHNICK for each nickname in the + * presented list. At the end of all reply batches, there must be RPL_ENDOFWHOWAS + * (even if there was only one reply and it was an error). + */ + const RPL_ENDOFWHOWAS = '369'; + + /** + * Channel Users Name + */ + const RPL_LISTSTART = '321'; + + /** + * <# visible> + */ + const RPL_LIST = '322'; + + /** + * End of /LIST + * + * Replies RPL_LISTSTART, RPL_LIST, RPL_LISTEND mark the start, actual replies + * with data and end of the server's response to a LIST command. If there are no + * channels available to return, only the start and end reply must be sent. + */ + const RPL_LISTEND = '323'; + + /** + * + */ + const RPL_CHANNELMODEIS = '324'; + + /** + * No topic is set + */ + const RPL_NOTOPIC = '331'; + + /** + * + * + * When sending a TOPIC message to determine the channel topic, one of two + * replies is sent. If the topic is set, RPL_TOPIC is sent back else RPL_NOTOPIC. + */ + const RPL_TOPIC = '332'; + + /** + * + * + * Returned by the server to indicate that the attempted INVITE message was + * successful and is being passed onto the end client. + */ + const RPL_INVITING = '341'; + + /** + * Summoning user to IRC + * + * Returned by a server answering a SUMMON message to indicate that it is + * summoning that user. + */ + const RPL_SUMMONING = '342'; + + /** + * . + * + * Reply by the server showing its version details. The is the version + * of the software being used (including any patchlevel revisions) and the + * is used to indicate if the server is running in "debug mode". The + * "comments" field may contain any comments about the version or further version + * details. + */ + const RPL_VERSION = '351'; + + /** + * [*][@|+] + */ + const RPL_WHOREPLY = '352'; + + /** + * End of /WHO list + * + * The RPL_WHOREPLY and RPL_ENDOFWHO pair are used to answer a WHO message. The + * RPL_WHOREPLY is only sent if there is an appropriate match to the WHO query. + * If there is a list of parameters supplied with a WHO message, a RPL_ENDOFWHO + * must be sent after processing each list item with being the item. + */ + const RPL_ENDOFWHO = '315'; + + /** + * [[@|+] [[@|+] [...]]] + */ + const RPL_NAMREPLY = '353'; + + /** + * End of /NAMES list + * + * To reply to a NAMES message, a reply pair consisting of RPL_NAMREPLY and + * RPL_ENDOFNAMES is sent by the server back to the client. If there is no + * channel found as in the query, then only RPL_ENDOFNAMES is returned. The + * exception to this is when a NAMES message is sent with no parameters and all + * visible channels and contents are sent back in a series of RPL_NAMEREPLY + * messages with a RPL_ENDOFNAMES to mark the end. + */ + const RPL_ENDOFNAMES = '366'; + + /** + * + */ + const RPL_LINKS = '364'; + + /** + * End of /LINKS list + * + * In replying to the LINKS message, a server must send replies back using the + * RPL_LINKS numeric and mark the end of the list using an RPL_ENDOFLINKS reply.v + */ + const RPL_ENDOFLINKS = '365'; + + /** + * + */ + const RPL_BANLIST = '367'; + + /** + * End of channel ban list + * + * When listing the active 'bans' for a given channel, a server is required to + * send the list back using the RPL_BANLIST and RPL_ENDOFBANLIST messages. A + * separate RPL_BANLIST is sent for each active banid. After the banids have been + * listed (or if none present) a RPL_ENDOFBANLIST must be sent. + */ + const RPL_ENDOFBANLIST = '368'; + + /** + * + */ + const RPL_INFO = '371'; + + /** + * End of /INFO list + * + * A server responding to an INFO message is required to send all its 'info' in a + * series of RPL_INFO messages with a RPL_ENDOFINFO reply to indicate the end of + * the replies. + */ + const RPL_ENDOFINFO = '374'; + + /** + * - Message of the day - + */ + const RPL_MOTDSTART = '375'; + + /** + * - + */ + const RPL_MOTD = '372'; + + /** + * End of /MOTD command + * + * When responding to the MOTD message and the MOTD file is found, the file is + * displayed line by line, with each line no longer than 80 characters, using + * RPL_MOTD format replies. These should be surrounded by a RPL_MOTDSTART (before + * the RPL_MOTDs) and an RPL_ENDOFMOTD (after). + */ + const RPL_ENDOFMOTD = '376'; + + /** + * You are now an IRC operator + * + * RPL_YOUREOPER is sent back to a client which has just successfully issued an + * OPER message and gained operator status. + */ + const RPL_YOUREOPER = '381'; + + /** + * Rehashing + * + * If the REHASH option is used and an operator sends a REHASH message, an + * RPL_REHASHING is sent back to the operator. + */ + const RPL_REHASHING = '382'; + + /** + * + * + * When replying to the TIME message, a server must send the reply using the + * RPL_TIME format above. The string showing the time need only contain the + * correct day and time there. There is no further requirement for the time + * string. + */ + const RPL_TIME = '391'; + + /** + * UserID Terminal Host + */ + const RPL_USERSSTART = '392'; + + /** + * %-8s %-9s %-8s + */ + const RPL_USERS = '393'; + + /** + * End of users + */ + const RPL_ENDOFUSERS = '394'; + + /** + * Nobody logged in + * + * If the USERS message is handled by a server, the replies RPL_USERSTART, + * RPL_USERS, RPL_ENDOFUSERS and RPL_NOUSERS are used. RPL_USERSSTART must be + * sent first, following by either a sequence of RPL_USERS or a single + * RPL_NOUSER. Following this is RPL_ENDOFUSERS. + */ + const RPL_NOUSERS = '395'; + + /** + * Link + */ + const RPL_TRACELINK = '200'; + + /** + * Try. + */ + const RPL_TRACECONNECTING = '201'; + + /** + * H.S. + */ + const RPL_TRACEHANDSHAKE = '202'; + + /** + * ???? [] + */ + const RPL_TRACEUNKNOWN = '203'; + + /** + * Oper + */ + const RPL_TRACEOPERATOR = '204'; + + /** + * User + */ + const RPL_TRACEUSER = '205'; + + /** + * Serv S C @ + */ + const RPL_TRACESERVER = '206'; + + /** + * 0 + */ + const RPL_TRACENEWTYPE = '208'; + + /** + * File + * + * The RPL_TRACE* are all returned by the server in response to the TRACE + * message. How many are returned is dependent on the the TRACE message and + * whether it was sent by an operator or not. There is no predefined order for + * which occurs first. Replies RPL_TRACEUNKNOWN, RPL_TRACECONNECTING and + * RPL_TRACEHANDSHAKE are all used for connections which have not been fully + * established and are either unknown, still attempting to connect or in the + * process of completing the 'server handshake'. RPL_TRACELINK is sent by any + * server which handles a TRACE message and has to pass it on to another server. + * The list of RPL_TRACELINKs sent in response to a TRACE command traversing the + * IRC network should reflect the actual connectivity of the servers themselves + * along that path. RPL_TRACENEWTYPE is to be used for any connection which does + * not fit in the other categories but is being displayed anyway. + */ + const RPL_TRACELOG = '261'; + + /** + *