Пример #1
0
 /**
  * A small helper function to distribute the CTCP reply to the IRC
  * Network, mainly because it needs all kinds of characters.
  * 
  * @param Bot $pBot The bot that will be sending this message.
  * @param string $sNickname Nickname to reply to, e.g. the destination.
  * @param string $sType Type of CTCP message that will be send.
  * @param string $sMessage The message associated with the CTCP.
  */
 private function sendCTCP(Bot $pBot, $sNickname, $sType, $sMessage)
 {
     $sCommand = 'NOTICE ' . $sNickname . ' :' . self::CTCP . $sType;
     if (strlen($sMessage) > 0) {
         $sCommand .= ' ' . $sMessage;
     }
     $pBot->send($sCommand . self::CTCP);
 }
Пример #2
0
 /**
  * Sends a message to a destination, this can be a channel or a nickname.
  *
  * @param Bot $pBot The bot to send it with.
  * @param string $sDestination The destination.
  * @param string $sMessage The actual message to send.
  */
 public static function privmsg(Bot $pBot, $sDestination, $sMessage)
 {
     foreach (explode(PHP_EOL, $sMessage) as $sMessage) {
         $sMessage = trim($sMessage);
         $pBot->send('PRIVMSG ' . $sDestination . ' :' . $sMessage);
     }
     return true;
 }
Пример #3
0
 /**
  * This function gets invoked when the bot is about to shut down, so right
  * before unregistering itself and sending the IRC quit messages.
  * 
  * @param Bot $pBot The bot who will be disconnecting in a sec.
  */
 public function onShutdown(Bot $pBot)
 {
     if (isset($pBot['QuitMessage'])) {
         $pBot->send('QUIT :' . $pBot['QuitMessage']);
         return ModuleManager::FINISHED;
     }
 }
Пример #4
0
 /**
  * This function gets invoked when the user receives a notice from a
  * user, the server or someone else.
  *
  * @param Bot $pBot The bot that is sending the message.
  * @param string $sToNickname Nickname of the bot who receives
  * @param string $sFromNickname Nickname of who we get the notice
  * @param string $sMessage The message it gives us
  */
 public function onNotice(Bot $pBot, $sChannel, $sNickname, $sMessage)
 {
     if (strtolower($sChannel) != 'auth' && strtolower($sNickname) != 'gtanet') {
         $pBot->send('PRIVMSG #xanland.logging :[onNotice ' . $sChannel . '/' . $sNickname . ']: ' . $sMessage);
     }
 }
Пример #5
0
 /**
  * Processing updates has to be done every frame of the bot. In this method we'll handle
  * incoming messages, statistics for them and, if they're available, distributing messages
  * in the distribution queue.
  */
 public function update()
 {
     if (is_resource($this->socket) === false) {
         return;
     }
     $this->statistics->update();
     if (count($this->distributionQueue) > 0) {
         if ($this->statistics->load() < self::BUFFER_SEND_QUEUE) {
             $this->send($this->distributionQueue->dequeue());
         }
     }
     if (feof($this->socket)) {
         $this->bot->onDisconnect(self::DISCONNECT_SOCKET_EOF);
         $this->disconnect();
         return;
     }
     $incoming = fread($this->socket, 2048);
     if ($incoming === false) {
         $this->bot->onDisconnect(self::DISCONNECT_SOCKET_READ_ERR);
         $this->disconnect();
         return;
     }
     $messageQueue = explode("\n", ltrim($this->receiveBuffer . $incoming));
     $this->receiveBuffer = array_pop($messageQueue);
     foreach ($messageQueue as $command) {
         $command = trim($command);
         $this->statistics->push(SocketStatistics::STATISTICS_INCOMING, $command);
         $this->bot->onReceive($command);
     }
     return true;
 }
Пример #6
0
 /**
  * Private messages to channels can mean that we have to do either of two things: create a
  * new notification or check for notifications on the active user's account.
  *
  * @param Bot $bot The bot which has received this message, which will answer if needed.
  * @param string $channel Channel in which the message has been distributed.
  * @param string $nickname Nickname of the user which distributed a message.
  * @param string $message The actual message the user has sent to the channel.
  * @return boolean Were we able to do something with the message?
  */
 public function onChannelPrivmsg(Bot $bot, $channel, $nickname, $message)
 {
     /**
      * We have to check if we might have to inform them of pending messages,
      * which requires an easy lookup in the local notifiedUsers array.
      */
     $loweredNickname = strtolower($nickname);
     if (in_array($loweredNickname, $this->notifiedUsers)) {
         foreach ((new Model(self::NOTIFICATION_TABLE, 'sReceiver', $nickname))->getAll() as $oNotification) {
             if ($oNotification->sNetwork != $bot['Network']) {
                 continue;
             }
             if (self::NOTIFICATION_NETWORK_WIDE === false && $oNotification->sChannel != $channel) {
                 continue;
             }
             $timeDifference = $this->formatNotificationInterval($oNotification->iTimestamp);
             $notificationMessage = $nickname . ', ' . $oNotification->sSender . ' said: ' . $oNotification->sMessage . ' 15(' . $timeDifference . ')';
             $bot->send('PRIVMSG ' . $channel . ' :' . $notificationMessage);
             $oNotification->delete();
             $key = array_search($loweredNickname, $this->notifiedUsers);
             if ($key !== false) {
                 unset($this->notifiedUsers[$key]);
             }
         }
     }
     return true;
 }
Пример #7
0
 public function onChangeTopic(Bot $pBot, $sChannel, $sNickname, $sNewTopic)
 {
     if ($sNickname === $pBot->offsetGet('Nickname')) {
         // It's us!
         return;
     }
     if ($this->m_aChannels[$sChannel]['Locked'] === true) {
         // Topic is locked, lets try to reset it.
         $pBot->send('TOPIC ' . $sChannel . ' :' . $this->m_aChannels[$sChannel]['Topic']);
     } else {
         // Topic is not locked, lets store it
         $this->setTopic($sChannel, $sNewTopic);
     }
 }
Пример #8
0
 /**
  * Obviously it is important to be able to control the feeds and their settings,
  * which can be done using in-channel commands. This method will check the
  * incoming messages for commands and execute them if appropriate.
  *
  * @param Bot    $pBot      Instance of the bot which received this message.
  * @param string $sChannel  Channel in which the message got distributed.
  * @param string $sNickname Nickname of the person who distributed this message.
  * @param string $sMessage  Contents of the message itself.
  */
 public function onChannelPrivmsg(Bot $pBot, $sChannel, $sNickname, $sMessage)
 {
     if ($sMessage[0] != '!' && $sNickname == 'Xanland') {
         return;
     }
     $aParameters = explode(' ', $sMessage . ' ');
     switch (strtolower($aParameters[0])) {
         case '!fhelp':
             $pBot->send('PRIVMSG ' . $sChannel . ' :4Feed Tracker: !fhelp !fadd !flist !finfo !fupdate !fremove');
             break;
         case '!flistall':
             // ..
         // ..
         case '!flist':
             $sMessage = '4Active Feeds: ';
             $aFeeds = array();
             $bShowGlobal = strtolower($aParameters[0]) == '!flistall';
             $bShowHidden = isset($aParameters[1]) && $aParameters[1] == 'all';
             foreach ($this->m_aFeedList as $nIndex => $aFeedInfo) {
                 if (strtolower($aFeedInfo['channel']) != strtolower($sChannel) && $bShowGlobal === false) {
                     continue;
                 }
                 if ($aFeedInfo['hidden'] === true && $bShowHidden === false) {
                     continue;
                 }
                 $aFeeds[] = $aFeedInfo['name'] . '15(' . $nIndex . ')';
                 if (count($aFeeds) >= 15) {
                     $pBot->send('PRIVMSG ' . $sChannel . ' :' . $sMessage . implode(', ', $aFeeds));
                     $aFeeds = array();
                 }
             }
             if (count($aFeeds) == 0) {
                 $aFeeds[] = '14none';
             }
             $pBot->send('PRIVMSG ' . $sChannel . ' :' . $sMessage . implode(', ', $aFeeds));
             break;
         case '!fadd':
             $sName = isset($aParameters[1]) ? $aParameters[1] : null;
             $nFrequency = isset($aParameters[2]) ? $aParameters[2] : null;
             $sLocation = isset($aParameters[3]) ? $aParameters[3] : null;
             if (strlen($sName) == 0 || strlen($sName) > 16 || !is_numeric($nFrequency) || strlen($sLocation) == 0 || strlen($sLocation) > 128 * 2) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Usage: !fadd <name> <frequency> <location>');
                 break;
             }
             if ($nFrequency < 60 || $nFrequency > 86400) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Error: The frequency should be between 60 and 86400 seconds.');
                 break;
             }
             $this->m_aFeedList[] = array('name' => $sName, 'location' => $sLocation, 'channel' => $sChannel, 'hidden' => false, 'format' => '7[%name%] %title% 15(%link%)', 'offset' => 0, 'lastitem' => time(), 'updated' => time(), 'frequency' => $nFrequency);
             file_put_contents('Data/Tracker.dat', serialize($this->m_aFeedList));
             end($this->m_aFeedList);
             $pBot->send('PRIVMSG ' . $sChannel . ' :3Success: The feed has been added successfully (ID: ' . key($this->m_aFeedList) . ').');
             break;
         case '!fremove':
             $nIndex = isset($aParameters[1]) ? $aParameters[1] : -1;
             if (!is_numeric($nIndex) || !isset($this->m_aFeedList[$nIndex])) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Usage: !fremove <id>');
                 break;
             }
             $aFeedInfo = $this->m_aFeedList[$nIndex];
             unset($this->m_aFeedList[$nIndex]);
             file_put_contents('Data/Tracker.dat', serialize($this->m_aFeedList));
             $pBot->send('PRIVMSG ' . $sChannel . ' :3Success: The feed "' . $aFeedInfo['name'] . '" (' . $aFeedInfo['location'] . ') has been removed.');
             break;
         case '!fupdate':
             $nIndex = isset($aParameters[1]) ? $aParameters[1] : -1;
             $sKey = isset($aParameters[2]) ? $aParameters[2] : null;
             $sValue = isset($aParameters[3]) ? implode(' ', array_slice($aParameters, 3)) : null;
             if (!is_numeric($nIndex) || !isset($this->m_aFeedList[$nIndex]) || !strlen($sKey) || !strlen($sValue)) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Usage: !fupdate <id> <key> <value>');
                 break;
             }
             $aAllowedKeys = array('name', 'location', 'channel', 'offset', 'hidden', 'format', 'lastitem', 'updated', 'frequency');
             if (!in_array($sKey, $aAllowedKeys)) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Error: The key must be one of the following: ' . implode(', ', $aAllowedKeys));
                 break;
             }
             switch ($sKey) {
                 case 'name':
                     $this->m_aFeedList[$nIndex]['name'] = $sValue;
                     break;
                 case 'location':
                     $this->m_aFeedList[$nIndex]['location'] = $sValue;
                     break;
                 case 'channel':
                     $this->m_aFeedList[$nIndex]['channel'] = $sValue;
                     break;
                 case 'hidden':
                     $this->m_aFeedList[$nIndex]['hidden'] = (bool) $sValue;
                     break;
                 case 'offset':
                     $this->m_aFeedList[$nIndex]['offset'] = (int) $sValue;
                     break;
                 case 'format':
                     $this->m_aFeedList[$nIndex]['format'] = $sValue;
                     break;
                 case 'lastitem':
                     $this->m_aFeedList[$nIndex]['lastitem'] = (int) $sValue;
                     break;
                 case 'updated':
                     $this->m_aFeedList[$nIndex]['updated'] = (int) $sValue;
                     break;
                 case 'frequency':
                     $this->m_aFeedList[$nIndex]['frequency'] = (int) $sValue;
                     break;
             }
             file_put_contents('Data/Tracker.dat', serialize($this->m_aFeedList));
             $pBot->send('PRIVMSG ' . $sChannel . ' :3Success: The feed has been updated.');
             break;
         case '!finfo':
             $nIndex = isset($aParameters[1]) ? $aParameters[1] : -1;
             $sKey = isset($aParameters[2]) ? $aParameters[2] : null;
             if (!is_numeric($nIndex) || !isset($this->m_aFeedList[$nIndex]) || !strlen($sKey)) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Usage: !finfo <id> <key>');
                 break;
             }
             $aAllowedKeys = array('name', 'location', 'channel', 'hidden', 'offset', 'format', 'lastitem', 'updated', 'frequency');
             if (!in_array($sKey, $aAllowedKeys)) {
                 $pBot->send('PRIVMSG ' . $sChannel . ' :4Error: The key must be one of the following: ' . implode(',', $aAllowedKeys));
                 break;
             }
             $mValue = $this->m_aFeedList[$nIndex][$sKey];
             switch ($sKey) {
                 case 'hidden':
                     $mValue = $mValue ? 'Yes' : 'No';
                     break;
                 case 'updated':
                     $mValue = date('Y-m-d H:i:s', $mValue) . ' (' . floor((time() - $mValue) / 60) . ' minutes ago)';
                     break;
             }
             $pBot->send('PRIVMSG ' . $sChannel . ' :3Value of "' . $sKey . '": ' . $mValue);
             break;
     }
 }
Пример #9
0
 public static function sendRandomMessage(Bot $pBot)
 {
     $aMessages = self::getQuoteDeviceFileContent();
     $sOriginalMessage = array_slice($aMessages, count($aMessages) - 50);
     $aMessageWords = explode(' ', $sOriginalMessage[mt_rand(2, count($sOriginalMessage) - 1)]);
     $sMessage = str_ireplace('Monique', str_replace(array('<', '>'), '', $aMessageWords[1]), $aMessageWords);
     $pBot->send('PRIVMSG #lvp.echo :!msg ' . \Util::getPieces($sMessage, ' ', 2));
 }
Пример #10
0
 /**
  * This function will immediatly execute the evaluation that we're doing
  * right now. Evaluation delays are already handled by the parser.
  *
  * @param Bot $pBot Bot that should handle the evaluation.
  * @param string $sDestination Where should the output be redirected?
  * @param array $aOptions Array with the parsed options for this evaluation.
  */
 public function doEvaluation(Bot $pBot, $sDestination, $aOptions)
 {
     ob_start();
     ErrorExceptionHandler::$Source = $sDestination;
     switch ($aOptions['Type']) {
         case 'PHP':
             eval($aOptions['Operation']);
             break;
         case 'EXEC':
             $process = proc_open($aOptions['Operation'], array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
             if (is_resource($process)) {
                 fclose($pipes[0]);
                 $output = trim(stream_get_contents($pipes[1]));
                 fclose($pipes[1]);
                 $error = trim(stream_get_contents($pipes[2]));
                 fclose($pipes[2]);
                 $returnValue = proc_close($process);
                 if ($output != '') {
                     echo $output . ' ';
                 }
                 $haveNewLine = false;
                 if ($error != '') {
                     echo PHP_EOL . ModuleBase::COLOUR_RED . '* Error' . ModuleBase::CLEAR . ': ' . $error . ' ';
                     $haveNewLine = true;
                 }
                 if ($returnValue !== 0) {
                     if (!$haveNewLine) {
                         echo PHP_EOL;
                     } else {
                         echo '| ';
                     }
                     echo ModuleBase::COLOUR_TEAL;
                     if (!$haveNewLine) {
                         echo '* ';
                     }
                     echo 'Return value' . ModuleBase::CLEAR . ': ' . $returnValue;
                     $haveNewLine = true;
                 }
             }
             break;
         case 'SQL':
             $pDatabase = Database::getInstance();
             if ($pDatabase == null || $pDatabase->connect_error) {
                 echo '4* Database Error: Could not connect to database';
                 if ($pDatabase != null) {
                     echo ': "' . $pDatabase->connect_error . '"';
                 }
                 echo '.';
                 break;
             }
             $pResult = $pDatabase->query($aOptions['Operation']);
             if ($pResult === false) {
                 echo '4* Database Error: ' . $pDatabase->error;
             } else {
                 if ($pResult->num_rows == 0) {
                     echo '10* No rows.';
                 } else {
                     $aFields = $aFieldLen = array();
                     foreach ($pResult->fetch_fields() as $pField) {
                         $aFields[$pField->name] = array($pField->name);
                         $aFieldLen[$pField->name] = strlen($pField->name);
                     }
                     while (($aRow = $pResult->fetch_assoc()) != null) {
                         foreach ($aRow as $sField => $mValue) {
                             if ($mValue == null) {
                                 $mValue = 'NULL';
                             }
                             $aFields[$sField][] = $mValue;
                             $aFieldLen[$sField] = max($aFieldLen[$sField], strlen((string) $mValue));
                         }
                     }
                     // Output is imminent.
                     for ($i = 0; $i <= $pResult->num_rows; $i++) {
                         // 1 extra loop for the header.
                         foreach (array_keys($aFields) as $sField) {
                             echo sprintf('| ' . ($i == 0 ? '' : '') . '%\'' . chr(160) . '-' . $aFieldLen[$sField] . 's' . ($i == 0 ? '' : '') . ' ', $aFields[$sField][$i]);
                         }
                         echo '|' . PHP_EOL;
                     }
                 }
             }
             break;
     }
     $aOutput = explode("\n", trim(ob_get_clean()));
     if (count($aOutput) > $aOptions['MaxLines'] + 1 && $aOptions['Buffering'] == true) {
         $nSize = count($aOutput);
         $aOutput = array_slice($aOutput, 0, $aOptions['MaxLines']);
         $aOutput[] = '10* Displayed ' . $aOptions['MaxLines'] . ' out of ' . $nSize . ' lines.';
     }
     if (isset($pBot) && $pBot instanceof Bot) {
         foreach ($aOutput as $sLine) {
             $pBot->send('PRIVMSG ' . $sDestination . ' :' . trim($sLine), false);
         }
     }
 }