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

<?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;
}
}