/** * When a message arrives that contains a trigger, this is started * * @param $msgData */ public function onMessage(stdClass $msgData) { $message = $msgData->message->message; $data = $this->trigger->trigger($message, $this->information()["trigger"]); if (isset($data["trigger"])) { $channelName = $msgData->channel->name; $guildName = $msgData->guild->name; // Most EVE players on Discord use their ingame name, so lets support @highlights $messageString = stristr($data["messageString"], "@") ? str_replace("<@", "", str_replace(">", "", $data["messageString"])) : $data["messageString"]; if (is_numeric($messageString)) { // The person used @highlighting, so now we got a discord id, lets map that to a name $messageString = $this->sluggardDB->queryField("SELECT name FROM usersSeen WHERE id = :id", "name", array(":id" => $messageString)); } $url = "http://rena.karbowiak.dk/api/search/character/{$messageString}/"; $data = @json_decode($this->curl->getData($url), true)["character"]; if (empty($msgData)) { return $msgData->user->reply("**Error:** no results was returned."); } if (count($msgData) > 1) { $results = array(); foreach ($msgData as $char) { $results[] = $char["characterName"]; } return $msgData->user->reply("**Error:** more than one result was returned: " . implode(", ", $results)); } // Get stats $characterID = $data[0]["characterID"]; $statsURL = "https://beta.eve-kill.net/api/charInfo/characterID/" . urlencode($characterID) . "/"; $stats = json_decode($this->curl->getData($statsURL), true); if (empty($stats)) { return $msgData->user->reply("**Error:** no data available"); } $characterName = @$stats["characterName"]; $corporationName = @$stats["corporationName"]; $allianceName = isset($stats["allianceName"]) ? $stats["allianceName"] : "None"; $factionName = isset($stats["factionName"]) ? $stats["factionName"] : "None"; $securityStatus = @$stats["securityStatus"]; $lastSeenSystem = @$stats["lastSeenSystem"]; $lastSeenRegion = @$stats["lastSeenRegion"]; $lastSeenShip = @$stats["lastSeenShip"]; $lastSeenDate = @$stats["lastSeenDate"]; $corporationActiveArea = @$stats["corporationActiveArea"]; $allianceActiveArea = @$stats["allianceActiveArea"]; $soloKills = @$stats["soloKills"]; $blobKills = @$stats["blobKills"]; $lifeTimeKills = @$stats["lifeTimeKills"]; $lifeTimeLosses = @$stats["lifeTimeLosses"]; $amountOfSoloPVPer = @$stats["percentageSoloPVPer"]; $ePeenSize = @$stats["ePeenSize"]; $facepalms = @$stats["facepalms"]; $lastUpdated = @$stats["lastUpdatedOnBackend"]; $url = "https://beta.eve-kill.net/character/" . $stats["characterID"] . "/"; $msg = "```characterName: {$characterName}\r\ncorporationName: {$corporationName}\r\nallianceName: {$allianceName}\r\nfactionName: {$factionName}\r\nsecurityStatus: {$securityStatus}\r\nlastSeenSystem: {$lastSeenSystem}\r\nlastSeenRegion: {$lastSeenRegion}\r\nlastSeenShip: {$lastSeenShip}\r\nlastSeenDate: {$lastSeenDate}\r\ncorporationActiveArea: {$corporationActiveArea}\r\nallianceActiveArea: {$allianceActiveArea}\r\nsoloKills: {$soloKills}\r\nblobKills: {$blobKills}\r\nlifeTimeKills: {$lifeTimeKills}\r\nlifeTimeLosses: {$lifeTimeLosses}\r\npercentageSoloPVPer: {$amountOfSoloPVPer}\r\nePeenSize: {$ePeenSize}\r\nfacepalms: {$facepalms}\r\nlastUpdated: {$lastUpdated}```\r\nFor more info, visit: {$url}"; $this->log->info("Sending char info to {$channelName} on {$guildName}"); $msgData->user->reply($msg); } }
/** * When a message arrives that contains a trigger, this is started * * @param $msgData */ public function onMessage($msgData) { $message = $msgData->message->message; $data = $this->trigger->trigger($message, $this->information()["trigger"]); if (isset($data["trigger"])) { $channelName = $msgData->channel->name; $guildName = $msgData->guild->name; $crestData = json_decode($this->curl->getData("https://public-crest.eveonline.com/"), true); $tqStatus = isset($crestData["serviceStatus"]["eve"]) ? $crestData["serviceStatus"]["eve"] : "offline"; $tqOnline = (int) $crestData["userCounts"]["eve"]; $msg = "**TQ Status:** {$tqStatus} with {$tqOnline} users online."; $this->log->info("Sending eveStatus info to {$channelName} on {$guildName}"); $msgData->user->reply($msg); } }
/** * When a message arrives that contains a trigger, this is started * * @param $msgData */ public function onMessage(stdClass $msgData) { $message = $msgData->message->message; $data = $this->trigger->trigger($message, $this->information()["trigger"]); if (isset($data["trigger"])) { $channelName = $msgData->channel->name; $guildName = $msgData->guild->name; $systemName = $data["trigger"]; $itemName = $data["messageString"]; if ($itemName) { // Quick lookups if (isset($this->quickLookUps[$itemName])) { $single = $this->quickLookUps[$itemName]; $multiple = null; } else { $single = $this->ccpDB->queryRow("SELECT typeID, typeName FROM invTypes WHERE typeName = :item COLLATE NOCASE", array(":item" => ucfirst($itemName))); $multiple = $this->ccpDB->query("SELECT typeID, typeName FROM invTypes WHERE typeName LIKE :item COLLATE NOCASE LIMIT 5", array(":item" => "%" . ucfirst($itemName) . "%")); } // Sometimes the multiple lookup is returning just one if (count($multiple) == 1) { $single = $multiple[0]; } // If there are multiple results, and not a single result, it's an error if (empty($single) && !empty($multiple)) { $items = array(); foreach ($multiple as $item) { $items[] = $item["typeName"]; } $items = implode(", ", $items); return $msgData->user->reply("**Multiple results found:** {$items}"); } // If there is a single result, we'll get data now! if ($single) { $typeID = $single["typeID"]; $typeName = $single["typeName"]; $solarSystemID = $systemName == "pc" ? "global" : $this->solarSystems[$systemName]; // Get pricing data if ($solarSystemID == "global") { $data = new SimpleXMLElement($this->curl->getData("https://api.eve-central.com/api/marketstat?typeid={$typeID}")); } else { $data = new SimpleXMLElement($this->curl->getData("https://api.eve-central.com/api/marketstat?usesystem={$solarSystemID}&typeid={$typeID}")); } $lowBuy = number_format((double) $data->marketstat->type->buy->min, 2); $avgBuy = number_format((double) $data->marketstat->type->buy->avg, 2); $highBuy = number_format((double) $data->marketstat->type->buy->max, 2); $lowSell = number_format((double) $data->marketstat->type->sell->min, 2); $avgSell = number_format((double) $data->marketstat->type->sell->avg, 2); $highSell = number_format((double) $data->marketstat->type->sell->max, 2); $this->log->info("Sending pricing info to {$channelName} on {$guildName}"); $solarSystemName = $systemName == "pc" ? "Global" : ucfirst($systemName); $messageData = "```\r\ntypeName: {$typeName}\r\nsolarSystemName: {$solarSystemName}\r\nBuy:\r\n Low: {$lowBuy}\r\n Avg: {$avgBuy}\r\n High: {$highBuy}\r\nSell:\r\n Low: {$lowSell}\r\n Avg: {$avgSell}\r\n High: {$highSell}```"; $msgData->user->reply($messageData); } else { $msgData->user->reply("**Error:** ***{$itemName}*** not found"); } } else { $msgData->user->reply("**Error:** No itemName set.."); } } }
/** * When a message arrives that contains a trigger, this is started * * @param $msgData */ public function onMessage(stdClass $msgData) { $message = $msgData->message->message; $data = $this->trigger->trigger($message, $this->information()["trigger"]); if (isset($data["trigger"])) { $channelName = $msgData->channel->name; $guildName = $msgData->guild->name; $messageString = $data["messageString"]; $url = "http://rena.karbowiak.dk/api/search/corporation/{$messageString}/"; $data = @json_decode($this->curl->getData($url), true)["corporation"]; if (empty($data)) { return $msgData->user->reply("**Error:** no results was returned."); } if (count($data) > 1) { $results = array(); foreach ($data as $corp) { $results[] = $corp["corporationName"]; } return $msgData->user->reply("**Error:** more than one result was returned: " . implode(", ", $results)); } // Get stats $corporationID = $data[0]["corporationID"]; $statsURL = "https://beta.eve-kill.net/api/corpInfo/corporationID/" . urlencode($corporationID) . "/"; $stats = json_decode($this->curl->getData($statsURL), true); if (empty($stats)) { return $msgData->user->reply("**Error:** no data available"); } $corporationName = @$stats["corporationName"]; $allianceName = isset($stats["allianceName"]) ? $stats["allianceName"] : "None"; $factionName = isset($stats["factionName"]) ? $stats["factionName"] : "None"; $ceoName = @$stats["ceoName"]; $homeStation = @$stats["stationName"]; $taxRate = @$stats["taxRate"]; $corporationActiveArea = @$stats["corporationActiveArea"]; $allianceActiveArea = @$stats["allianceActiveArea"]; $lifeTimeKills = @$stats["lifeTimeKills"]; $lifeTimeLosses = @$stats["lifeTimeLosses"]; $memberCount = @$stats["memberArrayCount"]; $superCaps = @count($stats["superCaps"]); $ePeenSize = @$stats["ePeenSize"]; $url = "https://beta.eve-kill.net/corporation/" . @$stats["corporationID"] . "/"; $msg = "```corporationName: {$corporationName}\r\nallianceName: {$allianceName}\r\nfactionName: {$factionName}\r\nceoName: {$ceoName}\r\nhomeStation: {$homeStation}\r\ntaxRate: {$taxRate}\r\ncorporationActiveArea: {$corporationActiveArea}\r\nallianceActiveArea: {$allianceActiveArea}\r\nlifeTimeKills: {$lifeTimeKills}\r\nlifeTimeLosses: {$lifeTimeLosses}\r\nmemberCount: {$memberCount}\r\nsuperCaps: {$superCaps}\r\nePeenSize: {$ePeenSize}\r\n```\r\nFor more info, visit: {$url}"; $this->log->info("Sending corp info to {$channelName} on {$guildName}"); $msgData->user->reply($msg); } }
private function checkMails($keyID, $vCode, $characterID) { $updateMaxID = false; $url = "https://api.eveonline.com/char/MailMessages.xml.aspx?keyID={$keyID}&vCode={$vCode}&characterID={$characterID}"; $data = json_decode(json_encode(simplexml_load_string($this->curl->getData($url), "SimpleXMLElement", LIBXML_NOCDATA)), true); $data = $data["result"]["rowset"]["row"]; $mails = array(); // Sometimes there is only ONE notification, so.. yeah.. if (count($data) > 1) { foreach ($data as $getFuckedCCP) { $mails[] = $getFuckedCCP["@attributes"]; } } else { $mails[] = $data["@attributes"]; } usort($mails, array($this, "sortByDate")); foreach ($mails as $mail) { if (in_array($mail["toCorpOrAllianceID"], $this->toIDs) && $mail["messageID"] > $this->newestMailID) { $sentBy = $mail["senderName"]; $title = $mail["title"]; $sentDate = $mail["sentDate"]; $url = "https://api.eveonline.com/char/MailBodies.xml.aspx?keyID={$keyID}&vCode={$vCode}&characterID={$characterID}&ids=" . $mail["messageID"]; $content = strip_tags(str_replace("<br>", "\n", json_decode(json_encode(simplexml_load_string($this->curl->getData($url), "SimpleXMLElement", LIBXML_NOCDATA)))->result->rowset->row)); $messageSplit = null; if (strlen($content) > 1850) { $messageSplit = str_split($content, 1850); } // Stitch the mail together $msg = "**Mail By: **{$sentBy}\n"; $msg .= "**Sent Date: **{$sentDate}\n"; $msg .= "**Title: ** {$title}\n"; $msg .= "**Content: **\n"; if (!$messageSplit) { $msg .= htmlspecialchars_decode(trim($content)); } // Send the mails to the channel $channel = \Discord\Parts\Channel\Channel::find($this->toDiscordChannel); if (strlen($content) > 1850 && !empty($longMessage)) { foreach ($longMessage as $msg) { $channel->sendMessage($msg); } } else { $channel->sendMessage($msg); } sleep(1); // Lets sleep for a second, so we don't rage spam // Find the maxID so we don't spit this message out ever again $this->maxID = max($mail["messageID"], $this->maxID); $this->newestMailID = $this->maxID; //$mail["messageID"]; $updateMaxID = true; // set the maxID if ($updateMaxID) { $this->storage->set("newestCorpMailID", $this->maxID); } } } }
/** * */ public function createCCPDB() { $ccpDataURL = "https://www.fuzzwork.co.uk/dump/sqlite-latest.sqlite.bz2"; $ccpDataMD5URL = "https://www.fuzzwork.co.uk/dump/sqlite-latest.sqlite.bz2.md5"; $dbLocation = BASEDIR . "/config/database/"; $md5 = explode(" ", $this->curl->getData($ccpDataMD5URL))[0]; $lastSeenMd5 = $this->storage->get("ccpDataMd5"); // If the last seen md5, isn't equal the current seen md5, we'll update! if ($lastSeenMd5 !== $md5) { try { $this->log->notice("Updating CCP SQLite Database"); $this->log->notice("Downloading bz2 file, and writing it to {$dbLocation}ccpData.sqlite.bz2"); $downloadedData = $this->curl->getLargeData($ccpDataURL, "{$dbLocation}ccpData.sqlite.bz2"); if ($downloadedData == false) { $this->log->warn("Error: File not downloaded successfully!"); die; } $this->log->notice("Opening bz2 file"); $sqliteData = bzopen("{$dbLocation}ccpData.sqlite.bz2", "r"); $this->log->notice("Reading from bz2 file"); $data = ""; while (!feof($sqliteData)) { $data .= bzread($sqliteData, 4096); } $this->log->notice("Writing bz2 file contents into .sqlite file"); file_put_contents("{$dbLocation}ccpData.sqlite", $data); $this->log->notice("Deleting bz2 file"); unlink("{$dbLocation}ccpData.sqlite.bz2"); $this->log->notice("Creating mapCelestials view"); $this->ccpDB->execute("CREATE VIEW mapAllCelestials AS SELECT itemID, itemName, typeName, mapDenormalize.typeID, solarSystemName, mapDenormalize.solarSystemID, mapDenormalize.constellationID, mapDenormalize.regionID, mapRegions.regionName, orbitID, mapDenormalize.x, mapDenormalize.y, mapDenormalize.z FROM mapDenormalize JOIN invTypes ON (mapDenormalize.typeID = invTypes.typeID) JOIN mapSolarSystems ON (mapSolarSystems.solarSystemID = mapDenormalize.solarSystemID) JOIN mapRegions ON (mapDenormalize.regionID = mapRegions.regionID) JOIN mapConstellations ON (mapDenormalize.constellationID = mapConstellations.constellationID)"); $this->log->notice("CCP Database updated!"); $this->storage->set("ccpDataMd5", $md5); } catch (\Exception $e) { $this->log->warn("Error updating the CCPDatabase. Bot can't run"); die; } } }
/** * When the bot's tick hits a specified time, this is started * * Runtime is defined in $this->information(), timerFrequency */ public function onTimer() { // Fetch all the characterIDs from the database $users = $this->sluggardDB->query("SELECT * FROM authentications"); foreach ($users as $user) { $discordID = $user["discordID"]; $guildID = $user["guildID"]; $characterID = $user["characterID"]; $corporationID = $user["corporationID"]; $allianceID = $user["allianceID"]; // Get the information for this user from CCP try { $ccpData = json_decode(json_encode(new SimpleXMLElement($this->curl->getData("https://api.eveonline.com/eve/CharacterAffiliation.xml.aspx?ids={$characterID}"))), true); $data = $ccpData["result"]["rowset"]["row"]["@attributes"]; $currentCharacterID = $data["characterID"]; $currentCorporationID = $data["corporationID"]; $currentAllianceID = $data["allianceID"]; // Lets just be sure we're doing this for the correct character.. CCP is weird sometimes if ($currentCharacterID == $characterID) { $remove = false; // Remove if the guy switched corp if ($currentCorporationID != $corporationID) { $remove = true; } // Remove if the guy switched alliance if ($currentAllianceID != $allianceID) { $remove = true; } // Lets remove the groups from this user (Every single role!) if ($remove == true) { $guild = $this->discord->guilds->first(); $guildName = $guild->name; $member = $guild->members->get("id", $discordID); $memberName = $member->user->username; $roles = $member->roles; // Remove all roles, we don't care what roles they are, remove them all.. // Can't remove server owner tho, so.. mehe.. foreach ($roles as $role) { $member->removeRole($role); } // Delete the auth info from the db $this->sluggardDB->execute("DELETE FROM authentications WHERE discordID = :discordID", array(":discordID" => $discordID)); $this->log->info("Deleted all roles for {$memberName} on {$guildName}"); } } } catch (\Exception $e) { $this->log->err("Error with character check: " . $e->getMessage()); } } }
/** * @param $type * @param $typeID * @return mixed */ private function apiData($type, $typeID) { $downloadFrom = ""; switch ($type) { case "char": $downloadFrom = $this->charApi; break; case "corp": $downloadFrom = $this->corpApi; break; case "alli": $downloadFrom = $this->alliApi; break; } return json_decode($this->curl->getData($downloadFrom . $typeID . "/"), true); }
/** * @param $keyID * @param $vCode */ private function checkForSiphons($keyID, $vCode) { try { // Seriously CCP.. *sigh* $url = "https://api.eveonline.com/corp/AssetList.xml.aspx?keyID={$keyID}&vCode={$vCode}"; $data = json_decode(json_encode(simplexml_load_string($this->curl->getData($url), "SimpleXMLElement", LIBXML_NOCDATA)), true); $data = $data["result"]["rowset"]["row"]; // If there is no data, just quit.. if (empty($data)) { return; } $fixedData = array(); foreach ($data as $key => $getFuckedCCP) { if ($getFuckedCCP["@attributes"]["typeID"] == 14343) { $fixedData[$key] = $getFuckedCCP["@attributes"]; $fixedData[$key]["siloContents"] = @$getFuckedCCP["rowset"]["row"]["@attributes"]; } } foreach ($fixedData as $silos) { $locationID = $silos["locationID"]; $locationName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $locationID)); $siloContents = $silos["siloContents"]; $quantity = $siloContents["quantity"]; $siloHarvesting = $siloContents["typeID"]; $siloHarvestingName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $siloHarvesting)); // Skip this silo if it has no data if ($siloContents == null || empty($siloContents)) { continue; } // If we're being siphoned if ($quantity % 100 != 0) { $msg = "**Alert:** Possible Siphon detected in {$locationName}.. What is being siphoned: {$siloHarvestingName}"; $channel = \Discord\Parts\Channel\Channel::find($this->toDiscordChannel); $channel->sendMessage($msg); } } } catch (Exception $e) { $this->log->debug("Error: " . $e->getMessage()); } }
/** * When a message arrives that contains a trigger, this is started * * @param $msgData * @return mixed */ public function onMessage($msgData) { $message = $msgData->message->message; $data = $this->trigger->trigger($message, $this->information()["trigger"]); // If this channel is not in the allowed channels array for this plugin, we'll just quit if (!in_array($msgData->message->channelID, $this->channelLimit[get_class($this)])) { $channelIDs = array(); foreach ($this->channelLimit[get_class($this)] as $c) { $channelIDs[] = "<#" . $c . "> "; } $channelsAllowed = implode(" ", $channelIDs); $msg = "**Error:** this plugin only works in {$channelsAllowed}"; return $msgData->user->reply($msg); } if (isset($data["trigger"])) { $urls = array(); // If it doesn't exist, we'll just make it an empty string.. if (!isset($data["messageArray"][0])) { $data["messageArray"][0] = ""; } switch ($data["messageArray"][0]) { case "redheads": case "redhead": case "red": $urls = array("https://api.imgur.com/3/gallery/r/redheads/time/all/", "https://api.imgur.com/3/gallery/r/ginger/time/all/", "https://api.imgur.com/3/gallery/r/FireCrotch/time/all/"); break; case "blondes": $urls = array("https://api.imgur.com/3/gallery/r/blondes/time/all/"); break; case "asians": $urls = array("https://api.imgur.com/3/gallery/r/AsiansGoneWild/time/all/"); break; case "gonewild": $urls = array("https://api.imgur.com/3/gallery/r/gonewild/time/all/"); break; case "realgirls": $urls = array("https://api.imgur.com/3/gallery/r/realgirls/time/all/"); break; case "palegirls": $urls = array("https://api.imgur.com/3/gallery/r/palegirls/time/all/"); break; case "gif": $urls = array("https://api.imgur.com/3/gallery/r/NSFW_GIF/time/all/"); break; case "lesbians": $urls = array("https://api.imgur.com/3/gallery/r/lesbians/time/all/"); break; case "tattoos": $urls = array("https://api.imgur.com/3/gallery/r/Hotchickswithtattoos/time/all/"); break; case "mgw": case "militarygonewild": $urls = array("https://api.imgur.com/3/gallery/r/MilitaryGoneWild/time/all/"); break; case "amateur": $urls = array("https://api.imgur.com/3/gallery/r/AmateurArchives/time/all/"); break; case "college": $urls = array("https://api.imgur.com/3/gallery/r/collegesluts/time/all/"); break; case "bondage": $urls = array("https://api.imgur.com/3/gallery/r/bondage/time/all/"); break; case "milf": $urls = array("https://api.imgur.com/3/gallery/r/milf/time/all/"); break; case "freckles": $urls = array("https://api.imgur.com/3/gallery/r/FreckledGirls/time/all/"); break; case "cosplay": $urls = array("https://api.imgur.com/3/gallery/r/cosplay/time/all/"); break; case "boobs": $urls = array("https://api.imgur.com/3/gallery/r/boobs/time/all/"); break; case "ass": $urls = array("https://api.imgur.com/3/gallery/r/ass/time/all/"); break; default: $msg = "No endpoint selected. Currently available are: redheads, blondes, asians, gonewild, realgirls, palegirls, gif, lesbians, tattoos, mgw/militarygonewild, amateur, college, bondage, milf, freckles, boobs, ass and cosplay"; $msgData->user->reply($msg); break; } if (!empty($urls)) { // Select a random url $url = $urls[array_rand($urls)]; $clientID = $this->config->get("clientID", "imgur"); $headers = array(); $headers[] = "Content-type: application/json"; $headers[] = "Authorization: Client-ID {$clientID}"; $data = $this->curl->getData($url, $headers); if ($data) { $json = json_decode($data, true)["data"]; $count = count($json); $img = $json[array_rand($json)]; // Get gifv over gif, if it's infact a gif gallery //$imageURL = isset($img["gifv"]) ? $img["gifv"] : $img["link"]; $imageURL = $img["link"]; // gifv doesn't embed properly in discord, yet.. $message = "**Title:** {$img["title"]} | **Section:** {$img["section"]} | **url:** {$imageURL}"; $msgData->user->reply($message); } } } }