/** * Sending a command to the server may be done by invoking this method. Internally we'll * manage the outgoing buffer, statistics and bot load tracking, as well as actually sending * the message over the server like we're expected to. * * @param string $command The command which has to be send to the server. * @return integer The number of bytes which have been send at this very invocation. */ public function send($command) { if (is_resource($this->socket) === false) { return -1; } $command = trim($command); if ($this->statistics->load() >= self::BUFFER_SEND_QUEUE) { $this->distributionQueue->enqueue($command); return 0; } $this->statistics->push(SocketStatistics::STATISTICS_OUTGOING, $command); if (($bytesWritten = fwrite($this->socket, $command . PHP_EOL)) === false) { $this->bot->onDisconnect(self::DISCONNECT_SOCKET_READ_ERR); $this->disconnect(); return -1; } if (strtoupper(substr($command, 0, 4)) == 'QUIT') { $this->bot->onDisconnect(self::DISCONNECT_QUIT); $this->disconnect(); BotManager::getInstance()->destroy($this->bot); } return $bytesWritten; }
/** * The function which tells this bot to connect to the IRC network. * Basically we just call the socket's connect function and we check if * the connection went well. If not, we'll try again after a timeout. If * we do somehow get connected, we send in our NICK and USER commands to * register with the IRC server. After that, the process () methods will * take over. * * @return boolean */ public function connect() { $this->m_aBotInfo['NextTry'] = 15 * pow(2, $this->m_aBotInfo['ConnectTry']); $this->m_aBotInfo['ConnectTry']++; if (!$this->m_pSocket->connect()) { if ($this->m_aBotInfo['ConnectTry'] >= 5) { echo '[Bot] Destroying bot ' . $this->m_sNickname . ' after 5 failed connection attempts.' . PHP_EOL; BotManager::getInstance()->destroy($this->m_pBot); return false; } echo '[Bot] Retrying in ' . $this->m_aBotInfo['NextTry'] . ' seconds...' . PHP_EOL; Timer::create(array($this, 'connect'), $this->m_aBotInfo['NextTry'] * 1000); return false; } $sUsername = isset($this->m_aBotInfo['Username']) && !empty($this->m_aBotInfo['Username']) ? $this->m_aBotInfo['Username'] : NUWANI_NAME; $sRealname = isset($this->m_aBotInfo['Realname']) && !empty($this->m_aBotInfo['Realname']) ? $this->m_aBotInfo['Realname'] : NUWANI_VERSION_STR; $this->m_pSocket->send('NICK ' . $this->m_sNickname); $this->m_pSocket->send('USER ' . $sUsername . ' - - :' . $sRealname); if (isset($this->m_aBotInfo['Network']['Options']['Password'])) { $this->m_pSocket->send('PASS ' . $this->m_aBotInfo['Network']['Options']['Password']); } return true; }
/** * This method will quickly look up a bot which we can use to send * information to a specific channel. * * @param string $sChannel The channel in which we need a bot. * @throws Exception when no bots were found. * @return Bot */ public function getBot($sChannel) { $pBot = BotManager::getInstance()->offsetGet('network:' . LVP::NETWORK . ' channel:' . $sChannel); if ($pBot instanceof BotGroup) { if (count($pBot) == 0) { // Wait. That's not right. throw new Exception('No bot could be found which is connected to network "' . LVP::NETWORK . '" and in channel ' . $sChannel); } else { if (count($pBot) > 1) { $pBot = $pBot->seek(0); } } } return $pBot; }