/** * 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; $guildID = $msgData->guild->id; $switch = $data["messageArray"][0]; switch ($switch) { case "save": $fittingURL = $data["messageArray"][1]; unset($data["messageArray"][0]); unset($data["messageArray"][1]); $fittingName = implode(" ", $data["messageArray"]); $this->sluggardDB->execute("REPLACE INTO fittings (guildID, fittingName, fittingURL) VALUES (:guildID, :fittingName, :fittingURL)", array(":guildID" => $guildID, ":fittingName" => $fittingName, ":fittingURL" => $fittingURL)); $this->log->info("Saved fitting ({$fittingName}) on {$guildName}"); $msg = "Fitting saved, you can now call upon it by using !fit {$fittingName}"; $msgData->user->reply($msg); break; case "delete": unset($data["messageArray"][0]); $fittingName = implode(" ", $data["messageArray"]); if (strlen($fittingName) > 1) { $fittingData = $this->sluggardDB->queryField("SELECT fittingURL FROM fittings WHERE fittingName = :fittingName AND guildID = :guildID", "fittingURL", array(":fittingName" => $fittingName, ":guildID" => $guildID)); if ($fittingData) { $this->sluggardDB->execute("DELETE FROM fittings WHERE fittingName = :fittingName AND guildID = :guildID", array(":fittingName" => $fittingName, ":guildID" => $guildID)); $msg = "Fitting {$fittingName} was deleted"; } else { $msg = "Fitting {$fittingName} not found for this server"; } } else { $msg = "Error with your search"; } $msgData->user->reply($msg); break; default: $search = $data["messageString"]; if (strlen($search) > 1) { $fittingData = $this->sluggardDB->queryField("SELECT fittingURL FROM fittings WHERE fittingName = :fittingName AND guildID = :guildID", "fittingURL", array(":fittingName" => $search, ":guildID" => $guildID)); if ($fittingData) { $msg = "Fitting {$search} can be seen here: {$fittingData}"; } else { $msg = "Fitting {$search} not found for this server"; } } else { $msg = "Error with your search"; } $msgData->user->reply($msg); break; } } }
/** * 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"]); $username = $msgData->message->from; $channelName = $msgData->channel->name; $guildName = $msgData->guild->name; if (isset($data["trigger"])) { $this->log->info("Sending log stats info to {$username} in {$channelName} on {$guildName}"); $msg = "To view the log stats for this channel, look at: http://pisg.karbowiak.dk/" . urlencode(urlencode($guildName) . "." . urlencode($channelName)) . ".html"; $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($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; $date = date("d-m-Y"); $fullDate = date("Y-m-d H:i:s"); $dateTime = new DateTime($fullDate); $et = $dateTime->setTimezone(new DateTimeZone("America/New_York")); $et = $et->format("H:i:s"); $pt = $dateTime->setTimezone(new DateTimeZone("America/Los_Angeles")); $pt = $pt->format("H:i:s"); $utc = $dateTime->setTimezone(new DateTimeZone("UTC")); $utc = $utc->format("H:i:s"); $cet = $dateTime->setTimezone(new DateTimeZone("Europe/Copenhagen")); $cet = $cet->format("H:i:s"); $msk = $dateTime->setTimezone(new DateTimeZone("Europe/Moscow")); $msk = $msk->format("H:i:s"); $aest = $dateTime->setTimezone(new DateTimeZone("Australia/Sydney")); $aest = $aest->format("H:i:s"); $msg = "**Current EVE Time:** {$utc} / **EVE Date:** {$date} / **PT:** {$pt} / **ET:** {$et} / **CET:** {$cet} / **MSK:** {$msk} / **AEST:** {$aest}"; $this->log->info("Sending time 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 the bot does a tick (every second), this is started */ public function onTick() { $check = true; foreach ($this->keys as $keyOwner => $api) { try { if ($check == false) { return; } $keyID = $api["keyID"]; $vCode = $api["vCode"]; if (@$api["corpKey"] == true) { continue; } $characterID = $api["characterID"]; $lastChecked = $this->storage->get("corpMailCheck{$keyID}{$keyOwner}{$characterID}"); if ($lastChecked <= time()) { $this->log->info("Checking API Key {$keyID} belonging to {$keyOwner} for new corp mails"); $this->checkMails($keyID, $vCode, $characterID); $this->storage->set("corpMailCheck{$keyID}{$keyOwner}{$characterID}", time() + 1807); // Reschedule it's check for 30minutes from now (plus 7 seconds, because CCP isn't known to adhere strictly to timeouts, lol) $check = false; } } catch (\Exception $e) { $this->log->err("Error with eve mail checker: " . $e->getMessage()); } } }
/** * 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; $startTime = $this->app->startTime; $time1 = new DateTime(date("Y-m-d H:i:s", $startTime)); $time2 = new DateTime(date("Y-m-d H:i:s")); $interval = $time1->diff($time2); $gitRevision = $this->app->gitrevision->getRevision(); $msg = "```Hello, i am Sluggard - i am a bot created for EVE Online related Discord servers.\r\nAlso, i am the half-brother of Sovereign, atleast in the Blasto 7 movie..\r\n\r\nAbout Me:\r\nAuthor: Karbowiak (Discord ID: 118440839776174081)\r\nLibrary: DiscordPHP (https://github.com/teamreflex/DiscordPHP\\)\r\nCurrent version: " . $gitRevision["short"] . " (Last Update: " . $gitRevision["lastChangeDate"] . ")\r\nGithub Repo: https://github.com/karbowiak/Sluggard\\\r\n\r\nStatistics:\r\nUptime: " . $interval->y . " Year(s), " . $interval->m . " Month(s), " . $interval->d . " Days, " . $interval->h . " Hours, " . $interval->i . " Minutes, " . $interval->s . " seconds.\r\nMemory Usage: ~" . round(memory_get_usage() / 1024 / 1024, 3) . "MB```"; $this->log->info("Sending about 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; // 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); } }
/** * */ public function createSluggardDB() { $tables = array("users", "usersSeen", "storage", "authentications"); $tableCreateCode = array("users" => "\r\n BEGIN;\r\n CREATE TABLE IF NOT EXISTS `users` (\r\n `id` INTEGER PRIMARY KEY AUTOINCREMENT,\r\n `serverID` BIGINT(20) NOT NULL,\r\n `userID` BIGINT(20) NOT NULL,\r\n `discordID` BIGINT(20) NOT NULL,\r\n `characterID` INT(16) NOT NULL,\r\n `corporationID` VARCHAR(255) NOT NULL,\r\n `allianceID` VARCHAR(255) NOT NULL,\r\n `authString` VARCHAR(255) NOT NULL,\r\n `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP\r\n );\r\n CREATE UNIQUE INDEX userID ON users (userID);\r\n CREATE INDEX serverID ON users (serverID);\r\n CREATE INDEX corporationID ON users (corporationID);\r\n CREATE INDEX allianceID ON users (allianceID);\r\n COMMIT;", "usersSeen" => "\r\n BEGIN;\r\n CREATE TABLE IF NOT EXISTS `usersSeen` (\r\n `id` INTEGER PRIMARY KEY,\r\n `name` VARCHAR(255) NOT NULL,\r\n `isAdmin` TINYINT(1) NOT NULL DEFAULT '0',\r\n `lastSeen` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r\n `lastSpoke` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',\r\n `lastStatus` VARCHAR(50) NULL DEFAULT NULL,\r\n `lastWritten` TEXT NULL\r\n );\r\n CREATE INDEX name ON usersSeen (name);\r\n COMMIT;", "storage" => "\r\n BEGIN;\r\n CREATE TABLE IF NOT EXISTS `storage` (\r\n `id` INTEGER PRIMARY KEY AUTOINCREMENT,\r\n `key` VARCHAR(255) NOT NULL,\r\n `value` VARCHAR(255) NOT NULL\r\n );\r\n CREATE UNIQUE INDEX key ON storage (key);\r\n COMMIT;", "authentications" => "\r\n BEGIN;\r\n CREATE TABLE IF NOT EXISTS `authentications` (\r\n `discordID` INTEGER PRIMARY KEY,\r\n `characterID` BIGINT(40) NOT NULL,\r\n `corporationID` BIGINT(40) NOT NULL,\r\n `allianceID` BIGINT(40) NOT NULL,\r\n `guildID` BIGINT(128) DEFAULT 0 NOT NULL\r\n );\r\n CREATE UNIQUE INDEX discordID ON authentications (discordID);\r\n COMMIT;\r\n ", "fittings" => "\r\n BEGIN;\r\n CREATE TABLE `fittings` (\r\n `guildID` INTEGER PRIMARY KEY,\r\n `fittingName` VARCHAR(255) NOT NULL,\r\n `fittingURL` VARCHAR(255) NOT NULL\r\n );\r\n CREATE UNIQUE INDEX fittingName ON fittings (guildID, fittingName);\r\n COMMIT;"); $dbName = $this->config->get("botName", "bot"); // Does the file exist? if (!file_exists(BASEDIR . "/config/database/{$dbName}.sqlite")) { touch(BASEDIR . "/config/database/{$dbName}.sqlite"); } // Check if the tables exist, if not, create them foreach ($tables as $table) { $exists = $this->sluggardDB->queryField("SELECT name FROM sqlite_master WHERE type = 'table' AND name = :name", "name", array(":name" => $table)); if (!$exists) { $this->log->warn("Creating {$table} in {$dbName}.sqlite, since it does not exist"); $this->sluggardDB->execute(trim($tableCreateCode[$table])); } } }
/** * 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; $user = stristr($data["messageString"], "@") ? str_replace("<@", "", str_replace(">", "", $data["messageString"])) : $data["messageString"]; // Get data for user $userData = $this->sluggardDB->queryRow("SELECT * FROM usersSeen WHERE (name = :name COLLATE NOCASE OR id = :name)", array(":name" => $user)); if ($userData) { $msg = "```ID: {$userData["id"]}\nName: {$userData["name"]}\nisAdmin: {$userData["isAdmin"]}\nLast Seen: {$userData["lastSeen"]}\nLast Spoken: {$userData["lastSpoke"]}\nLast Status: {$userData["lastStatus"]}```"; $this->log->info("Sending time info to {$channelName} on {$guildName}"); $msgData->user->reply($msg); } else { $msgData->user->reply("**Error:** no such user in the users table"); } } }
/** * @param $url * @param $storagePath * @return bool */ public function getLargeData($url, $storagePath) { try { $readHandle = fopen($url, "rb"); $writeHandle = fopen($storagePath, "w+b"); if (!$readHandle || !$writeHandle) { return false; } while (!feof($readHandle)) { if (fwrite($writeHandle, fread($readHandle, 4096)) == FALSE) { return false; } } fclose($readHandle); fclose($writeHandle); return true; } catch (\Exception $e) { $this->log->warn("cURL Error: " . $e->getMessage()); return false; } }
/** * 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()); } } }
/** * 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; $item = $data["messageString"]; if (is_numeric($item)) { $data = $this->ccpDB->queryRow("SELECT * FROM invTypes WHERE typeID = :item", array(":item" => $item)); } else { $data = $this->ccpDB->queryRow("SELECT * FROM invTypes WHERE typeName = :item COLLATE NOCASE", array(":item" => $item)); } if ($data) { $msg = "```"; foreach ($data as $key => $value) { $msg .= $key . ": " . $value . "\n"; } $msg .= "```"; $this->log->info("Sending item 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; $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); } }
/** * 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; $authString = trim($data["messageString"]); $private = (bool) $msgData->channel->is_private; $authData = $this->authData->queryRow("SELECT * FROM registrations WHERE authString = :authString AND active = 1", array(":authString" => $authString)); if ($private) { return $msgData->user->reply("**Error:** you are trying to send your auth token in private. This won't work because i need Guild information. Post it in a channel on the server where you want to be authed"); } // Someone had a valid auth string, amazing if (!empty($authData)) { $groups = json_decode($authData["groups"], true); $roles = $msgData->guild->roles; $guild = $this->discord->guilds->first(); //$guild = $this->discord->guilds->get("id", $msgData->guild->id); $member = $guild->members->get("id", $msgData->user->author->id); $username = $msgData->user->author->username; $discordID = $msgData->user->author->id; $characterID = $authData["characterID"]; $corporationID = $authData["corporationID"]; $allianceID = $authData["allianceID"]; foreach ($roles as $role) { $roleName = $role->name; if (in_array($roleName, $groups)) { // Add user to group $member->addRole($role); $member->save(); } } // Add the user data to the local database so we can recheck it $this->sluggardDB->execute("REPLACE INTO authentications (discordID, characterID, corporationID, allianceID) VALUES (:discordID, :characterID, :corporationID, :allianceID)", array("discordID" => $discordID, ":characterID" => $characterID, ":corporationID" => $corporationID, ":allianceID" => $allianceID)); // Now set the auth to inactive, and we'll be golden $this->authData->execute("UPDATE registrations SET active = 0 WHERE authString = :authString", array(":authString" => $authString)); $this->log->info("Authenticating {$username} in {$channelName} on {$guildName}"); $msgData->user->reply("You have now been added to the following groups: " . implode(", ", $groups)); } else { $msgData->user->reply("**Error:** you are trying to use an already used auth code, or a non-existing auth code. Either way, prepare to get #rekt"); } } }
/** * When the bot's tick hits a specified time, this is started * * Runtime is defined in $this->information(), timerFrequency */ public function onTimer() { $continue = false; $data = array(); // Fetch the last 5 twitter replies and/or searches try { $data = $this->twitter->load(Twitter::ME_AND_FRIENDS, 5); foreach ($data as $message) { $text = (array) $message->text; $createdAt = (array) $message->created_at; $postedBy = (array) $message->user->name; $screenName = (array) $message->user->screen_name; $id = (int) $message->id; $this->lastID = $this->storage->get("twitterLatestID"); // get the last posted ID if ($id <= $this->lastID) { continue; } $this->maxID = max($id, $this->maxID); $url = "https://twitter.com/" . $screenName[0] . "/status/" . $id; $message = array("message" => $text[0], "postedAt" => $createdAt[0], "postedBy" => $postedBy[0], "screenName" => $screenName[0], "url" => $url . $id[0]); $msg = "**@" . $screenName[0] . "** (" . $message["postedBy"] . ") / " . htmlspecialchars_decode($message["message"]); $messages[$id] = $msg; $continue = true; if (sizeof($data)) { $this->storage->set("twitterLatestID", $this->maxID); } } } catch (Exception $e) { $this->log->err("Twitter Error: " . $e->getMessage()); // Don't show there was an error, it's most likely just a rate limit } if ($continue == true) { ksort($messages); $channel = \Discord\Parts\Channel\Channel::find($this->channelID); foreach ($messages as $id => $msg) { $channel->sendMessage($msg); sleep(1); // Lets sleep for a second, so we don't rage spam } } }
/** * @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 the bot's tick hits a specified time, this is started * * Runtime is defined in $this->information(), timerFrequency */ public function onTimer() { $this->log->info("Memory in use: " . memory_get_usage() / 1024 / 1024 . "MB"); gc_collect_cycles(); $this->log->info("Memory in use after garbage collection: " . memory_get_usage() / 1024 / 1024 . "MB"); }
/** * @param $keyID * @param $vCode * @param $characterID */ private function getNotifications($keyID, $vCode, $characterID) { try { // Seriously CCP.. *sigh* // Ignore notifications from these douchebags.. $ignoreNames = array("CCP"); $url = "https://api.eveonline.com/char/Notifications.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"]; // If there is no data, just quit.. if (empty($data)) { return; } $fixedData = array(); // Sometimes there is only ONE notification, so.. yeah.. if (count($data) > 1) { foreach ($data as $getFuckedCCP) { $fixedData[] = $getFuckedCCP["@attributes"]; } } else { $fixedData[] = $data["@attributes"]; } foreach ($fixedData as $notification) { $notificationID = $notification["notificationID"]; $typeID = $notification["typeID"]; //$senderID = $notification["senderID"]; $senderName = $notification["senderName"]; $sentDate = $notification["sentDate"]; //$read = $notification["read"]; // If the senderName is in the list of ignores names, then continue and ignore it.. if (in_array($senderName, $ignoreNames)) { continue; } if ($notificationID > $this->newestNotificationID) { $notificationString = explode("\n", $this->getNotificationText($keyID, $vCode, $characterID, $notificationID)); $msg = null; // Seriously, get f****d CCP switch ($typeID) { case 5: // War Declared $aggressorAllianceID = trim(explode(": ", $notificationString[2])[1]); $aggressorAllianceName = $this->apiData("alli", $aggressorAllianceID)["allianceName"]; $delayHours = trim(explode(": ", $notificationString[3])[1]); $msg = "War declared by {$aggressorAllianceName}. Fighting begins in roughly {$delayHours} hours."; break; case 8: // Alliance war invalidated by CONCORD $aggressorAllianceID = trim(explode(": ", $notificationString[2])[1]); $aggressorAllianceName = $this->apiData("alli", $aggressorAllianceID)["allianceName"]; $msg = "War declared by {$aggressorAllianceName} has been invalidated. Fighting ends in roughly 24 hours."; break; case 75: // POS / POS Module under attack $aggressorAllianceID = trim(explode(": ", $notificationString[0])[1]); $aggressorAllianceName = $this->apiData("alli", $aggressorAllianceID)["allianceName"]; $aggressorCorpID = trim(explode(": ", $notificationString[1])[1]); $aggressorCorpName = $this->apiData("corp", $aggressorCorpID)["corporationName"]; $aggressorID = trim(explode(": ", $notificationString[2])[1]); $aggressorCharacterName = $this->apiData("char", $aggressorID)["characterName"]; $armorValue = trim(explode(": ", $notificationString[3])[1]); $hullValue = trim(explode(": ", $notificationString[4])[1]); $moonID = trim(explode(": ", $notificationString[5])[1]); $moonName = $this - $this->ccpDB->queryField("SELECT itemName FROM mapAllCelestials WHERE itemID = :id", "itemName", array(":id" => $moonID)); $shieldValue = trim(explode(": ", $notificationString[6])[1]); $solarSystemID = trim(explode(": ", $notificationString[7])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $solarSystemID)); $msg = "POS under attack in **{$systemName} - {$moonName}** by {$aggressorCharacterName} ({$aggressorCorpName} / {$aggressorAllianceName}). Status: Hull: {$hullValue}, Armor: {$armorValue}, Shield: {$shieldValue}"; break; case 76: // Tower resource alert $moonID = trim(explode(": ", $notificationString[2])[1]); $moonName = $this->ccpDB->queryField("SELECT itemName FROM mapAllCelestials WHERE itemID = :id", "itemName", array(":id" => $moonID)); $solarSystemID = trim(explode(": ", $notificationString[3])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $solarSystemID)); $blocksRemaining = trim(explode(": ", $notificationString[6])[1]); $typeID = trim(explode(": ", $notificationString[7])[1]); $typeName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $typeID)); $msg = "POS in {$systemName} - {$moonName} needs fuel. Only {$blocksRemaining} {$typeName}'s remaining."; break; case 88: // IHUB is being attacked $aggressorAllianceID = trim(explode(": ", $notificationString[0])[1]); $aggressorAllianceName = $this->apiData("alli", $aggressorAllianceID)["allianceName"]; $aggressorCorpID = trim(explode(": ", $notificationString[0])[1]); $aggressorCorpName = $this->apiData("corp", $aggressorCorpID)["corporationName"]; $aggressorID = trim(explode(": ", $notificationString[1])[1]); $aggressorCharacterName = $this->apiData("char", $aggressorID)["characterName"]; $armorValue = trim(explode(": ", $notificationString[3])[1]); $hullValue = trim(explode(": ", $notificationString[4])[1]); $shieldValue = trim(explode(": ", $notificationString[5])[1]); $solarSystemID = trim(explode(": ", $notificationString[6])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $solarSystemID)); $msg = "IHUB under attack in **{$systemName}** by {$aggressorCharacterName} ({$aggressorCorpName} / {$aggressorAllianceName}). Status: Hull: {$hullValue}, Armor: {$armorValue}, Shield: {$shieldValue}"; break; case 93: // Customs office is being attacked $aggressorAllianceID = trim(explode(": ", $notificationString[0])[1]); $aggressorAllianceName = $this->apiData("alli", $aggressorAllianceID)["allianceName"]; $aggressorCorpID = trim(explode(": ", $notificationString[0])[1]); $aggressorCorpName = $this->apiData("corp", $aggressorCorpID)["corporationName"]; $aggressorID = trim(explode(": ", $notificationString[2])[1]); $aggressorCharacterName = $this->apiData("char", $aggressorID)["characterName"]; $planetID = trim(explode(": ", $notificationString[3])[1]); $planetName = $this->ccpDB->queryField("SELECT itemName FROM mapAllCelestials WHERE itemID = :id", "itemName", array(":id" => $planetID)); $shieldValue = trim(explode(": ", $notificationString[5])[1]); $solarSystemID = trim(explode(": ", $notificationString[6])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $solarSystemID)); $typeID = trim(explode(": ", $notificationString[7])[1]); $typeName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $typeID)); $msg = "Customs Office under attack in **{$systemName}** ({$planetName}) by {$aggressorCharacterName} ({$aggressorCorpName} / {$aggressorAllianceName}). Shield Status: {$shieldValue}"; break; case 147: // Entosis has stated $systemID = trim(explode(": ", $notificationString[0])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID)); $typeID = trim(explode(": ", $notificationString[1])[1]); $typeName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $typeID)); $msg = "Entosis has started in **{$systemName}** on **{$typeName}** (Date: **{$sentDate}**)"; break; case 148: // Entosis enabled a module ?????? $systemID = trim(explode(": ", $notificationString[0])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID)); $typeID = trim(explode(": ", $notificationString[1])[1]); $typeName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $typeID)); $msg = "Entosis has enabled a module in **{$systemName}** on **{$typeName}** (Date: **{$sentDate}**)"; break; case 149: // Entosis disabled a module $systemID = trim(explode(": ", $notificationString[0])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID)); $typeID = trim(explode(": ", $notificationString[1])[1]); $typeName = $this->ccpDB->queryField("SELECT typeName FROM invTypes WHERE typeID = :id", "typeName", array(":id" => $typeID)); $msg = "Entosis has disabled a module in **{$systemName}** on **{$typeName}** (Date: **{$sentDate}**)"; break; case 160: // Entosis successful $systemID = trim(explode(": ", $notificationString[2])[1]); $systemName = dbQueryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID), "ccp"); $msg = "Hostile entosis successful. A structure in **{$systemName}** has entered reinforced mode."; break; case 161: // Command Nodes Decloaking $systemID = trim(explode(": ", $notificationString[2])[1]); $systemName = $this->ccpDB->queryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID)); $msg = "Command nodes decloaking for **{$systemName}**"; break; case 163: // Freeport $systemID = trim(explode(": ", $notificationString[1])[1]); $systemName = dbQueryField("SELECT solarSystemName FROM mapSolarSystems WHERE solarSystemID = :id", "solarSystemName", array(":id" => $systemID), "ccp"); $msg = "Station in **{$systemName}** has entered freeport mode."; break; } if ($msg) { $channel = \Discord\Parts\Channel\Channel::find($this->toDiscordChannel); $channel->sendMessage($msg); } // Find the maxID so we don't output this message again in the future $this->maxID = max($notificationID, $this->maxID); $this->newestNotificationID = $this->maxID; $this->storage->set("newestNotificationID", $this->maxID); } } } catch (Exception $e) { $this->log->debug("Error: " . $e->getMessage()); } }
/** * */ 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; } } }