_config = $config; // Initialise events $this->eveDataSent = new event(); $this->eveDataReceived = new event(); $this->evePing = new event(); $this->eveConnected = new event(); $this->eveJoin = new event(); $this->evePrivmsg = new event(); $this->eveAction = new event(); $this->eveNotice = new event(); // Register core functionality $this->evePing->register( 'corePingHandler' ); $this->eveDataSent->register( 'coreDebugger' ); $this->eveDataReceived->register( 'coreDebugger' ); } // Attempt to connect to an IRC server on the hostname/IP and port provided in the ircConfig object public function connect() { // Throw a detailed exception if it is not possible to connect to a given server if ( ! $this->_socket = fsockopen( $this->getHost(), $this->getPort(), $errno, $errstr ) ) { throw new Exception( 'Could not connect to "' . $this->getHost() . ':' . $this->getPort . '" [' . $errno . '] ' . $errstr ); } else { // Make the socket non-blocking stream_set_blocking( $this->_socket, 0 ); // Register with the server: send a nickname and user details $this->sendString( 'NICK ' . $this->getNick() ); $this->sendString( 'USER ' . $this->getIdent() . ' 0 0 :' . $this->getName() ); } } // Listen for incoming data on a connection public function listen() { // Throw an exception if listen() is called without first connecting to an IRC server if ( ! $this->_socket ) { throw new Exception( 'Could not initiate the listen loop because a connection has not yet been established' ); } else { while ( ! feof( $this->_socket ) ) { // Check the output buffer for data to send to the server $this->checkOutputBuffer(); // Read data from the server $this->readData(); } } } // Read from the server at set intervals private function readData() { $time = microtime( true ); if ( ( $time - $this->_lastStringReceived ) >= $this->_readDelay / 1000 ) { // Read from the server in "lines", cut at n bytes or linebreaks $line = trim( fgets( $this->_socket, 1024 ) ); // Catch 0-length packets if ( strlen( $line ) ) { // Trigger the eveDataReceived event $data = new eveDataTransitArgs( $line, 'eveDataReceived' ); $this->eveDataReceived->trigger( $this, $data ); // Pass incoming data to the event handler eventHandler( $this, $line ); $this->_lastStringReceived = $time; } } } // Disconnect from the active IRC connection and close the socket public function disconnect( $quit = 'Exiting' ) { // Throw an exception if disconnect() is called without first connecting to an IRC server if ( ! $this->_socket ) { throw new Exception( 'Could not disconnect from the server because a connection has not yet been established' ); } else { // Send a quit message to the server $this->sendString( 'QUIT :' . $quit ); fclose( $this->_socket ); } } // Check the output buffer for new messages private function checkOutputBuffer() { $time = microtime( true ); if ( ( $time - $this->_lastStringSent ) >= $this->sendDelay / 1000 ) { $string = array_shift( $this->_outputBuffer ); if ( $string != '' ) { // Write to the socket and update the time for the lastStringSent $this->sendStringNow( $string ); $this->_lastStringSent = $time; } } } // Add a string to the output buffering system's queue public function sendString( $string ) { $this->_outputBuffer[] = $string; } // Send a string directly over the socket by avoiding the output buffering system private function sendStringNow( $string ) { // Throw an exception if the sendStringNow() function is called without first connecting to an IRC server if ( ! $this->_socket ) { throw new Exception( 'Cannot write to the server because a connection has not yet been established' ); } else { if ( fwrite( $this->_socket, $string . "\n" ) ) { // Trigger the eveDataSent event $data = new eveDataTransitArgs( $string, 'eveDataSent' ); $this->eveDataSent->trigger( $this, $data ); } } } }