public function command() { // We don't want any trailing \n, \r or anything in that area. $command = \Library\FunctionCollection::removeLineBreaks(implode(' ', $this->arguments)); $user = \Library\FunctionCollection::getUserNickName($this->data); $time = @end(explode(' in ', $command)); $message = str_replace(' in ' . $time, '', $command); $currTime = time(); if (!preg_match('/(\\d+)(s|m|h|d)/i', $time, $out)) { $this->say('Invalid arguments.'); return; } $newtime = 0; switch ($out[2]) { case 's': $newtime = $currTime + $out[1]; break; case 'm': $newtime = $currTime + $out[1] * 60; break; case 'h': $newtime = $currTime + $out[1] * 60 * 60; break; case 'd': $newtime = $currTime + $out[1] * 60 * 60 * 24; break; } $message = $user . ', ' . $message; $this->bot->reminders[$newtime] = $message; $this->say('Reminder "' . $message . '" set at ' . date('d-m-Y H:i:s', $newtime) . ' GMT+1, current time: ' . date('d-m-Y H:i:s')); }
/** * Search for IMDB Data, and give response to channel * * IRC-Syntax: PRIVMSG Movie title */ public function command() { $imdbTitle = implode(' ', $this->arguments); $imdbTitle = preg_replace('/\\s\\s+/', ' ', $imdbTitle); $imdbTitle = trim($imdbTitle); $imdbTitle = urlencode($imdbTitle); if (!strlen($imdbTitle)) { $this->say(sprintf('Enter movie title. (Usage: !imdb movie title)')); return; } $apiUri = sprintf($this->apiUri, $imdbTitle); $getJson = func::fetch($apiUri); $json = json_decode($getJson, true); $title = $json['Title']; $rating = $json['imdbRating']; $shortPlot = $json['Plot']; $link = 'http://www.imdb.com/title/' . $json['imdbID']; /* * Check if response is given */ if (!strlen($title)) { $this->say('IMDB: Error fetching data'); return; } $this->say(sprintf('Title: %s | Rating: %s | %s | %s', $title, $rating, $shortPlot, $link)); }
private function getYtTitle($data) { preg_match('/https?:\\/\\/(?:www.)?(?:youtu.be|youtube.com)\\/(?:[a-zA-Z0-9_?=]+)/', $data, $matches); if (!empty($matches) && !empty($matches[0])) { // We've got a YT URL. Parse it. $matches = parse_url($matches[0]); // We could have parsed a youtube.com link which parses in more pieces, and one piece must always be the same. // We take advantage of this. if ($matches['path'] == '/watch') { $vid_id = substr($matches['query'], 2); } else { $vid_id = substr($matches['path'], 1); } // We got a video ID longer or smaller than 11 characters...? That's, um, special. if (empty($vid_id) || strlen($vid_id) != 11) { return false; } // Put it into the final URL. $ytApi = sprintf($this->apiUri, $vid_id); // Make a request. $Ytdata = func::fetch($ytApi); // Attempt to fetch the title from the garbage we received. preg_match("/(?<=<title type=\\'text\\'>).*(?=<\\/title>)/", $Ytdata, $ytTitle); // And return it. return $ytTitle[0]; } // Sorry pals, non-YouTube URLs ain't going to cut it. return false; }
/** * * @param string $data * @return array */ protected function getArguments($data) { $args = explode(' ', $data); $func = function ($value) { return trim(\Library\FunctionCollection::removeLineBreaks($value)); }; return array_map($func, $args); }
/** * Adds a single command to the bot. * * @param IRCCommand $command The command to add. * @author Daniel Siepmann <*****@*****.**> */ public function addListener(\Library\IRC\Listener\Base $listener) { $listenerName = \Library\FunctionCollection::getClassName($listener); $listener->setIRCConnection($this->bot->getConnection()); $listener->setIRCBot($this->bot); $this->listeners[$listenerName] = $listener; $this->bot->log('The following Listener was added to the Bot: "' . $listenerName . '".', 'INFO'); }
/** * Adds a single command to the bot. * * @param IRCCommand $command The command to add. * @author Daniel Siepmann <*****@*****.**> */ public function addCommand(\Library\IRC\Command\Base $command) { $commandName = \Library\FunctionCollection::getClassName($command); $command->setIRCConnection($this->bot->getConnection()); $command->setIRCBot($this->bot); $this->commands[$commandName] = $command; $this->bot->log('The following Command was added to the Bot: "' . $commandName . '".', 'INFO'); }
public function command() { // We don't want any trailing \n, \r or anything in that area. $subcomm = $this->arguments[0]; $command = \Library\FunctionCollection::removeLineBreaks(implode(' ', $this->arguments)); $user = \Library\FunctionCollection::getUserNickName($this->data); if (!empty($subcomm)) { switch ($subcomm) { case 'show': $this->arguments[1] = (int) $this->arguments[1]; if (!empty($this->notes[$user][$this->arguments[1]])) { $this->say('Note #' . $this->arguments[1] . ': ' . $this->notes[$user][$this->arguments[1]]['note']); } else { $this->say('No note with ID ' . $this->arguments[1] . ' found.'); } break; case 'delete': $this->arguments[1] = (int) $this->arguments[1]; if (!empty($this->notes[$user][$this->arguments[1]])) { $this->say('Note #' . $this->arguments[1] . ': "' . $this->notes[$user][$this->arguments[1]]['name'] . '" was deleted.'); unset($this->notes[$user][$this->arguments[1]]); } else { $this->say('No note with ID ' . $this->arguments[1] . ' found.'); } break; case 'list': if (!empty($this->notes[$user])) { $notenames = array(); foreach ($this->notes[$user] as $id => $note) { $notenames[] = '#' . $id . ': ' . $note['name']; } $this->say($user . ', I have ' . count($this->notes[$user]) . ' notes for you: ' . implode(', ', $notenames)); } else { $this->say($user . ', I don\'t have any notes for you.'); } break; default: $dname = '(unnamed)'; $message = $command; if (preg_match('/@ (.+)$/', $command, $name)) { $dname = preg_replace('/[^a-zA-Z0-9!?_ -]+/', '', $name[1]); if ($name[1] != $dname) { $this->say('Invalid note name. Names can contain the characters A-Z, a-z, 0-9, !, ?, _ and - only.'); return; } // Cut it off the message. $message = preg_replace('/ @ ' . preg_quote($dname) . '/', '', $message); } // Add the note. $note = array('name' => $dname, 'note' => $message); // Count it. $count = !empty($this->notes[$user]) ? end(array_keys($this->notes[$user])) + 1 : 1; $this->notes[$user][$count] = $note; $this->say('Note ' . $dname . ' set with ID ' . $count . '. You can use "' . $this->bot->commandPrefix . 'note list" to view your saved notes, or "' . $this->bot->commandPrefix . 'note show ' . $count . '" to show this specific note.'); } } }
/** * * @param string $data * @return array */ protected function getArguments($data) { $args = explode(' ', $data); $func = function ($value) { return trim(\Library\FunctionCollection::removeLineBreaks($value)); }; if (isset($args[3])) { // remove the ':' from the message! $args[3] = substr($args[3], 1); } return $args; }
/** * Sends the arguments to the channel. A random joke. * * IRC-Syntax: PRIVMSG [#channel]or[user] : [message] */ public function command() { $this->bot->log("Fetching joke."); $data = func::fetch("http://api.icndb.com/jokes/random"); // ICNDB has escaped slashes in JSON response. $data = stripslashes($data); $joke = json_decode($data); if ($joke) { if (isset($joke->value->joke)) { $this->say(html_entity_decode($joke->value->joke)); return; } } $this->say("I don't feel like laughing today. :("); }
/** * Checks Version of Bot and Latest Version */ public function command() { $jsonfile = func::fetch($this->updateUri); $jsondata = json_decode($jsonfile); $latestversion = $jsondata->update[0]->version; $botversion = $this->bot->botVersion; $result = version_compare($botversion, $latestversion); if ($result === -1) { $updated = chr(3) . "07Out of Date!"; } elseif ($result === 0) { $updated = chr(3) . "03Up to Date!"; } else { $updated = chr(3) . "04You Broke Something :'("; } $this->say('The Latest Bot Version is ' . $latestversion . '. Your Bot is Version is ' . $botversion . "."); $this->say('Your Bot is ' . $updated); }
/** * Adds a log entry to the log file. * * @param string $log The log entry to add. * @param string $status The status, used to prefix the log entry. * * @author Daniel Siepmann <*****@*****.**> */ public function log($log, $status = '') { if (empty($status)) { $status = 'LOG'; } $msg = date('d.m.Y - H:i:s') . "\t [ " . $status . " ] \t" . \Library\FunctionCollection::removeLineBreaks($log) . "\r\n"; echo $msg; if (!is_null($this->logFileHandler)) { fwrite($this->logFileHandler, $msg); } }
/** * Returns location name of $ip. * * @param $ip * * @return string */ protected function getLocationNameFromIp($ip) { $uri = sprintf($this->ipUri, $ip); $response = func::fetch($uri); $jsonResponse = json_decode($response); if ($jsonResponse) { if (isset($jsonResponse->city)) { return $jsonResponse->city; } } return null; }
/** * This is the workhorse function, grabs the data from the server and displays on the browser * * @author Super3 <*****@*****.**> * @author Daniel Siepmann <*****@*****.**> */ private function main() { global $config; $this->commandPrefix = $config['prefix']; do { $command = ''; $arguments = array(); $data = $this->connection->getData(); // Check for some special situations and react: // The nickname is in use, create a now one using a counter and try again. if (stripos($data, 'Nickname is already in use.') !== false && $this->getUserNickName($data) == 'NickServ') { $this->nickToUse = $this->nick . ++$this->nickCounter; $this->sendDataToServer('NICK ' . $this->nickToUse); } // We're welcome. Let's join the configured channel/-s. if (stripos($data, 'Welcome') !== false) { $this->join_channel($this->channel); } // Something realy went wrong. if (stripos($data, 'Registration Timeout') !== false || stripos($data, 'Erroneous Nickname') !== false || stripos($data, 'Closing Link') !== false) { // If the error occurs to often, create a log entry and exit. if ($this->numberOfReconnects >= (int) $this->maxReconnects) { $this->log('Closing Link after "' . $this->numberOfReconnects . '" reconnects.', 'EXIT'); exit; } // Notice the error. $this->log($data, 'CONNECTION LOST'); // Wait before reconnect ... sleep(60 * 1); ++$this->numberOfReconnects; // ... and reconnect. $this->connection->connect(); return; } // Get the response from irc: $args = explode(' ', $data); $this->log($data); // Play ping pong with server, to stay connected: if ($args[0] == 'PING') { $this->sendDataToServer('PONG ' . $args[1]); } // Try to flush log buffers, if needed. $this->log->intervalFlush(); // Nothing new from the server, step over. if ($args[0] == 'PING' || !isset($args[1])) { continue; } /* @var $listener \Library\IRC\Listener\Base */ foreach ($this->listeners as $listener) { if (is_array($listener->getKeywords())) { foreach ($listener->getKeywords() as $keyword) { //compare listeners keyword and 1st arguments of server response if ($keyword === $args[1]) { $listener->execute($data); } } } } if (isset($args[3])) { // Explode the server response and get the command. // $source finds the channel or user that the command originated. $source = substr(trim(\Library\FunctionCollection::removeLineBreaks($args[2])), 0); $command = substr(trim(\Library\FunctionCollection::removeLineBreaks($args[3])), 1); // Someone PMed me? Oh noes. if ($source == $this->nickToUse && $args[1] == 'PRIVMSG') { $source = $this->getUserNickName($args[0]); } $arguments = array_slice($args, 4); unset($args); // Check if the response was a command. if (stripos($command, $this->commandPrefix) === 0) { $command = ucfirst(substr($command, strlen($this->commandPrefix))); // Command does not exist: if (!array_key_exists($command, $this->commands)) { $this->log('The following, not existing, command was called: "' . $command . '".', 'MISSING'); $this->log('The following commands are known by the bot: "' . implode(',', array_keys($this->commands)) . '".', 'MISSING'); continue; } $this->executeCommand($source, $command, $arguments, $data); } } } while (true); }
/** * Add data to the log. * @param string $data The data to add. * @param string $status The status message to add to the data. */ public function log($data, $status = '') { // No status? Use log. if (empty($status)) { $status = 'LOG'; } // Add the date and status to the message. $msg = date('d.m.Y - H:i:s') . "\t [ " . $status . " ] \t" . \Library\FunctionCollection::removeLineBreaks($data) . "\r\n"; // Print the message to the console. echo $msg; // If we're filtering channel messages, do so now. if (!empty($this->filterChannels)) { $isFromChannel = false; foreach ($this->filterChannels as $channel) { if (stripos($data, 'PRIVMSG ' . $channel . ' :') !== false) { $isFromChannel = true; } } if (!$isFromChannel) { return; } } // Are we using a buffer? If so, queue the message; we'll write it later. if ($this->useBuffer) { $this->buffer = $this->buffer . $msg; } else { if (!fwrite($this->handle, $msg)) { echo 'Failed to write message to file...'; } } }
/** * This is the workhorse function, grabs the data from the server and displays on the browser * * @author Super3 <*****@*****.**> * @author Daniel Siepmann <*****@*****.**> */ private function main() { // And fire up a connection. $this->log('Main loop ignited! GO GO GO!', 'STARTUP'); do { foreach ($this->reminders as $time => $reminder) { if (time() >= $time) { $this->sendDataToServer('PRIVMSG #wildphp :' . $this->reminders[$time]); unset($this->reminders[$time]); } } $command = ''; $arguments = array(); $data = $this->connection->getData(); // Check for some special situations and react: // The nickname is in use, create a now one using a counter and try again. if (stripos($data, 'Nickname is already in use.') !== false && \Library\FunctionCollection::getUserNickName($data) == $this->nickserv) { $this->nickToUse = $this->nick . ++$this->nickCounter; $this->sendDataToServer('NICK ' . $this->nickToUse); } // We're welcome without password or identified with password. Lets join. if (empty($this->password) && stripos($data, 'Welcome') !== false || !empty($this->password) && stripos($data, 'You are now identified') && \Library\FunctionCollection::getUserNickName($data) == $this->nickserv) { $this->join_channel($this->channel); } // Something realy went wrong. if (stripos($data, 'Registration Timeout') !== false || stripos($data, 'Erroneous Nickname') !== false || stripos($data, 'Closing Link') !== false) { // If the error occurs to often, create a log entry and exit. if ($this->numberOfReconnects >= (int) $this->maxReconnects) { $this->log('Closing Link after "' . $this->numberOfReconnects . '" reconnects.', 'EXIT'); exit; } // Notice the error. $this->log($data, 'CONNECTION LOST'); // Wait before reconnect ... sleep(60 * 1); ++$this->numberOfReconnects; // ... and reconnect. $this->connection->connect(); return; } // Get the response from irc: $args = explode(' ', $data); if (!empty($data)) { $this->log($data); } // Play ping pong with server, to stay connected: if ($args[0] == 'PING') { $this->sendDataToServer('PONG ' . $args[1]); } // Try to flush log buffers, if needed. $this->log->intervalFlush(); // Nothing new from the server, step over. if ($args[0] == 'PING' || !isset($args[1])) { unset($data, $args); continue; } if (isset($args[3])) { // Explode the server response and get the command. // $source finds the channel or user that the command originated. $source = substr(trim(\Library\FunctionCollection::removeLineBreaks($args[2])), 0); $command = substr(trim(\Library\FunctionCollection::removeLineBreaks($args[3])), 1); // Someone PMed me? Oh noes. if ($source == $this->nickToUse && $args[1] == 'PRIVMSG') { $source = \Library\FunctionCollection::getUserNickName($args[0]); } $this->source = $source; $arguments = array_slice($args, 4); // Check if the response was a command. if (stripos($command, $this->commandPrefix) === 0) { $command = ucfirst(substr($command, strlen($this->commandPrefix))); // Command does not exist: if (!$this->commandManager->commandExists($command)) { $this->log('The following, not existing, command was called: "' . $command . '".', 'MISSING'); continue; } $this->commandManager->executeCommand($source, $command, $arguments, $data); } } // Call the listeners! $this->listenerManager->listenerHook($args, $data); unset($data, $args); } while (true); }