smrealms /
smr
We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.
| 1 | <?php declare(strict_types=1); |
||
| 2 | |||
| 3 | use Smr\Database; |
||
| 4 | use Smr\Template; |
||
| 5 | |||
| 6 | class Rankings { |
||
| 7 | |||
| 8 | /** |
||
| 9 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 10 | * @return array<int, array<string, mixed>> |
||
| 11 | */ |
||
| 12 | public static function collectSectorRankings(array $rankedStats, AbstractSmrPlayer $player, int $minRank = 1, int $maxRank = 10): array { |
||
| 13 | $rankedStats = self::filterRanks($rankedStats, $minRank, $maxRank); |
||
| 14 | $currRank = $minRank; |
||
| 15 | |||
| 16 | $rankings = []; |
||
| 17 | foreach ($rankedStats as $sectorID => $dbRecord) { |
||
| 18 | if ($player->getSectorID() == $sectorID) { |
||
| 19 | $class = ' class="bold"'; |
||
| 20 | } else { |
||
| 21 | $class = ''; |
||
| 22 | } |
||
| 23 | |||
| 24 | $rankings[$currRank++] = [ |
||
| 25 | 'Class' => $class, |
||
| 26 | 'SectorID' => $sectorID, |
||
| 27 | 'Value' => $dbRecord->getInt('amount'), |
||
| 28 | ]; |
||
| 29 | } |
||
| 30 | return $rankings; |
||
| 31 | } |
||
| 32 | |||
| 33 | /** |
||
| 34 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 35 | * @return array<int, array<string, mixed>> |
||
| 36 | */ |
||
| 37 | public static function collectRaceRankings(array $rankedStats, AbstractSmrPlayer $player): array { |
||
| 38 | $currRank = 1; |
||
| 39 | $rankings = []; |
||
| 40 | foreach ($rankedStats as $raceID => $dbRecord) { |
||
| 41 | if ($player->getRaceID() == $raceID) { |
||
| 42 | $style = ' class="bold"'; |
||
| 43 | } else { |
||
| 44 | $style = ''; |
||
| 45 | } |
||
| 46 | |||
| 47 | $rankings[$currRank++] = [ |
||
| 48 | 'style' => $style, |
||
| 49 | 'race_id' => $raceID, |
||
| 50 | 'amount' => $dbRecord->getInt('amount'), |
||
| 51 | 'amount_avg' => IRound($dbRecord->getInt('amount') / $dbRecord->getInt('num_players')), |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 52 | 'num_players' => $dbRecord->getInt('num_players'), |
||
| 53 | ]; |
||
| 54 | } |
||
| 55 | return $rankings; |
||
| 56 | } |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 60 | * @return array<int, array<string, mixed>> |
||
| 61 | */ |
||
| 62 | public static function collectAllianceRankings(array $rankedStats, ?AbstractSmrPlayer $player, int $minRank = 1, int $maxRank = 10): array { |
||
| 63 | $rankedStats = self::filterRanks($rankedStats, $minRank, $maxRank); |
||
| 64 | $currRank = $minRank; |
||
| 65 | |||
| 66 | $rankings = []; |
||
| 67 | foreach ($rankedStats as $allianceID => $dbRecord) { |
||
| 68 | $currentAlliance = SmrAlliance::getAlliance($allianceID, $dbRecord->getInt('game_id'), false, $dbRecord); |
||
| 69 | |||
| 70 | $class = ''; |
||
| 71 | if ($player !== null && $player->getAllianceID() == $currentAlliance->getAllianceID()) { |
||
| 72 | $class = ' class="bold"'; |
||
| 73 | } elseif ($currentAlliance->hasDisbanded()) { |
||
| 74 | $class = ' class="red"'; |
||
| 75 | } |
||
| 76 | |||
| 77 | $rankings[$currRank++] = [ |
||
| 78 | 'Alliance' => $currentAlliance, |
||
| 79 | 'Class' => $class, |
||
| 80 | 'Value' => $dbRecord->getInt('amount'), |
||
| 81 | ]; |
||
| 82 | } |
||
| 83 | return $rankings; |
||
| 84 | } |
||
| 85 | |||
| 86 | /** |
||
| 87 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 88 | * @return array<int, array<string, mixed>> |
||
| 89 | */ |
||
| 90 | public static function collectRankings(array $rankedStats, ?AbstractSmrPlayer $player, int $minRank = 1, int $maxRank = 10): array { |
||
| 91 | $rankedStats = self::filterRanks($rankedStats, $minRank, $maxRank); |
||
| 92 | $currRank = $minRank; |
||
| 93 | |||
| 94 | $rankings = []; |
||
| 95 | foreach ($rankedStats as $dbRecord) { |
||
| 96 | $currentPlayer = SmrPlayer::getPlayer($dbRecord->getInt('account_id'), $dbRecord->getInt('game_id'), false, $dbRecord); |
||
| 97 | |||
| 98 | $class = ''; |
||
| 99 | if ($player !== null && $player->equals($currentPlayer)) { |
||
| 100 | $class .= 'bold'; |
||
| 101 | } |
||
| 102 | if ($currentPlayer->hasNewbieStatus()) { |
||
| 103 | $class .= ' newbie'; |
||
| 104 | } |
||
| 105 | if ($class != '') { |
||
| 106 | $class = ' class="' . trim($class) . '"'; |
||
| 107 | } |
||
| 108 | |||
| 109 | $rankings[$currRank++] = [ |
||
| 110 | 'Player' => $currentPlayer, |
||
| 111 | 'Class' => $class, |
||
| 112 | 'Value' => $dbRecord->getInt('amount'), |
||
| 113 | ]; |
||
| 114 | } |
||
| 115 | return $rankings; |
||
| 116 | } |
||
| 117 | |||
| 118 | /** |
||
| 119 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 120 | * @return array<int, Smr\DatabaseRecord> |
||
| 121 | */ |
||
| 122 | private static function filterRanks(array $rankedStats, int $minRank, int $maxRank): array { |
||
| 123 | $offset = $minRank - 1; |
||
| 124 | $length = $maxRank - $offset; |
||
| 125 | return array_slice($rankedStats, $offset, $length, preserve_keys: true); |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Get stats from the player table grouped by race and sorted by $stat (high to low). |
||
| 130 | * |
||
| 131 | * @return array<int, Smr\DatabaseRecord> |
||
| 132 | */ |
||
| 133 | public static function raceStats(string $stat, int $gameID): array { |
||
| 134 | $db = Database::getInstance(); |
||
| 135 | $raceStats = []; |
||
| 136 | $dbResult = $db->read('SELECT race_id, COALESCE(SUM(' . $stat . '), 0) as amount, count(*) as num_players FROM player WHERE game_id = ' . $db->escapeNumber($gameID) . ' GROUP BY race_id ORDER BY amount DESC'); |
||
| 137 | foreach ($dbResult->records() as $dbRecord) { |
||
| 138 | $raceStats[$dbRecord->getInt('race_id')] = $dbRecord; |
||
| 139 | } |
||
| 140 | return $raceStats; |
||
| 141 | } |
||
| 142 | |||
| 143 | /** |
||
| 144 | * Get stats from the player table sorted by $stat (high to low). |
||
| 145 | * |
||
| 146 | * @return array<int, Smr\DatabaseRecord> |
||
| 147 | */ |
||
| 148 | public static function playerStats(string $stat, int $gameID, ?int $limit = null): array { |
||
| 149 | $db = Database::getInstance(); |
||
| 150 | $playerStats = []; |
||
| 151 | $query = 'SELECT player.*, ' . $stat . ' AS amount FROM player WHERE game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY amount DESC, player_name'; |
||
| 152 | if ($limit !== null) { |
||
| 153 | $query .= ' LIMIT ' . $limit; |
||
| 154 | } |
||
| 155 | $dbResult = $db->read($query); |
||
| 156 | foreach ($dbResult->records() as $dbRecord) { |
||
| 157 | $playerStats[$dbRecord->getInt('player_id')] = $dbRecord; |
||
| 158 | } |
||
| 159 | return $playerStats; |
||
| 160 | } |
||
| 161 | |||
| 162 | /** |
||
| 163 | * Gets player stats from the hof table sorted by $category (high to low). |
||
| 164 | * |
||
| 165 | * @param array<string> $category |
||
| 166 | * @return array<int, Smr\DatabaseRecord> |
||
| 167 | */ |
||
| 168 | public static function playerStatsFromHOF(array $category, int $gameID): array { |
||
| 169 | $db = Database::getInstance(); |
||
| 170 | $playerStats = []; |
||
| 171 | $dbResult = $db->read('SELECT p.*, COALESCE(ph.amount,0) amount FROM player p LEFT JOIN player_hof ph ON p.account_id = ph.account_id AND p.game_id = ph.game_id AND ph.type = ' . $db->escapeString(implode(':', $category)) . ' WHERE p.game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY amount DESC, player_name'); |
||
| 172 | foreach ($dbResult->records() as $dbRecord) { |
||
| 173 | $playerStats[$dbRecord->getInt('player_id')] = $dbRecord; |
||
| 174 | } |
||
| 175 | return $playerStats; |
||
| 176 | } |
||
| 177 | |||
| 178 | /** |
||
| 179 | * Gets alliance stats from the hof table sorted by $category (high to low). |
||
| 180 | * |
||
| 181 | * @param array<string> $category |
||
| 182 | * @return array<int, Smr\DatabaseRecord> |
||
| 183 | */ |
||
| 184 | public static function allianceStatsFromHOF(array $category, int $gameID): array { |
||
| 185 | $db = Database::getInstance(); |
||
| 186 | $allianceStats = []; |
||
| 187 | $dbResult = $db->read('SELECT alliance.*, COALESCE(SUM(amount), 0) amount |
||
| 188 | FROM alliance |
||
| 189 | LEFT JOIN player p USING (game_id, alliance_id) |
||
| 190 | LEFT JOIN player_hof ph ON p.account_id = ph.account_id AND p.game_id = ph.game_id AND ph.type = ' . $db->escapeString(implode(':', $category)) . ' |
||
| 191 | WHERE p.game_id = ' . $db->escapeNumber($gameID) . ' |
||
| 192 | GROUP BY alliance_id |
||
| 193 | ORDER BY amount DESC, alliance_name'); |
||
| 194 | foreach ($dbResult->records() as $dbRecord) { |
||
| 195 | $allianceStats[$dbRecord->getInt('alliance_id')] = $dbRecord; |
||
| 196 | } |
||
| 197 | return $allianceStats; |
||
| 198 | } |
||
| 199 | |||
| 200 | /** |
||
| 201 | * Get stats from the alliance table sorted by $stat (high to low). |
||
| 202 | * |
||
| 203 | * @return array<int, Smr\DatabaseRecord> |
||
| 204 | */ |
||
| 205 | public static function allianceStats(string $stat, int $gameID, ?int $limit = null): array { |
||
| 206 | $db = Database::getInstance(); |
||
| 207 | $allianceStats = []; |
||
| 208 | if ($stat === 'experience') { |
||
| 209 | $query = 'SELECT alliance.*, COALESCE(SUM(experience), 0) amount |
||
| 210 | FROM alliance |
||
| 211 | LEFT JOIN player USING (game_id, alliance_id) |
||
| 212 | WHERE game_id = ' . $db->escapeNumber($gameID) . ' |
||
| 213 | GROUP BY alliance_id |
||
| 214 | ORDER BY amount DESC, alliance_name ASC'; |
||
| 215 | } else { |
||
| 216 | $query = 'SELECT alliance.*, alliance_' . $stat . ' AS amount |
||
| 217 | FROM alliance WHERE game_id = ' . $db->escapeNumber($gameID) . ' ORDER BY amount DESC, alliance_name'; |
||
| 218 | } |
||
| 219 | if ($limit !== null) { |
||
| 220 | $query .= ' LIMIT ' . $limit; |
||
| 221 | } |
||
| 222 | $dbResult = $db->read($query); |
||
| 223 | foreach ($dbResult->records() as $dbRecord) { |
||
| 224 | $allianceStats[$dbRecord->getInt('alliance_id')] = $dbRecord; |
||
| 225 | } |
||
| 226 | return $allianceStats; |
||
| 227 | } |
||
| 228 | |||
| 229 | /** |
||
| 230 | * Given a $rankedStats array returned by one of the stats functions, |
||
| 231 | * find the rank associated with a specific ID. |
||
| 232 | * |
||
| 233 | * @param array<int, Smr\DatabaseRecord> $rankedStats |
||
| 234 | */ |
||
| 235 | public static function ourRank(array $rankedStats, int $ourID): int { |
||
| 236 | return array_search($ourID, array_keys($rankedStats)) + 1; |
||
| 237 | } |
||
| 238 | |||
| 239 | /** |
||
| 240 | * @return array{int, int} |
||
|
0 ignored issues
–
show
|
|||
| 241 | */ |
||
| 242 | public static function calculateMinMaxRanks(int $ourRank, int $totalRanks): array { |
||
| 243 | $session = Smr\Session::getInstance(); |
||
| 244 | $minRank = $session->getRequestVarInt('min_rank', $ourRank - 5); |
||
| 245 | $maxRank = $session->getRequestVarInt('max_rank', $ourRank + 5); |
||
| 246 | |||
| 247 | // Swap min and max if user input them in the wrong order |
||
| 248 | if ($minRank > $maxRank) { |
||
| 249 | [$minRank, $maxRank] = [$maxRank, $minRank]; |
||
| 250 | } |
||
| 251 | |||
| 252 | if ($minRank <= 0 || $minRank > $totalRanks) { |
||
| 253 | $minRank = 1; |
||
| 254 | } |
||
| 255 | |||
| 256 | $maxRank = min($maxRank, $totalRanks); |
||
| 257 | |||
| 258 | $template = Template::getInstance(); |
||
| 259 | $template->assign('MinRank', $minRank); |
||
| 260 | $template->assign('MaxRank', $maxRank); |
||
| 261 | $template->assign('TotalRanks', $totalRanks); |
||
| 262 | |||
| 263 | return [$minRank, $maxRank]; |
||
| 264 | } |
||
| 265 | |||
| 266 | } |
||
| 267 |