diff --git a/bin/monitor.php b/bin/monitor.php
index abaf95d3a..5d7d4bc17 100644
--- a/bin/monitor.php
+++ b/bin/monitor.php
@@ -9,7 +9,7 @@ require_once(dirname(__FILE__)."/../lib/showsleep.php");
require_once(dirname(__FILE__)."/../lib/functions.php");
-$version="0.3r1052";
+$version="0.3r1053";
$db = new DB();
$functions = new Functions();
diff --git a/lib/IRCScraper.php b/lib/IRCScraper.php
index 149b14161..7ca0b75ce 100644
--- a/lib/IRCScraper.php
+++ b/lib/IRCScraper.php
@@ -128,7 +128,7 @@ class IRCScraper
*/
public function __destruct()
{
- // Disconnect from IRC cleanly.
+ // Close the socket.
if (!is_null($this->IRC)) {
if (!$this->silent) {
echo
@@ -137,7 +137,7 @@ class IRCScraper
'.' .
PHP_EOL;
}
- $this->IRC->disconnect();
+ $this->IRC->disconnect(true);
}
}
@@ -278,7 +278,7 @@ class IRCScraper
}
// Login to IRC.
- $this->IRC->login(
+ if (!$this->IRC->login(
// Nick name.
$nickname,
// Real name.
@@ -289,10 +289,18 @@ class IRCScraper
$username,
// Password.
(empty($password) ? null : $password)
- );
+ )) {
+ exit('Error logging in to: (' .
+ $server . ':' . $port . ') nickname: (' . $nickname .
+ '). Verify your connection information, you might also be banned from this server or there might have been a connection issue.' .
+ PHP_EOL
+ );
+ }
// Join channels.
- $this->IRC->join($channelList);
+ if (!$this->IRC->joinChannels($channelList)) {
+ exit('Error joining channels on (' . $server . ':' . $port . ') might be an issue with the server.' . PHP_EOL);
+ }
if (!$this->silent) {
echo
diff --git a/lib/Net_SmartIRC/Net/SmartIRC.php b/lib/Net_SmartIRC/Net/SmartIRC.php
index 5f5c4e3a0..668295575 100644
--- a/lib/Net_SmartIRC/Net/SmartIRC.php
+++ b/lib/Net_SmartIRC/Net/SmartIRC.php
@@ -58,2839 +58,2805 @@ define('SMARTIRC_VERSIONSTRING', 'Net_SmartIRC '.SMARTIRC_VERSION);
*/
class Net_SmartIRC_base
{
- /**
- * @var resource
- * @access private
- */
- var $_socket;
-
- /**
- * @var string
- * @access private
- */
- var $_address;
-
- /**
- * @var integer
- * @access private
- */
- var $_port;
-
- /**
- * @var string
- * @access private
- */
- var $_bindaddress = null;
-
- /**
- * @var integer
- * @access private
- */
- var $_bindport = 0;
-
- /**
- * @var string
- * @access private
- */
- var $_nick;
-
- /**
- * @var string
- * @access private
- */
- var $_username;
-
- /**
- * @var string
- * @access private
- */
- var $_realname;
-
- /**
- * @var string
- * @access private
- */
- var $_usermode;
-
- /**
- * @var string
- * @access private
- */
- var $_password;
-
- /**
- * @var array
- * @access private
- */
- var $_performs = array();
-
- /**
- * @var boolean
- * @access private
- */
- var $_state = false;
-
- /**
- * @var array
- * @access private
- */
- var $_actionhandler = array();
-
- /**
- * @var array
- * @access private
- */
- var $_timehandler = array();
-
- /**
- * @var integer
- * @access private
- */
- var $_debug = SMARTIRC_DEBUG_NOTICE;
-
- /**
- * @var array
- * @access private
- */
- var $_messagebuffer = array();
-
- /**
- * @var integer
- * @access private
- */
- var $_messagebuffersize;
-
- /**
- * @var boolean
- * @access private
- */
- var $_usesockets = false;
-
- /**
- * @var integer
- * @access private
- */
- var $_receivedelay = 100;
-
- /**
- * @var integer
- * @access private
- */
- var $_senddelay = 250;
-
- /**
- * @var integer
- * @access private
- */
- var $_logdestination = SMARTIRC_STDOUT;
-
- /**
- * @var resource
- * @access private
- */
- var $_logfilefp = 0;
-
- /**
- * @var string
- * @access private
- */
- var $_logfile = 'Net_SmartIRC.log';
-
- /**
- * @var integer
- * @access private
- */
- var $_disconnecttime = 1000;
-
- /**
- * @var boolean
- * @access private
- */
- var $_loggedin = false;
-
- /**
- * @var boolean
- * @access private
- */
- var $_benchmark = false;
-
- /**
- * @var integer
- * @access private
- */
- var $_benchmark_starttime;
-
- /**
- * @var integer
- * @access private
- */
- var $_benchmark_stoptime;
-
- /**
- * @var integer
- * @access private
- */
- var $_actionhandlerid = 0;
-
- /**
- * @var integer
- * @access private
- */
- var $_timehandlerid = 0;
-
- /**
- * @var array
- * @access private
- */
- var $_motd = array();
-
- /**
- * @var array
- * @access private
- */
- var $_channels = array();
-
- /**
- * @var boolean
- * @access private
- */
- var $_channelsyncing = false;
-
- /**
- * @var array
- * @access private
- */
- var $_users = array();
-
- /**
- * @var boolean
- * @access private
- */
- var $_usersyncing = false;
-
- /**
- * Stores the path to the modules that can be loaded.
- *
- * @var string
- * @access private
- */
- var $_modulepath = '';
-
- /**
- * Stores all objects of the modules.
- *
- * @var string
- * @access private
- */
- var $_modules = array();
-
- /**
- * @var string
- * @access private
- */
- var $_ctcpversion;
-
- /**
- * @var mixed
- * @access private
- */
- var $_mintimer = false;
-
- /**
- * @var integer
- * @access private
- */
- var $_maxtimer = 300000;
-
- /**
- * @var integer
- * @access private
- */
- var $_txtimeout = 300;
-
- /**
- * @var integer
- * @access private
- */
- var $_rxtimeout = 300;
-
- /**
- * @var integer
- * @access private
- */
- var $_selecttimeout;
-
- /**
- * @var integer
- * @access private
- */
- var $_lastrx;
-
- /**
- * @var integer
- * @access private
- */
- var $_lasttx;
-
- /**
- * @var boolean
- * @access private
- */
- var $_autoreconnect = false;
-
- /**
- * @var integer
- * @access private
- */
- var $_reconnectdelay = 10000;
-
- /**
- * @var boolean
- * @access private
- */
- var $_autoretry = false;
-
- /**
- * @var integer
- * @access private
- */
- var $_autoretrymax = 5;
-
- /**
- * @var integer
- * @access private
- */
- var $_autoretrycount = 0;
-
- /**
- * @var boolean
- * @access private
- */
- var $_connectionerror = false;
-
- /**
- * @var boolean
- * @access private
- */
- var $_runasdaemon = false;
-
-
- /**
- * All IRC replycodes, the index is the replycode name.
- *
- * @see $SMARTIRC_replycodes
- * @var array
- * @access public
- */
- var $replycodes;
-
- /**
- * All numeric IRC replycodes, the index is the numeric replycode.
- *
- * @see $SMARTIRC_nreplycodes
- * @var array
- * @access public
- */
- var $nreplycodes;
-
- /**
- * Stores all channels in this array where we are joined, works only if channelsyncing is activated.
- * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
- * $irc->channel['#test']->users['meebey']->nick;
- *
- * @see setChannelSyncing()
- * @see Net_SmartIRC_channel
- * @see Net_SmartIRC_channeluser
- * @var array
- * @access public
- */
- var $channel;
-
- /**
- * Stores all users that had/have contact with us (channel/query/notice etc.), works only if usersyncing is activated.
- * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
- * $irc->user['meebey']->host;
- *
- * @see setUserSyncing()
- * @see Net_SmartIRC_ircuser
- * @var array
- * @access public
- */
- var $user;
-
- /**
- * Constructor. Initiates the messagebuffer and "links" the replycodes from
- * global into properties. Also some PHP runtime settings are configured.
- *
- * @access public
- */
- function __construct()
- {
- // precheck
- $this->_checkPHPVersion();
-
- ob_implicit_flush(true);
- @set_time_limit(0);
- $this->_messagebuffer[SMARTIRC_CRITICAL] = array();
- $this->_messagebuffer[SMARTIRC_HIGH] = array();
- $this->_messagebuffer[SMARTIRC_MEDIUM] = array();
- $this->_messagebuffer[SMARTIRC_LOW] = array();
-
- $this->replycodes = &$GLOBALS['SMARTIRC_replycodes'];
- $this->nreplycodes = &$GLOBALS['SMARTIRC_nreplycodes'];
-
- // hack till PHP allows (PHP5) $object->somemethod($param)->memberofobject
- $this->channel = &$this->_channels;
- // another hack
- $this->user = &$this->_users;
-
- if (isset($_SERVER['REQUEST_METHOD'])) {
- // the script is called from a browser, lets set default log destination
- // to SMARTIRC_BROWSEROUT (makes browser friendly output)
- $this->setLogdestination(SMARTIRC_BROWSEROUT);
- }
- }
-
- /**
- * Enables/disables the usage of real sockets.
- *
- * Enables/disables the usage of real sockets instead of fsocks
- * (works only if your PHP build has loaded the PHP socket extension)
- * Default: false
- *
- * @param bool $boolean
- * @return void
- * @access public
- */
- function setUseSockets($boolean)
- {
- if ($boolean === true) {
- if (@extension_loaded('sockets')) {
- $this->_usesockets = true;
- } else {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket extension not loaded, trying to load it...', __FILE__, __LINE__);
-
- if (strtoupper(substr(PHP_OS, 0,3) == 'WIN')) {
- $load_status = @dl('php_sockets.dll');
- } else {
- $load_status = @dl('sockets.so');
- }
-
- if ($load_status) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket extension succesfully loaded', __FILE__, __LINE__);
- $this->_usesockets = true;
- } else {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: couldn\'t load the socket extension', __FILE__, __LINE__);
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: your PHP build doesn\'t support real sockets, will use fsocks instead', __FILE__, __LINE__);
- $this->_usesockets = false;
- }
- }
- } else {
- $this->_usesockets = false;
- }
- }
-
- /**
- * Sets an IP address (and optionally, a port) to bind the socket to.
- *
- * Limits the bot to claiming only one of the machine's IPs as its home.
- * Only works with setUseSockets(TRUE). Call with no parameters to unbind.
- *
- * @param string $addr
- * @return bool
- * @access public
- */
- function setBindAddress($addr=null,$port=0)
- {
- if ($this->_usesockets) {
- $this->bindaddress = $addr;
- $this->bindport = $port;
- }
- return $this->_usesockets;
- }
-
- /**
- * Sets the level of debug messages.
- *
- * Sets the debug level (bitwise), useful for testing/developing your code.
- * Here the list of all possible debug levels:
- * SMARTIRC_DEBUG_NONE
- * SMARTIRC_DEBUG_NOTICE
- * SMARTIRC_DEBUG_CONNECTION
- * SMARTIRC_DEBUG_SOCKET
- * SMARTIRC_DEBUG_IRCMESSAGES
- * SMARTIRC_DEBUG_MESSAGETYPES
- * SMARTIRC_DEBUG_ACTIONHANDLER
- * SMARTIRC_DEBUG_TIMEHANDLER
- * SMARTIRC_DEBUG_MESSAGEHANDLER
- * SMARTIRC_DEBUG_CHANNELSYNCING
- * SMARTIRC_DEBUG_MODULES
- * SMARTIRC_DEBUG_USERSYNCING
- * SMARTIRC_DEBUG_ALL
- *
- * Default: SMARTIRC_DEBUG_NOTICE
- *
- * @see DOCUMENTATION
- * @see SMARTIRC_DEBUG_NOTICE
- * @param integer $level
- * @return void
- * @access public
- */
- function setDebug($level)
- {
- $this->_debug = $level;
- }
-
- /**
- * Enables/disables the benchmark engine.
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setBenchmark($boolean)
- {
- if (is_bool($boolean)) {
- $this->_benchmark = $boolean;
- } else {
- $this->_benchmark = false;
- }
- }
-
- /**
- * Deprecated, use setChannelSyncing() instead!
- *
- * @deprecated
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setChannelSynching($boolean)
- {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: you are using setChannelSynching() which is a deprecated method, use setChannelSyncing() instead!', __FILE__, __LINE__);
- $this->setChannelSyncing($boolean);
- }
-
- /**
- * Enables/disables channel syncing.
- *
- * Channel syncing means, all users on all channel we are joined are tracked in the
- * channel array. This makes it very handy for botcoding.
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setChannelSyncing($boolean)
- {
- if (is_bool($boolean)) {
- $this->_channelsyncing = $boolean;
- } else {
- $this->_channelsyncing = false;
- }
-
- if ($this->_channelsyncing == true) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing enabled', __FILE__, __LINE__);
- } else {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing disabled', __FILE__, __LINE__);
- }
- }
-
- /**
- * Enables/disables user syncing.
- *
- * User syncing means, all users we have or had contact with through channel, query or
- * notice are tracked in the $irc->user array. This is very handy for botcoding.
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setUserSyncing($boolean)
- {
- if (is_bool($boolean)) {
- $this->_usersyncing = $boolean;
- } else {
- $this->_usersyncing = false;
- }
-
- if ($this->_usersyncing == true) {
- $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing enabled', __FILE__, __LINE__);
- } else {
- $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing disabled', __FILE__, __LINE__);
- }
- }
-
- /**
- * Sets the CTCP version reply string.
- *
- * @param string $versionstring
- * @return void
- * @access public
- */
- function setCtcpVersion($versionstring)
- {
- $this->_ctcpversion = $versionstring;
- }
-
- /**
- * Sets the destination of all log messages.
- *
- * Sets the destination of log messages.
- * $type can be:
- * SMARTIRC_FILE for saving the log into a file
- * SMARTIRC_STDOUT for echoing the log to stdout
- * SMARTIRC_SYSLOG for sending the log to the syslog
- * Default: SMARTIRC_STDOUT
- *
- * @see SMARTIRC_STDOUT
- * @param integer $type must be on of the constants
- * @return void
- * @access public
- */
- function setLogdestination($type)
- {
- switch ($type) {
- case SMARTIRC_FILE:
- case SMARTIRC_STDOUT:
- case SMARTIRC_SYSLOG:
- case SMARTIRC_BROWSEROUT:
- case SMARTIRC_NONE:
- $this->_logdestination = $type;
- break;
- default:
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: unknown logdestination type ('.$type.'), will use STDOUT instead', __FILE__, __LINE__);
- $this->_logdestination = SMARTIRC_STDOUT;
- }
- }
-
- /**
- * Sets the file for the log if the destination is set to file.
- *
- * Sets the logfile, if {@link setLogdestination logdestination} is set to SMARTIRC_FILE.
- * This should be only used with full path!
- *
- * @param string $file
- * @return void
- * @access public
- */
- function setLogfile($file)
- {
- $this->_logfile = $file;
- }
-
- /**
- * Sets the delaytime before closing the socket when disconnect.
- *
- * @param integer $milliseconds
- * @return void
- * @access public
- */
- function setDisconnecttime($milliseconds)
- {
- if (is_integer($milliseconds) && $milliseconds >= 100) {
- $this->_disconnecttime = $milliseconds;
- } else {
- $this->_disconnecttime = 100;
- }
- }
-
- /**
- * Sets the delaytime before attempting reconnect.
- * Value of 0 disables the delay entirely.
- *
- * @param integer $milliseconds
- * @return void
- * @access public
- */
- function setReconnectdelay($milliseconds)
- {
- if (is_integer($milliseconds)) {
- $this->_reconnectdelay = $milliseconds;
- } else {
- $this->_reconnectdelay = 10000;
- }
- }
-
- /**
- * Sets the delay for receiving data from the IRC server.
- *
- * Sets the delaytime between messages that are received, this reduces your CPU load.
- * Don't set this too low (min 100ms).
- * Default: 100
- *
- * @param integer $milliseconds
- * @return void
- * @access public
- */
- function setReceivedelay($milliseconds)
- {
- if (is_integer($milliseconds) && $milliseconds >= 100) {
- $this->_receivedelay = $milliseconds;
- } else {
- $this->_receivedelay = 100;
- }
- }
-
- /**
- * Sets the delay for sending data to the IRC server.
- *
- * Sets the delaytime between messages that are sent, because IRC servers doesn't like floods.
- * This will avoid sending your messages too fast to the IRC server.
- * Default: 250
- *
- * @param integer $milliseconds
- * @return void
- * @access public
- */
- function setSenddelay($milliseconds)
- {
- if (is_integer($milliseconds)) {
- $this->_senddelay = $milliseconds;
- } else {
- $this->_senddelay = 250;
- }
- }
-
- /**
- * Enables/disables autoreconnecting.
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setAutoReconnect($boolean)
- {
- if (is_bool($boolean)) {
- $this->_autoreconnect = $boolean;
- } else {
- $this->_autoreconnect = false;
- }
- }
-
- /**
- * Enables/disables autoretry for connecting to a server.
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setAutoRetry($boolean)
- {
- if (is_bool($boolean)) {
- $this->_autoretry = $boolean;
- } else {
- $this->_autoretry = false;
- }
- }
-
- /**
- * Sets the maximum number of attempts to connect to a server
- * before giving up.
- *
- * @param integer $autoretrymax
- * @return void
- * @access public
- */
- function setAutoRetryMax($autoretrymax)
- {
- if (is_integer($autoretrymax)) {
- $this->_autoretrymax = $autoretrymax;
- } else {
- $this->_autoretrymax = 5;
- }
- }
-
- /**
- * Sets the receive timeout.
- *
- * If the timeout occurs, the connection will be reinitialized
- * Default: 300 seconds
- *
- * @param integer $seconds
- * @return void
- * @access public
- */
- function setReceiveTimeout($seconds)
- {
- if (is_integer($seconds)) {
- $this->_rxtimeout = $seconds;
- } else {
- $this->_rxtimeout = 300;
- }
- }
-
- /**
- * Sets the transmit timeout.
- *
- * If the timeout occurs, the connection will be reinitialized
- * Default: 300 seconds
- *
- * @param integer $seconds
- * @return void
- * @access public
- */
- function setTransmitTimeout($seconds)
- {
- if (is_integer($seconds)) {
- $this->_txtimeout = $seconds;
- } else {
- $this->_txtimeout = 300;
- }
- }
-
- /**
- * Sets the paths for the modules.
- *
- * @param integer $path
- * @return void
- * @access public
- */
- function setModulepath($path)
- {
- $this->_modulepath = $path;
- }
-
- /**
- * Sets wheter the script should be run as a daemon or not
- * ( actually disables/enables ignore_user_abort() )
- *
- * @param boolean $boolean
- * @return void
- * @access public
- */
- function setRunAsDaemon($boolean)
- {
- if ($boolean === true) {
- $this->_runasdaemon = true;
- ignore_user_abort(true);
- set_time_limit(0);
- } else {
- $this->_runasdaemon = false;
- }
- }
-
- /**
- * Starts the benchmark (sets the counters).
- *
- * @return void
- * @access public
- */
- function startBenchmark()
- {
- $this->_benchmark_starttime = $this->_microint();
- $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark started', __FILE__, __LINE__);
- }
-
- /**
- * Stops the benchmark and displays the result.
- *
- * @return void
- * @access public
- */
- function stopBenchmark()
- {
- $this->_benchmark_stoptime = $this->_microint();
- $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark stopped', __FILE__, __LINE__);
-
- if ($this->_benchmark) {
- $this->showBenchmark();
- }
- }
-
- /**
- * Shows the benchmark result.
- *
- * @return void
- * @access public
- */
- function showBenchmark()
- {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark time: '.((float)$this->_benchmark_stoptime-(float)$this->_benchmark_starttime), __FILE__, __LINE__);
- }
-
- /**
- * Adds an entry to the log.
- *
- * Adds an entry to the log with Linux style log format.
- * Possible $level constants (can also be combined with "|"s)
- * SMARTIRC_DEBUG_NONE
- * SMARTIRC_DEBUG_NOTICE
- * SMARTIRC_DEBUG_CONNECTION
- * SMARTIRC_DEBUG_SOCKET
- * SMARTIRC_DEBUG_IRCMESSAGES
- * SMARTIRC_DEBUG_MESSAGETYPES
- * SMARTIRC_DEBUG_ACTIONHANDLER
- * SMARTIRC_DEBUG_TIMEHANDLER
- * SMARTIRC_DEBUG_MESSAGEHANDLER
- * SMARTIRC_DEBUG_CHANNELSYNCING
- * SMARTIRC_DEBUG_MODULES
- * SMARTIRC_DEBUG_USERSYNCING
- * SMARTIRC_DEBUG_ALL
- *
- * @see SMARTIRC_DEBUG_NOTICE
- * @param integer $level bit constants (SMARTIRC_DEBUG_*)
- * @param string $entry the new log entry
- * @return void
- * @access public
- */
- function log($level, $entry, $file = null, $line = null)
- {
- // prechecks
- if (!(is_integer($level)) ||
- !($level & SMARTIRC_DEBUG_ALL)) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: invalid log level passed to log() ('.$level.')', __FILE__, __LINE__);
- return;
- }
-
- if (!($level & $this->_debug) ||
- ($this->_logdestination == SMARTIRC_NONE)) {
- return;
- }
-
- if (substr($entry, -1) != "\n") {
- $entry .= "\n";
- }
-
- if ($file !== null &&
- $line !== null) {
- $file = basename($file);
- $entry = $file.'('.$line.') '.$entry;
- } else {
- $entry = 'unknown(0) '.$entry;
- }
-
- $formatedentry = date('M d H:i:s ').$entry;
- switch ($this->_logdestination) {
- case SMARTIRC_STDOUT:
- echo $formatedentry;
- flush();
- break;
- case SMARTIRC_BROWSEROUT:
- echo '
'.htmlentities($formatedentry).'
';
- break;
- case SMARTIRC_FILE:
- if (!is_resource($this->_logfilefp)) {
- if ($this->_logfilefp === null) {
- // we reconncted and don't want to destroy the old log entries
- $this->_logfilefp = fopen($this->_logfile,'a');
- } else {
- $this->_logfilefp = fopen($this->_logfile,'w');
- }
- }
- fwrite($this->_logfilefp, $formatedentry);
- fflush($this->_logfilefp);
- break;
- case SMARTIRC_SYSLOG:
- if (version_compare(PHP_VERSION, '5.3.0', '<')) {
- define_syslog_variables();
- }
- if (!is_int($this->_logfilefp)) {
- $this->_logfilefp = openlog('Net_SmartIRC', LOG_NDELAY, LOG_DAEMON);
- }
- syslog(LOG_INFO, $entry);
- break;
- }
- }
-
- /**
- * 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;
- }
-
- /**
- * Returns a reference to the channel object of the specified channelname.
- *
- * @param string $channelname
- * @return object
- * @access public
- */
- function &getChannel($channelname)
- {
- if ($this->_channelsyncing != true) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getChannel() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
- return false;
- }
-
- if ($this->isJoined($channelname)) {
- return $this->_channels[strtolower($channelname)];
- } else {
- return false;
- }
- }
-
- /**
- * Returns a reference to the user object for the specified username and channelname.
- *
- * @param string $channelname
- * @param string $username
- * @return object
- * @access public
- */
- function &getUser($channelname, $username)
- {
- if ($this->_channelsyncing != true) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getUser() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
- return false;
- }
-
- if ($this->isJoined($channelname, $username)) {
- return $this->_channels[strtolower($channelname)]->users[strtolower($username)];
- } else {
- return false;
- }
- }
-
- /**
- * Creates the sockets and connects to the IRC server on the given port.
- *
- * @param string $address
- * @param integer $port
- * @return boolean
- * @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);
- if ($this->_bindaddress !== null) {
- if (socket_bind($this->_socket, $this->_bindaddress, $this->_bindport)) {
- $this->log(SMARTIRC_DEBUG_SOCKET,
- 'DEBUG_SOCKET: bound to '.$this->_bindaddress.':'
- .$this->_bindport, __FILE__, __LINE__);
- } else {
- $errno = socket_last_error($this->_socket);
- $error_msg = 'ERROR: Unable to bind '.$this->_bindaddress.':'
- .$this->_bindport.' reason: '.socket_strerror($errno)
- .' ('.$errno.')';
- $this->log(SMARTIRC_DEBUG_NOTICE,
- 'DEBUG_NOTICE: '.$error_msg, __FILE__, __LINE__);
- echo $error_msg . PHP_EOL;
- return false;
- }
- }
- $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! needs to be return value
- //$this->throwError($error_msg); // This returns, preventing reconnect.
-
- if (($this->_autoretry == true) &&
- ($this->_autoretrycount < $this->_autoretrymax)) {
- echo 'ERROR connecting to (' .
- $address .
- ':' .
- $port .
- ') error: (' .
- $error .
- ') retry (' .
- $this->_autoretrycount .
- '/' .
- $this->_autoretrymax .
- '). Sleeping for (' .
- $this->_reconnectdelay .
- ') ms.' .
- PHP_EOL;
- $this->_delayReconnect();
- $this->_autoretrycount++;
- $this->reconnect();
- } else {
- echo 'ERROR connecting to (' .
- $address .
- ':' .
- $port .
- ') after (' .
- $this->_autoretrymax .
- ') retries, error: (' .
- $error .
- ').' .
- PHP_EOL;
- return false;
- }
- } else {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connected', __FILE__, __LINE__);
- $this->_autoretrycount = 0;
- $this->_connectionerror = false;
-
- if ($this->_usesockets != true) {
- $this->_socket = $result;
- $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: activating nonblocking fsocket mode', __FILE__, __LINE__);
- stream_set_blocking($this->_socket, 0);
- }
- }
-
- $this->_lastrx = time();
- $this->_lasttx = $this->_lastrx;
- $this->_updatestate();
-
- return $result !== 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->_usersyncing == true) {
- // let's clean our user array
- $this->_users = array();
- $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: cleaned user 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);
-
- if (count($this->_performs)) {
- // if we have extra commands to send, do it now
- foreach($this->_performs as $command) {
- $this->_send($command, SMARTIRC_HIGH);
- }
- // if we sent "ns auth" commands, we may need to resend our nick
- $this->_send('NICK '.$this->_nick, SMARTIRC_HIGH);
- }
- }
-
- //
-
- /**
- * adds a command to the list of commands to be sent after login() info
- *
- * @param string $cmd the command to add to the perform list
- * @access public
- */
- function perform($cmd)
- {
- $this->_performs[] = $cmd;
- }
-
- /**
- * checks if the passed nickname is our own nickname
- *
- * @param string $nickname
- * @return boolean
- * @access public
- */
- function isMe($nickname)
- {
- if ($nickname == $this->_nick) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * 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 founder 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 isFounder($channel, $nickname = null)
- {
- if ($this->_channelsyncing != true) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isFounder() 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)]->founder) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Checks if we or the given user is admin 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 isAdmin($channel, $nickname = null)
- {
- if ($this->_channelsyncing != true) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isAdmin() 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)]->admin) {
- 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 hopped 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 isHopped($channel, $nickname = null)
- {
- if ($this->_channelsyncing != true) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isHopped() 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)]->hop) {
- 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()
- {
- while ($this->_state() == SMARTIRC_STATE_CONNECTED) {
- $this->listenOnce();
- }
-
- return false;
- }
-
- /**
- * goes into receive mode _only_ for one pass
- *
- * Goes into receive mode. It will return when one pass is complete.
- * Use this when you want to connect to multiple IRC servers.
- *
- * @return boolean
- * @access public
- */
- function listenOnce()
- {
- if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
- $this->_rawreceive();
- if ($this->_connectionerror) {
- if ($this->_autoreconnect) {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will reconnect!', __FILE__, __LINE__);
- $this->reconnect();
- } else {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will disconnect!', __FILE__, __LINE__);
- $this->disconnect();
- }
- }
- 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;
- }
-
- /**
- * registers a new actionhandler and returns the assigned id
- *
- * Registers an actionhandler in Net_SmartIRC for calling it later.
- * The actionhandler id is needed for unregistering the actionhandler.
- *
- * @see example.php
- * @param integer $handlertype bits constants, see in this documentation Message Types
- * @param string $regexhandler the message that has to be in the IRC message in regex syntax
- * @param object $object a reference to the objects of the method
- * @param string $methodname the methodname that will be called when the handler happens
- * @return integer assigned actionhandler id
- * @access public
- */
- function registerActionhandler($handlertype, $regexhandler, &$object, $methodname)
- {
- // precheck
- if (!$this->_isValidType($handlertype)) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to registerActionhandler()', __FILE__, __LINE__);
- return false;
- }
-
- $id = $this->_actionhandlerid++;
- $newactionhandler = new Net_SmartIRC_actionhandler();
-
- $newactionhandler->id = $id;
- $newactionhandler->type = $handlertype;
- $newactionhandler->message = $regexhandler;
- $newactionhandler->object = &$object;
- $newactionhandler->method = $methodname;
-
- $this->_actionhandler[] = &$newactionhandler;
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') registered', __FILE__, __LINE__);
- return $id;
- }
-
- /**
- * unregisters an existing actionhandler
- *
- * @param integer $handlertype
- * @param string $regexhandler
- * @param object $object
- * @param string $methodname
- * @return boolean
- * @access public
- */
- function unregisterActionhandler($handlertype, $regexhandler, &$object, $methodname)
- {
- // precheck
- if (!$this->_isValidType($handlertype)) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to unregisterActionhandler()', __FILE__, __LINE__);
- return false;
- }
-
- $handler = &$this->_actionhandler;
- $handlercount = count($handler);
-
- for ($i = 0; $i < $handlercount; $i++) {
- $handlerobject = &$handler[$i];
-
- if ($handlerobject->type == $handlertype &&
- $handlerobject->message == $regexhandler &&
- $handlerobject->method == $methodname) {
-
- $id = $handlerobject->id;
-
- if (isset($this->_actionhandler[$i])) {
- unset($this->_actionhandler[$i]);
- }
-
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
- $this->_reorderactionhandler();
- return true;
- }
- }
-
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler type: "'.$handlertype.'" message: "'.$regexhandler.'" method: "'.$methodname.'" from object "'.get_class($object).'" _not_ unregistered', __FILE__, __LINE__);
- return false;
- }
-
- /**
- * unregisters an existing actionhandler via the id
- *
- * @param integer $id
- * @return boolean
- * @access public
- */
- function unregisterActionid($id)
- {
- $handler = &$this->_actionhandler;
- $handlercount = count($handler);
- for ($i = 0; $i < $handlercount; $i++) {
- $handlerobject = &$handler[$i];
-
- if ($handlerobject->id == $id) {
- if (isset($this->_actionhandler[$i])) {
- unset($this->_actionhandler[$i]);
- }
-
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
- $this->_reorderactionhandler();
- return true;
- }
- }
-
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
- return false;
- }
-
- /**
- * registers a timehandler and returns the assigned id
- *
- * Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
- * The timehandler id is needed for unregistering the timehandler.
- *
- * @see example7.php
- * @param integer $interval interval time in milliseconds
- * @param object $object a reference to the objects of the method
- * @param string $methodname the methodname that will be called when the handler happens
- * @return integer assigned timehandler id
- * @access public
- */
- function registerTimehandler($interval, &$object, $methodname)
- {
- $id = $this->_timehandlerid++;
- $newtimehandler = new Net_SmartIRC_timehandler();
-
- $newtimehandler->id = $id;
- $newtimehandler->interval = $interval;
- $newtimehandler->object = &$object;
- $newtimehandler->method = $methodname;
- $newtimehandler->lastmicrotimestamp = $this->_microint();
-
- $this->_timehandler[] = &$newtimehandler;
- $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') registered', __FILE__, __LINE__);
-
- if (($interval < $this->_mintimer) || ($this->_mintimer == false)) {
- $this->_mintimer = $interval;
- }
-
- return $id;
- }
-
- /**
- * unregisters an existing timehandler via the id
- *
- * @see example7.php
- * @param integer $id
- * @return boolean
- * @access public
- */
- function unregisterTimeid($id)
- {
- $handler = &$this->_timehandler;
- $handlercount = count($handler);
- for ($i = 0; $i < $handlercount; $i++) {
- $handlerobject = &$handler[$i];
-
- if ($handlerobject->id == $id) {
- if (isset($this->_timehandler[$i])) {
- unset($this->_timehandler[$i]);
- }
-
- $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') unregistered', __FILE__, __LINE__);
- $this->_reordertimehandler();
- $this->_updatemintimer();
- return true;
- }
- }
-
- $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: could not find timehandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
- return false;
- }
-
- function loadModule($name)
- {
- // is the module already loaded?
- if (in_array($name, $this->_modules)) {
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING! module with the name "'.$name.'" already loaded!', __FILE__, __LINE__);
- return false;
- }
-
- $filename = $this->_modulepath.'/'.$name.'.php';
- if (!file_exists($filename)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t load module "'.$filename.'" file doesn\'t exist', __FILE__, __LINE__);
- return false;
- }
-
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: loading module: "'.$name.'"...', __FILE__, __LINE__);
- // pray that there is no parse error, it will kill us!
- include_once($filename);
- $classname = 'Net_SmartIRC_module_'.$name;
-
- if (!class_exists($classname)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: class '.$classname.' not found in '.$filename, __FILE__, __LINE__);
- return false;
- }
-
- $methods = get_class_methods($classname);
- if (!in_array('__construct', $methods) && !in_array('module_init', $methods)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::__construct not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- if (!in_array('__destruct', $methods) && !in_array('module_exit', $methods)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::__destruct not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- $vars = array_keys(get_class_vars($classname));
- if (!in_array('name', $vars)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::name not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- if (!in_array('description', $vars)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::description not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- if (!in_array('author', $vars)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::author not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- if (!in_array('license', $vars)) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::license not found, aborting...', __FILE__, __LINE__);
- return false;
- }
-
- // looks like the module satisfies us, so instantiate it
- if (in_array('module_init', $methods)) {
- // we're using an old module_init style module
- $module = new $classname;
- } else if (func_num_args() == 1) {
- // we're using a new __construct style module, which maintains its
- // own reference to the $irc client object it's being used on
- $module = new $classname($this);
- } else {
- // we're using new style AND we have args to pass to the constructor
- if (func_num_args() == 2) {
- // only one arg, so pass it as is
- $module = new $classname($this, func_get_arg(1));
- } else {
- // multiple args, so pass them in an array
- $module = new $classname($this, array_slice(func_get_args(), 1));
- }
- }
-
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully created'
- .' instance of: '.$classname, __FILE__, __LINE__
- );
-
- // check for deprecated init function and run it if it exists
- if (in_array('module_init', get_class_methods($classname))) {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: calling '
- .$classname.'::module_init()', __FILE__, __LINE__
- );
- $module->module_init($this);
- }
-
- $this->_modules[$name] = &$module;
-
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully loaded'
- .' module: '.$name, __FILE__, __LINE__
- );
- return true;
- }
-
- function unloadModule($name)
- {
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: unloading module: '.$name.'...', __FILE__, __LINE__);
-
- $modules_keys = array_keys($this->_modules);
- $modulecount = count($modules_keys);
- for ($i = 0; $i < $modulecount; $i++) {
- $module = &$this->_modules[$modules_keys[$i]];
- $modulename = strtolower(get_class($module));
-
- if ($modulename == 'net_smartirc_module_'.$name) {
- if (in_array('module_exit', get_class_methods($modulename))) {
- $module->module_exit($this);
- }
- unset($this->_modules[$i]); // should call __destruct() on it
- $this->_reordermodules();
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully'
- .' unloaded module: '.$name, __FILE__, __LINE__);
- return true;
- }
- }
-
- $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t unload'
- .' module: '.$name.' (it\'s not loaded!)', __FILE__, __LINE__
- );
- return false;
- }
-
- //
- /**
- * changes a already used nickname to a new nickname plus 3 random digits
- *
- * @return void
- * @access private
- */
- function _nicknameinuse()
- {
- $newnickname = substr($this->_nick, 0, 5).rand(0, 999);
- $this->changeNick($newnickname, SMARTIRC_CRITICAL);
- }
-
- /**
- * sends an IRC message
- *
- * Adds a message to the messagequeue, with the optional priority.
- * $priority:
- * SMARTIRC_CRITICAL
- * SMARTIRC_HIGH
- * SMARTIRC_MEDIUM
- * SMARTIRC_LOW
- *
- * @param string $data
- * @param integer $priority must be one of the priority constants
- * @return boolean
- * @access public
- */
- function send($data, $priority = SMARTIRC_MEDIUM)
- {
- return $this->_send($data, $priority);
- }
-
- /**
- * sends an IRC message
- *
- * Adds a message to the messagequeue, with the optional priority.
- * $priority:
- * SMARTIRC_CRITICAL
- * SMARTIRC_HIGH
- * SMARTIRC_MEDIUM
- * SMARTIRC_LOW
- *
- * @param string $data
- * @param integer $priority must be one of the priority constants
- * @return boolean
- * @access private
- */
- function _send($data, $priority = SMARTIRC_MEDIUM)
- {
- switch ($priority) {
- case SMARTIRC_CRITICAL:
- $this->_rawsend($data);
- break;
- case SMARTIRC_HIGH:
- case SMARTIRC_MEDIUM:
- case SMARTIRC_LOW:
- $this->_messagebuffer[$priority][] = $data;
- break;
- default:
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: message ('.$data.') with an invalid priority passed ('.$priority.'), message is ignored!', __FILE__, __LINE__);
- return false;
- }
-
- return true;
- }
-
- /**
- * checks the buffer if there are messages to send
- *
- * @return void
- * @access private
- */
- function _checkbuffer()
- {
- if (!$this->_loggedin) {
- return;
- }
-
- static $highsent = 0;
- static $lastmicrotimestamp = 0;
-
- if ($lastmicrotimestamp == 0) {
- $lastmicrotimestamp = $this->_microint();
- }
-
- $highcount = count($this->_messagebuffer[SMARTIRC_HIGH]);
- $mediumcount = count($this->_messagebuffer[SMARTIRC_MEDIUM]);
- $lowcount = count($this->_messagebuffer[SMARTIRC_LOW]);
- $this->_messagebuffersize = $highcount+$mediumcount+$lowcount;
-
- // don't send them too fast
- if ($this->_microint() >= ($lastmicrotimestamp+($this->_senddelay/1000))) {
- $result = null;
- if ($highcount > 0 && $highsent <= 2) {
- $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_HIGH]));
- $lastmicrotimestamp = $this->_microint();
- $highsent++;
- } else if ($mediumcount > 0) {
- $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_MEDIUM]));
- $lastmicrotimestamp = $this->_microint();
- $highsent = 0;
- } else if ($lowcount > 0) {
- $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_LOW]));
- $lastmicrotimestamp = $this->_microint();
- }
- }
- }
-
- /**
- * Checks the running timers and calls the registered timehandler,
- * when the interval is reached.
- *
- * @return void
- * @access private
- */
- function _checktimer()
- {
- if (!$this->_loggedin) {
- return;
- }
-
- // has to be count() because the array may change during the loop!
- for ($i = 0; $i < count($this->_timehandler); $i++) {
- $handlerobject = &$this->_timehandler[$i];
- $microtimestamp = $this->_microint();
- if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+($handlerobject->interval/1000))) {
- $methodobject = &$handlerobject->object;
- $method = $handlerobject->method;
- $handlerobject->lastmicrotimestamp = $microtimestamp;
-
- if (@method_exists($methodobject, $method)) {
- $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
- $methodobject->$method($this);
- }
- }
- }
- }
-
- /**
- * Checks if a receive or transmit timeout occured and reconnects if configured
- *
- * @return void
- * @access private
- */
- function _checktimeout()
- {
- if ($this->_autoreconnect == true) {
- $timestamp = time();
- if ($this->_lastrx < ($timestamp - $this->_rxtimeout)) {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: receive timeout detected, doing reconnect...', __FILE__, __LINE__);
- $this->_delayReconnect();
- $this->reconnect();
- } else if ($this->_lasttx < ($timestamp - $this->_txtimeout)) {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: transmit timeout detected, doing reconnect...', __FILE__, __LINE__);
- $this->_delayReconnect();
- $this->reconnect();
- }
- }
- }
-
- /**
- * sends a raw message to the IRC server (don't use this!!)
- *
- * Use message() or send() instead.
- *
- * @param string $data
- * @return boolean
- * @access private
- */
- function _rawsend($data)
- {
- if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
- $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: sent: "'.$data.'"', __FILE__, __LINE__);
-
- if ($this->_usesockets == true) {
- $result = socket_write($this->_socket, $data.SMARTIRC_CRLF);
- } else {
- $result = fwrite($this->_socket, $data.SMARTIRC_CRLF);
- }
-
-
- if ($result === false) {
- // writing to the socket failed, means the connection is broken
- $this->_connectionerror = true;
-
- return false;
- } else {
- $this->_lasttx = time();
- return true;
- }
- } else {
- return false;
- }
- }
-
- /**
- * goes into main receive mode _once_ per call and waits for messages from the IRC server
- *
- * @return void
- * @access private
- */
- function _rawreceive()
- {
- $lastpart = '';
- $rawdataar = array();
-
- $this->_checkbuffer();
-
- $timeout = $this->_selecttimeout();
- if ($this->_usesockets == true) {
- $sread = array($this->_socket);
- // this will trigger a warning when catching a signal
- $result = @socket_select($sread, $w = null, $e = null, 0, $timeout*1000);
-
- if ($result == 1) {
- // the socket got data to read
- $rawdata = socket_read($this->_socket, 10240);
- } else if ($result === false) {
- if (socket_last_error() == 4) {
- // we got hit with a SIGHUP signal
- $rawdata = null;
- global $bot;
-
- if (is_callable(array($bot, 'reload'))) {
- $bot->reload();
- }
- } else {
- // panic! panic! something went wrong!
- $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket_select() returned false, something went wrong! Reason: '.socket_strerror(socket_last_error()), __FILE__, __LINE__);
- exit;
- }
- } else {
- // no data
- $rawdata = null;
- }
- } else {
- usleep($this->_receivedelay*1000);
- $rawdata = fread($this->_socket, 10240);
- }
- if ($rawdata === false) {
- // reading from the socket failed, the connection is broken
- $this->_connectionerror = true;
- }
-
- $this->_checktimer();
- $this->_checktimeout();
-
- if ($rawdata !== null && !empty($rawdata)) {
- $this->_lastrx = time();
- $rawdata = str_replace("\r", '', $rawdata);
- $rawdata = $lastpart.$rawdata;
-
- $lastpart = substr($rawdata, strrpos($rawdata ,"\n")+1);
- $rawdata = substr($rawdata, 0, strrpos($rawdata ,"\n"));
- $rawdataar = explode("\n", $rawdata);
- }
-
- // loop through our received messages
- while (count($rawdataar) > 0) {
- $rawline = array_shift($rawdataar);
- $validmessage = false;
-
- $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: received: "'.$rawline.'"', __FILE__, __LINE__);
-
- // building our data packet
- $ircdata = new Net_SmartIRC_data();
- $ircdata->rawmessage = $rawline;
- $lineex = explode(' ', $rawline);
- $ircdata->rawmessageex = $lineex;
- $messagecode = $lineex[0];
-
- if (substr($rawline, 0, 1) == ':') {
- $validmessage = true;
- $line = substr($rawline, 1);
- $lineex = explode(' ', $line);
-
- // conform to RFC 2812
- $from = $lineex[0];
- $messagecode = $lineex[1];
- $exclamationpos = strpos($from, '!');
- $atpos = strpos($from, '@');
- $colonpos = strpos($line, ' :');
- if ($colonpos !== false) {
- // we want the exact position of ":" not beginning from the space
- $colonpos += 1;
- }
- $ircdata->nick = substr($from, 0, $exclamationpos);
- $ircdata->ident = substr($from, $exclamationpos+1, ($atpos-$exclamationpos)-1);
- $ircdata->host = substr($from, $atpos+1);
- $ircdata->type = $this->_gettype($rawline);
- $ircdata->from = $from;
- if ($colonpos !== false) {
- $ircdata->message = substr($line, $colonpos+1);
- $ircdata->messageex = explode(' ', $ircdata->message);
- }
-
- if ($ircdata->type & (SMARTIRC_TYPE_CHANNEL|
- SMARTIRC_TYPE_ACTION|
- SMARTIRC_TYPE_MODECHANGE|
- SMARTIRC_TYPE_TOPICCHANGE|
- SMARTIRC_TYPE_KICK|
- SMARTIRC_TYPE_PART|
- SMARTIRC_TYPE_JOIN)) {
- $ircdata->channel = $lineex[2];
- } else if ($ircdata->type & (SMARTIRC_TYPE_WHO|
- SMARTIRC_TYPE_BANLIST|
- SMARTIRC_TYPE_TOPIC|
- SMARTIRC_TYPE_CHANNELMODE)) {
- $ircdata->channel = $lineex[3];
- } else if ($ircdata->type & SMARTIRC_TYPE_NAME) {
- $ircdata->channel = $lineex[4];
- }
-
- if ($ircdata->channel !== null) {
- if (substr($ircdata->channel, 0, 1) == ':') {
- $ircdata->channel = substr($ircdata->channel, 1);
- }
- }
-
- $this->log(SMARTIRC_DEBUG_MESSAGEPARSER, 'DEBUG_MESSAGEPARSER: ircdata nick: "'.$ircdata->nick.
- '" ident: "'.$ircdata->ident.
- '" host: "'.$ircdata->host.
- '" type: "'.$ircdata->type.
- '" from: "'.$ircdata->from.
- '" channel: "'.$ircdata->channel.
- '" message: "'.$ircdata->message.
- '"', __FILE__, __LINE__);
- }
-
- // lets see if we have a messagehandler for it
- $this->_handlemessage($messagecode, $ircdata);
-
- if ($validmessage == true) {
- // now the actionhandlers are comming
- $this->_handleactionhandler($ircdata);
- }
-
- if (isset($ircdata)) {
- unset($ircdata);
- }
- }
- }
-
- /**
- * sends the pong for keeping alive
- *
- * Sends the PONG signal as reply of the PING from the IRC server.
- *
- * @param string $data
- * @return void
- * @access private
- */
- function _pong($data)
- {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: Ping? Pong!', __FILE__, __LINE__);
- $this->_send('PONG '.$data, SMARTIRC_CRITICAL);
- }
-
- /**
- * returns the calculated selecttimeout value
- *
- * @return integer selecttimeout in microseconds
- * @access private
- */
- function _selecttimeout()
- {
- if ($this->_messagebuffersize == 0) {
- $this->_selecttimeout = null;
-
- if ($this->_mintimer != false) {
- $this->_calculateselecttimeout($this->_mintimer);
- }
-
- if ($this->_autoreconnect == true) {
- $this->_calculateselecttimeout($this->_rxtimeout*1000);
- }
-
- $this->_calculateselecttimeout($this->_maxtimer);
- return $this->_selecttimeout;
- } else {
- return $this->_senddelay;
- }
- }
-
- /**
- * calculates the selecttimeout value
- *
- * @return void
- * @access private
- */
- function _calculateselecttimeout($microseconds)
- {
- if (($this->_selecttimeout > $microseconds) || $this->_selecttimeout === null) {
- $this->_selecttimeout = $microseconds;
- }
- }
-
- /**
- * updates _mintimer to the smallest timer interval
- *
- * @return void
- * @access private
- */
- function _updatemintimer()
- {
- $timerarray = array();
- foreach ($this->_timehandler as $values) {
- $timerarray[] = $values->interval;
- }
-
- $result = array_multisort($timerarray, SORT_NUMERIC, SORT_ASC);
- if ($result == true && isset($timerarray[0])) {
- $this->_mintimer = $timerarray[0];
- } else {
- $this->_mintimer = false;
- }
- }
-
- /**
- * reorders the actionhandler array, needed after removing one
- *
- * @return void
- * @access private
- */
- function _reorderactionhandler()
- {
- $orderedactionhandler = array();
- foreach ($this->_actionhandler as $value) {
- $orderedactionhandler[] = $value;
- }
- $this->_actionhandler = &$orderedactionhandler;
- }
-
- /**
- * reorders the timehandler array, needed after removing one
- *
- * @return void
- * @access private
- */
- function _reordertimehandler()
- {
- $orderedtimehandler = array();
- foreach ($this->_timehandler as $value) {
- $orderedtimehandler[] = $value;
- }
- $this->_timehandler = &$orderedtimehandler;
- }
-
- /**
- * reorders the modules array, needed after removing one
- *
- * @return void
- * @access private
- */
- function _reordermodules()
- {
- $orderedmodules = array();
- foreach ($this->_modules as $value) {
- $orderedmodules[] = $value;
- }
- $this->_modules = &$orderedmodules;
- }
-
- /**
- * determines the messagetype of $line
- *
- * Analyses the type of an IRC message and returns the type.
- *
- * @param string $line
- * @return integer SMARTIRC_TYPE_* constant
- * @access private
- */
- function _gettype($line)
- {
- if (preg_match('/^:[^ ]+? [0-9]{3} .+$/', $line) == 1) {
- $lineex = explode(' ', $line);
- $code = $lineex[1];
-
- switch ($code) {
- case SMARTIRC_RPL_WELCOME:
- case SMARTIRC_RPL_YOURHOST:
- case SMARTIRC_RPL_CREATED:
- case SMARTIRC_RPL_MYINFO:
- case SMARTIRC_RPL_BOUNCE:
- return SMARTIRC_TYPE_LOGIN;
- case SMARTIRC_RPL_LUSERCLIENT:
- case SMARTIRC_RPL_LUSEROP:
- case SMARTIRC_RPL_LUSERUNKNOWN:
- case SMARTIRC_RPL_LUSERME:
- case SMARTIRC_RPL_LUSERCHANNELS:
- return SMARTIRC_TYPE_INFO;
- case SMARTIRC_RPL_MOTDSTART:
- case SMARTIRC_RPL_MOTD:
- case SMARTIRC_RPL_ENDOFMOTD:
- return SMARTIRC_TYPE_MOTD;
- case SMARTIRC_RPL_NAMREPLY:
- case SMARTIRC_RPL_ENDOFNAMES:
- return SMARTIRC_TYPE_NAME;
- case SMARTIRC_RPL_WHOREPLY:
- case SMARTIRC_RPL_ENDOFWHO:
- return SMARTIRC_TYPE_WHO;
- case SMARTIRC_RPL_LISTSTART:
- return SMARTIRC_TYPE_NONRELEVANT;
- case SMARTIRC_RPL_LIST:
- case SMARTIRC_RPL_LISTEND:
- return SMARTIRC_TYPE_LIST;
- case SMARTIRC_RPL_BANLIST:
- case SMARTIRC_RPL_ENDOFBANLIST:
- return SMARTIRC_TYPE_BANLIST;
- case SMARTIRC_RPL_TOPIC:
- return SMARTIRC_TYPE_TOPIC;
- case SMARTIRC_RPL_WHOISUSER:
- case SMARTIRC_RPL_WHOISSERVER:
- case SMARTIRC_RPL_WHOISOPERATOR:
- case SMARTIRC_RPL_WHOISIDLE:
- case SMARTIRC_RPL_ENDOFWHOIS:
- case SMARTIRC_RPL_WHOISCHANNELS:
- return SMARTIRC_TYPE_WHOIS;
- case SMARTIRC_RPL_WHOWASUSER:
- case SMARTIRC_RPL_ENDOFWHOWAS:
- return SMARTIRC_TYPE_WHOWAS;
- case SMARTIRC_RPL_UMODEIS:
- return SMARTIRC_TYPE_USERMODE;
- case SMARTIRC_RPL_CHANNELMODEIS:
- return SMARTIRC_TYPE_CHANNELMODE;
- case SMARTIRC_ERR_NICKNAMEINUSE:
- case SMARTIRC_ERR_NOTREGISTERED:
- return SMARTIRC_TYPE_ERROR;
- default:
- $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: replycode UNKNOWN ('.$code.'): "'.$line.'"', __FILE__, __LINE__);
- }
- }
-
- if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'ACTION .*'.chr(1).'$/', $line) == 1) {
- return SMARTIRC_TYPE_ACTION;
- } else if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
- return (SMARTIRC_TYPE_CTCP_REQUEST|SMARTIRC_TYPE_CTCP);
- } else if (preg_match('/^:.*? NOTICE .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
- return (SMARTIRC_TYPE_CTCP_REPLY|SMARTIRC_TYPE_CTCP);
- } else if (preg_match('/^:.*? PRIVMSG (\&|\#|\+|\!).* :.*$/', $line) == 1) {
- return SMARTIRC_TYPE_CHANNEL;
- } else if (preg_match('/^:.*? PRIVMSG .*:.*$/', $line) == 1) {
- return SMARTIRC_TYPE_QUERY;
- } else if (preg_match('/^:.*? NOTICE .* :.*$/', $line) == 1) {
- return SMARTIRC_TYPE_NOTICE;
- } else if (preg_match('/^:.*? INVITE .* .*$/', $line) == 1) {
- return SMARTIRC_TYPE_INVITE;
- } else if (preg_match('/^:.*? JOIN .*$/', $line) == 1) {
- return SMARTIRC_TYPE_JOIN;
- } else if (preg_match('/^:.*? TOPIC .* :.*$/', $line) == 1) {
- return SMARTIRC_TYPE_TOPICCHANGE;
- } else if (preg_match('/^:.*? NICK .*$/', $line) == 1) {
- return SMARTIRC_TYPE_NICKCHANGE;
- } else if (preg_match('/^:.*? KICK .* .*$/', $line) == 1) {
- return SMARTIRC_TYPE_KICK;
- } else if (preg_match('/^:.*? PART .*$/', $line) == 1) {
- return SMARTIRC_TYPE_PART;
- } else if (preg_match('/^:.*? MODE .* .*$/', $line) == 1) {
- return SMARTIRC_TYPE_MODECHANGE;
- } else if (preg_match('/^:.*? QUIT :.*$/', $line) == 1) {
- return SMARTIRC_TYPE_QUIT;
- } else {
- $this->log(SMARTIRC_DEBUG_MESSAGETYPES, 'DEBUG_MESSAGETYPES: SMARTIRC_TYPE_UNKNOWN!: "'.$line.'"', __FILE__, __LINE__);
- return SMARTIRC_TYPE_UNKNOWN;
- }
- }
-
- /**
- * updates the current connection state
- *
- * @return boolean
- * @access private
- */
- function _updatestate()
- {
- if (is_resource($this->_socket)) {
- $rtype = get_resource_type($this->_socket);
- if (($this->_socket !== false) &&
- ($rtype == 'socket' || $rtype == 'Socket' || $rtype == 'stream')) {
- $this->_state = true;
- return true;
- }
- } else {
- $this->_state = false;
- $this->_loggedin = false;
- return false;
- }
- }
-
- /**
- * returns the current connection state
- *
- * @return integer SMARTIRC_STATE_CONNECTED or SMARTIRC_STATE_DISCONNECTED
- * @access private
- */
- function _state()
- {
- $result = $this->_updatestate();
-
- if ($result == true) {
- return SMARTIRC_STATE_CONNECTED;
- } else {
- return SMARTIRC_STATE_DISCONNECTED;
- }
- }
-
- /**
- * tries to find a messagehandler for the received message ($ircdata) and calls it
- *
- * @param string $messagecode
- * @param object $ircdata
- * @return void
- * @access private
- */
- function _handlemessage($messagecode, &$ircdata)
- {
- $found = false;
-
- if (is_numeric($messagecode)) {
- if (!array_key_exists($messagecode, $this->nreplycodes)) {
- $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: ignoring unrecognized messagecode! "'.$messagecode.'"', __FILE__, __LINE__);
- $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: this IRC server ('.$this->_address.') doesn\'t conform to the RFC 2812!', __FILE__, __LINE__);
- return;
- }
-
- $methodname = 'event_'.strtolower($this->nreplycodes[$messagecode]);
- $_methodname = '_'.$methodname;
- $_codetype = 'by numeric';
- } else if (is_string($messagecode)) { // its not numericcode so already a name/string
- $methodname = 'event_'.strtolower($messagecode);
- $_methodname = '_'.$methodname;
- $_codetype = 'by string';
- }
-
- // if exists call internal method for the handling
- if (@method_exists($this, $_methodname)) {
- $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling internal method "'.get_class($this).'->'.$_methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
- $this->$_methodname($ircdata);
- $found = true;
- }
-
- // if exist, call user defined method for the handling
- if (@method_exists($this, $methodname)) {
- $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling user defined method "'.get_class($this).'->'.$methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
- $this->$methodname($ircdata);
- $found = true;
- }
-
- if ($found == false) {
- $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: no method found for "'.$messagecode.'" ('.$methodname.')', __FILE__, __LINE__);
- }
- }
-
- /**
- * Strips control characters from a IRC message.
- *
- * @param string $text
- *
- * @return string
- */
- function stripControlCharacters($text) {
- $controlCodes = array(
- '/(\x03(?:\d{1,2}(?:,\d{1,2})?)?)/', // Color code
- '/\x02/', // Bold
- '/\x0F/', // Escaped
- '/\x16/', // Italic
- '/\x1F/', // Underline
- '/\x12/'
- );
- return preg_replace($controlCodes,'',$text);
- }
-
- /**
- * tries to find a actionhandler for the received message ($ircdata) and calls it
- *
- * @param object $ircdata
- * @return void
- * @access private
- */
- function _handleactionhandler(&$ircdata)
- {
- $handler = &$this->_actionhandler;
- $handlercount = count($handler);
- for ($i = 0; $i < $handlercount; $i++) {
- $handlerobject = &$handler[$i];
-
- if (substr($handlerobject->message, 0, 1) == '/') {
- $regex = $handlerobject->message;
- } else {
- $regex = '/'.$handlerobject->message.'/';
- }
-
- $ircdata->message = $this->stripControlCharacters($ircdata->message);
- if (($handlerobject->type & $ircdata->type) &&
- (preg_match($regex, $ircdata->message) == 1)) {
-
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler match found for id: '.$i.' type: '.$ircdata->type.' message: "'.$ircdata->message.'" regex: "'.$regex.'"', __FILE__, __LINE__);
-
- $methodobject = &$handlerobject->object;
- $method = $handlerobject->method;
-
- if (@method_exists($methodobject, $method)) {
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
- $methodobject->$method($this, $ircdata);
- } else {
- $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: method doesn\'t exist! "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
- }
- }
- }
- }
-
- /**
- * Delay reconnect
- *
- * @return void
- * @access private
- */
- function _delayReconnect()
- {
- if ($this->_reconnectdelay > 0) {
- $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: delaying reconnect for '.$this->_reconnectdelay.' ms', __FILE__, __LINE__);
- usleep($this->_reconnectdelay * 1000);
- }
- }
-
- /**
- * getting current microtime, needed for benchmarks
- *
- * @return float
- * @access private
- */
- function _microint()
- {
- $tmp = microtime();
- $parts = explode(' ', $tmp);
- $floattime = (float)$parts[0] + (float)$parts[1];
- return $floattime;
- }
-
- /**
- * adds an user to the channelobject or updates his info
- *
- * @param object $channel
- * @param object $newuser
- * @return void
- * @access private
- */
- function _adduser(&$channel, &$newuser)
- {
- $lowerednick = strtolower($newuser->nick);
- if ($this->isJoined($channel->name, $newuser->nick)) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: updating user: '.$newuser->nick.' on channel: '.$channel->name, __FILE__, __LINE__);
-
- // lets update the existing user
- $currentuser = &$channel->users[$lowerednick];
-
- if ($newuser->ident !== null) {
- $currentuser->ident = $newuser->ident;
- }
- if ($newuser->host !== null) {
- $currentuser->host = $newuser->host;
- }
- if ($newuser->realname !== null) {
- $currentuser->realname = $newuser->realname;
- }
- if ($newuser->ircop !== null) {
- $currentuser->ircop = $newuser->ircop;
- }
- if ($newuser->founder !== null) {
- $currentuser->founder = $newuser->founder;
- }
- if ($newuser->admin !== null) {
- $currentuser->admin = $newuser->admin;
- }
- if ($newuser->op !== null) {
- $currentuser->op = $newuser->op;
- }
- if ($newuser->hop !== null) {
- $currentuser->hop = $newuser->hop;
- }
- if ($newuser->voice !== null) {
- $currentuser->voice = $newuser->voice;
- }
- if ($newuser->away !== null) {
- $currentuser->away = $newuser->away;
- }
- if ($newuser->server !== null) {
- $currentuser->server = $newuser->server;
- }
- if ($newuser->hopcount !== null) {
- $currentuser->hopcount = $newuser->hopcount;
- }
- } else {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding user: '.$newuser->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
-
- // he is new just add the reference to him
- $channel->users[$lowerednick] = &$newuser;
- }
-
- $user = &$channel->users[$lowerednick];
- if ($user->founder) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding founder: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
- $channel->founders[$user->nick] = true;
- }
- if ($user->admin) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding admin: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
- $channel->admins[$user->nick] = true;
- }
- if ($user->op) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding op: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
- $channel->ops[$user->nick] = true;
- }
- if ($user->hop) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding half-op: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
- $channel->hops[$user->nick] = true;
- }
- if ($user->voice) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding voice: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
- $channel->voices[$user->nick] = true;
- }
- }
-
- /**
- * removes an user from one channel or all if he quits
- *
- * @param object $ircdata
- * @return void
- * @access private
- */
- function _removeuser(&$ircdata)
- {
- if ($ircdata->type & (SMARTIRC_TYPE_PART|SMARTIRC_TYPE_QUIT)) {
- $nick = $ircdata->nick;
- } else if ($ircdata->type & SMARTIRC_TYPE_KICK) {
- $nick = $ircdata->rawmessageex[3];
- } else {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: unknown TYPE ('.$ircdata->type.') in _removeuser(), trying default', __FILE__, __LINE__);
- $nick = $ircdata->nick;
- }
-
- $lowerednick = strtolower($nick);
-
- if ($this->_nick == $nick) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: we left channel: '.$ircdata->channel.' destroying...', __FILE__, __LINE__);
- unset($this->_channels[strtolower($ircdata->channel)]);
- } else {
- if ($ircdata->type & SMARTIRC_TYPE_QUIT) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: user '.$nick.' quit, removing him from all channels', __FILE__, __LINE__);
- // remove the user from all channels
- $channelkeys = array_keys($this->_channels);
- foreach ($channelkeys as $channelkey) {
- // loop through all channels
- $channel = &$this->_channels[$channelkey];
- foreach ($channel->users as $uservalue) {
- // loop through all user in this channel
- if ($nick == $uservalue->nick) {
- // found him
- // kill him
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: found him on channel: '.$channel->name.' destroying...', __FILE__, __LINE__);
- unset($channel->users[$lowerednick]);
-
- if (isset($channel->founders[$nick])) {
- // die!
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from founder list', __FILE__, __LINE__);
- unset($channel->founders[$nick]);
- }
-
- if (isset($channel->admins[$nick])) {
- // die!
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from admin list', __FILE__, __LINE__);
- unset($channel->admins[$nick]);
- }
-
- if (isset($channel->ops[$nick])) {
- // die!
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
- unset($channel->ops[$nick]);
- }
-
- if (isset($channel->hops[$nick])) {
- // die!
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from hop list', __FILE__, __LINE__);
- unset($channel->hops[$nick]);
- }
-
- if (isset($channel->voices[$nick])) {
- // die!!
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
- unset($channel->voices[$nick]);
- }
-
- // ups this was not DukeNukem 3D
- }
- }
- }
- } else {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing user: '.$nick.' from channel: '.$ircdata->channel, __FILE__, __LINE__);
- $channel = &$this->_channels[strtolower($ircdata->channel)];
- unset($channel->users[$lowerednick]);
-
- if (isset($channel->founders[$nick])) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from founder list', __FILE__, __LINE__);
- unset($channel->founders[$nick]);
- }
-
- if (isset($channel->admins[$nick])) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from admin list', __FILE__, __LINE__);
- unset($channel->admins[$nick]);
- }
-
- if (isset($channel->ops[$nick])) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
- unset($channel->ops[$nick]);
- }
-
- if (isset($channel->hops[$nick])) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from hop list', __FILE__, __LINE__);
- unset($channel->hops[$nick]);
- }
-
- if (isset($channel->voices[$nick])) {
- $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
- unset($channel->voices[$nick]);
- }
- }
- }
- }
-
- /**
- * @return void
- * @access private
- */
- function _checkPHPVersion()
- {
- // doing nothing at the moment
- }
-
- /**
- * checks if the passed handlertype is valid
- *
- * @param integer $handlertype
- * @return boolean
- * @access private
- */
- function _isValidType($handlertype) {
- if ($handlertype & SMARTIRC_TYPE_ALL) {
- return true;
- } else {
- return false;
- }
- }
-
- function _addIrcUser()
- {
- }
-
- function _updateIrcUser()
- {
- }
-
- function _removeIrcUser()
- {
- }
-
- function _addChannelUser()
- {
- }
-
- function _updateChannelUser()
- {
- }
-
- function _removeChannelUser()
- {
- }
-
- //
-
- function isError($object)
- {
- return (bool)(is_object($object) && (strtolower(get_class($object)) == 'net_smartirc_error'));
- }
-
- function &throwError($message)
- {
- $error = new Net_SmartIRC_Error($message);
- return $error;
- }
+ /**
+ * @var resource
+ * @access private
+ */
+ protected $_socket;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_address;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_port;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_bindaddress = null;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_bindport = 0;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_nick;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_username;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_realname;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_usermode;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_password;
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_performs = array();
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_state = false;
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_actionhandler = array();
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_timehandler = array();
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_debug = SMARTIRC_DEBUG_NOTICE;
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_messagebuffer = array();
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_messagebuffersize;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_usesockets = false;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_receivedelay = 100;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_senddelay = 250;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_logdestination = SMARTIRC_STDOUT;
+
+ /**
+ * @var resource
+ * @access private
+ */
+ protected $_logfilefp = 0;
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_logfile = 'Net_SmartIRC.log';
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_disconnecttime = 1000;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_loggedin = false;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_benchmark = false;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_benchmark_starttime;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_benchmark_stoptime;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_actionhandlerid = 0;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_timehandlerid = 0;
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_motd = array();
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_channels = array();
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_channelsyncing = false;
+
+ /**
+ * @var array
+ * @access private
+ */
+ protected $_users = array();
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_usersyncing = false;
+
+ /**
+ * Stores the path to the modules that can be loaded.
+ *
+ * @var string
+ * @access private
+ */
+ protected $_modulepath = '';
+
+ /**
+ * Stores all objects of the modules.
+ *
+ * @var string
+ * @access private
+ */
+ protected $_modules = array();
+
+ /**
+ * @var string
+ * @access private
+ */
+ protected $_ctcpversion;
+
+ /**
+ * @var mixed
+ * @access private
+ */
+ protected $_mintimer = false;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_maxtimer = 300000;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_txtimeout = 300;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_rxtimeout = 300;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_selecttimeout;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_lastrx;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_lasttx;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_autoreconnect = false;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_reconnectdelay = 10000;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_autoretry = false;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_autoretrymax = 5;
+
+ /**
+ * @var integer
+ * @access private
+ */
+ protected $_autoretrycount = 0;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_connectionerror = false;
+
+ /**
+ * @var boolean
+ * @access private
+ */
+ protected $_runasdaemon = false;
+
+ /**
+ * @var array
+ */
+ protected $channelList = array();
+
+ /**
+ * All IRC replycodes, the index is the replycode name.
+ *
+ * @see $SMARTIRC_replycodes
+ * @var array
+ * @access public
+ */
+ public $replycodes;
+
+ /**
+ * All numeric IRC replycodes, the index is the numeric replycode.
+ *
+ * @see $SMARTIRC_nreplycodes
+ * @var array
+ * @access public
+ */
+ public $nreplycodes;
+
+ /**
+ * Stores all channels in this array where we are joined, works only if channelsyncing is activated.
+ * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
+ * $irc->channel['#test']->users['meebey']->nick;
+ *
+ * @see setChannelSyncing()
+ * @see Net_SmartIRC_channel
+ * @see Net_SmartIRC_channeluser
+ * @var array
+ * @access public
+ */
+ public $channel;
+
+ /**
+ * Stores all users that had/have contact with us (channel/query/notice etc.), works only if usersyncing is activated.
+ * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
+ * $irc->user['meebey']->host;
+ *
+ * @see setUserSyncing()
+ * @see Net_SmartIRC_ircuser
+ * @var array
+ * @access public
+ */
+ public $user;
+
+ /**
+ * Constructor. Initiates the messagebuffer and "links" the replycodes from
+ * global into properties. Also some PHP runtime settings are configured.
+ *
+ * @access public
+ */
+ public function __construct()
+ {
+ ob_implicit_flush(true);
+ @set_time_limit(0);
+ $this->_messagebuffer[SMARTIRC_CRITICAL] = array();
+ $this->_messagebuffer[SMARTIRC_HIGH] = array();
+ $this->_messagebuffer[SMARTIRC_MEDIUM] = array();
+ $this->_messagebuffer[SMARTIRC_LOW] = array();
+
+ $this->replycodes = &$GLOBALS['SMARTIRC_replycodes'];
+ $this->nreplycodes = &$GLOBALS['SMARTIRC_nreplycodes'];
+
+ // hack till PHP allows (PHP5) $object->somemethod($param)->memberofobject
+ $this->channel = &$this->_channels;
+ // another hack
+ $this->user = &$this->_users;
+
+ if (isset($_SERVER['REQUEST_METHOD'])) {
+ // the script is called from a browser, lets set default log destination
+ // to SMARTIRC_BROWSEROUT (makes browser friendly output)
+ $this->setLogdestination(SMARTIRC_BROWSEROUT);
+ }
+ }
+
+ /**
+ * Enables/disables the usage of real sockets.
+ *
+ * Enables/disables the usage of real sockets instead of fsocks
+ * (works only if your PHP build has loaded the PHP socket extension)
+ * Default: false
+ *
+ * @param bool $boolean
+ * @return void
+ * @access public
+ */
+ public function setUseSockets($boolean)
+ {
+ $this->_usesockets = false;
+ if ($boolean === true) {
+ if (@extension_loaded('sockets')) {
+ $this->_usesockets = true;
+ } else {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: your PHP build doesn\'t support real sockets, will use fsocks instead', __FILE__, __LINE__);
+ }
+ }
+ }
+
+ /**
+ * Sets an IP address (and optionally, a port) to bind the socket to.
+ *
+ * Limits the bot to claiming only one of the machine's IPs as its home.
+ * Only works with setUseSockets(TRUE). Call with no parameters to unbind.
+ *
+ * @param string $addr
+ * @param int $port
+ * @return bool
+ * @access public
+ */
+ public function setBindAddress($addr=null, $port=0)
+ {
+ if ($this->_usesockets) {
+ $this->_bindaddress = $addr;
+ $this->_bindport = $port;
+ }
+ return $this->_usesockets;
+ }
+
+ /**
+ * Sets the level of debug messages.
+ *
+ * Sets the debug level (bitwise), useful for testing/developing your code.
+ * Here the list of all possible debug levels:
+ * SMARTIRC_DEBUG_NONE
+ * SMARTIRC_DEBUG_NOTICE
+ * SMARTIRC_DEBUG_CONNECTION
+ * SMARTIRC_DEBUG_SOCKET
+ * SMARTIRC_DEBUG_IRCMESSAGES
+ * SMARTIRC_DEBUG_MESSAGETYPES
+ * SMARTIRC_DEBUG_ACTIONHANDLER
+ * SMARTIRC_DEBUG_TIMEHANDLER
+ * SMARTIRC_DEBUG_MESSAGEHANDLER
+ * SMARTIRC_DEBUG_CHANNELSYNCING
+ * SMARTIRC_DEBUG_MODULES
+ * SMARTIRC_DEBUG_USERSYNCING
+ * SMARTIRC_DEBUG_ALL
+ *
+ * Default: SMARTIRC_DEBUG_NOTICE
+ *
+ * @see DOCUMENTATION
+ * @see SMARTIRC_DEBUG_NOTICE
+ * @param integer $level
+ * @return void
+ * @access public
+ */
+ public function setDebug($level)
+ {
+ $this->_debug = $level;
+ }
+
+ /**
+ * Enables/disables the benchmark engine.
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setBenchmark($boolean)
+ {
+ if (is_bool($boolean)) {
+ $this->_benchmark = $boolean;
+ } else {
+ $this->_benchmark = false;
+ }
+ }
+
+ /**
+ * Enables/disables channel syncing.
+ *
+ * Channel syncing means, all users on all channel we are joined are tracked in the
+ * channel array. This makes it very handy for botcoding.
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setChannelSyncing($boolean)
+ {
+ if (is_bool($boolean)) {
+ $this->_channelsyncing = $boolean;
+ } else {
+ $this->_channelsyncing = false;
+ }
+
+ if ($this->_channelsyncing == true) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing enabled', __FILE__, __LINE__);
+ } else {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing disabled', __FILE__, __LINE__);
+ }
+ }
+
+ /**
+ * Enables/disables user syncing.
+ *
+ * User syncing means, all users we have or had contact with through channel, query or
+ * notice are tracked in the $irc->user array. This is very handy for botcoding.
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setUserSyncing($boolean)
+ {
+ if (is_bool($boolean)) {
+ $this->_usersyncing = $boolean;
+ } else {
+ $this->_usersyncing = false;
+ }
+
+ if ($this->_usersyncing == true) {
+ $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing enabled', __FILE__, __LINE__);
+ } else {
+ $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing disabled', __FILE__, __LINE__);
+ }
+ }
+
+ /**
+ * Sets the CTCP version reply string.
+ *
+ * @param string $versionstring
+ * @return void
+ * @access public
+ */
+ public function setCtcpVersion($versionstring)
+ {
+ $this->_ctcpversion = $versionstring;
+ }
+
+ /**
+ * Sets the destination of all log messages.
+ *
+ * Sets the destination of log messages.
+ * $type can be:
+ * SMARTIRC_FILE for saving the log into a file
+ * SMARTIRC_STDOUT for echoing the log to stdout
+ * SMARTIRC_SYSLOG for sending the log to the syslog
+ * Default: SMARTIRC_STDOUT
+ *
+ * @see SMARTIRC_STDOUT
+ * @param integer $type must be on of the constants
+ * @return void
+ * @access public
+ */
+ public function setLogdestination($type)
+ {
+ switch ($type) {
+ case SMARTIRC_FILE:
+ case SMARTIRC_STDOUT:
+ case SMARTIRC_SYSLOG:
+ case SMARTIRC_BROWSEROUT:
+ case SMARTIRC_NONE:
+ $this->_logdestination = $type;
+ break;
+ default:
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: unknown logdestination type ('.$type.'), will use STDOUT instead', __FILE__, __LINE__);
+ $this->_logdestination = SMARTIRC_STDOUT;
+ }
+ }
+
+ /**
+ * Sets the file for the log if the destination is set to file.
+ *
+ * Sets the logfile, if {@link setLogdestination logdestination} is set to SMARTIRC_FILE.
+ * This should be only used with full path!
+ *
+ * @param string $file
+ * @return void
+ * @access public
+ */
+ public function setLogfile($file)
+ {
+ $this->_logfile = $file;
+ }
+
+ /**
+ * Sets the delaytime before closing the socket when disconnect.
+ *
+ * @param integer $milliseconds
+ * @return void
+ * @access public
+ */
+ public function setDisconnecttime($milliseconds)
+ {
+ if (is_integer($milliseconds) && $milliseconds >= 100) {
+ $this->_disconnecttime = $milliseconds;
+ } else {
+ $this->_disconnecttime = 100;
+ }
+ }
+
+ /**
+ * Sets the delaytime before attempting reconnect.
+ * Value of 0 disables the delay entirely.
+ *
+ * @param integer $milliseconds
+ * @return void
+ * @access public
+ */
+ public function setReconnectdelay($milliseconds)
+ {
+ if (is_integer($milliseconds)) {
+ $this->_reconnectdelay = $milliseconds;
+ } else {
+ $this->_reconnectdelay = 10000;
+ }
+ }
+
+ /**
+ * Sets the delay for receiving data from the IRC server.
+ *
+ * Sets the delaytime between messages that are received, this reduces your CPU load.
+ * Don't set this too low (min 100ms).
+ * Default: 100
+ *
+ * @param integer $milliseconds
+ * @return void
+ * @access public
+ */
+ public function setReceivedelay($milliseconds)
+ {
+ if (is_integer($milliseconds) && $milliseconds >= 100) {
+ $this->_receivedelay = $milliseconds;
+ } else {
+ $this->_receivedelay = 100;
+ }
+ }
+
+ /**
+ * Sets the delay for sending data to the IRC server.
+ *
+ * Sets the delaytime between messages that are sent, because IRC servers doesn't like floods.
+ * This will avoid sending your messages too fast to the IRC server.
+ * Default: 250
+ *
+ * @param integer $milliseconds
+ * @return void
+ * @access public
+ */
+ public function setSenddelay($milliseconds)
+ {
+ if (is_integer($milliseconds)) {
+ $this->_senddelay = $milliseconds;
+ } else {
+ $this->_senddelay = 250;
+ }
+ }
+
+ /**
+ * Enables/disables autoreconnecting.
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setAutoReconnect($boolean)
+ {
+ if (is_bool($boolean)) {
+ $this->_autoreconnect = $boolean;
+ } else {
+ $this->_autoreconnect = false;
+ }
+ }
+
+ /**
+ * Enables/disables autoretry for connecting to a server.
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setAutoRetry($boolean)
+ {
+ if (is_bool($boolean)) {
+ $this->_autoretry = $boolean;
+ } else {
+ $this->_autoretry = false;
+ }
+ }
+
+ /**
+ * Sets the maximum number of attempts to connect to a server
+ * before giving up.
+ *
+ * @param integer $autoretrymax
+ * @return void
+ * @access public
+ */
+ public function setAutoRetryMax($autoretrymax)
+ {
+ if (is_integer($autoretrymax)) {
+ $this->_autoretrymax = $autoretrymax;
+ } else {
+ $this->_autoretrymax = 5;
+ }
+ }
+
+ /**
+ * Sets the receive timeout.
+ *
+ * If the timeout occurs, the connection will be reinitialized
+ * Default: 300 seconds
+ *
+ * @param integer $seconds
+ * @return void
+ * @access public
+ */
+ public function setReceiveTimeout($seconds)
+ {
+ if (is_integer($seconds)) {
+ $this->_rxtimeout = $seconds;
+ } else {
+ $this->_rxtimeout = 300;
+ }
+ }
+
+ /**
+ * Sets the transmit timeout.
+ *
+ * If the timeout occurs, the connection will be reinitialized
+ * Default: 300 seconds
+ *
+ * @param integer $seconds
+ * @return void
+ * @access public
+ */
+ public function setTransmitTimeout($seconds)
+ {
+ if (is_integer($seconds)) {
+ $this->_txtimeout = $seconds;
+ } else {
+ $this->_txtimeout = 300;
+ }
+ }
+
+ /**
+ * Sets the paths for the modules.
+ *
+ * @param integer $path
+ * @return void
+ * @access public
+ */
+ public function setModulepath($path)
+ {
+ $this->_modulepath = $path;
+ }
+
+ /**
+ * Sets wheter the script should be run as a daemon or not
+ * ( actually disables/enables ignore_user_abort() )
+ *
+ * @param boolean $boolean
+ * @return void
+ * @access public
+ */
+ public function setRunAsDaemon($boolean)
+ {
+ if ($boolean === true) {
+ $this->_runasdaemon = true;
+ ignore_user_abort(true);
+ set_time_limit(0);
+ } else {
+ $this->_runasdaemon = false;
+ }
+ }
+
+ /**
+ * Starts the benchmark (sets the counters).
+ *
+ * @return void
+ * @access public
+ */
+ public function startBenchmark()
+ {
+ $this->_benchmark_starttime = $this->_microint();
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark started', __FILE__, __LINE__);
+ }
+
+ /**
+ * Stops the benchmark and displays the result.
+ *
+ * @return void
+ * @access public
+ */
+ public function stopBenchmark()
+ {
+ $this->_benchmark_stoptime = $this->_microint();
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark stopped', __FILE__, __LINE__);
+
+ if ($this->_benchmark) {
+ $this->showBenchmark();
+ }
+ }
+
+ /**
+ * Shows the benchmark result.
+ *
+ * @return void
+ * @access public
+ */
+ public function showBenchmark()
+ {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark time: '.((float)$this->_benchmark_stoptime-(float)$this->_benchmark_starttime), __FILE__, __LINE__);
+ }
+
+ /**
+ * Adds an entry to the log.
+ *
+ * Adds an entry to the log with Linux style log format.
+ * Possible $level constants (can also be combined with "|"s)
+ * SMARTIRC_DEBUG_NONE
+ * SMARTIRC_DEBUG_NOTICE
+ * SMARTIRC_DEBUG_CONNECTION
+ * SMARTIRC_DEBUG_SOCKET
+ * SMARTIRC_DEBUG_IRCMESSAGES
+ * SMARTIRC_DEBUG_MESSAGETYPES
+ * SMARTIRC_DEBUG_ACTIONHANDLER
+ * SMARTIRC_DEBUG_TIMEHANDLER
+ * SMARTIRC_DEBUG_MESSAGEHANDLER
+ * SMARTIRC_DEBUG_CHANNELSYNCING
+ * SMARTIRC_DEBUG_MODULES
+ * SMARTIRC_DEBUG_USERSYNCING
+ * SMARTIRC_DEBUG_ALL
+ *
+ * @see SMARTIRC_DEBUG_NOTICE
+ * @param integer $level bit constants (SMARTIRC_DEBUG_*)
+ * @param string $file
+ * @param string $entry the new log entry
+ * @param string $line
+ * @return void
+ * @access protected
+ */
+ protected function log($level, $entry, $file = null, $line = null)
+ {
+ // prechecks
+ if (!(is_integer($level)) ||
+ !($level & SMARTIRC_DEBUG_ALL)) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: invalid log level passed to log() ('.$level.')', __FILE__, __LINE__);
+ return;
+ }
+
+ if (!($level & $this->_debug) ||
+ ($this->_logdestination == SMARTIRC_NONE)) {
+ return;
+ }
+
+ if (substr($entry, -1) != "\n") {
+ $entry .= "\n";
+ }
+
+ if ($file !== null &&
+ $line !== null) {
+ $file = basename($file);
+ $entry = $file.'('.$line.') '.$entry;
+ } else {
+ $entry = 'unknown(0) '.$entry;
+ }
+
+ $formatedentry = date('M d H:i:s ').$entry;
+ switch ($this->_logdestination) {
+ case SMARTIRC_STDOUT:
+ echo $formatedentry;
+ flush();
+ break;
+ case SMARTIRC_BROWSEROUT:
+ echo ''.htmlentities($formatedentry).'
';
+ break;
+ case SMARTIRC_FILE:
+ if (!is_resource($this->_logfilefp)) {
+ if ($this->_logfilefp === null) {
+ // we reconncted and don't want to destroy the old log entries
+ $this->_logfilefp = fopen($this->_logfile,'a');
+ } else {
+ $this->_logfilefp = fopen($this->_logfile,'w');
+ }
+ }
+ fwrite($this->_logfilefp, $formatedentry);
+ fflush($this->_logfilefp);
+ break;
+ case SMARTIRC_SYSLOG:
+ if (!is_int($this->_logfilefp)) {
+ $this->_logfilefp = openlog('Net_SmartIRC', LOG_NDELAY, LOG_DAEMON);
+ }
+ syslog(LOG_INFO, $entry);
+ break;
+ }
+ }
+
+ /**
+ * Returns the full motd.
+ *
+ * @return array
+ * @access public
+ */
+ public function getMotd()
+ {
+ return $this->_motd;
+ }
+
+ /**
+ * Returns the usermode.
+ *
+ * @return string
+ * @access public
+ */
+ public function getUsermode()
+ {
+ return $this->_usermode;
+ }
+
+ /**
+ * Returns a reference to the channel object of the specified channelname.
+ *
+ * @param string $channelname
+ * @return object
+ * @access public
+ */
+ public function getChannel($channelname)
+ {
+ if ($this->_channelsyncing != true) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getChannel() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
+ return false;
+ }
+
+ if ($this->isJoined($channelname)) {
+ return $this->_channels[strtolower($channelname)];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a reference to the user object for the specified username and channelname.
+ *
+ * @param string $channelname
+ * @param string $username
+ * @return object
+ * @access public
+ */
+ public function getUser($channelname, $username)
+ {
+ if ($this->_channelsyncing != true) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getUser() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
+ return false;
+ }
+
+ if ($this->isJoined($channelname, $username)) {
+ return $this->_channels[strtolower($channelname)]->users[strtolower($username)];
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Creates the sockets and connects to the IRC server on the given port.
+ *
+ * @param string $address
+ * @param integer $port
+ * @return boolean
+ * @access public
+ */
+ public function connect($address, $port)
+ {
+ $this->_address = $address;
+ $this->_port = $port;
+ $this->_autoretrycount = 0;
+ $connected = false;
+ if ($this->_autoretry === true && ($this->_autoretrycount < $this->_autoretrymax)) {
+ while ($this->_autoretrycount < $this->_autoretrymax) {
+ $connected = $this->connectHelper($address, $port);
+ if ($connected === true) {
+ break;
+ } else {
+ $this->_delayReconnect();
+ $this->_autoretrycount++;
+ }
+ }
+ } else {
+ $connected = $this->connectHelper($address, $port);
+ }
+ if ($connected === false) {
+ $this->_connectionerror = true;
+ }
+ return $connected;
+ }
+
+ /**
+ * Helper method for connecting.
+ *
+ * @return boolean
+ * @access protected
+ */
+ protected function connectHelper()
+ {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connecting', __FILE__, __LINE__);
+ $errno = $errstr = 0;
+
+ 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);
+ if ($this->_bindaddress !== null) {
+ if (socket_bind($this->_socket, $this->_bindaddress, $this->_bindport)) {
+ $this->log(SMARTIRC_DEBUG_SOCKET,
+ 'DEBUG_SOCKET: bound to '.$this->_bindaddress.':'
+ .$this->_bindport, __FILE__, __LINE__);
+ } else {
+ $errno = socket_last_error($this->_socket);
+
+ $error_msg =
+ 'ERROR: Unable to bind '.$this->_bindaddress.':'
+ .$this->_bindport.' reason: '.socket_strerror($errno)
+ .' ('.$errno.')';
+
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'Warning: '.$error_msg, __FILE__, __LINE__);
+ echo $error_msg . PHP_EOL;
+ return false;
+ }
+ }
+ $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 "'.$this->_address.'" reason: "'.$error.'"';
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'Warning: '.$error_msg, __FILE__, __LINE__);
+
+ if (($this->_autoretry == true) &&
+ ($this->_autoretrycount < $this->_autoretrymax)) {
+ echo 'ERROR connecting to (' . $this->_address . ':' . $this->_port .
+ ') error: (' . $error . ') retry (' . $this->_autoretrycount .
+ '/' . $this->_autoretrymax .
+ '). Sleeping for (' . $this->_reconnectdelay . ') ms.' . PHP_EOL;
+ return false;
+ } else {
+ echo 'ERROR connecting to (' . $this->_address . ':' . $this->_port .
+ ') after (' . $this->_autoretrymax . ') retries, error: (' .
+ $error . ').' . PHP_EOL;
+ return false;
+ }
+ } else {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connected', __FILE__, __LINE__);
+ $this->_autoretrycount = 0;
+ $this->_connectionerror = false;
+
+ if ($this->_usesockets != true) {
+ $this->_socket = $result;
+ $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: activating nonblocking fsocket mode', __FILE__, __LINE__);
+ stream_set_blocking($this->_socket, 0);
+ }
+ }
+
+ $this->_lastrx = $this->_lasttx = time();
+ $this->_updatestate();
+
+ return $result;
+ }
+
+ /**
+ * 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
+ */
+ public function disconnect($quickdisconnect = false)
+ {
+ if ($this->_connectionerror === false && $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__);
+ }
+
+ 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->_usersyncing == true) {
+ // let's clean our user array
+ $this->_users = array();
+ $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: cleaned user 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
+ */
+ public function reconnect()
+ {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: reconnecting...', __FILE__, __LINE__);
+ $this->disconnect(true);
+ $this->connect($this->_address, $this->_port);
+ $this->login($this->_nick, $this->_realname, $this->_usermode, $this->_username, $this->_password);
+ $this->joinChannels($this->channelList);
+ }
+
+ /**
+ * Join one or more channel.
+ *
+ * @param array $channelarray array('#channelname1' => 'password', '#channelname2' => null);
+ * @param int $priority
+ *
+ * @return bool
+ */
+ public function joinChannels($channelarray, $priority = SMARTIRC_MEDIUM)
+ {
+ if ($this->_connectionerror === true || $this->_state() === SMARTIRC_STATE_DISCONNECTED) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'Warning: you must connect to IRC before joining channels!', __FILE__, __LINE__);
+ return false;
+ }
+
+ $this->channelList = $channelarray;
+ return $this->join($channelarray, $priority);
+ }
+
+ /**
+ * 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 bool
+ * @access public
+ */
+ public function login($nick, $realname, $usermode = 0, $username = null, $password = null)
+ {
+ if ($this->_connectionerror === true || $this->_state() === SMARTIRC_STATE_DISCONNECTED) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'Warning: you must connect to IRC before logging in!', __FILE__, __LINE__);
+ return false;
+ }
+
+ $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, 'Warning: login() usermode ('.$usermode.') is not valid, will use 0 instead', __FILE__, __LINE__);
+ $usermode = 0;
+ }
+ $this->_usermode = $usermode;
+
+ $this->_send('NICK '.$this->_nick, SMARTIRC_CRITICAL);
+ $this->_send('USER '.$this->_username.' '.$this->_usermode.' '.SMARTIRC_UNUSED.' :'.$this->_realname, SMARTIRC_CRITICAL);
+
+ if (count($this->_performs)) {
+ // if we have extra commands to send, do it now
+ foreach($this->_performs as $command) {
+ $this->_send($command, SMARTIRC_HIGH);
+ }
+ // if we sent "ns auth" commands, we may need to resend our nick
+ $this->_send('NICK '.$this->_nick, SMARTIRC_HIGH);
+ }
+ return true;
+ }
+
+ //
+
+ /**
+ * adds a command to the list of commands to be sent after login() info
+ *
+ * @param string $cmd the command to add to the perform list
+ * @access public
+ */
+ public function perform($cmd)
+ {
+ $this->_performs[] = $cmd;
+ }
+
+ /**
+ * checks if the passed nickname is our own nickname
+ *
+ * @param string $nickname
+ * @return boolean
+ * @access public
+ */
+ public function isMe($nickname)
+ {
+ if ($nickname == $this->_nick) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 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
+ */
+ 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 founder 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
+ */
+ public function isFounder($channel, $nickname = null)
+ {
+ if ($this->_channelsyncing != true) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isFounder() 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)]->founder) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if we or the given user is admin 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
+ */
+ public function isAdmin($channel, $nickname = null)
+ {
+ if ($this->_channelsyncing != true) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isAdmin() 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)]->admin) {
+ 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
+ */
+ 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 hopped 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
+ */
+ public function isHopped($channel, $nickname = null)
+ {
+ if ($this->_channelsyncing != true) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isHopped() 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)]->hop) {
+ 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
+ */
+ 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
+ */
+ 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
+ */
+ public function listen()
+ {
+ while (true) {
+ if ($this->listenOnce() === false) {
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * goes into receive mode _only_ for one pass
+ *
+ * Goes into receive mode. It will return when one pass is complete.
+ * Use this when you want to connect to multiple IRC servers.
+ *
+ * @return boolean
+ * @access public
+ */
+ public function listenOnce()
+ {
+ if ($this->checkConnection()) {
+ $this->_rawreceive();
+ if ($this->checkConnection()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if the connection is still up.
+ *
+ * @return bool
+ */
+ protected function checkConnection()
+ {
+ if ($this->_connectionerror || $this->_state() === SMARTIRC_STATE_DISCONNECTED) {
+ if ($this->_autoreconnect) {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will reconnect!', __FILE__, __LINE__);
+ $this->reconnect();
+ return ($this->_connectionerror && $this->_state() === SMARTIRC_STATE_DISCONNECTED);
+ } else {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will disconnect!', __FILE__, __LINE__);
+ $this->disconnect();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 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
+ */
+ 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;
+ }
+
+ /**
+ * registers a new actionhandler and returns the assigned id
+ *
+ * Registers an actionhandler in Net_SmartIRC for calling it later.
+ * The actionhandler id is needed for unregistering the actionhandler.
+ *
+ * @see example.php
+ * @param integer $handlertype bits constants, see in this documentation Message Types
+ * @param string $regexhandler the message that has to be in the IRC message in regex syntax
+ * @param object $object a reference to the objects of the method
+ * @param string $methodname the methodname that will be called when the handler happens
+ * @return integer assigned actionhandler id
+ * @access public
+ */
+ public function registerActionhandler($handlertype, $regexhandler, &$object, $methodname)
+ {
+ // precheck
+ if (!$this->_isValidType($handlertype)) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to registerActionhandler()', __FILE__, __LINE__);
+ return false;
+ }
+
+ $id = $this->_actionhandlerid++;
+ $newactionhandler = new Net_SmartIRC_actionhandler();
+
+ $newactionhandler->id = $id;
+ $newactionhandler->type = $handlertype;
+ $newactionhandler->message = $regexhandler;
+ $newactionhandler->object = &$object;
+ $newactionhandler->method = $methodname;
+
+ $this->_actionhandler[] = &$newactionhandler;
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') registered', __FILE__, __LINE__);
+ return $id;
+ }
+
+ /**
+ * unregisters an existing actionhandler
+ *
+ * @param integer $handlertype
+ * @param string $regexhandler
+ * @param object $object
+ * @param string $methodname
+ * @return boolean
+ * @access public
+ */
+ public function unregisterActionhandler($handlertype, $regexhandler, &$object, $methodname)
+ {
+ // precheck
+ if (!$this->_isValidType($handlertype)) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to unregisterActionhandler()', __FILE__, __LINE__);
+ return false;
+ }
+
+ $handler = &$this->_actionhandler;
+ $handlercount = count($handler);
+
+ for ($i = 0; $i < $handlercount; $i++) {
+ $handlerobject = &$handler[$i];
+
+ if ($handlerobject->type == $handlertype &&
+ $handlerobject->message == $regexhandler &&
+ $handlerobject->method == $methodname) {
+
+ $id = $handlerobject->id;
+
+ if (isset($this->_actionhandler[$i])) {
+ unset($this->_actionhandler[$i]);
+ }
+
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
+ $this->_reorderactionhandler();
+ return true;
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler type: "'.$handlertype.'" message: "'.$regexhandler.'" method: "'.$methodname.'" from object "'.get_class($object).'" _not_ unregistered', __FILE__, __LINE__);
+ return false;
+ }
+
+ /**
+ * unregisters an existing actionhandler via the id
+ *
+ * @param integer $id
+ * @return boolean
+ * @access public
+ */
+ public function unregisterActionid($id)
+ {
+ $handler = &$this->_actionhandler;
+ $handlercount = count($handler);
+ for ($i = 0; $i < $handlercount; $i++) {
+ $handlerobject = &$handler[$i];
+
+ if ($handlerobject->id == $id) {
+ if (isset($this->_actionhandler[$i])) {
+ unset($this->_actionhandler[$i]);
+ }
+
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
+ $this->_reorderactionhandler();
+ return true;
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
+ return false;
+ }
+
+ /**
+ * registers a timehandler and returns the assigned id
+ *
+ * Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
+ * The timehandler id is needed for unregistering the timehandler.
+ *
+ * @see example7.php
+ * @param integer $interval interval time in milliseconds
+ * @param object $object a reference to the objects of the method
+ * @param string $methodname the methodname that will be called when the handler happens
+ * @return integer assigned timehandler id
+ * @access public
+ */
+ public function registerTimehandler($interval, &$object, $methodname)
+ {
+ $id = $this->_timehandlerid++;
+ $newtimehandler = new Net_SmartIRC_timehandler();
+
+ $newtimehandler->id = $id;
+ $newtimehandler->interval = $interval;
+ $newtimehandler->object = &$object;
+ $newtimehandler->method = $methodname;
+ $newtimehandler->lastmicrotimestamp = $this->_microint();
+
+ $this->_timehandler[] = &$newtimehandler;
+ $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') registered', __FILE__, __LINE__);
+
+ if (($interval < $this->_mintimer) || ($this->_mintimer == false)) {
+ $this->_mintimer = $interval;
+ }
+
+ return $id;
+ }
+
+ /**
+ * unregisters an existing timehandler via the id
+ *
+ * @see example7.php
+ * @param integer $id
+ * @return boolean
+ * @access public
+ */
+ public function unregisterTimeid($id)
+ {
+ $handler = &$this->_timehandler;
+ $handlercount = count($handler);
+ for ($i = 0; $i < $handlercount; $i++) {
+ $handlerobject = &$handler[$i];
+
+ if ($handlerobject->id == $id) {
+ if (isset($this->_timehandler[$i])) {
+ unset($this->_timehandler[$i]);
+ }
+
+ $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') unregistered', __FILE__, __LINE__);
+ $this->_reordertimehandler();
+ $this->_updatemintimer();
+ return true;
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: could not find timehandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
+ return false;
+ }
+
+ public function loadModule($name)
+ {
+ // is the module already loaded?
+ if (in_array($name, $this->_modules)) {
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING! module with the name "'.$name.'" already loaded!', __FILE__, __LINE__);
+ return false;
+ }
+
+ $filename = $this->_modulepath.'/'.$name.'.php';
+ if (!file_exists($filename)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t load module "'.$filename.'" file doesn\'t exist', __FILE__, __LINE__);
+ return false;
+ }
+
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: loading module: "'.$name.'"...', __FILE__, __LINE__);
+ // pray that there is no parse error, it will kill us!
+ include_once($filename);
+ $classname = 'Net_SmartIRC_module_'.$name;
+
+ if (!class_exists($classname)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: class '.$classname.' not found in '.$filename, __FILE__, __LINE__);
+ return false;
+ }
+
+ $methods = get_class_methods($classname);
+ if (!in_array('__construct', $methods) && !in_array('module_init', $methods)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::__construct not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ if (!in_array('__destruct', $methods) && !in_array('module_exit', $methods)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::__destruct not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ $vars = array_keys(get_class_vars($classname));
+ if (!in_array('name', $vars)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::name not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ if (!in_array('description', $vars)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::description not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ if (!in_array('author', $vars)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::author not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ if (!in_array('license', $vars)) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::license not found, aborting...', __FILE__, __LINE__);
+ return false;
+ }
+
+ // looks like the module satisfies us, so instantiate it
+ if (in_array('module_init', $methods)) {
+ // we're using an old module_init style module
+ $module = new $classname;
+ } else if (func_num_args() == 1) {
+ // we're using a new __construct style module, which maintains its
+ // own reference to the $irc client object it's being used on
+ $module = new $classname($this);
+ } else {
+ // we're using new style AND we have args to pass to the constructor
+ if (func_num_args() == 2) {
+ // only one arg, so pass it as is
+ $module = new $classname($this, func_get_arg(1));
+ } else {
+ // multiple args, so pass them in an array
+ $module = new $classname($this, array_slice(func_get_args(), 1));
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully created'
+ .' instance of: '.$classname, __FILE__, __LINE__
+ );
+
+ // check for deprecated init function and run it if it exists
+ if (in_array('module_init', get_class_methods($classname))) {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: calling '
+ .$classname.'::module_init()', __FILE__, __LINE__
+ );
+ $module->module_init($this);
+ }
+
+ $this->_modules[$name] = &$module;
+
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully loaded'
+ .' module: '.$name, __FILE__, __LINE__
+ );
+ return true;
+ }
+
+ public function unloadModule($name)
+ {
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: unloading module: '.$name.'...', __FILE__, __LINE__);
+
+ $modules_keys = array_keys($this->_modules);
+ $modulecount = count($modules_keys);
+ for ($i = 0; $i < $modulecount; $i++) {
+ $module = &$this->_modules[$modules_keys[$i]];
+ $modulename = strtolower(get_class($module));
+
+ if ($modulename == 'net_smartirc_module_'.$name) {
+ if (in_array('module_exit', get_class_methods($modulename))) {
+ $module->module_exit($this);
+ }
+ unset($this->_modules[$i]); // should call __destruct() on it
+ $this->_reordermodules();
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successfully'
+ .' unloaded module: '.$name, __FILE__, __LINE__);
+ return true;
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t unload'
+ .' module: '.$name.' (it\'s not loaded!)', __FILE__, __LINE__
+ );
+ return false;
+ }
+
+ /**
+ * sends an IRC message
+ *
+ * Adds a message to the messagequeue, with the optional priority.
+ * $priority:
+ * SMARTIRC_CRITICAL
+ * SMARTIRC_HIGH
+ * SMARTIRC_MEDIUM
+ * SMARTIRC_LOW
+ *
+ * @param string $data
+ * @param integer $priority must be one of the priority constants
+ * @return boolean
+ * @access public
+ */
+ public function send($data, $priority = SMARTIRC_MEDIUM)
+ {
+ return $this->_send($data, $priority);
+ }
+
+ //
+ /**
+ * changes a already used nickname to a new nickname plus 3 random digits
+ *
+ * @return void
+ * @access private
+ */
+ protected function _nicknameinuse()
+ {
+ $newnickname = substr($this->_nick, 0, 5).rand(0, 999);
+ $this->changeNick($newnickname, SMARTIRC_CRITICAL);
+ }
+
+ /**
+ * sends an IRC message
+ *
+ * Adds a message to the messagequeue, with the optional priority.
+ * $priority:
+ * SMARTIRC_CRITICAL
+ * SMARTIRC_HIGH
+ * SMARTIRC_MEDIUM
+ * SMARTIRC_LOW
+ *
+ * @param string $data
+ * @param integer $priority must be one of the priority constants
+ * @return boolean
+ * @access private
+ */
+ protected function _send($data, $priority = SMARTIRC_MEDIUM)
+ {
+ switch ($priority) {
+ case SMARTIRC_CRITICAL:
+ $this->_rawsend($data);
+ break;
+ case SMARTIRC_HIGH:
+ case SMARTIRC_MEDIUM:
+ case SMARTIRC_LOW:
+ $this->_messagebuffer[$priority][] = $data;
+ break;
+ default:
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: message ('.$data.') with an invalid priority passed ('.$priority.'), message is ignored!', __FILE__, __LINE__);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * checks the buffer if there are messages to send
+ *
+ * @return void
+ * @access private
+ */
+ protected function _checkbuffer()
+ {
+ if (!$this->_loggedin) {
+ return;
+ }
+
+ static $highsent = 0;
+ static $lastmicrotimestamp = 0;
+
+ if ($lastmicrotimestamp == 0) {
+ $lastmicrotimestamp = $this->_microint();
+ }
+
+ $highcount = count($this->_messagebuffer[SMARTIRC_HIGH]);
+ $mediumcount = count($this->_messagebuffer[SMARTIRC_MEDIUM]);
+ $lowcount = count($this->_messagebuffer[SMARTIRC_LOW]);
+ $this->_messagebuffersize = $highcount+$mediumcount+$lowcount;
+
+ // don't send them too fast
+ if ($this->_microint() >= ($lastmicrotimestamp+($this->_senddelay/1000))) {
+ $result = null;
+ if ($highcount > 0 && $highsent <= 2) {
+ $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_HIGH]));
+ $lastmicrotimestamp = $this->_microint();
+ $highsent++;
+ } else if ($mediumcount > 0) {
+ $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_MEDIUM]));
+ $lastmicrotimestamp = $this->_microint();
+ $highsent = 0;
+ } else if ($lowcount > 0) {
+ $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_LOW]));
+ $lastmicrotimestamp = $this->_microint();
+ }
+ }
+ }
+
+ /**
+ * Checks the running timers and calls the registered timehandler,
+ * when the interval is reached.
+ *
+ * @return void
+ * @access private
+ */
+ protected function _checktimer()
+ {
+ if (!$this->_loggedin) {
+ return;
+ }
+
+ // has to be count() because the array may change during the loop!
+ for ($i = 0; $i < count($this->_timehandler); $i++) {
+ $handlerobject = &$this->_timehandler[$i];
+ $microtimestamp = $this->_microint();
+ if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+($handlerobject->interval/1000))) {
+ $methodobject = &$handlerobject->object;
+ $method = $handlerobject->method;
+ $handlerobject->lastmicrotimestamp = $microtimestamp;
+
+ if (@method_exists($methodobject, $method)) {
+ $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
+ $methodobject->$method($this);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks if a receive or transmit timeout occured and reconnects if configured
+ *
+ * @return void
+ * @access private
+ */
+ protected function _checktimeout()
+ {
+ if ($this->_autoreconnect == true) {
+ $timestamp = time();
+ if ($this->_lastrx < ($timestamp - $this->_rxtimeout)) {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: receive timeout detected, doing reconnect...', __FILE__, __LINE__);
+ $this->_delayReconnect();
+ $this->reconnect();
+ } else if ($this->_lasttx < ($timestamp - $this->_txtimeout)) {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: transmit timeout detected, doing reconnect...', __FILE__, __LINE__);
+ $this->_delayReconnect();
+ $this->reconnect();
+ }
+ }
+ }
+
+ /**
+ * sends a raw message to the IRC server (don't use this!!)
+ *
+ * Use message() or send() instead.
+ *
+ * @param string $data
+ * @return boolean
+ * @access private
+ */
+ protected function _rawsend($data)
+ {
+ if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
+ $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: sent: "'.$data.'"', __FILE__, __LINE__);
+
+ if ($this->_usesockets == true) {
+ $result = socket_write($this->_socket, $data.SMARTIRC_CRLF);
+ } else {
+ $result = fwrite($this->_socket, $data.SMARTIRC_CRLF);
+ }
+
+
+ if ($result === false) {
+ // writing to the socket failed, means the connection is broken
+ $this->_connectionerror = true;
+
+ return false;
+ } else {
+ $this->_lasttx = time();
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * goes into main receive mode _once_ per call and waits for messages from the IRC server
+ *
+ * @return bool
+ * @access private
+ */
+ protected function _rawreceive()
+ {
+ $lastpart = '';
+ $rawdataar = array();
+
+ $this->_checkbuffer();
+
+ $timeout = $this->_selecttimeout();
+ if ($this->_usesockets == true) {
+ $sread = array($this->_socket);
+ // this will trigger a warning when catching a signal
+ $result = @socket_select($sread, $w = null, $e = null, 0, $timeout*1000);
+
+ if ($result == 1) {
+ // the socket got data to read
+ $rawdata = socket_read($this->_socket, 10240);
+ } else if ($result === false) {
+ if (socket_last_error() == 4) {
+ // we got hit with a SIGHUP signal
+ $rawdata = null;
+ global $bot;
+
+ if (is_callable(array($bot, 'reload'))) {
+ $bot->reload();
+ }
+ } else {
+ // panic! panic! something went wrong!
+ $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket_select() returned false, something went wrong! Reason: '.socket_strerror(socket_last_error()), __FILE__, __LINE__);
+ exit;
+ }
+ } else {
+ // no data
+ $rawdata = null;
+ }
+ } else {
+ usleep($this->_receivedelay*1000);
+ $rawdata = fread($this->_socket, 10240);
+ }
+ if ($rawdata === false) {
+ // reading from the socket failed, the connection is broken
+ $this->_connectionerror = true;
+ return false;
+ }
+
+ $this->_checktimer();
+ $this->_checktimeout();
+
+ if ($rawdata !== null && !empty($rawdata)) {
+ $this->_lastrx = time();
+ $rawdata = str_replace("\r", '', $rawdata);
+ $rawdata = $lastpart.$rawdata;
+
+ $lastpart = substr($rawdata, strrpos($rawdata ,"\n")+1);
+ $rawdata = substr($rawdata, 0, strrpos($rawdata ,"\n"));
+ $rawdataar = explode("\n", $rawdata);
+ }
+
+ // loop through our received messages
+ while (count($rawdataar) > 0) {
+ $rawline = array_shift($rawdataar);
+ $validmessage = false;
+
+ $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: received: "'.$rawline.'"', __FILE__, __LINE__);
+
+ // building our data packet
+ $ircdata = new Net_SmartIRC_data();
+ $ircdata->rawmessage = $rawline;
+ $lineex = explode(' ', $rawline);
+ $ircdata->rawmessageex = $lineex;
+ $messagecode = $lineex[0];
+
+ if (substr($rawline, 0, 1) == ':') {
+ $validmessage = true;
+ $line = substr($rawline, 1);
+ $lineex = explode(' ', $line);
+
+ // conform to RFC 2812
+ $from = $lineex[0];
+ // Fix for ZNC.
+ $messagecode = (isset($lineex[1]) ? $lineex[1] : '');
+ $exclamationpos = strpos($from, '!');
+ $atpos = strpos($from, '@');
+ $colonpos = strpos($line, ' :');
+ if ($colonpos !== false) {
+ // we want the exact position of ":" not beginning from the space
+ $colonpos += 1;
+ }
+ $ircdata->nick = substr($from, 0, $exclamationpos);
+ $ircdata->ident = substr($from, $exclamationpos+1, ($atpos-$exclamationpos)-1);
+ $ircdata->host = substr($from, $atpos+1);
+ $ircdata->type = $this->_gettype($rawline);
+ $ircdata->from = $from;
+ if ($colonpos !== false) {
+ $ircdata->message = substr($line, $colonpos+1);
+ $ircdata->messageex = explode(' ', $ircdata->message);
+ }
+
+ if ($ircdata->type & (SMARTIRC_TYPE_CHANNEL|
+ SMARTIRC_TYPE_ACTION|
+ SMARTIRC_TYPE_MODECHANGE|
+ SMARTIRC_TYPE_TOPICCHANGE|
+ SMARTIRC_TYPE_KICK|
+ SMARTIRC_TYPE_PART|
+ SMARTIRC_TYPE_JOIN)) {
+ $ircdata->channel = $lineex[2];
+ } else if ($ircdata->type & (SMARTIRC_TYPE_WHO|
+ SMARTIRC_TYPE_BANLIST|
+ SMARTIRC_TYPE_TOPIC|
+ SMARTIRC_TYPE_CHANNELMODE)) {
+ $ircdata->channel = $lineex[3];
+ } else if ($ircdata->type & SMARTIRC_TYPE_NAME) {
+ $ircdata->channel = $lineex[4];
+ }
+
+ if ($ircdata->channel !== null) {
+ if (substr($ircdata->channel, 0, 1) == ':') {
+ $ircdata->channel = substr($ircdata->channel, 1);
+ }
+ }
+
+ $this->log(SMARTIRC_DEBUG_MESSAGEPARSER, 'DEBUG_MESSAGEPARSER: ircdata nick: "'.$ircdata->nick.
+ '" ident: "'.$ircdata->ident.
+ '" host: "'.$ircdata->host.
+ '" type: "'.$ircdata->type.
+ '" from: "'.$ircdata->from.
+ '" channel: "'.$ircdata->channel.
+ '" message: "'.$ircdata->message.
+ '"', __FILE__, __LINE__);
+ }
+
+ // lets see if we have a messagehandler for it
+ $this->_handlemessage($messagecode, $ircdata);
+
+ if ($validmessage == true) {
+ // now the actionhandlers are comming
+ $this->_handleactionhandler($ircdata);
+ }
+
+ if (isset($ircdata)) {
+ unset($ircdata);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * sends the pong for keeping alive
+ *
+ * Sends the PONG signal as reply of the PING from the IRC server.
+ *
+ * @param string $data
+ * @return void
+ * @access private
+ */
+ protected function _pong($data)
+ {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: Ping? Pong!', __FILE__, __LINE__);
+ $this->_send('PONG '.$data, SMARTIRC_CRITICAL);
+ }
+
+ /**
+ * returns the calculated selecttimeout value
+ *
+ * @return integer selecttimeout in microseconds
+ * @access private
+ */
+ protected function _selecttimeout()
+ {
+ if ($this->_messagebuffersize == 0) {
+ $this->_selecttimeout = null;
+
+ if ($this->_mintimer != false) {
+ $this->_calculateselecttimeout($this->_mintimer);
+ }
+
+ if ($this->_autoreconnect == true) {
+ $this->_calculateselecttimeout($this->_rxtimeout*1000);
+ }
+
+ $this->_calculateselecttimeout($this->_maxtimer);
+ return $this->_selecttimeout;
+ } else {
+ return $this->_senddelay;
+ }
+ }
+
+ /**
+ * calculates the selecttimeout value
+ *
+ * @param int $microseconds
+ * @return void
+ * @access private
+ */
+ protected function _calculateselecttimeout($microseconds)
+ {
+ if (($this->_selecttimeout > $microseconds) || $this->_selecttimeout === null) {
+ $this->_selecttimeout = $microseconds;
+ }
+ }
+
+ /**
+ * updates _mintimer to the smallest timer interval
+ *
+ * @return void
+ * @access private
+ */
+ protected function _updatemintimer()
+ {
+ $timerarray = array();
+ foreach ($this->_timehandler as $values) {
+ $timerarray[] = $values->interval;
+ }
+
+ $result = array_multisort($timerarray, SORT_NUMERIC, SORT_ASC);
+ if ($result == true && isset($timerarray[0])) {
+ $this->_mintimer = $timerarray[0];
+ } else {
+ $this->_mintimer = false;
+ }
+ }
+
+ /**
+ * reorders the actionhandler array, needed after removing one
+ *
+ * @return void
+ * @access private
+ */
+ protected function _reorderactionhandler()
+ {
+ $orderedactionhandler = array();
+ foreach ($this->_actionhandler as $value) {
+ $orderedactionhandler[] = $value;
+ }
+ $this->_actionhandler = &$orderedactionhandler;
+ }
+
+ /**
+ * reorders the timehandler array, needed after removing one
+ *
+ * @return void
+ * @access private
+ */
+ protected function _reordertimehandler()
+ {
+ $orderedtimehandler = array();
+ foreach ($this->_timehandler as $value) {
+ $orderedtimehandler[] = $value;
+ }
+ $this->_timehandler = &$orderedtimehandler;
+ }
+
+ /**
+ * reorders the modules array, needed after removing one
+ *
+ * @return void
+ * @access private
+ */
+ protected function _reordermodules()
+ {
+ $orderedmodules = array();
+ foreach ($this->_modules as $value) {
+ $orderedmodules[] = $value;
+ }
+ $this->_modules = &$orderedmodules;
+ }
+
+ /**
+ * determines the messagetype of $line
+ *
+ * Analyses the type of an IRC message and returns the type.
+ *
+ * @param string $line
+ * @return integer SMARTIRC_TYPE_* constant
+ * @access private
+ */
+ protected function _gettype($line)
+ {
+ if (preg_match('/^:[^ ]+? [0-9]{3} .+$/', $line) == 1) {
+ $lineex = explode(' ', $line);
+ $code = $lineex[1];
+
+ switch ($code) {
+ case SMARTIRC_RPL_WELCOME:
+ case SMARTIRC_RPL_YOURHOST:
+ case SMARTIRC_RPL_CREATED:
+ case SMARTIRC_RPL_MYINFO:
+ case SMARTIRC_RPL_BOUNCE:
+ return SMARTIRC_TYPE_LOGIN;
+ case SMARTIRC_RPL_LUSERCLIENT:
+ case SMARTIRC_RPL_LUSEROP:
+ case SMARTIRC_RPL_LUSERUNKNOWN:
+ case SMARTIRC_RPL_LUSERME:
+ case SMARTIRC_RPL_LUSERCHANNELS:
+ return SMARTIRC_TYPE_INFO;
+ case SMARTIRC_RPL_MOTDSTART:
+ case SMARTIRC_RPL_MOTD:
+ case SMARTIRC_RPL_ENDOFMOTD:
+ return SMARTIRC_TYPE_MOTD;
+ case SMARTIRC_RPL_NAMREPLY:
+ case SMARTIRC_RPL_ENDOFNAMES:
+ return SMARTIRC_TYPE_NAME;
+ case SMARTIRC_RPL_WHOREPLY:
+ case SMARTIRC_RPL_ENDOFWHO:
+ return SMARTIRC_TYPE_WHO;
+ case SMARTIRC_RPL_LISTSTART:
+ return SMARTIRC_TYPE_NONRELEVANT;
+ case SMARTIRC_RPL_LIST:
+ case SMARTIRC_RPL_LISTEND:
+ return SMARTIRC_TYPE_LIST;
+ case SMARTIRC_RPL_BANLIST:
+ case SMARTIRC_RPL_ENDOFBANLIST:
+ return SMARTIRC_TYPE_BANLIST;
+ case SMARTIRC_RPL_TOPIC:
+ return SMARTIRC_TYPE_TOPIC;
+ case SMARTIRC_RPL_WHOISUSER:
+ case SMARTIRC_RPL_WHOISSERVER:
+ case SMARTIRC_RPL_WHOISOPERATOR:
+ case SMARTIRC_RPL_WHOISIDLE:
+ case SMARTIRC_RPL_ENDOFWHOIS:
+ case SMARTIRC_RPL_WHOISCHANNELS:
+ return SMARTIRC_TYPE_WHOIS;
+ case SMARTIRC_RPL_WHOWASUSER:
+ case SMARTIRC_RPL_ENDOFWHOWAS:
+ return SMARTIRC_TYPE_WHOWAS;
+ case SMARTIRC_RPL_UMODEIS:
+ return SMARTIRC_TYPE_USERMODE;
+ case SMARTIRC_RPL_CHANNELMODEIS:
+ return SMARTIRC_TYPE_CHANNELMODE;
+ case SMARTIRC_ERR_NICKNAMEINUSE:
+ case SMARTIRC_ERR_NOTREGISTERED:
+ return SMARTIRC_TYPE_ERROR;
+ default:
+ $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: replycode UNKNOWN ('.$code.'): "'.$line.'"', __FILE__, __LINE__);
+ }
+ }
+
+ if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'ACTION .*'.chr(1).'$/', $line) == 1) {
+ return SMARTIRC_TYPE_ACTION;
+ } else if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
+ return (SMARTIRC_TYPE_CTCP_REQUEST|SMARTIRC_TYPE_CTCP);
+ } else if (preg_match('/^:.*? NOTICE .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
+ return (SMARTIRC_TYPE_CTCP_REPLY|SMARTIRC_TYPE_CTCP);
+ } else if (preg_match('/^:.*? PRIVMSG (\&|\#|\+|\!).* :.*$/', $line) == 1) {
+ return SMARTIRC_TYPE_CHANNEL;
+ } else if (preg_match('/^:.*? PRIVMSG .*:.*$/', $line) == 1) {
+ return SMARTIRC_TYPE_QUERY;
+ } else if (preg_match('/^:.*? NOTICE .* :.*$/', $line) == 1) {
+ return SMARTIRC_TYPE_NOTICE;
+ } else if (preg_match('/^:.*? INVITE .* .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_INVITE;
+ } else if (preg_match('/^:.*? JOIN .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_JOIN;
+ } else if (preg_match('/^:.*? TOPIC .* :.*$/', $line) == 1) {
+ return SMARTIRC_TYPE_TOPICCHANGE;
+ } else if (preg_match('/^:.*? NICK .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_NICKCHANGE;
+ } else if (preg_match('/^:.*? KICK .* .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_KICK;
+ } else if (preg_match('/^:.*? PART .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_PART;
+ } else if (preg_match('/^:.*? MODE .* .*$/', $line) == 1) {
+ return SMARTIRC_TYPE_MODECHANGE;
+ } else if (preg_match('/^:.*? QUIT :.*$/', $line) == 1) {
+ return SMARTIRC_TYPE_QUIT;
+ } else {
+ $this->log(SMARTIRC_DEBUG_MESSAGETYPES, 'DEBUG_MESSAGETYPES: SMARTIRC_TYPE_UNKNOWN!: "'.$line.'"', __FILE__, __LINE__);
+ return SMARTIRC_TYPE_UNKNOWN;
+ }
+ }
+
+ /**
+ * updates the current connection state
+ *
+ * @return boolean
+ * @access private
+ */
+ protected function _updatestate()
+ {
+ if (is_resource($this->_socket)) {
+ $rtype = get_resource_type($this->_socket);
+ if (($this->_socket !== false) &&
+ ($rtype == 'socket' || $rtype == 'Socket' || $rtype == 'stream')) {
+ $this->_state = true;
+ return true;
+ }
+ } else {
+ $this->_state = false;
+ $this->_loggedin = false;
+ }
+ return false;
+ }
+
+ /**
+ * returns the current connection state
+ *
+ * @return integer SMARTIRC_STATE_CONNECTED or SMARTIRC_STATE_DISCONNECTED
+ * @access private
+ */
+ protected function _state()
+ {
+ $result = $this->_updatestate();
+
+ if ($result == true) {
+ return SMARTIRC_STATE_CONNECTED;
+ } else {
+ return SMARTIRC_STATE_DISCONNECTED;
+ }
+ }
+
+ /**
+ * tries to find a messagehandler for the received message ($ircdata) and calls it
+ *
+ * @param string $messagecode
+ * @param object $ircdata
+ * @return void
+ * @access private
+ */
+ protected function _handlemessage($messagecode, &$ircdata)
+ {
+ $found = false;
+ $_methodname = $methodname = $_codetype = '';
+
+ if (is_numeric($messagecode)) {
+ if (!array_key_exists($messagecode, $this->nreplycodes)) {
+ $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: ignoring unrecognized messagecode! "'.$messagecode.'"', __FILE__, __LINE__);
+ $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: this IRC server ('.$this->_address.') doesn\'t conform to the RFC 2812!', __FILE__, __LINE__);
+ return;
+ }
+
+ $methodname = 'event_'.strtolower($this->nreplycodes[$messagecode]);
+ $_methodname = '_'.$methodname;
+ $_codetype = 'by numeric';
+ } else if (is_string($messagecode)) { // its not numericcode so already a name/string
+ $methodname = 'event_'.strtolower($messagecode);
+ $_methodname = '_'.$methodname;
+ $_codetype = 'by string';
+ }
+
+ // if exists call internal method for the handling
+ if (@method_exists($this, $_methodname)) {
+ $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling internal method "'.get_class($this).'->'.$_methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
+ $this->$_methodname($ircdata);
+ $found = true;
+ }
+
+ // if exist, call user defined method for the handling
+ if (@method_exists($this, $methodname)) {
+ $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling user defined method "'.get_class($this).'->'.$methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
+ $this->$methodname($ircdata);
+ $found = true;
+ }
+
+ if ($found == false) {
+ $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: no method found for "'.$messagecode.'" ('.$methodname.')', __FILE__, __LINE__);
+ }
+ }
+
+ /**
+ * Strips control characters from a IRC message.
+ *
+ * @param string $text
+ *
+ * @return string
+ */
+ protected function _stripControlCharacters($text) {
+ $controlCodes = array(
+ '/(\x03(?:\d{1,2}(?:,\d{1,2})?)?)/', // Color code
+ '/\x02/', // Bold
+ '/\x0F/', // Escaped
+ '/\x16/', // Italic
+ '/\x1F/', // Underline
+ '/\x12/'
+ );
+ return preg_replace($controlCodes,'',$text);
+ }
+
+ /**
+ * tries to find a actionhandler for the received message ($ircdata) and calls it
+ *
+ * @param object $ircdata
+ * @return void
+ * @access private
+ */
+ protected function _handleactionhandler(&$ircdata)
+ {
+ $handler = &$this->_actionhandler;
+ $handlercount = count($handler);
+ for ($i = 0; $i < $handlercount; $i++) {
+ $handlerobject = &$handler[$i];
+
+ if (substr($handlerobject->message, 0, 1) == '/') {
+ $regex = $handlerobject->message;
+ } else {
+ $regex = '/'.$handlerobject->message.'/';
+ }
+
+ $ircdata->message = $this->_stripControlCharacters($ircdata->message);
+ if (($handlerobject->type & $ircdata->type) &&
+ (preg_match($regex, $ircdata->message) == 1)) {
+
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler match found for id: '.$i.' type: '.$ircdata->type.' message: "'.$ircdata->message.'" regex: "'.$regex.'"', __FILE__, __LINE__);
+
+ $methodobject = &$handlerobject->object;
+ $method = $handlerobject->method;
+
+ if (@method_exists($methodobject, $method)) {
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
+ $methodobject->$method($this, $ircdata);
+ } else {
+ $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: method doesn\'t exist! "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
+ }
+ }
+ }
+ }
+
+ /**
+ * Delay reconnect
+ *
+ * @return void
+ * @access private
+ */
+ protected function _delayReconnect()
+ {
+ if ($this->_reconnectdelay > 0) {
+ $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: delaying reconnect for '.$this->_reconnectdelay.' ms', __FILE__, __LINE__);
+ usleep($this->_reconnectdelay * 1000);
+ }
+ }
+
+ /**
+ * getting current microtime, needed for benchmarks
+ *
+ * @return float
+ * @access private
+ */
+ protected function _microint()
+ {
+ $tmp = microtime();
+ $parts = explode(' ', $tmp);
+ $floattime = (float)$parts[0] + (float)$parts[1];
+ return $floattime;
+ }
+
+ /**
+ * adds an user to the channelobject or updates his info
+ *
+ * @param object $channel
+ * @param object $newuser
+ * @return void
+ * @access private
+ */
+ protected function _adduser(&$channel, &$newuser)
+ {
+ $lowerednick = strtolower($newuser->nick);
+ if ($this->isJoined($channel->name, $newuser->nick)) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: updating user: '.$newuser->nick.' on channel: '.$channel->name, __FILE__, __LINE__);
+
+ // lets update the existing user
+ $currentuser = &$channel->users[$lowerednick];
+
+ if ($newuser->ident !== null) {
+ $currentuser->ident = $newuser->ident;
+ }
+ if ($newuser->host !== null) {
+ $currentuser->host = $newuser->host;
+ }
+ if ($newuser->realname !== null) {
+ $currentuser->realname = $newuser->realname;
+ }
+ if ($newuser->ircop !== null) {
+ $currentuser->ircop = $newuser->ircop;
+ }
+ if ($newuser->founder !== null) {
+ $currentuser->founder = $newuser->founder;
+ }
+ if ($newuser->admin !== null) {
+ $currentuser->admin = $newuser->admin;
+ }
+ if ($newuser->op !== null) {
+ $currentuser->op = $newuser->op;
+ }
+ if ($newuser->hop !== null) {
+ $currentuser->hop = $newuser->hop;
+ }
+ if ($newuser->voice !== null) {
+ $currentuser->voice = $newuser->voice;
+ }
+ if ($newuser->away !== null) {
+ $currentuser->away = $newuser->away;
+ }
+ if ($newuser->server !== null) {
+ $currentuser->server = $newuser->server;
+ }
+ if ($newuser->hopcount !== null) {
+ $currentuser->hopcount = $newuser->hopcount;
+ }
+ } else {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding user: '.$newuser->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+
+ // he is new just add the reference to him
+ $channel->users[$lowerednick] = &$newuser;
+ }
+
+ $user = &$channel->users[$lowerednick];
+ if ($user->founder) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding founder: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+ $channel->founders[$user->nick] = true;
+ }
+ if ($user->admin) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding admin: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+ $channel->admins[$user->nick] = true;
+ }
+ if ($user->op) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding op: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+ $channel->ops[$user->nick] = true;
+ }
+ if ($user->hop) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding half-op: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+ $channel->hops[$user->nick] = true;
+ }
+ if ($user->voice) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding voice: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
+ $channel->voices[$user->nick] = true;
+ }
+ }
+
+ /**
+ * removes an user from one channel or all if he quits
+ *
+ * @param object $ircdata
+ * @return void
+ * @access private
+ */
+ protected function _removeuser(&$ircdata)
+ {
+ if ($ircdata->type & (SMARTIRC_TYPE_PART|SMARTIRC_TYPE_QUIT)) {
+ $nick = $ircdata->nick;
+ } else if ($ircdata->type & SMARTIRC_TYPE_KICK) {
+ $nick = $ircdata->rawmessageex[3];
+ } else {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: unknown TYPE ('.$ircdata->type.') in _removeuser(), trying default', __FILE__, __LINE__);
+ $nick = $ircdata->nick;
+ }
+
+ $lowerednick = strtolower($nick);
+
+ if ($this->_nick == $nick) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: we left channel: '.$ircdata->channel.' destroying...', __FILE__, __LINE__);
+ unset($this->_channels[strtolower($ircdata->channel)]);
+ } else {
+ if ($ircdata->type & SMARTIRC_TYPE_QUIT) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: user '.$nick.' quit, removing him from all channels', __FILE__, __LINE__);
+ // remove the user from all channels
+ $channelkeys = array_keys($this->_channels);
+ foreach ($channelkeys as $channelkey) {
+ // loop through all channels
+ $channel = &$this->_channels[$channelkey];
+ foreach ($channel->users as $uservalue) {
+ // loop through all user in this channel
+ if ($nick == $uservalue->nick) {
+ // found him
+ // kill him
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: found him on channel: '.$channel->name.' destroying...', __FILE__, __LINE__);
+ unset($channel->users[$lowerednick]);
+
+ if (isset($channel->founders[$nick])) {
+ // die!
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from founder list', __FILE__, __LINE__);
+ unset($channel->founders[$nick]);
+ }
+
+ if (isset($channel->admins[$nick])) {
+ // die!
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from admin list', __FILE__, __LINE__);
+ unset($channel->admins[$nick]);
+ }
+
+ if (isset($channel->ops[$nick])) {
+ // die!
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
+ unset($channel->ops[$nick]);
+ }
+
+ if (isset($channel->hops[$nick])) {
+ // die!
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from hop list', __FILE__, __LINE__);
+ unset($channel->hops[$nick]);
+ }
+
+ if (isset($channel->voices[$nick])) {
+ // die!!
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
+ unset($channel->voices[$nick]);
+ }
+
+ // ups this was not DukeNukem 3D
+ }
+ }
+ }
+ } else {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing user: '.$nick.' from channel: '.$ircdata->channel, __FILE__, __LINE__);
+ $channel = &$this->_channels[strtolower($ircdata->channel)];
+ unset($channel->users[$lowerednick]);
+
+ if (isset($channel->founders[$nick])) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from founder list', __FILE__, __LINE__);
+ unset($channel->founders[$nick]);
+ }
+
+ if (isset($channel->admins[$nick])) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from admin list', __FILE__, __LINE__);
+ unset($channel->admins[$nick]);
+ }
+
+ if (isset($channel->ops[$nick])) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
+ unset($channel->ops[$nick]);
+ }
+
+ if (isset($channel->hops[$nick])) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from hop list', __FILE__, __LINE__);
+ unset($channel->hops[$nick]);
+ }
+
+ if (isset($channel->voices[$nick])) {
+ $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
+ unset($channel->voices[$nick]);
+ }
+ }
+ }
+ }
+
+ /**
+ * checks if the passed handlertype is valid
+ *
+ * @param integer $handlertype
+ * @return boolean
+ * @access private
+ */
+ protected function _isValidType($handlertype) {
+ if ($handlertype & SMARTIRC_TYPE_ALL) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected function isError($object)
+ {
+ return (bool)(is_object($object) && (strtolower(get_class($object)) == 'net_smartirc_error'));
+ }
+
}
// includes must be after the base class definition, required for PHP5
@@ -2899,7 +2865,7 @@ require_once 'SmartIRC/messagehandler.php';
class Net_SmartIRC extends Net_SmartIRC_messagehandler
{
- // empty
+ // empty
}
/**
@@ -2907,65 +2873,65 @@ class Net_SmartIRC extends Net_SmartIRC_messagehandler
*/
class Net_SmartIRC_data
{
- /**
- * @var string
- * @access public
- */
- var $from;
+ /**
+ * @var string
+ * @access public
+ */
+ var $from;
- /**
- * @var string
- * @access public
- */
- var $nick;
+ /**
+ * @var string
+ * @access public
+ */
+ var $nick;
- /**
- * @var string
- * @access public
- */
- var $ident;
+ /**
+ * @var string
+ * @access public
+ */
+ var $ident;
- /**
- * @var string
- * @access public
- */
- var $host;
+ /**
+ * @var string
+ * @access public
+ */
+ var $host;
- /**
- * @var string
- * @access public
- */
- var $channel;
+ /**
+ * @var string
+ * @access public
+ */
+ var $channel;
- /**
- * @var string
- * @access public
- */
- var $message;
+ /**
+ * @var string
+ * @access public
+ */
+ var $message;
- /**
- * @var array
- * @access public
- */
- var $messageex = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $messageex = array();
- /**
- * @var integer
- * @access public
- */
- var $type;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $type;
- /**
- * @var string
- * @access public
- */
- var $rawmessage;
+ /**
+ * @var string
+ * @access public
+ */
+ var $rawmessage;
- /**
- * @var array
- * @access public
- */
- var $rawmessageex = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $rawmessageex = array();
}
/**
@@ -2973,35 +2939,35 @@ class Net_SmartIRC_data
*/
class Net_SmartIRC_actionhandler
{
- /**
- * @var integer
- * @access public
- */
- var $id;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $id;
- /**
- * @var integer
- * @access public
- */
- var $type;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $type;
- /**
- * @var string
- * @access public
- */
- var $message;
+ /**
+ * @var string
+ * @access public
+ */
+ var $message;
- /**
- * @var object
- * @access public
- */
- var $object;
+ /**
+ * @var object
+ * @access public
+ */
+ var $object;
- /**
- * @var string
- * @access public
- */
- var $method;
+ /**
+ * @var string
+ * @access public
+ */
+ var $method;
}
/**
@@ -3009,35 +2975,35 @@ class Net_SmartIRC_actionhandler
*/
class Net_SmartIRC_timehandler
{
- /**
- * @var integer
- * @access public
- */
- var $id;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $id;
- /**
- * @var integer
- * @access public
- */
- var $interval;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $interval;
- /**
- * @var integer
- * @access public
- */
- var $lastmicrotimestamp;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $lastmicrotimestamp;
- /**
- * @var object
- * @access public
- */
- var $object;
+ /**
+ * @var object
+ * @access public
+ */
+ var $object;
- /**
- * @var string
- * @access public
- */
- var $method;
+ /**
+ * @var string
+ * @access public
+ */
+ var $method;
}
/**
@@ -3045,95 +3011,95 @@ class Net_SmartIRC_timehandler
*/
class Net_SmartIRC_channel
{
- /**
- * @var string
- * @access public
- */
- var $name;
+ /**
+ * @var string
+ * @access public
+ */
+ var $name;
- /**
- * @var string
- * @access public
- */
- var $key;
+ /**
+ * @var string
+ * @access public
+ */
+ var $key;
- /**
- * @var array
- * @access public
- */
- var $users = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $users = array();
- /**
- * @var array
- * @access public
- */
- var $founders = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $founders = array();
- /**
- * @var array
- * @access public
- */
- var $admins = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $admins = array();
- /**
- * @var array
- * @access public
- */
- var $ops = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $ops = array();
- /**
- * @var array
- * @access public
- */
- var $hops = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $hops = array();
- /**
- * @var array
- * @access public
- */
- var $voices = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $voices = array();
- /**
- * @var array
- * @access public
- */
- var $bans = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $bans = array();
- /**
- * @var string
- * @access public
- */
- var $topic;
+ /**
+ * @var string
+ * @access public
+ */
+ var $topic;
- /**
- * @var string
- * @access public
- */
- var $user_limit = false;
+ /**
+ * @var string
+ * @access public
+ */
+ var $user_limit = false;
- /**
- * @var string
- * @access public
- */
- var $mode;
+ /**
+ * @var string
+ * @access public
+ */
+ var $mode;
- /**
- * @var integer
- * @access public
- */
- var $synctime_start = 0;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $synctime_start = 0;
- /**
- * @var integer
- * @access public
- */
- var $synctime_stop = 0;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $synctime_stop = 0;
- /**
- * @var integer
- * @access public
- */
- var $synctime;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $synctime;
}
/**
@@ -3141,53 +3107,53 @@ class Net_SmartIRC_channel
*/
class Net_SmartIRC_user
{
- /**
- * @var string
- * @access public
- */
- var $nick;
+ /**
+ * @var string
+ * @access public
+ */
+ var $nick;
- /**
- * @var string
- * @access public
- */
- var $ident;
+ /**
+ * @var string
+ * @access public
+ */
+ var $ident;
- /**
- * @var string
- * @access public
- */
- var $host;
+ /**
+ * @var string
+ * @access public
+ */
+ var $host;
- /**
- * @var string
- * @access public
- */
- var $realname;
+ /**
+ * @var string
+ * @access public
+ */
+ var $realname;
- /**
- * @var boolean
- * @access public
- */
- var $ircop;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $ircop;
- /**
- * @var boolean
- * @access public
- */
- var $away;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $away;
- /**
- * @var string
- * @access public
- */
- var $server;
+ /**
+ * @var string
+ * @access public
+ */
+ var $server;
- /**
- * @var integer
- * @access public
- */
- var $hopcount;
+ /**
+ * @var integer
+ * @access public
+ */
+ var $hopcount;
}
/**
@@ -3195,35 +3161,35 @@ class Net_SmartIRC_user
*/
class Net_SmartIRC_channeluser extends Net_SmartIRC_user
{
- /**
- * @var boolean
- * @access public
- */
- var $founder;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $founder;
- /**
- * @var boolean
- * @access public
- */
- var $admin;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $admin;
- /**
- * @var boolean
- * @access public
- */
- var $op;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $op;
- /**
- * @var boolean
- * @access public
- */
- var $hop;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $hop;
- /**
- * @var boolean
- * @access public
- */
- var $voice;
+ /**
+ * @var boolean
+ * @access public
+ */
+ var $voice;
}
/**
@@ -3231,11 +3197,11 @@ class Net_SmartIRC_channeluser extends Net_SmartIRC_user
*/
class Net_SmartIRC_ircuser extends Net_SmartIRC_user
{
- /**
- * @var array
- * @access public
- */
- var $joinedchannels = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $joinedchannels = array();
}
/**
@@ -3243,39 +3209,38 @@ class Net_SmartIRC_ircuser extends Net_SmartIRC_user
*/
class Net_SmartIRC_listenfor
{
- /**
- * @var array
- * @access public
- */
- var $result = array();
+ /**
+ * @var array
+ * @access public
+ */
+ var $result = array();
- /**
- * stores the received answer into the result array
- *
- * @param object $irc
- * @param object $ircdata
- * @return void
- */
- function handler(&$irc, &$ircdata)
- {
- $irc->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: listenfor handler called', __FILE__, __LINE__);
- $this->result[] = $ircdata;
- $irc->disconnect(true);
- }
+ /**
+ * stores the received answer into the result array
+ *
+ * @param object $irc
+ * @param object $ircdata
+ * @return void
+ */
+ function handler(&$irc, &$ircdata)
+ {
+ $irc->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: listenfor handler called', __FILE__, __LINE__);
+ $this->result[] = $ircdata;
+ $irc->disconnect(true);
+ }
}
class Net_SmartIRC_Error
{
- var $error_msg;
+ var $error_msg;
- function __construct($message)
- {
- $this->error_msg = $message;
- }
+ function __construct($message)
+ {
+ $this->error_msg = $message;
+ }
- function getMessage()
- {
- return $this->error_msg;
- }
-}
-?>
+ function getMessage()
+ {
+ return $this->error_msg;
+ }
+}
\ No newline at end of file
diff --git a/lib/Net_SmartIRC/Net/SmartIRC/irccommands.php b/lib/Net_SmartIRC/Net/SmartIRC/irccommands.php
index a85f37f07..9e33857b9 100644
--- a/lib/Net_SmartIRC/Net/SmartIRC/irccommands.php
+++ b/lib/Net_SmartIRC/Net/SmartIRC/irccommands.php
@@ -105,7 +105,7 @@ class Net_SmartIRC_irccommands extends Net_SmartIRC_base
*
* @param array $channelarray ; array('#channelname1' => 'password', '#channelname2' => null);
* @param integer $priority message priority, default is SMARTIRC_MEDIUM
- * @return void
+ * @return bool
* @access public
*/
function join($channelarray, $priority = SMARTIRC_MEDIUM)
@@ -113,6 +113,7 @@ class Net_SmartIRC_irccommands extends Net_SmartIRC_base
foreach ($channelarray as $channel => $password) {
$this->_send('JOIN ' . $channel . ($password === null ? '' : ' ' . $password), $priority);
}
+ return true;
}
/**
@@ -522,5 +523,4 @@ class Net_SmartIRC_irccommands extends Net_SmartIRC_base
$this->disconnect(true);
}
-}
-?>
+}
\ No newline at end of file
diff --git a/lib/Net_SmartIRC/Net/SmartIRC/messagehandler.php b/lib/Net_SmartIRC/Net/SmartIRC/messagehandler.php
index 8ff8358ff..187ae75dc 100644
--- a/lib/Net_SmartIRC/Net/SmartIRC/messagehandler.php
+++ b/lib/Net_SmartIRC/Net/SmartIRC/messagehandler.php
@@ -523,5 +523,4 @@ class Net_SmartIRC_messagehandler extends Net_SmartIRC_irccommands
{
$this->_nicknameinuse();
}
-}
-?>
+}
\ No newline at end of file
diff --git a/lib/prehash.php b/lib/prehash.php
index fe067c249..cf9a36402 100644
--- a/lib/prehash.php
+++ b/lib/prehash.php
@@ -10,6 +10,8 @@ require_once("consoletools.php");
require_once("ColorCLI.php");
require_once("nzbcontents.php");
require_once("simple_html_dom.php");
+require_once("IRCScraper.php");
+
/*
* Class for inserting names/categories/md5 etc from predb sources into the DB, also for matching names on files / subjects.
@@ -39,6 +41,7 @@ Class PreHash
$this->echooutput = $echooutput;
$this->db = new DB();
$this->c = new ColorCLI;
+ $this->functions = new Functions();
}
// Retrieve pre info from predb sources and store them in the DB.
@@ -177,7 +180,7 @@ Class PreHash
{
$db = new DB();
$f = new Functions();
- $newnames = $updated = 0;
+ $newNames = $updated = 0;
$matches2 = $matches = $match = $m = '';
$buffer = $this->fileContents('http://www.newshost.co.za');
@@ -226,7 +229,7 @@ Class PreHash
if (strlen($matches2['title']) > 15) {
if($db->exec(sprintf("INSERT INTO prehash (title, nfo, size, category, predate, source, md5) VALUES (%s, %s, %s, %s, FROM_UNIXTIME(".strtotime($matches2["date"])."), %s, %s)", $db->escapeString($matches2["title"]), $nfo, $size, $db->escapeString($matches2["category"]), $db->escapeString("womble"), $md5)));{
- $newnames++;
+ $newNames++;
}
}
}
@@ -240,14 +243,14 @@ Class PreHash
{
echo $this->c->error("Update from Womble failed.");
}
- return $newnames;
+ return $newNames;
}
public function retrieveOmgwtfnzbs()
{
$db = new DB();
$f = new Functions();
- $newnames = $updated = 0;
+ $newNames = $updated = 0;
$matches2 = $matches = $match = $m = '';
$buffer = $this->fileContents('http://rss.omgwtfnzbs.org/rss-info.php');
@@ -259,47 +262,59 @@ Class PreHash
{
foreach ($match as $m)
{
- if (preg_match('/(?P.+?)<\/title.+?pubDate>(?P.+?)<\/pubDate.+?gory:<\/b> (?P.+?)
(?P.+?) (?P[a-zA-Z]+)escapeString(md5($title));
- $oldname = $db->queryOneRow(sprintf('SELECT md5, source, ID FROM prehash WHERE md5 = %s', $md5));
- if ($oldname !== false) {
- if ($oldname['source'] == 'womble' || $oldname['source'] == 'omgwtfnzbs') {
- continue;
- } else {
- $size = $db->escapeString(round($matches2["size1"]).$matches2["size2"]);
- $db->exec(sprintf("UPDATE prehash SET size = %s, category = %s, predate = FROM_UNIXTIME(".strtotime($matches2["date"])."), source = %s where ID = %d", $size, $db->escapeString($matches2["category"]), $db->escapeString("omgwtfnzbs"), $oldname["ID"]));
- $updated++;
- }
+ if (preg_match('/(?P.+?)\s+-\s+omgwtfnzbs\.org.*?<\/title.+?pubDate>(?P.+?)<\/pubDate.+?gory:<\/b> (?P.+?)
(?P.+?) (?P[a-zA-Z]+)escapeString(round($matches2["size1"]).$matches2["size2"]);
- if (strlen($title) > 15) {
- if($db->exec(sprintf("INSERT INTO prehash (title, size, category, predate, source, md5) VALUES (%s, %s, %s, FROM_UNIXTIME(".strtotime($matches2["date"])."), %s, %s)", $db->escapeString($title), $size, $db->escapeString($matches2["category"]), $db->escapeString("omgwtfnzbs"),$md5))); {
- $newnames++;
- }
- }
+ $title = $matches2['title'];
+ $md5 = $this->db->escapeString(md5($title));
+ $oldName = $this->db->queryOneRow(sprintf('SELECT md5, source, ID FROM prehash WHERE md5 = %s', $md5));
+ // If we have it already and the source is womble or omg, continue.
+ if ($oldName !== false && ($oldName['source'] === 'womble' || $oldName['source'] === 'omgwtfnzbs')) {
+ continue;
+ }
+ $size = $this->db->escapeString(round($matches2['size1']) . $matches2['size2']);
+ $category = $this->db->escapeString($matches2['category']);
+ $time = $this->functions->from_unixtime(strtotime($matches2['date']));
+ $source = $this->db->escapeString('omgwtfnzbs');
+
+ // If we have it already, update it.
+ if ($oldName !== false) {
+ $this->db->exec(
+ sprintf('
+ UPDATE prehash
+ SET size = %s, category = %s, predate = %s, source = %s
+ WHERE ID = %d',
+ $size, $category, $time, $source, $oldName['ID']
+ )
+ );
+ $updated++;
+ } elseif ($this->db->exec(
+ sprintf('
+ INSERT INTO prehash (title, size, category, predate, source, md5)
+ VALUES (%s, %s, %s, %s, %s, %s)',
+ $this->db->escapeString($title), $size, $category, $time, $source, $md5))) {
+ $newNames++;
}
}
}
}
}
- echo $this->c->primary($updated . " \tUpdated from Omgwtfnzbs.");
- }
- else
- {
+ if ($this ->echooutput) {
+ echo $this->c->primary($updated . " \tUpdated from Omgwtfnzbs.");
+ }
+ } elseif ($this ->echooutput) {
echo $this->c->error("Update from Omgwtfnzbs failed.");
}
- return $newnames;
+ return $newNames;
}
public function retrieveZenet()
{
$db = new DB();
$f = new Functions();
- $newnames = $updated = 0;
+ $newNames = $updated = 0;
$matches2 = $matches = $match = $m = '';
$buffer = $this->fileContents('http://pre.zenet.org/live.php');
@@ -311,206 +326,240 @@ Class PreHash
{
foreach ($match as $m)
{
- if (preg_match('/(?P\d{4}-\d{2}-\d{2} \d{2}:\d{2})<\/span>.+(?P.+)<\/font><\/b><\/a>.+(?P.+)<\/font><\/a> \| (?P[\d\.,]+)?(?P[MGK]B)? \/.+<\/div>/s', $m, $matches2))
- {
- $md5 = $db->escapeString(md5($matches2['title']));
- $title = $db->escapeString($matches2['title']);
- $dupeCheck = $db->queryOneRow(sprintf('SELECT md5 FROM prehash WHERE md5 = %s', $md5));
- if ($dupeCheck !== false) {
- continue;
- } else {
- if (!isset($matches2['size1']) && empty($matches2['size1'])) {
- $size = 'NULL';
- } else {
- $size = $db->escapeString(round($matches2['size1']).$matches2['size2']);
- }
- if (isset($matches2['category']) && !empty($matches2['category'])) {
- $category = $db->escapeString($matches2['category']);
- } else {
- $category = 'NULL';
- }
- if (strlen($title) > 15) {
- if ($db->queryInsert(sprintf('INSERT INTO prehash (title, size, category, predate, source, md5) VALUES (%s, %s, %s, %s, %s, %s)', $title, $size, $category, $db->escapeString($matches2['predate']), $db->escapeString('zenet'), $md5)));{
- $newnames++;
- }
- }
- }
- }
- }
- }
- }
- }
- else
- {
- echo $this->c->error("Update from Zenet failed.");
- }
- return $newnames;
- }
+ if (preg_match('/(?P\d{4}-\d{2}-\d{2} \d{2}:\d{2})<\/span>.+(?P.+)<\/font><\/b><\/a>.+(?P.+)<\/font><\/a> \| (?P[\d\.,]+)?(?P[MGK]B)? \/\s+(?P\d+).+<\/div>/s', $m, $matches2)) {
- public function retrievePrelist()
- {
- $db = new DB();
- $f = new Functions();
- $newnames = $updated = 0;
- $matches2 = $matches = $match = $m = '';
-
- $buffer = $this->fileContents('http://www.prelist.ws/');
- if ($buffer !== false && strlen($buffer))
- {
- if (preg_match_all('/<\/small>/s', $buffer, $matches))
- {
- foreach ($matches as $match)
- {
- foreach ($match as $m)
- {
- if (!preg_match('/NUKED/', $m) && preg_match('/">\[ (?P.+?) U.+?">(?P.+?)<\/a>.+?">(?P.+?)<\/a>.+?(b>\[ (?P.+?) \]<\/b)?/si', $m, $matches2))
- {
- $md5 = $db->escapeString(md5($matches2['title']));
- $oldname = $db->queryOneRow(sprintf('SELECT md5 FROM prehash WHERE md5 = %s', $md5));
- if ($oldname !== false) {
+ // If it's too short, don't bother.
+ if (strlen($matches2['title']) < 15) {
continue;
- }
- else
- {
- if (!isset($matches2["size"]) && empty($matches2["size"])){
- $size = "NULL";
- } else {
- $size = $db->escapeString(round($matches2["size"]));
- }
- if (strlen($matches2['title']) > 15) {
- if($db->exec(sprintf("INSERT INTO prehash (title, size, category, predate, source, md5) VALUES (%s, %s, %s, FROM_UNIXTIME(".strtotime($matches2["date"])."), %s, %s)", $db->escapeString($matches2["title"]), $size, $db->escapeString($matches2["category"]), $db->escapeString("prelist"), $md5)));{
- $newnames++;
- }
- }
}
- }
- else if (preg_match('/">\[ (?P.+?) U.+?">(?P.+?)<\/a>.+?">(?P.+?)<\/a.+">(?P.+?)<\/a>/si', $m, $matches2))
- {
- $md5 = $db->escapeString(md5($matches2['title']));
- $dupeCheck = $db->queryOneRow(sprintf('SELECT md5 FROM prehash WHERE md5 = %s', $md5));
+ $md5 = $this->db->escapeString(md5($matches2['title']));
+ $dupeCheck = $this->db->queryOneRow(sprintf('SELECT md5 FROM prehash WHERE md5 = %s', $md5));
if ($dupeCheck !== false) {
- continue;
- }else
- {
- $category = $db->escapeString($matches2["category"].", ".$matches2["category1"]);
- if (strlen($matches2['title']) > 15) {
- if($db->exec(sprintf("INSERT INTO prehash (title, category, predate, source, md5) VALUES (%s, %s, FROM_UNIXTIME(".strtotime($matches2["date"])."), %s, %s)", $db->escapeString($matches2["title"]), $category, $db->escapeString("prelist"), $md5))); {
- $newnames++;
- }
- }
+ continue;
+ } elseif ($this->db->exec(
+ sprintf('
+ INSERT INTO prehash (title, size, category, predate, source, md5, files)
+ VALUES (%s, %s, %s, %s, %s, %s, %s)',
+ $this->db->escapeString($matches2['title']),
+ ((!isset($matches2['size1']) && empty($matches2['size1']))
+ ? 'NULL'
+ : $this->db->escapeString(round($matches2['size1']) . $matches2['size2'])
+ ),
+ ((isset($matches2['category']) && !empty($matches2['category']))
+ ? $this->db->escapeString($matches2['category'])
+ : 'NULL'
+ ),
+ $this->functions->from_unixtime(strtotime($matches2['predate'])),
+ $this->db->escapeString('zenet'),
+ $md5,
+ $this->db->escapeString($matches2['files'])))) {
+ $newNames++;
}
}
}
}
}
+ } elseif ($this->echooutput) {
+ echo $this->c->error("Update from Zenet failed.");
}
- else
- {
- echo $this->c->error("Update from Prelist failed.");
- }
- return $newnames;
+ return $newNames;
}
- public function retrieveOrlydb()
+ /**
+ * Get new pre from pre list.
+ *
+ * @note - Probably has to be remade.
+ *
+ * @return int
+ */
+ protected function retrievePrelist()
{
- $db = new DB();
- $f = new Functions();
- $newnames = $updated = 0;
- $matches2 = $matches = $match = $m = '';
+ $newNames = 0;
+ $buffer = $this->getUrl('http://www.prelist.ws/');
+ if ($buffer !== false) {
+ $matches = $matches2 = $matches3 = array();
+ if (preg_match_all('/.+?<\/div>\s*<\/div>\s*<\/div>/s', $buffer, $matches)) {
+ foreach($matches as $matches2) {
+ foreach ($matches2 as $matches3) {
+ if (preg_match('/">(?P
.+?)<\/a><\/div>(?P
.+?)<\/a>.+?"Time">(?P.+?)<\/div.+?"FilesSize">(?P\d+F).*?(?P\d+[KMGPT]?B).+?"Reason">(?P.*?)<\/div>/is', $matches3, $matches4)) {
- $buffer = $this->fileContents('http://www.orlydb.com/');
- if ($buffer !== false && strlen($buffer))
- {
- if (preg_match('/(.+)