diff --git a/.gitignore b/.gitignore index 87fc47f..3e47f89 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea/ -/vendor/ -logs/* +vendor/* +var/* \ No newline at end of file diff --git a/Settings.php b/Settings.php index 5e3f5a0..527dcce 100644 --- a/Settings.php +++ b/Settings.php @@ -1,14 +1,13 @@ getMessage()); + if (Settings::$ENV === 'PROD' && Settings::$SEND_MAIL) { + AlertHandler::sendAlertMail($exception->getMessage(), $exception->getFile(), $exception->getLine()); + } elseif (Settings::$ENV === 'DEV') { + throw $exception; + } + } +); + +function runBot() +{ + $killbot = new Killbot(); + $killbot->run(); +} + +runBot(); \ No newline at end of file diff --git a/bin/mailcheck.php b/bin/mailcheck.php new file mode 100644 index 0000000..c33320b --- /dev/null +++ b/bin/mailcheck.php @@ -0,0 +1,8 @@ +=7.0.0" + "php": ">=7.0.0", + "symfony/polyfill-iconv": "^1.0", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { "mockery/mockery": "~0.9.1", - "symfony/phpunit-bridge": "~3.3@dev" + "symfony/phpunit-bridge": "^3.4.19|^4.1.8" + }, + "suggest": { + "ext-intl": "Needed to support internationalized email addresses", + "true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.0-dev" + "dev-master": "6.2-dev" } }, "autoload": { @@ -164,26 +298,205 @@ } ], "description": "Swiftmailer, free feature-rich PHP mailer", - "homepage": "http://swiftmailer.symfony.com", + "homepage": "https://swiftmailer.symfony.com", "keywords": [ "email", "mail", "mailer" ], - "time": "2017-09-30T22:39:41+00:00" + "time": "2019-04-21T09:21:45+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "82ebae02209c21113908c229e9883c419720738a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", + "reference": "82ebae02209c21113908c229e9883c419720738a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "f037ea22acfaee983e271dd9c3b8bb4150bd8ad7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f037ea22acfaee983e271dd9c3b8bb4150bd8ad7", + "reference": "f037ea22acfaee983e271dd9c3b8bb4150bd8ad7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c766e95bec706cdd89903b1eda8afab7d7a6b7af", + "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.9" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "time": "2019-03-04T13:44:35+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.6.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296" + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", + "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", "shasum": "" }, "require": { @@ -195,7 +508,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.11-dev" } }, "autoload": { @@ -229,35 +542,91 @@ "portable", "shim" ], - "time": "2017-10-11T12:05:26+00:00" + "time": "2019-02-06T07:57:58+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-02-06T07:57:58+00:00" }, { "name": "twig/twig", - "version": "v2.4.4", + "version": "v2.9.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "eddb97148ad779f27e670e1e3f19fb323aedafeb" + "reference": "82a1c055c8ed4c4705023bfd0405f3c74db6e3ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/eddb97148ad779f27e670e1e3f19fb323aedafeb", - "reference": "eddb97148ad779f27e670e1e3f19fb323aedafeb", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/82a1c055c8ed4c4705023bfd0405f3c74db6e3ae", + "reference": "82a1c055c8ed4c4705023bfd0405f3c74db6e3ae", "shasum": "" }, "require": { "php": "^7.0", - "symfony/polyfill-mbstring": "~1.0" + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "psr/container": "^1.0", - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.3@dev" + "symfony/debug": "^2.7", + "symfony/phpunit-bridge": "^3.4.19|^4.1.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.4-dev" + "dev-master": "2.9-dev" } }, "autoload": { @@ -286,16 +655,16 @@ }, { "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", + "homepage": "https://twig.symfony.com/contributors", "role": "Contributors" } ], "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", + "homepage": "https://twig.symfony.com", "keywords": [ "templating" ], - "time": "2017-09-27T18:10:31+00:00" + "time": "2019-04-28T06:57:38+00:00" } ], "packages-dev": [], @@ -305,7 +674,9 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.0" + "php": "^7.0", + "ext-json": "*", + "ext-curl": "*" }, "platform-dev": [] } diff --git a/cron.php b/cron.php deleted file mode 100644 index fc1f014..0000000 --- a/cron.php +++ /dev/null @@ -1,35 +0,0 @@ -run(); -} - -if (!Settings::$DEBUG) { - - try { - - runBot(); - } catch (Exception $e) { - - if (Settings::$SEND_MAIL) { - AlertHandler::sendAlertMail($e); - } - } -} else { - runBot(); -} diff --git a/mailcheck.php b/mailcheck.php deleted file mode 100644 index 154bf95..0000000 --- a/mailcheck.php +++ /dev/null @@ -1,8 +0,0 @@ -setFrom(Settings::$MAIL_SENDER) ->setTo(Settings::$MAIL_RECIPIENT) - ->setBody(self::generateBody($e)); + ->setBody(self::generateBody($errorMessage, $file, $line)); if ($mailer->send($message)) { - echo 'Alert mail sent' . PHP_EOL; + Logger::log('Alert mail sent'); } else { - echo 'Failed to send alert mail' . PHP_EOL; + Logger::log('Failed to send alert mail'); } } /** - * @param Exception $e + * @param $message + * @param $file + * @param $line * @return string - * @throws \Twig_Error_Loader - * @throws \Twig_Error_Runtime - * @throws \Twig_Error_Syntax + * @throws Twig_Error_Loader + * @throws Twig_Error_Runtime + * @throws Twig_Error_Syntax */ - protected static function generateBody(Exception $e) + protected static function generateBody($message, $file, $line) { - $loader = new \Twig_Loader_Filesystem('.'); + $loader = new Twig_Loader_Filesystem('.'); $twig = new Twig_Environment($loader); $body = $twig->render( 'mail.html.twig', array( - 'message' => $e->getMessage(), - 'path' => $e->getFile(), - 'line' => $e->getLine(), + 'message' => $message, + 'path' => $file, + 'line' => $line, ) ); diff --git a/src/CurlWrapper.php b/src/CurlWrapper.php new file mode 100644 index 0000000..243a692 --- /dev/null +++ b/src/CurlWrapper.php @@ -0,0 +1,84 @@ += 400) { + throw new Exception('HTTP error : ' . $http_code . ' on ' . curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); + + } + } +} \ No newline at end of file diff --git a/src/ESIClient.php b/src/ESIClient.php new file mode 100644 index 0000000..d0be5e1 --- /dev/null +++ b/src/ESIClient.php @@ -0,0 +1,127 @@ + [], + 'ships' => [], + 'characters' => [], + ]; + + /** + * Retrieves ship name from ESI + * + * @param $shipId + * + * @return string + * @throws Exception + */ + public function getShipName($shipId) + { + + return $this->getEntityName( + $shipId, + 'ships', + Settings::$ESI_URL."v3/universe/types/$shipId/" + ); + } + + /** + * Retrieves character name from ESI + * + * @param $characterId + * + * @return string + * @throws Exception + */ + public function getCharacterName($characterId) + { + + return $this->getEntityName( + $characterId, + 'characters', + Settings::$ESI_URL."v4/characters/$characterId/" + ); + } + + /** + * Retrieves corporation name from ESI + * + * @param $corporationId + * + * @return string + * @throws Exception + */ + public function getCorporationName($corporationId) + { + + return $this->getEntityName( + $corporationId, + 'corporations', + Settings::$ESI_URL."v4/corporations/$corporationId/" + ); + } + + /** + * Requests the name property of a given entity, using the provided endpoint + * @param $id + * @param $type + * @param $endpoint + * @return mixed|string + * @throws Exception + */ + protected function getEntityName($id, $type, $endpoint) + { + + if (in_array($id, $this->knownEntities[$type])) { + return $this->knownEntities[$type][$id]; + } + + $name = $this->requestEntityProperty( + $endpoint, + 'name' + ); + + $this->knownEntities[$type][$id] = $name; + + return $name; + } + + /** + * Retrieves an entity property from the given endpoint response + * @param $endpoint + * @param $property + * @return string + * @throws Exception + */ + protected function requestEntityProperty($endpoint, $property) + { + $json = CurlWrapper::curlRequest($endpoint); + $data = json_decode($json, true); + + if (isset($data['error'])) { + $error = 'ESI error : '.$data['error'].' on '.$endpoint; + throw new Exception($error); + } else { + if (!isset($data[$property])) { + $error = 'ESI error : non-existent property '.$property.' on '.$endpoint; + throw new Exception($error); + } else { + $value = $data[$property]; + } + } + + return $value; + } + +} \ No newline at end of file diff --git a/Killbot.php b/src/Killbot.php similarity index 57% rename from Killbot.php rename to src/Killbot.php index 4a09b71..2fdc84f 100644 --- a/Killbot.php +++ b/src/Killbot.php @@ -2,64 +2,111 @@ namespace Killbot; +use Exception; +use Ramsey\Uuid\Uuid; +use Settings; use stdClass; class Killbot { - - protected $knownShips = array(); - protected $knownCharacters = array(); - protected $knownCorporations = array(); + /** + * @var ESIClient + */ + protected $esiClient; /** * Runs the bot + * @throws Exception */ public function run() { - $isFeedEmpty = false; $timeout = time() + Settings::$MAX_RUN_TIME; + // Processing queue while (!$isFeedEmpty && time() < $timeout) { $isFeedEmpty = !$this->processKill(); } + + // Processing previously failed kills + $files = $this->getPendingFiles(); + foreach ($files as $file) { + + Logger::log('Retrying pending kill '.$file, 'INFO'); + + $filepath = Utils::getUnprocessedPath().DIRECTORY_SEPARATOR.$file; + $this->processKill( + json_decode(file_get_contents($filepath)) + ); + + unlink($filepath); + } } /** * Fetch and process one kill from RedisQ * Return false if the queue is empty, true otherwise + * + * If provided, uses $data as datasource + * + * @param string $data + * @return bool + * @throws Exception */ - private function processKill() + private function processKill($data = null) { - $rawOutput = $this->curlRequest(Settings::$REDISQ_URL); + if ($data === null) { + $this->esiClient = new ESIClient(); + $rawOutput = CurlWrapper::curlRequest(Settings::$REDISQ_URL); - $data = json_decode($rawOutput); + $data = json_decode($rawOutput); + } if (!isset($data->{'package'}) || $data->{'package'} == null) { return false; } - foreach (Settings::$watchingConfigurations as $watchingConfiguration) { + try { + + foreach (Settings::$watchingConfigurations as $watchingConfiguration) { + + $slackHook = $watchingConfiguration['SLACK_HOOK']; + $watchedEntities = $watchingConfiguration['WATCHED_ENTITIES']; - $slackHook = $watchingConfiguration['SLACK_HOOK']; - $watchedEntities = $watchingConfiguration['WATCHED_ENTITIES']; + // Only process kill that match settings entities + if ($this->isWatchedKill($data, $watchedEntities)) { - // Only process kill that match settings entities - if ($this->isWatchedKill($data, $watchedEntities)) { + if (Settings::$DEBUG) { + Logger::storeKillJson($data->{'package'}->{'killID'}, $rawOutput); + } - if (Settings::$DEBUG) { - $this->storeKillJson($data->{'package'}->{'killID'}, $rawOutput); + $jsonAttachments = $this->formatKillData($data, $watchedEntities); + + $this->pushToSlack($jsonAttachments, $slackHook); } + } + + return true; + } catch (Exception $exception) { + + if (!isset($rawOutput)) { + $rawOutput = json_encode($data); + } - $jsonAttachments = $this->formatKillData($data, $watchedEntities); + if ($rawOutput != '') { - $this->pushToSlack($jsonAttachments, $slackHook); + Utils::writeFile( + $rawOutput, + Utils::getUnprocessedPath(), + Uuid::uuid4() . '.kill', + 'w' + ); } - } - return true; + throw $exception; + } } /** @@ -155,97 +202,6 @@ private function isSystemWatched($killmail, $watchedEntities) return false; } - /** - * Retrieves ship name from ESI - * - * @param $victimShipId - * - * @return string - */ - private function getShipName($victimShipId) - { - - if (in_array($victimShipId, $this->knownShips)) { - return $this->knownShips[$victimShipId]; - } - - $json = $this->curlRequest(Settings::$ESI_URL . "v3/universe/types/$victimShipId/"); - $data = json_decode($json); - - $shipName = $data->{'name'}; - $this->knownShips[$victimShipId] = $shipName; - - return $shipName; - } - - /** - * Retrieves character name from ESI - * - * @param $characterId - * - * @return string - */ - private function getCharacterName($characterId) - { - - if (in_array($characterId, $this->knownCharacters)) { - return $this->knownCharacters[$characterId]; - } - - $json = $this->curlRequest(Settings::$ESI_URL . "v4/characters/$characterId/"); - $data = json_decode($json); - - $characterName = $data->{'name'}; - $this->knownCharacters[$characterId] = $characterName; - - return $characterName; - } - - /** - * Retrieves corporation name from ESI - * - * @param $corporationId - * - * @return string - */ - private function getCorporationName($corporationId) - { - - if (in_array($corporationId, $this->knownCorporations)) { - return $this->knownCorporations[$corporationId]; - } - - $json = $this->curlRequest(Settings::$ESI_URL . "v4/corporations/$corporationId/"); - $data = json_decode($json); - - $corporationName = $data->{'name'}; - $this->knownCorporations[$corporationId] = $corporationName; - - return $corporationName; - } - - /** - * @param $url - * - * @return bool|string - */ - private function curlRequest($url) - { - - $ch = curl_init(); - - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($ch, CURLOPT_USERAGENT, Settings::$HTTP_HEADER); - - $output = curl_exec($ch); - curl_close($ch); - - return $output; - } - /** * Push the formatted kill to slack * @@ -261,37 +217,7 @@ private function pushToSlack($killData, $slackHook) $data = "payload=" . json_encode($killData); - $ch = curl_init($slackHook); - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - - curl_exec($ch); - curl_close($ch); - } - - /** - * Stores the kill in a file as json - * - * @param $killId - * @param $data - */ - private function storeKillJson($killId, $data) - { - - $directoryName = __DIR__ . DIRECTORY_SEPARATOR . Settings::$KILL_LOG_FOLDER; - - if (!file_exists($directoryName)) { - mkdir($directoryName, 0755, true); - } - - $fileName = $directoryName . DIRECTORY_SEPARATOR . $killId . '.json'; - - $file = fopen($fileName, 'a+'); - fwrite($file, $data); - fclose($file); + CurlWrapper::post($slackHook, $data); } /** @@ -301,6 +227,7 @@ private function storeKillJson($killId, $data) * @param $watchedEntities * * @return stdClass + * @throws Exception */ protected function formatKillData($data, $watchedEntities): stdClass { @@ -322,24 +249,30 @@ protected function formatKillData($data, $watchedEntities): stdClass } } + $killerName = 'Unknown entity'; + // Handling NPC kills - if (!isset($killer->{'character_id'})) { - $killerName = $this->getShipName($killer->{'ship_type_id'}); - } else { - $killerName = $this->getCharacterName($killer->{'character_id'}); + if ($killer) { + if (isset($killer->{'character_id'})) { + $killerName = $this->esiClient->getCharacterName($killer->{'character_id'}); + } else { + if (isset($killer->{'ship_type_id'})) { + $killerName = $this->esiClient->getShipName($killer->{'ship_type_id'}); + } + } } // Handling case with no pilots victims $victim = $killmail->{'victim'}; if (!isset($victim->{'character_id'})) { $noVictim = true; - $victimName = $this->getCorporationName($victim->{'corporation_id'}); + $victimName = $this->esiClient->getCorporationName($victim->{'corporation_id'}); } else { - $victimName = $this->getCharacterName($victim->{'character_id'}); + $victimName = $this->esiClient->getCharacterName($victim->{'character_id'}); } $victimShipId = $victim->{'ship_type_id'}; - $victimShipName = $this->getShipName($victimShipId); + $victimShipName = $this->esiClient->getShipName($victimShipId); $isVictimCorpWatched = in_array($victim->{'corporation_id'}, $watchedEntities['corporations']); $isVictimAllianceWatched = @@ -351,12 +284,12 @@ protected function formatKillData($data, $watchedEntities): stdClass $jsonKill->fallback = "$victimName's $victimShipName got killed by $killerName"; if (isset($killer->{'corporation_id'})) { - $jsonKill->fallback .= ' (' . $this->getCorporationName($killer->{'corporation_id'}) . ')'; + $jsonKill->fallback .= ' ('.$this->esiClient->getCorporationName($killer->{'corporation_id'}).')'; } $jsonKill->color = 'danger'; } else { - $victimCorpName = $this->getCorporationName($victim->{'corporation_id'}); + $victimCorpName = $this->esiClient->getCorporationName($victim->{'corporation_id'}); if ($noVictim) { $jsonKill->fallback = "$killerName killed $victimName's $victimShipName"; @@ -367,14 +300,13 @@ protected function formatKillData($data, $watchedEntities): stdClass $jsonKill->color = 'good'; } - /* * Formatting data for slack */ $jsonKill->title = $jsonKill->fallback; $jsonKill->title_link = "https://zkillboard.com/kill/$killId/"; - $jsonKill->thumb_url = "https://imageserver.eveonline.com/Render/" . $victimShipId . "_64.png"; + $jsonKill->thumb_url = "https://imageserver.eveonline.com/Type/" . $victimShipId . "_64.png"; $killValue = number_format($zkb->{'totalValue'}, 2, ',', ' '); @@ -394,4 +326,15 @@ protected function formatKillData($data, $watchedEntities): stdClass return $jsonAttachments; } + /** + * @return array + */ + protected function getPendingFiles(): array + { + $unprocessedPath = Utils::getUnprocessedPath(); + Utils::createPath($unprocessedPath); + $files = array_diff(scandir($unprocessedPath), array('..', '.')); + + return $files; + } } diff --git a/src/Logger.php b/src/Logger.php new file mode 100644 index 0000000..c5a8c75 --- /dev/null +++ b/src/Logger.php @@ -0,0 +1,37 @@ +