private static function populateCharacters($db) { global $baseDir; $timer = new Timer(); $maxTime = 65 * 1000; // Reset 222's that are over a week old $db->execute("update zz_api set errorCode = 0 where errorCode = 222 and lastValidation <= date_sub(now(), interval 7 day)"); $apiCount = $db->queryField("select count(*) count from zz_api where errorCode not in (203, 220, 222) and lastValidation <= date_add(now(), interval 1 minute)", "count", array(), 0); if ($apiCount == 0) { return; } $fetchesPerSecond = 25; $iterationCount = 0; while ($timer->stop() < $maxTime) { $keyIDs = $db->query("select distinct keyID from zz_api where errorCode not in (203, 220, 222) and lastValidation < date_sub(now(), interval 2 hour)\r\n\t\t\t\t\torder by lastValidation, dateAdded desc limit 100", array(), 0); foreach ($keyIDs as $row) { if (Util::isMaintenanceMode()) { return; } $keyID = $row["keyID"]; $m = $iterationCount % $fetchesPerSecond; $db->execute("update zz_api set lastValidation = date_add(lastValidation, interval 5 minute) where keyID = :keyID", array(":keyID" => $keyID)); $command = "flock -w 60 {$baseDir}/cache/locks/populate.{$m} php5 {$baseDir}/cli.php apiFetchCharacters " . escapeshellarg($keyID); //Log::log("$command"); exec("{$command} >/dev/null 2>/dev/null &"); $iterationCount++; if ($iterationCount % $fetchesPerSecond == 0) { sleep(1); } } sleep(1); } }
public function execute($parameters, $db) { if (Util::isMaintenanceMode()) { return; } Api::fetchApis(); }
private static function updateCharacters($db) { $minute = (int) date("i"); if ($minute == 0) { $db->execute("insert ignore into zz_characters (characterID) select ceoID from zz_corporations"); $db->execute("insert ignore into zz_characters (characterID) select characterID from zz_api_characters where characterID != 0"); } $result = $db->query("select characterID, name from zz_characters where lastUpdated < date_sub(now(), interval 7 day) and corporationID != 1000001 order by lastUpdated limit 600", array(), 0); foreach ($result as $row) { if (Util::isMaintenanceMode()) { return; } $id = $row["characterID"]; $db->execute("update zz_characters set lastUpdated = now() where characterID = :id", array(":id" => $id)); if ($id >= 2100000000 && $id < 2199999999) { continue; } // Dust Characters if ($id >= 30000000 && $id <= 31004590) { continue; } // NPC's if ($id >= 40000000 && $id <= 41004590) { continue; } // NPC's $pheal = Util::getPheal(); $pheal->scope = "eve"; try { $charInfo = $pheal->CharacterInfo(array("characterid" => $id)); $name = $charInfo->characterName; $corpID = $charInfo->corporationID; $alliID = $charInfo->allianceID; //CLI::out("|g|$name|n| $id $corpID $alliID"); if ($name != "") { $db->execute("update zz_characters set name = :name, corporationID = :corpID, allianceID = :alliID where characterID = :id", array(":id" => $id, ":name" => $name, ":corpID" => $corpID, ":alliID" => $alliID)); } } catch (Exception $ex) { // Is this name even a participant? $count = $db->queryField("select count(*) count from zz_participants where characterID = :id", "count", array(":id" => $id)); if ($count == 0) { $db->execute("delete from zz_characters where characterID = :id", array(":id" => $id)); } elseif ($ex->getCode() != 503) { Log::log("ERROR Validating Character {$id}" . $ex->getMessage()); } } usleep(100000); // Try not to spam the API servers (pauses 1/10th of a second) } }
public function execute($parameters, $db) { global $enableAnalyze; $actualKills = Storage::retrieve("ActualKillCount"); $iteration = 0; while ($actualKills > 0) { $iteration++; $actualKills -= 1000000; if ($actualKills > 0 && Storage::retrieve("{$iteration}mAnnounced", null) == null) { Storage::store("{$iteration}mAnnounced", true); $message = "|g|Woohoo!|r| {$iteration} million kills surpassed!"; Log::irc($message); Log::ircAdmin($message); } } $highKillID = $db->queryField("select max(killID) highKillID from zz_killmails", "highKillID"); if ($highKillID > 2000000) { Storage::store("notRecentKillID", $highKillID - 2000000); } self::apiPercentage($db); $db->execute("delete from zz_api_log where requestTime < date_sub(now(), interval 2 hour)"); //$db->execute("update zz_killmails set kill_json = '' where processed = 2 and killID < 0 and kill_json != ''"); $db->execute("delete from zz_errors where date < date_sub(now(), interval 1 day)"); $fileCache = new FileCache(); $fileCache->cleanup(); $tableQuery = $db->query("show tables"); $tables = array(); foreach ($tableQuery as $row) { foreach ($row as $column) { $tables[] = $column; } } if ($enableAnalyze) { $tableisgood = array("OK", "Table is already up to date", "The storage engine for the table doesn't support check"); $count = 0; foreach ($tables as $table) { $count++; if (Util::isMaintenanceMode()) { continue; } $result = $db->queryRow("analyze table {$table}"); if (!in_array($result["Msg_text"], $tableisgood)) { Log::ircAdmin("|r|Error analyzing table |g|{$table}|r|: " . $result["Msg_text"]); } } } }
public function execute($parameters, $db) { global $stompServer, $stompUser, $stompPassword; // Ensure the class exists if (!class_exists("Stomp")) { die("ERROR! Stomp not installed! Check the README to learn how to install Stomp...\n"); } $stomp = new Stomp($stompServer, $stompUser, $stompPassword); $stompKey = "StompSend::lastFetch"; $lastFetch = date("Y-m-d H:i:s", time() - 12 * 3600); $lastFetch = Storage::retrieve($stompKey, $lastFetch); $stompCount = 0; $timer = new Timer(); while ($timer->stop() < 60000) { if (Util::isMaintenanceMode()) { return; } $result = $db->query("SELECT killID, insertTime, kill_json FROM zz_killmails WHERE insertTime > :lastFetch AND processed > 0 ORDER BY killID limit 1000", array(":lastFetch" => $lastFetch), 0); foreach ($result as $kill) { $lastFetch = max($lastFetch, $kill["insertTime"]); if (!empty($kill["kill_json"])) { if ($kill["killID"] > 0) { $stompCount++; $destinations = self::getDestinations($kill["kill_json"]); foreach ($destinations as $destination) { $stomp->send($destination, $kill["kill_json"]); } } $data = json_decode($kill["kill_json"], true); $json = json_encode(array("solarSystemID" => $data["solarSystemID"], "killID" => $data["killID"], "characterID" => $data["victim"]["characterID"], "corporationID" => $data["victim"]["corporationID"], "allianceID" => $data["victim"]["allianceID"], "shipTypeID" => $data["victim"]["shipTypeID"], "killTime" => $data["killTime"])); $stomp->send("/topic/starmap.systems.active", $json); } } Storage::store($stompKey, $lastFetch); sleep(5); } if ($stompCount > 0) { Log::log("Stomped {$stompCount} killmails"); } }
public function execute($parameters, $db) { if (Util::isMaintenanceMode()) { return; } if (sizeof($parameters) == 0 || $parameters[0] == "") { CLI::out("Usage: |g|recentStatsAndRanks <type>|n| To see a list of commands, use: |g|methods recentStatsAndRanks", true); } $command = $parameters[0]; switch ($command) { case "all": self::stats($db); self::ranks($db); break; case "ranks": self::ranks($db); break; case "stats": self::stats($db); break; } }
public function execute($nick, $uhost, $channel, $command, $parameters, $nickAccessLevel) { if (Util::isMaintenanceMode()) { irc_error("|r|Cannot reprice while in maintenance mode"); } @($killID = (int) $parameters[0]); if ($killID == 0) { irc_error("|r|Please provide a valid killID."); } $count = Db::queryField("select count(*) count from zz_participants where killID = :killID", "count", array(":killID" => $killID)); if ($count == 0) { irc_error("|r|KillID {$killID} does not exist!"); } Stats::calcStats($killID, false); Db::execute("update zz_killmails set processed = 0 where killID = :killID", array(":killID" => $killID)); do { sleep(1); $processed = Db::queryField("select processed from zz_killmails where killID = :killID", "processed", array(":killID" => $killID), 0); } while ($processed == 0); $kill = Db::queryRow("select * from zz_participants where isVictim = 1 and killID = :killID", array(":killID" => $killID), 0); $total = $kill["total_price"]; $points = $kill["points"]; irc_out("|g|{$killID}|n| repriced to|g| " . number_format($total, 2) . "|n| ISK and |g|" . number_format($points, 0) . "|n| points"); }
private static function stats($db) { Log::irc("|g|Stats calculation started - checking for unknown groupID's"); // Fix unknown group ID's $result = $db->query("select distinct shipTypeID from zz_participants where groupID = 0 and shipTypeID != 0"); foreach ($result as $row) { $shipTypeID = $row["shipTypeID"]; $groupID = Info::getGroupID($shipTypeID); if ($groupID == 0) { continue; } Log::log("Updating {$shipTypeID} to group {$groupID}"); $db->execute("update zz_participants set groupID = {$groupID} where groupID = 0 and shipTypeID = {$shipTypeID}"); } $db->execute("set session wait_timeout = 6000"); if (!Util::isMaintenanceMode()) { $db->execute("replace into zz_storage values ('MaintenanceReason', 'Full stats calculation in progress')"); $db->execute("replace into zz_storage values ('maintenance', 'true')"); Log::log("Maintenance mode engaged"); Log::irc("|r|Engaging maintenance mode for full stat calculations..."); sleep(60); // Wait for processes to finish and cleanup } $db->execute("truncate zz_stats"); try { self::recalc('faction', 'factionID', true, $db); self::recalc('alli', 'allianceID', true, $db); self::recalc('corp', 'corporationID', true, $db); self::recalc('pilot', 'characterID', true, $db); self::recalc('group', 'groupID', true, $db); self::recalc('ship', 'shipTypeID', true, $db); self::recalc('system', 'solarSystemID', false, $db); self::recalc('region', 'regionID', false, $db); } catch (Exception $e) { print_r($e); } $db->execute("delete from zz_storage where locker = 'maintenance'"); Log::irc("|g|Stat recalculations have completed, leaving Maintenance mode and now reverting to business as usual..."); }
public function execute($parameters, $db) { if (Util::isMaintenanceMode()) { return; } @($apiRowID = $parameters[0]); $notRecentKillID = Storage::retrieve("notRecentKillID", 0); $apiRow = $db->queryRow("select * from zz_api_characters where apiRowID = :id", array(":id" => $apiRowID), 0); $maxKillID = $apiRow["maxKillID"]; $beforeKillID = 0; if (!$apiRow) { CLI::out("|r|No such apiRowID: {$apiRowID}", true); } $keyID = trim($apiRow["keyID"]); $vCode = $db->queryField("select vCode from zz_api where keyID = :keyID", "vCode", array(":keyID" => $keyID)); $isDirector = $apiRow["isDirector"]; $charID = $apiRow["characterID"]; if ($keyID == "" || $vCode == "") { die("no keyID or vCode"); } $pheal = null; try { do { $pheal = Util::getPheal($keyID, $vCode); $charCorp = $isDirector == "T" ? 'corp' : 'char'; $pheal->scope = $charCorp; $result = null; // Update last checked $db->execute("update zz_api_characters set errorCode = 0, lastChecked = now() where apiRowID = :id", array(":id" => $apiRowID)); $params = array(); if ($isDirector != "T") { $params['characterID'] = $charID; } if ($beforeKillID > 0) { $params['beforeKillID'] = $beforeKillID; } if ($isDirector == "T") { $result = $pheal->KillMails($params); } else { $result = $pheal->KillMails($params); } $cachedUntil = $result->cached_until; if ($cachedUntil == "" || !$cachedUntil) { $cachedUntil = date("Y-m-d H:i:s", time() + 3600); } $db->execute("UPDATE zz_api_characters SET cachedUntil = :cachedUntil, errorCount = 0, errorCode = 0 WHERE apiRowID = :id", array(":id" => $apiRowID, ":cachedUntil" => $cachedUntil)); $keyID = trim($keyID); $file = "/var/killboard/zkb_killlogs/{$keyID}_{$charID}_{$beforeKillID}.xml"; @unlink($file); $aff = Api::processRawApi($keyID, $charID, $result); if ($aff > 0) { $keyID = "{$keyID}"; while (strlen($keyID) < 8) { $keyID = " " . $keyID; } Log::log("KeyID: {$keyID} ({$charCorp}) added {$aff} kill" . ($aff == 1 ? "" : "s")); } $beforeKillID = 0; foreach ($result->kills as $kill) { $killID = $kill->killID; if ($beforeKillID == 0) { $beforeKillID = $killID; } else { $beforeKillID = min($beforeKillID, $killID); } } if ($beforeKillID < $notRecentKillID) { $db->execute("update zz_api_characters set cachedUntil = date_add(cachedUntil, interval 2 hour) where apiRowID = :id", array(":id" => $apiRowID)); } $hour = date("H"); if ($hour >= 12 && $hour <= 15) { @error_log($pheal->xml, 3, $file); } else { if ($aff > 0) { @error_log($pheal->xml, 3, $file); } } } while ($aff > 25 || $beforeKillID > 0 && $maxKillID == 0); } catch (Exception $ex) { $errorCode = $ex->getCode(); $db->execute("update zz_api_characters set cachedUntil = date_add(now(), interval 1 hour), errorCount = errorCount + 1, errorCode = :code where apiRowID = :id", array(":id" => $apiRowID, ":code" => $errorCode)); switch ($errorCode) { case 119: case 120: // Don't log it break; case 201: // Character does not belong to account. // Character does not belong to account. case 222: // API has expired // API has expired case 221: // Invalid access, delete the toon from the char list until later re-verification // Invalid access, delete the toon from the char list until later re-verification case 220: // Invalid Corporation Key. Key owner does not fullfill role requirements anymore. // Invalid Corporation Key. Key owner does not fullfill role requirements anymore. case 403: // New error code for invalid API $db->execute("delete from zz_api_characters where apiRowID = :id", array(":id" => $apiRowID)); break; case 1001: $db->execute("update zz_api_characters set cachedUntil = date_add(now(), interval 10 minute) where apiRowID = :id", array(":id" => $apiRowID)); break; default: Log::log($keyID . " " . $ex->getCode() . " " . $ex->getMessage()); } return; } }
public static function parseKills() { if (Util::isMaintenanceMode()) { return; } $timer = new Timer(); $maxTime = 65 * 1000; Db::execute("set session wait_timeout = 120000"); Db::execute("create temporary table if not exists zz_participants_temporary select * from zz_participants where 1 = 0"); $numKills = 0; while ($timer->stop() < $maxTime) { if (Util::isMaintenanceMode()) { self::removeTempTables(); return; } Db::execute("delete from zz_participants_temporary"); //Log::log("Fetching kills for processing..."); $result = Db::query("select * from zz_killmails where processed = 0 order by killID desc limit 100", array(), 0); if (sizeof($result) == 0) { $currentSecond = (int) date("s"); $sleepTime = max(1, 15 - $currentSecond % 15); sleep($sleepTime); continue; } //Log::log("Processing fetched kills..."); $processedKills = array(); $cleanupKills = array(); foreach ($result as $row) { $numKills++; $kill = json_decode($row['kill_json'], true); if (!isset($kill["killID"])) { Log::log("Problem with kill " . $row["killID"]); Db::execute("update zz_killmails set processed = 2 where killid = :killid", array(":killid" => $row["killID"])); continue; } $killID = $kill["killID"]; Db::execute("insert ignore into zz_killid values(:killID, 0)", array(":killID" => $killID)); // Cleanup if we're reparsing $cleanupKills[] = $killID; // Do some validation on the kill if (!self::validKill($kill)) { Db::execute("update zz_killmails set processed = 3 where killid = :killid", array(":killid" => $row["killID"])); continue; } $totalCost = 0; $itemInsertOrder = 0; $totalCost += self::processItems($kill, $killID, $kill["items"], $itemInsertOrder); $totalCost += self::processVictim($kill, $killID, $kill["victim"], false); foreach ($kill["attackers"] as $attacker) { self::processAttacker($kill, $killID, $attacker, $kill["victim"]["shipTypeID"], $totalCost); } $points = Points::calculatePoints($killID, true); Db::execute("update zz_participants_temporary set points = :points, number_involved = :numI, total_price = :tp where killID = :killID", array(":killID" => $killID, ":points" => $points, ":numI" => sizeof($kill["attackers"]), ":tp" => $totalCost)); $processedKills[] = $killID; } if (sizeof($cleanupKills)) { Db::execute("delete from zz_participants where killID in (" . implode(",", $cleanupKills) . ")"); } Db::execute("insert into zz_participants select * from zz_participants_temporary"); if (sizeof($processedKills)) { Db::execute("update zz_killmails set processed = 1 where killID in (" . implode(",", $processedKills) . ")"); } foreach ($processedKills as $killID) { Stats::calcStats($killID, true); // Add points and total value to the json stored in the database $raw = Db::queryField("select kill_json from zz_killmails where killID = :killID", "kill_json", array(":killID" => $killID), 0); $json = json_decode($raw, true); unset($json["_stringValue"]); unset($json["zkb"]); $stuff = Db::queryRow("select * from zz_participants where killID = :killID and isVictim = 1", array(":killID" => $killID), 0); if ($stuff != null) { $zkb = array(); $zkb["totalValue"] = $stuff["total_price"]; $zkb["points"] = $stuff["points"]; $json["zkb"] = $zkb; } $raw = json_encode($json); Db::execute("update zz_killmails set kill_json = :raw where killID = :killID", array(":killID" => $killID, ":raw" => $raw)); } } if ($numKills > 0) { Log::log("Processed {$numKills} kills"); } self::removeTempTables(); }
public function execute($parameters, $db) { if (Util::isMaintenanceMode()) { return; } $totalCount = 0; $data = ""; // Build the feeds from Admin's tracker list $adminID = Db::queryField("select id from zz_users where username = '******'", "id", array()); $trackers = Db::query("select locker, content from zz_users_config where locker like 'tracker_%' and id = :id", array(":id" => $adminID), 0); $feeds = array(); foreach ($trackers as $row) { $entityType = str_replace("tracker_", "", $row["locker"]); $entities = json_decode($row["content"], true); foreach ($entities as $entity) { $id = (int) $entity["id"]; $feed = array(); $feed["id"] = $id; $feed["entityType"] = $entityType; $locker = "feed.{$entityType}.{$id}.lastFetchTime"; $dontFetchThis = $db->queryField("select count(*) count from zz_users_config where locker = :locker and id = :adminID and content >= date_sub(now(), interval 1 hour)", "count", array(":locker" => $locker, ":adminID" => $adminID), 0); if ($dontFetchThis) { continue; } $locker = "feed.{$entityType}.{$id}.lastKillTime"; $lastKillTime = $db->queryField("select content from zz_users_config where locker = :locker and id = :adminID", "content", array(":locker" => $locker, ":adminID" => $adminID), 0); if ($lastKillTime == "") { $lastKillTime = null; } $feed["lastKillTime"] = $lastKillTime; $feed["url"] = "https://zkillboard.com/api/{$entityType}ID/{$id}/"; $feeds[] = $feed; } } if (sizeof($feeds) == 0) { return; } // Nothing to fetch... foreach ($feeds as $feed) { $id = $feed["id"]; $baseurl = $feed["url"]; $entityType = $feed["entityType"]; CLI::out("Fetching for |g|{$baseurl}|n|"); $lastKillTime = $feed["lastKillTime"]; do { $insertCount = 0; $url = "{$baseurl}orderDirection/asc/"; if ($lastKillTime != null && $lastKillTime != 0) { $url .= "startTime/" . preg_replace('/[^0-9]/', '', $lastKillTime) . "/"; } CLI::out($url); $fetchedData = self::fetchUrl($url); if ($fetchedData == "") { CLI::out("|r|Remote server returned an invalid response, moving along after 15 seconds...|n|"); sleep(15); continue; } $data = json_decode($fetchedData); $insertCount = 0; foreach ($data as $kill) { if (isset($kill->_stringValue)) { unset($kill->_stringValue); } if ($kill == "") { continue; } $hash = Util::getKillHash(null, $kill); $json = json_encode($kill); $killID = $kill->killID; $source = "zKB Feed Fetch"; $lastKillTime = $kill->killTime; //echo "$killID $lastKillTime\n"; $insertCount += $db->execute("INSERT IGNORE INTO zz_killmails (killID, hash, source, kill_json) VALUES (:killID, :hash, :source, :kill_json)", array(":killID" => $killID, ":hash" => $hash, ":source" => $source, ":kill_json" => $json)); } $locker = "feed.{$entityType}.{$id}.lastKillTime"; $db->execute("replace into zz_users_config values (:adminID, :locker, :content)", array(":adminID" => $adminID, ":locker" => $locker, ":content" => $lastKillTime)); $locker = "feed.{$entityType}.{$id}.lastFetchTime"; $db->execute("replace into zz_users_config values (:adminID, :locker, now())", array(":adminID" => $adminID, ":locker" => $locker)); $totalCount += $insertCount; CLI::out("Inserted |g|{$insertCount}|n|/|g|" . sizeof($data) . "|n| kills..."); Log::log("Inserted {$insertCount} new kills from {$url}"); } while ($insertCount > 0 || sizeof($data) >= 50); } if ($totalCount > 0) { CLI::out("Inserted a total of |g|" . number_format($totalCount, 0) . "|n| kills."); } }
<?php require_once '../init.php'; global $mdb; $lastWalletFetch = Storage::retrieve('NextWalletFetch'); $time = strtotime($lastWalletFetch); if ($time >= time()) { exit; } if (Util::isMaintenanceMode()) { return; } if (Util::is904Error()) { return; } global $walletApis; if (!is_array($walletApis)) { return; } foreach ($walletApis as $api) { $type = $api['type']; $keyID = $api['keyID']; $vCode = $api['vCode']; $charID = $api['charID']; $pheal = Util::getPheal($keyID, $vCode, true); $arr = array('characterID' => $charID, 'rowCount' => 1000); if ($type == 'char') { $q = $pheal->charScope->WalletJournal($arr); } elseif ($type == 'corp') { $q = $pheal->corpScope->WalletJournal($arr); } else {
public static function fetchApis() { global $baseDir; Db::execute("delete from zz_api_characters where isDirector = ''"); // Minor cleanup $fetchesPerSecond = (int) Storage::retrieve("APIFetchesPerSecond", 30); $timer = new Timer(); $maxTime = 60 * 1000; while ($timer->stop() < $maxTime) { if (Util::isMaintenanceMode()) { return; } $allChars = Db::query("select apiRowID, cachedUntil from zz_api_characters where errorCount < 10 and cachedUntil < date_sub(now(), interval 10 second) order by cachedUntil, keyID, characterID limit {$fetchesPerSecond}", array(), 0); $total = sizeof($allChars); $iterationCount = 0; if ($total == 0) { sleep(1); } else { foreach ($allChars as $char) { if (Util::isMaintenanceMode()) { return; } if ($timer->stop() > $maxTime) { return; } $apiRowID = $char["apiRowID"]; Db::execute("update zz_api_characters set cachedUntil = date_add(if(cachedUntil=0, now(), cachedUntil), interval 5 minute), lastChecked = now() where apiRowID = :id", array(":id" => $apiRowID)); $m = $iterationCount % $fetchesPerSecond; $command = "flock -w 60 {$baseDir}/cache/locks/preFetch.{$m} php5 {$baseDir}/cli.php apiFetchKillLog {$apiRowID}"; $command = escapeshellcmd($command); exec("{$command} >/dev/null 2>/dev/null &"); $iterationCount++; if ($m == 0) { sleep(1); } } } } }