You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
7.7 KiB
306 lines
7.7 KiB
<?php
|
|
|
|
require_once __DIR__."/../util/mysql_connect.php";
|
|
require_once __DIR__."/RiotRequest.php";
|
|
|
|
class Tracker {
|
|
private MySQLConnection $conn;
|
|
|
|
/**
|
|
* @var Account[]
|
|
*/
|
|
public array $accounts;
|
|
|
|
/**
|
|
* @var Elo[][]
|
|
*/
|
|
public array $entries;
|
|
|
|
/**
|
|
* @var Elo[][]
|
|
*/
|
|
public array $entriesByDateString;
|
|
|
|
public function __construct() {
|
|
$this->conn = new MySQLConnection();
|
|
$this->readAccounts();
|
|
$this->readEntries();
|
|
}
|
|
|
|
private function readAccounts(): void {
|
|
$accounts = [];
|
|
|
|
$sql = $this->conn->query("SELECT * FROM `accounts`");
|
|
while ($row = $sql->fetch_assoc()) {
|
|
$account = new Account();
|
|
$account->puuid = $row["puuid"];
|
|
$account->gameName = $row["gameName"];
|
|
$account->tagLine = $row["tagLine"];
|
|
$account->profileIconId = $row["profileIconId"];
|
|
|
|
$accounts[$account->puuid] = $account;
|
|
}
|
|
|
|
$this->accounts = $accounts;
|
|
}
|
|
private function readEntries(): void {
|
|
$sql = $this->conn->query("
|
|
SELECT accounts.puuid AS puuid, date, tier, `rank`, points
|
|
FROM accounts LEFT JOIN elo_entries ON id = accountId
|
|
ORDER BY accounts.puuid, date
|
|
");
|
|
|
|
$this->entries = [];
|
|
$this->entriesByDateString = [];
|
|
|
|
while ($row = $sql->fetch_assoc()) {
|
|
$puuid = $row["puuid"];
|
|
|
|
if (!isset($this->entries[$puuid]))
|
|
$this->entries[$puuid] = [];
|
|
|
|
if (!isset($this->entriesByDateString[$puuid]))
|
|
$this->entriesByDateString[$puuid] = [];
|
|
|
|
if ($dateString = $row["date"]){
|
|
$elo = new Elo();
|
|
$elo->tier = $row["tier"];
|
|
$elo->rank = $row["rank"];
|
|
$elo->points = $row["points"];
|
|
|
|
$datetime = new DateTime($dateString);
|
|
$this->entries[$puuid][$datetime->getTimestamp()] = $elo;
|
|
$this->entriesByDateString[$puuid][$dateString] = $elo;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return int[]
|
|
*/
|
|
public function getProgressions(): array {
|
|
$progressions = [];
|
|
|
|
foreach ($this->entries as $puuid => $eloEntries) {
|
|
if (sizeof($eloEntries) > 0){
|
|
$start = reset($eloEntries);
|
|
$end = end($eloEntries);
|
|
$progress = $end->value() - $start->value();
|
|
} else {
|
|
$progress = 0;
|
|
}
|
|
$progressions[$puuid] = $progress;
|
|
}
|
|
|
|
arsort($progressions);
|
|
|
|
return $progressions;
|
|
}
|
|
|
|
public function update(callable $progressCallback): void {
|
|
|
|
$counter = 0;
|
|
foreach ($this->accounts as $puuid => $account) {
|
|
$account->update($this->entries[$puuid]);
|
|
$counter++;
|
|
$progressCallback($counter / sizeof($this->accounts));
|
|
}
|
|
|
|
}
|
|
|
|
public function add($gameName, $tagLine, &$message): bool {
|
|
$request = new RiotRequest("riot/account/v1/accounts/by-riot-id/$gameName/$tagLine");
|
|
$request->useRouting();
|
|
$result = $request->run();
|
|
|
|
if ($request->responseCode === 200){
|
|
if (!key_exists($result->puuid, $this->accounts)){
|
|
$account = new Account();
|
|
$account->puuid = $result->puuid;
|
|
$account->gameName = $result->gameName;
|
|
$account->tagLine = $result->tagLine;
|
|
$this->accounts[$account->puuid] = $account;
|
|
$this->entries[$account->puuid] = [];
|
|
|
|
$this->conn->prepare("
|
|
INSERT INTO `accounts`
|
|
(`puuid`, `gameName`, `tagLine`)
|
|
VALUES (?, ?, ?)
|
|
")->execute([$account->puuid, $account->gameName, $account->tagLine]);
|
|
|
|
$message = "Success.";
|
|
|
|
$account->update($this->entries[$account->puuid]);
|
|
|
|
return true;
|
|
} else {
|
|
$message = "Riot ID already added.";
|
|
}
|
|
} else {
|
|
$message = "Riot ID not found.";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
public function remove($gameName, $tagLine, &$message): bool {
|
|
$request = new RiotRequest("riot/account/v1/accounts/by-riot-id/$gameName/$tagLine");
|
|
$request->useRouting();
|
|
$result = $request->run();
|
|
|
|
if ($request->responseCode === 200){
|
|
if (key_exists($result->puuid, $this->accounts)){
|
|
unset($this->accounts[$result->puuid]);
|
|
unset($this->entries[$result->puuid]);
|
|
|
|
$this->conn->query("
|
|
DELETE FROM `accounts`
|
|
WHERE puuid = '$result->puuid';
|
|
");
|
|
|
|
$message = "Success.";
|
|
return true;
|
|
} else {
|
|
$message = "Riot ID was not added.";
|
|
}
|
|
} else {
|
|
$message = "Riot ID not found.";
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
class Account {
|
|
public string $puuid;
|
|
public string $gameName;
|
|
public string $tagLine;
|
|
public int $profileIconId = 0;
|
|
|
|
/**
|
|
* @param Elo[] $eloEntries
|
|
*/
|
|
public function update(array &$eloEntries): void {
|
|
$summoner = (new RiotRequest("lol/summoner/v4/summoners/by-puuid/$this->puuid"))->run($isEUNE);
|
|
$this->profileIconId = $summoner->profileIconId;
|
|
|
|
$this->updateRiotIDAndProfileIcon();
|
|
$this->tryAddNewEloEntry($eloEntries, $summoner->id, $isEUNE);
|
|
}
|
|
|
|
/**
|
|
* @param Elo[] $eloEntries
|
|
*/
|
|
private function tryAddNewEloEntry(array &$eloEntries, string $summonerId, bool $isEUNE): void {
|
|
$fetchedLeagues = (new RiotRequest("lol/league/v4/entries/by-summoner/$summonerId", $isEUNE))->run();
|
|
|
|
$currentElo = end($eloEntries);
|
|
|
|
foreach ($fetchedLeagues as $fetchedElo) {
|
|
if ($fetchedElo->queueType === "RANKED_SOLO_5x5" && ($fetchedElo->wins + $fetchedElo->losses >= 5)) {
|
|
if (!$currentElo ||
|
|
$currentElo->tier !== $fetchedElo->tier ||
|
|
$currentElo->rank !== $fetchedElo->rank ||
|
|
$currentElo->points !== $fetchedElo->leaguePoints){
|
|
|
|
$currentElo = new Elo();
|
|
$currentElo->tier = $fetchedElo->tier;
|
|
$currentElo->rank = $fetchedElo->rank;
|
|
$currentElo->points = $fetchedElo->leaguePoints;
|
|
|
|
$latestMatchTimestamp = $this->getLatestMatchTimestamp();
|
|
|
|
$conn = new MySQLConnection();
|
|
$isMatchUnknown = $conn->query("
|
|
SELECT COUNT(date) = 0 AS match_unknown
|
|
FROM updates
|
|
WHERE date > FROM_UNIXTIME($latestMatchTimestamp) AND status = 'COMPLETE';
|
|
")->fetch_assoc()["match_unknown"];
|
|
|
|
$date = new DateTime();
|
|
if ($isMatchUnknown)
|
|
$date->setTimestamp($latestMatchTimestamp);
|
|
|
|
$eloEntries[$date->getTimestamp()] = $currentElo;
|
|
|
|
$sqlAccountId = $conn->query("
|
|
SELECT id
|
|
FROM `accounts`
|
|
WHERE puuid = '$this->puuid'
|
|
")->fetch_assoc()["id"];
|
|
|
|
$conn->prepare("
|
|
INSERT INTO `elo_entries`
|
|
(accountId, date, tier, `rank`, points)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
")->execute([
|
|
$sqlAccountId, $date->format("Y-m-d H:i:s"), $currentElo->tier, $currentElo->rank, $currentElo->points
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private function updateRiotIDAndProfileIcon(): void {
|
|
$request = new RiotRequest("riot/account/v1/accounts/by-puuid/$this->puuid");
|
|
$request->useRouting();
|
|
$fetchedAccount = $request->run();
|
|
|
|
$this->gameName = $fetchedAccount->gameName;
|
|
$this->tagLine = $fetchedAccount->tagLine;
|
|
|
|
$conn = new MySQLConnection();
|
|
$conn->prepare("
|
|
UPDATE `accounts`
|
|
SET `gameName` = ?, `tagLine` = ?, `profileIconId` = $this->profileIconId
|
|
WHERE `puuid` = ?
|
|
")->execute([$this->gameName, $this->tagLine, $this->puuid]);
|
|
}
|
|
private function getLatestMatchTimestamp(): int {
|
|
$matchIdsRequest = new RiotRequest("lol/match/v5/matches/by-puuid/$this->puuid/ids");
|
|
$matchIdsRequest->useRouting();
|
|
$matchIdsRequest->setQueries([
|
|
"count" => 1,
|
|
"queue" => 420 // 5x5 solo queue
|
|
]);
|
|
$latestMatchId = $matchIdsRequest->run()[0];
|
|
|
|
$latestMatchRequest = new RiotRequest("lol/match/v5/matches/$latestMatchId");
|
|
$latestMatchRequest->useRouting();
|
|
|
|
return intval($latestMatchRequest->run()->info->gameEndTimestamp / 1000);
|
|
}
|
|
}
|
|
|
|
class Elo {
|
|
public string $tier;
|
|
public string $rank;
|
|
public int $points;
|
|
public function value() : int {
|
|
$tiers = [
|
|
"CHALLENGER" => 2800,
|
|
"GRANDMASTER" => 2800,
|
|
"MASTER" => 2800,
|
|
"DIAMOND" => 2400,
|
|
"EMERALD" => 2000,
|
|
"PLATINUM" => 1600,
|
|
"GOLD" => 1200,
|
|
"SILVER" => 800,
|
|
"BRONZE" => 400,
|
|
"IRON" => 0,
|
|
];
|
|
|
|
$ranks = [
|
|
"I" => 300,
|
|
"II" => 200,
|
|
"III" => 100,
|
|
"IV" => 0,
|
|
];
|
|
|
|
$tier = $this->tier;
|
|
|
|
if ($tier === "MASTER" || $tier === "GRANDMASTER" || $tier === "CHALLENGER")
|
|
return $tiers[$tier] + $this->points;
|
|
|
|
return $tiers[$tier] + $ranks[$this->rank] + $this->points;
|
|
}
|
|
}
|
|
|