· 6 years ago · Jan 09, 2020, 01:32 PM
1// START FILE index.php
2
3<!DOCTYPE html>
4<html>
5 <head>
6 <meta charset="utf-8">
7 <h1><font color="#e3e3e3">Hypixel Stats Viewer</h1>
8 </head>
9 <body>
10 <body bgcolor="#0f0f0f">
11 <b>Please enter a username:</b>
12 <form action="stats.php" method="get">
13 <br><input type="text" name="ign" placeholder="Username">
14 </form>
15 </body>
16</html>
17
18// END FILE index.php
19
20// START FILE stats.php
21
22<?php $ign = $_GET['ign'];
23 include_once('HypixelPHP.php');
24 $HypixelPHP = new HypixelPHP\HypixelPHP(['api_key' => '1d0389e4-c3a7-4b3b-b231-7b25de06e55b']);
25 $player = $HypixelPHP->getPlayer([\HypixelPHP\KEYS::PLAYER_BY_NAME => $ign]);
26 $apikey = '1d0389e4-c3a7-4b3b-b231-7b25de06e55b';
27 if ($player != null) ?>
28
29
30 <body bgcolor="#0f0f0f">
31
32<?php
33 // $uuid = $player->getUUID('uuid,',);
34 // $key = '1d0389e4-c3a7-4b3b-b231-7b25de06e55b';
35 // $json = file_get_contents('https://api.hypixel.net/friends?key='.$key.'&uuid='.$uuid);
36 // $friends = json_decode($json, true);
37 // print_r ($friends);
38?>
39
40<?php
41 // $id = '5b95483f0cf24be3ce6e25cd';
42 // $json = file_get_contents('https://api.hypixel.net/guild?key='.$key.'&id='.$id);
43 // $guild = json_decode($json, true);
44 // print_r ($guild);
45?>
46
47<?php
48
49// GENERAL STATS
50 $json = json_decode(file_get_contents("https://api.hypixel.net/player?key=$apikey&name=$ign"), true);
51 $karma = $json["player"]["karma"];
52 $netexp = $json["player"]["networkExp"];
53 $bwstars = $json["player"]["achievements"]["bedwars_level"];
54 $netlvl = (sqrt($netexp+15312.5)-125/sqrt(2))/(25*sqrt(2));
55 $achpoints = $json["player"]["achievementPoints"];
56
57// ===== BEDWARS =====
58
59
60// FKDR
61 $finalkills = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('final_kills_bedwars');
62 $finaldeaths = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('final_deaths_bedwars');
63 $fkdr = $finalkills / $finaldeaths;
64
65// STARS
66 $bwexp = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('Experience');
67 $stars = ($bwexp / (96 * 5000 + 7000)) * 100;
68
69// WIN GAMES RATIO
70 $bwgames = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('games_played_bedwars_1');
71 $bwwins = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('wins_bedwars');
72 $bwwgratio = $bwwins / $bwgames;
73
74// WIN LOSE RATIO
75 $bwloses = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('losses_bedwars');
76 $bwwlratio = $bwwins / $bwloses;
77
78// KILL DEATH RATIO
79 $bwkills = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('kills_bedwars');
80 $bwdeaths = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('final_deaths_bedwars');
81 $bwkdr = $bwkills / $bwdeaths;
82
83// BREAK BED LOST BED RATIO
84 $bedl = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('beds_lost_bedwars');
85 $bedb = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('beds_broken_bedwars');
86 $bblb = $bedb / $bedl;
87
88
89// ===== SKYWARS =====
90
91
92// WIN GAMES RATIO
93 $swwins = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('wins');
94 $swgames = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('games_played_skywars');
95 $swwgratio = $swwins / $swgames;
96
97// WIN LOSE RATIO
98 $swloses = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('losses');
99 $swwlratio = $swwins / $swloses;
100
101// KILL DEATH RATIO
102 $swkills = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('kills');
103 $swdeaths = $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('deaths');
104 $swkdratio = $swkills / $swdeaths;
105
106 //$json = json_decode(file_get_contents("https://api.hypixel.net/player?key=1d0389e4-c3a7-4b3b-b231-7b25de06e55b&name=Lumixmas"), true);
107 //$karma = $json["player"]["path"]["to"]["wins_bedwars"];
108
109 echo $player->getFormattedName(true, true);
110 echo '<br><font color="#e3e3e3">UUID: ' . $player->getUUID('uuid,',);
111 echo '<br>Network Level: ' . number_format("$netlvl",1,".",".");
112 echo '<br>Achievement Points: ' . number_format("$achpoints",0,".",".");
113 echo '<br>Karma: ' . number_format("$karma",0,".",".");;
114 echo '<br>';
115 echo '<br><b><ins>BedWars</ins></b>';
116 echo '<br>';
117 echo '<br>';
118 echo '<b>General</b>';
119 echo '<br>Stars : ' . ($bwstars);
120 echo '<br>Coins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('coins');
121 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('wins_bedwars');
122 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('losses_bedwars');
123 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('games_played_bedwars_1');
124 echo '<br>W/L Ratio: ' . number_format("$bwwlratio",2,".",".");
125 echo '<br>W/G Ratio: ' . number_format("$bwwgratio",2,".",".");
126 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('winstreak');
127 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('kills_bedwars');
128 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('deaths_bedwars');
129 echo '<br>KDR: ' . number_format("$bwkdr",2,".",".");
130 echo '<br>Final Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('final_kills_bedwars');
131 echo '<br>Final Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('final_deaths_bedwars');
132 echo '<br>FKDR: ' . number_format("$fkdr",2,".",".");
133 echo '<br>Broken Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('beds_broken_bedwars');
134 echo '<br>Lost Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('beds_lost_bedwars');
135 echo '<br>BB/LR: ' . number_format("$bblb",2,".",".");
136 echo '<br>Iron collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('iron_resources_collected_bedwars');
137 echo '<br>Gold collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('gold_resources_collected_bedwars');
138 echo '<br>Diamonds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('diamond_resources_collected_bedwars');
139 echo '<br>Emeralds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('emerald_resources_collected_bedwars');
140 echo '<br>Recources collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('resources_collected_bedwars');
141 echo '<br>';
142 echo '<br>';
143 echo '<b>Solo</b>';
144 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_wins_bedwars');
145 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_losses_bedwars');
146 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_games_played_bedwars');
147 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_winstreak');
148 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_kills_bedwars');
149 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_deaths_bedwars');
150 echo '<br>Final Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_final_kills_bedwars');
151 echo '<br>Final Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_final_deaths_bedwars');
152 echo '<br>Lost Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_beds_lost_bedwars');
153 echo '<br>Broken Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_beds_broken_bedwars');
154 echo '<br>Iron collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_iron_resources_collected_bedwars');
155 echo '<br>Gold collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_gold_resources_collected_bedwars');
156 echo '<br>Diamonds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_diamond_resources_collected_bedwars');
157 echo '<br>Emeralds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_emerald_resources_collected_bedwars');
158 echo '<br>Recources collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_one_resources_collected_bedwars');
159 echo '<br>';
160 echo '<br>';
161 echo '<b>Doubles</b>';
162 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_wins_bedwars');
163 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_losses_bedwars');
164 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_games_played_bedwars');
165 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_winstreak');
166 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_kills_bedwars');
167 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_deaths_bedwars');
168 echo '<br>Final Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_final_kills_bedwars');
169 echo '<br>Final Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_final_deaths_bedwars');
170 echo '<br>Lost Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_beds_lost_bedwars');
171 echo '<br>Broken Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_beds_broken_bedwars');
172 echo '<br>Iron collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_iron_resources_collected_bedwars');
173 echo '<br>Gold collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_gold_resources_collected_bedwars');
174 echo '<br>Diamonds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_diamond_resources_collected_bedwars');
175 echo '<br>Emeralds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_emerald_resources_collected_bedwars');
176 echo '<br>Recources collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('eight_two_resources_collected_bedwars');
177 echo '<br>';
178 echo '<br>';
179 echo '<b>Threes</b>';
180 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_wins_bedwars');
181 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_losses_bedwars');
182 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_games_played_bedwars');
183 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_winstreak');
184 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_kills_bedwars');
185 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_deaths_bedwars');
186 echo '<br>Final Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_final_kills_bedwars');
187 echo '<br>Final Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_final_deaths_bedwars');
188 echo '<br>Lost Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_beds_lost_bedwars');
189 echo '<br>Broken Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_beds_broken_bedwars');
190 echo '<br>Iron collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_iron_resources_collected_bedwars');
191 echo '<br>Gold collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_gold_resources_collected_bedwars');
192 echo '<br>Diamonds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_diamond_resources_collected_bedwars');
193 echo '<br>Emeralds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_emerald_resources_collected_bedwars');
194 echo '<br>Recources collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_three_resources_collected_bedwars');
195 echo '<br>';
196 echo '<br>';
197 echo '<b>Fours</b>';
198 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_wins_bedwars');
199 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_losses_bedwars');
200 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_games_played_bedwars');
201 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_winstreak');
202 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_kills_bedwars');
203 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_deaths_bedwars');
204 echo '<br>Final Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_final_kills_bedwars');
205 echo '<br>Final Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_final_deaths_bedwars');
206 echo '<br>Lost Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_beds_lost_bedwars');
207 echo '<br>Broken Beds: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_beds_broken_bedwars');
208 echo '<br>Iron collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_iron_resources_collected_bedwars');
209 echo '<br>Gold collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_gold_resources_collected_bedwars');
210 echo '<br>Diamonds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_diamond_resources_collected_bedwars');
211 echo '<br>Emeralds collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_emerald_resources_collected_bedwars');
212 echo '<br>Recources collected: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::BEDWARS)->getInt('four_four_resources_collected_bedwars');
213 echo '<br>';
214 echo '<br><b><ins>SkyWars</ins></b>';
215 echo '<br>';
216 echo '<br>';
217 echo '<b>General</b>';
218 echo '<br>Coins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('coins');
219 echo '<br>Souls: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('souls');
220 echo '<br>Wins: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('wins');
221 echo '<br>Losses: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('losses');
222 echo '<br>Games played: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('games_played_skywars');
223 echo '<br>W/L: ' . number_format("$swwlratio",2,".",".");
224 echo '<br>W/G: ' . number_format("$swwgratio",2,".",".");
225 echo '<br>Winstreak: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('win_streak');
226 echo '<br>Kills: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('kills');
227 echo '<br>Deaths: ' . $player->getStats()->getGameFromID(\HypixelPHP\GameTypes::SKYWARS)->getInt('deaths');
228 echo '<br>KDR: ' . number_format("$swkdratio",2,".",".");
229?>
230
231// END FILE stats.php
232
233// START FILE hypixelphp.php
234
235<?php
236namespace HypixelPHP;
237
238use DateTime;
239
240/**
241 * HypixelPHP
242 *
243 * @author Plancke
244 * @version 2.0.1
245 * @link http://plancke.nl
246 *
247 */
248class HypixelPHP {
249 private $options;
250 private $getUrlErrors = [];
251 const MAX_CACHE_TIME = 999999999999;
252
253 /**
254 * @param array $input
255 */
256 public function __construct($input = []) {
257 $this->options = array_merge(
258 [
259 'api_key' => '',
260 'cache_times' => [
261 CACHE_TIMES::OVERALL => 600,
262 CACHE_TIMES::PLAYER => 600,
263 CACHE_TIMES::UUID => 864000,
264 CACHE_TIMES::UUID_NOT_FOUND => 600,
265 CACHE_TIMES::GUILD => 600,
266 CACHE_TIMES::GUILD_NOT_FOUND => 600,
267 ],
268 'timeout' => 2000,
269 'cache_folder_player' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/player',
270 'cache_folder_guild' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/guild',
271 'cache_folder_friends' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/friends',
272 'cache_folder_sessions' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/sessions',
273 'cache_folder_keyInfo' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/keyInfo/',
274 'cache_boosters' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/boosters.json',
275 'cache_leaderboards' => $_SERVER['DOCUMENT_ROOT'] . '/cache/HypixelAPI/leaderboards.json',
276 'log_folder' => $_SERVER['DOCUMENT_ROOT'] . '/logs/HypixelAPI',
277 'achievements_file' => $_SERVER['DOCUMENT_ROOT'] . '/assets/achievements.json',
278 'logging' => true,
279 'debug' => true,
280 'use_curl' => true
281 ],
282 $input
283 );
284
285 if (!file_exists($this->options['cache_folder_player'])) {
286 mkdir($this->options['cache_folder_player'], 0777, true);
287 }
288 if (!file_exists($this->options['cache_folder_guild'])) {
289 mkdir($this->options['cache_folder_guild'], 0777, true);
290 }
291 if (!file_exists($this->options['cache_folder_friends'])) {
292 mkdir($this->options['cache_folder_friends'], 0777, true);
293 }
294 if (!file_exists($this->options['cache_folder_sessions'])) {
295 mkdir($this->options['cache_folder_sessions'], 0777, true);
296 }
297 if (!file_exists($this->options['log_folder'])) {
298 mkdir($this->options['log_folder'], 0777, true);
299 }
300
301 $this->options['cache_times_original'] = $this->options['cache_times'];
302 }
303
304 /**
305 * @param $input
306 */
307 public function set($input) {
308 foreach ($input as $key => $val) {
309 if ($key != 'api_key' && $key != 'debug') {
310 if (array_key_exists($key, $this->options) || $this->options[$key] != $val) {
311 if (is_array($val)) {
312 $this->debug('Setting ' . $key . ' to ' . json_encode($val));
313 } else {
314 $this->debug('Setting ' . $key . ' to ' . $val);
315 }
316 }
317 }
318 $this->options[$key] = $val;
319 }
320 }
321
322 /**
323 * @param $message
324 * @param bool $log
325 */
326 public function debug($message, $log = true) {
327 if ($this->options['debug']) {
328 echo '<!-- ' . $message . ' -->';
329 }
330 if ($log && $this->options['logging']) {
331 $this->log($message);
332 }
333 }
334
335 /**
336 * @param $key
337 */
338 public function setKey($key) {
339 $this->set(['api_key' => $key]);
340 }
341
342 public function getKey() {
343 return $this->options['api_key'];
344 }
345
346 /**
347 * @return array
348 */
349 public function getOptions() {
350 return $this->options;
351 }
352
353 /**
354 * Checks if $name is a paid account
355 * @param $name
356 * @param string $url
357 * @return bool
358 */
359 public function hasPaid($name, $url = 'https://mcapi.ca/other/haspaid/%s') {
360 $hasPaid = $this->getUrlContents(sprintf($url, $name));
361 if (!isset($hasPaid['premium'])) return false;
362 $this->debug('Premium (' . $name . '): ' . ($hasPaid['premium'] ? 'true' : 'false'));
363 return $hasPaid['premium'];
364 }
365
366 /**
367 * @param $url
368 * @param int $timeout
369 * @return array|mixed json decoded array of response or error json
370 */
371 public function getUrlContents($url, $timeout = -1) {
372 if ($timeout == -1) {
373 $timeout = $this->getOptions()['timeout'];
374 }
375 $errorOut = ['success' => false];
376 if ($this->options['use_curl']) {
377 $ch = curl_init();
378 curl_setopt($ch, CURLOPT_URL, $url);
379 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
380 curl_setopt($ch, CURLOPT_TIMEOUT_MS, $timeout);
381 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, $timeout);
382 curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
383 $curlOut = curl_exec($ch);
384 $errorOut['cause'] = curl_error($ch);
385 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
386 $errorOut['status'] = $status;
387 curl_close($ch);
388 if ($curlOut === false || $status != '200') {
389 array_push($this->getUrlErrors, $errorOut);
390 return $errorOut;
391 }
392 $json_out = json_decode($curlOut, true);
393 if (isset($json_out['throttle'])) {
394 $errorOut['throttle'] = $json_out['throttle'];
395 array_push($this->getUrlErrors, $errorOut);
396 }
397 return $json_out;
398 } else {
399 $ctx = stream_context_create([
400 'https' => ['timeout' => $timeout / 1000]
401 ]);
402 $out = file_get_contents($url, 0, $ctx);
403 if ($out === false) {
404 return $errorOut;
405 }
406 return json_decode($out, true);
407 }
408 }
409
410 /**
411 * Returns the currently set cache threshold
412 * @param null|string $for
413 * @param bool $original
414 * @return int
415 */
416 public function getCacheTime($for = CACHE_TIMES::OVERALL, $original = false) {
417 $key = 'cache_times' . ($original ? '_original' : '');
418 if (isset($this->options[$key][$for])) {
419 return $this->options[$key][$for];
420 }
421 return HypixelPHP::MAX_CACHE_TIME;
422 }
423
424 /**
425 * @param int $cache_time
426 * @param array $for
427 */
428 public function setCacheTime($cache_time = 600, $for = [CACHE_TIMES::OVERALL]) {
429 $cache_times = $this->options['cache_times'];
430 if (!is_array($for)) {
431 $for = [$for]; // Backwards compatibility
432 }
433 foreach ($for as $f) {
434 $cache_times[$f] = $cache_time;
435 }
436 $this->set(['cache_times' => $cache_times]);
437 }
438
439 /**
440 * Set cache time for all of them
441 * @param int $cache_time
442 */
443 public function setAllCacheTimes($cache_time = 600) {
444 $this->setCacheTime($cache_time, CACHE_TIMES::getAllTypes());
445 }
446
447 /**
448 * Log $string to log files
449 * Directory setup:
450 * - LOG_FOLDER/DATE/1.log
451 * - LOG_FOLDER/DATE/2.log
452 * separated every 25MB
453 * @param $string
454 */
455 public function log($string) {
456 $dirName = $this->options['log_folder'] . DIRECTORY_SEPARATOR . date("Y-m-d");
457 if (!file_exists($dirName)) {
458 mkdir($dirName, 0777, true);
459 }
460 $scanDir = array_diff(scandir($dirName), ['.', '..']);
461 $numberOfLogs = sizeof($scanDir);
462 if ($numberOfLogs == 0) {
463 $numberOfLogs++;
464 }
465 $filename = $dirName . DIRECTORY_SEPARATOR . $numberOfLogs . '.log';
466 if (file_exists($filename)) {
467 if (filesize($filename) > 25600000) {
468 $filename = $dirName . DIRECTORY_SEPARATOR . ($numberOfLogs + 1) . '.log';
469 }
470 }
471 file_put_contents($filename, '[' . date("H:i:s") . '] ' . $string . "\r\n", FILE_APPEND);
472 }
473
474 /**
475 * @param $request
476 * @param null $key
477 * @param null $val
478 * @param $timeout
479 *
480 * @return array|mixed
481 */
482 public function fetch($request, $key = null, $val = null, $timeout = -1) {
483 if ($this->getCacheTime() >= self::MAX_CACHE_TIME) {
484 $return = ["success" => false, 'cause' => 'Max Cache Time!'];
485 return $return;
486 }
487
488 if ($timeout < 0) {
489 $timeout = $this->options['timeout'];
490 }
491
492 $requestURL = 'https://api.hypixel.net/' . $request . '?key=' . $this->getKey();
493 $debug = $request;
494 if ($key != null && $val != null) {
495 $val = trim($val);
496 $val = str_replace(' ', '%20', $val);
497 $requestURL .= '&' . $key . '=' . $val;
498 $debug .= '?' . $key . '=' . $val;
499 }
500 $this->debug('Starting Fetch: ' . $debug);
501
502 $response = $this->getUrlContents($requestURL, $timeout);
503 if ($response['success'] == false) {
504 if (!array_key_exists('cause', $response)) {
505 $response['cause'] = 'Unknown';
506 }
507 $this->debug('Fetch Failed: ' . $response['cause']);
508 $this->setAllCacheTimes(HypixelPHP::MAX_CACHE_TIME - 1);
509 } else {
510 $this->debug('Fetch successful!');
511 }
512 return $response;
513 }
514
515 /**
516 * @param array $pairs
517 * @return Player|null
518 */
519 public function getPlayer($pairs = []) {
520 foreach ($pairs as $key => $val) {
521 if ($val != null && $val != '') {
522 if ($key == KEYS::PLAYER_BY_UNKNOWN || $key == KEYS::PLAYER_BY_NAME) {
523 return $this->getPlayer([KEYS::PLAYER_BY_UUID => $this->getUUIDFromVar($val)]);
524 }
525
526 $filename = $this->options['cache_folder_player'] . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . $this->getCacheFileName($val) . '.json';
527 if ($key == KEYS::PLAYER_BY_UUID) {
528 $val = Utilities::ensureNoDashesUUID($val);
529 if (InputType::getType($val) != InputType::UUID) continue;
530
531 $content = $this->getCache($filename);
532 if ($content != null) {
533 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
534 if (time() - $this->getCacheTime() < $timestamp) {
535 return new Player($content, $this);
536 }
537 }
538
539 $response = $this->fetch(API_REQUESTS::PLAYER, $key, $val);
540 if ($response['success'] == true) {
541 $PLAYER = new Player([
542 'record' => $response['player'],
543 'extra' => $content['extra']
544 ], $this);
545 $PLAYER->setExtra(['filename' => $filename]);
546 $PLAYER->handleNew();
547 $this->setCache($filename, $PLAYER);
548 return $PLAYER;
549 }
550 }
551 }
552 }
553 if ($this->getCacheTime(CACHE_TIMES::PLAYER) < self::MAX_CACHE_TIME) {
554 $this->setCacheTime(self::MAX_CACHE_TIME, CACHE_TIMES::PLAYER);
555 return $this->getPlayer($pairs);
556 }
557 return null;
558 }
559
560 /**
561 * get Guild of Player
562 * @param array $pairs
563 * @return Guild|null
564 */
565 public function getGuild($pairs = []) {
566 foreach ($pairs as $key => $val) {
567 if ($val != null && $val != '') {
568 if ($key == KEYS::GUILD_BY_PLAYER_OBJECT ||
569 $key == KEYS::GUILD_BY_PLAYER_NAME
570 ) {
571 return $this->getGuild([KEYS::GUILD_BY_PLAYER_UUID => $this->getUUIDFromVar($val)]);
572 }
573
574 $filename = $this->options['cache_folder_guild'] . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . $this->getCacheFileName($val) . '.json';
575
576 if ($key == KEYS::GUILD_BY_NAME || $key == KEYS::GUILD_BY_PLAYER_UUID) {
577 $content = $this->getCache($filename);
578 if ($content != null) {
579 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
580 if (time() - $this->getCacheTime() < $timestamp) {
581 if (isset($content['guild'])) {
582 return $this->getGuild([KEYS::GUILD_BY_ID => $content['guild']]);
583 }
584 continue;
585 }
586 }
587
588 $response = $this->fetch(API_REQUESTS::FIND_GUILD, $key, $val, 5000);
589 if ($response['success'] == true) {
590 $content = ['timestamp' => time(), 'guild' => $response['guild']];
591 $this->setFileContent($filename, json_encode($content));
592 return $this->getGuild([KEYS::GUILD_BY_ID => $response['guild']]);
593 }
594 }
595
596 if ($key == KEYS::GUILD_BY_ID) {
597 $content = $this->getCache($filename);
598 if ($content != null) {
599 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
600 if (time() - $this->getCacheTime() < $timestamp) {
601 return new Guild($content, $this);
602 }
603 }
604
605 $response = $this->fetch(API_REQUESTS::GUILD, $key, $val);
606 if ($response['success'] == true) {
607 $GUILD = new Guild([
608 'record' => $response['guild'],
609 'extra' => $content['extra']
610 ], $this);
611 $GUILD->setExtra(['filename' => $filename]);
612 $GUILD->handleNew();
613 $this->setCache($filename, $GUILD);
614 return $GUILD;
615 }
616 }
617 }
618 }
619 if ($this->getCacheTime(CACHE_TIMES::GUILD) < self::MAX_CACHE_TIME) {
620 $this->setCacheTime(self::MAX_CACHE_TIME, CACHE_TIMES::GUILD);
621 return $this->getGuild($pairs);
622 }
623 return null;
624 }
625
626 /**
627 * Get Session of Player
628 * @param array $pairs
629 * @return Session|null
630 */
631 public function getSession($pairs = []) {
632 foreach ($pairs as $key => $val) {
633 if ($val != null && $val != '') {
634 if ($key == KEYS::SESSION_BY_PLAYER_OBJECT && $val instanceof Player) {
635 /* @var $val Player */
636 return $this->getSession([KEYS::SESSION_BY_UUID => $val->getUUID()]);
637 }
638
639 $filename = $this->options['cache_folder_sessions'] . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . $this->getCacheFileName($val) . '.json';
640
641 if ($key == KEYS::SESSION_BY_NAME) {
642 if (file_exists($filename) || $this->hasPaid($val)) {
643 $uuid = $this->getUUID($val);
644 return $this->getSession([KEYS::SESSION_BY_UUID => $uuid]);
645 }
646 } elseif ($key == KEYS::SESSION_BY_UUID) {
647 $content = $this->getCache($filename);
648 if ($content != null) {
649 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
650 if (time() - $this->getCacheTime() < $timestamp) {
651 return new Session($content, $this);
652 }
653 }
654
655 $response = $this->fetch(API_REQUESTS::SESSION, $key, $val);
656 if ($response['success'] == true) {
657 $SESSION = new Session([
658 'record' => $response['session'],
659 'extra' => $content['extra']
660 ], $this);
661 if (!is_array($SESSION->getRecord())) {
662 $SESSION->JSONArray['record'] = [];
663 }
664 $SESSION->JSONArray['record']['uuid'] = (string)$val;
665 $SESSION->setExtra(['filename' => $filename]);
666 $this->setCache($filename, $SESSION);
667 return $SESSION;
668 }
669 }
670 }
671 }
672
673 if ($this->getCacheTime() < self::MAX_CACHE_TIME) {
674 $this->setCacheTime(self::MAX_CACHE_TIME);
675 return $this->getSession($pairs);
676 }
677 return null;
678 }
679
680 /**
681 * get Friends of Player
682 * @param array $pairs
683 * @return FriendsList|null
684 */
685 public function getFriends($pairs = []) {
686 foreach ($pairs as $key => $val) {
687 if ($val != null && $val != '') {
688 if ($key == KEYS::FRIENDS_BY_PLAYER_OBJECT && $val instanceof Player) {
689 /* @var $val Player */
690 return $this->getFriends([KEYS::FRIENDS_BY_UUID => $val->getUUID()]);
691 }
692
693 $filename = $this->options['cache_folder_friends'] . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR . $this->getCacheFileName($val) . '.json';
694
695 if ($key == KEYS::FRIENDS_BY_NAME) {
696 if (file_exists($filename) || $this->hasPaid($val)) {
697 $uuid = $this->getUUID($val);
698 return $this->getFriends([KEYS::FRIENDS_BY_UUID => $uuid]);
699 }
700 } elseif ($key == KEYS::FRIENDS_BY_UUID) {
701 $content = $this->getCache($filename);
702 if ($content != null) {
703 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
704 if (time() - $this->getCacheTime() < $timestamp) {
705 return new FriendsList($content, $this);
706 }
707 }
708
709 $response = $this->fetch(API_REQUESTS::FRIENDS, $key, $val);
710 if ($response['success'] == true) {
711 $FRIENDS = new FriendsList([
712 'record' => ['list' => $response['records']],
713 'extra' => $content['extra']
714 ], $this);
715 $FRIENDS->setExtra(['filename' => $filename]);
716 $FRIENDS->handleNew();
717 $this->setCache($filename, $FRIENDS);
718 return $FRIENDS;
719 }
720 }
721 }
722 }
723
724 if ($this->getCacheTime() < self::MAX_CACHE_TIME) {
725 $this->setCacheTime(self::MAX_CACHE_TIME);
726 return $this->getFriends($pairs);
727 }
728 return null;
729 }
730
731 /**
732 * get boosters
733 * @return Boosters|null
734 */
735 public function getBoosters() {
736 $filename = $this->options['cache_boosters'];
737 $content = $this->getCache($filename);
738 if ($content != null) {
739 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
740 if (time() - $this->getCacheTime() < $timestamp) {
741 return new Boosters($content, $this);
742 }
743 }
744
745 $response = $this->fetch(API_REQUESTS::BOOSTERS);
746 if ($response['success'] == true) {
747 $BOOSTERS = new Boosters([
748 'record' => $response['boosters'],
749 'extra' => $content['extra']
750 ], $this);
751 $BOOSTERS->setExtra(['filename' => $filename]);
752 $BOOSTERS->handleNew();
753 $this->setCache($filename, $BOOSTERS);
754 return $BOOSTERS;
755 }
756
757 if ($this->getCacheTime() < self::MAX_CACHE_TIME) {
758 $this->setCacheTime(self::MAX_CACHE_TIME);
759 return $this->getBoosters();
760 }
761 return null;
762 }
763
764 /**
765 * get Leaderboards, Hypixel Format
766 * @return Leaderboards|null
767 */
768 public function getLeaderboards() {
769 $filename = $this->options['cache_leaderboards'];
770 $content = $this->getCache($filename);
771 if ($content != null) {
772 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
773 if (time() - $this->getCacheTime() < $timestamp) {
774 return new Leaderboards($content, $this);
775 }
776 }
777
778 $response = $this->fetch(API_REQUESTS::LEADERBOARDS);
779 if ($response['success'] == 'true') {
780 $LEADERBOARDS = new Leaderboards([
781 'record' => $response['leaderboards'],
782 'extra' => $content['extra']
783 ], $this);
784 $LEADERBOARDS->setExtra(['filename' => $filename]);
785 $LEADERBOARDS->handleNew();
786 $this->setCache($filename, $LEADERBOARDS);
787 return $LEADERBOARDS;
788 }
789
790 if ($this->getCacheTime() < self::MAX_CACHE_TIME) {
791 $this->setCacheTime(self::MAX_CACHE_TIME);
792 return $this->getLeaderboards();
793 }
794 return null;
795 }
796
797 /**
798 * get info about currently set API Key
799 * @return KeyInfo|null
800 */
801 public function getKeyInfo() {
802 $filename = $this->options['cache_folder_keyInfo'] . $this->getCacheFileName($this->getKey());
803 $content = $this->getCache($filename);
804 if ($content != null) {
805 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
806 if (time() - $this->getCacheTime() < $timestamp) {
807 $this->debug('Getting Cached data!');
808 return new KeyInfo($content, $this);
809 }
810 }
811
812 $response = $this->fetch(API_REQUESTS::KEY);
813 if ($response['success'] == true) {
814 $content = ['timestamp' => time(), 'record' => $response['record']];
815 $this->setFileContent($filename, json_encode($content));
816 return new KeyInfo($content, $this);
817 }
818
819 if ($this->getCacheTime() < self::MAX_CACHE_TIME) {
820 $this->setCacheTime(self::MAX_CACHE_TIME);
821 return $this->getKeyInfo();
822 }
823 return null;
824 }
825
826 /**
827 * @param $filename
828 *
829 * @return null|string
830 */
831 public function getFileContent($filename) {
832 $content = null;
833 if (file_exists($filename)) {
834 $this->debug('Getting contents of ' . $filename);
835 $file = fopen($filename, 'r+');
836 if (filesize($filename) > 0) {
837 $content = fread($file, filesize($filename));
838 }
839 fclose($file);
840 }
841 return $content;
842 }
843
844 /**
845 * @param $filename
846 * @param $content
847 */
848 public function setFileContent($filename, $content) {
849 $this->debug('Setting contents of ' . $filename);
850 if (!file_exists(dirname($filename))) {
851 @mkdir(dirname($filename), 0777, true);
852 }
853 $file = fopen($filename, 'w+');
854 fwrite($file, $content);
855 fclose($file);
856 }
857
858 /**
859 * @param $input
860 *
861 * @return string
862 */
863 public function getCacheFileName($input) {
864 $input = strtolower($input);
865 $input = trim($input);
866 $input = str_replace(' ', '%20', $input);
867 if (strlen($input) < 3) {
868 return implode(DIRECTORY_SEPARATOR, str_split($input, 1));
869 }
870 return substr($input, 0, 1) . DIRECTORY_SEPARATOR . substr($input, 1, 1) . DIRECTORY_SEPARATOR . substr($input, 2);
871 }
872
873 /**
874 * @param $filename
875 *
876 * @return mixed|null|string
877 */
878 public function getCache($filename) {
879 $content = $this->getFileContent($filename);
880 if ($content == null) {
881 return null;
882 }
883 $content = json_decode($content, true);
884 if ($content == null) {
885 return null;
886 }
887 if (!array_key_exists('extra', $content)) {
888 $content['extra'] = [];
889 }
890 return $content;
891 }
892
893 /**
894 * @param $filename
895 * @param HypixelObject $obj
896 */
897 public function setCache($filename, HypixelObject $obj) {
898 $content = json_encode($obj->getRaw());
899 $this->setFileContent($filename, $content);
900 }
901
902 /**
903 * Function to get and cache UUID from username.
904 * @param string $username
905 * @param string $url
906 *
907 * @return string|bool
908 */
909 public function getUUID($username, $url = 'https://api.mojang.com/users/profiles/minecraft/%s') {
910 $uuidURL = sprintf($url, $username);
911 $filename = $this->options['cache_folder_player'] . DIRECTORY_SEPARATOR . 'name' . DIRECTORY_SEPARATOR . $this->getCacheFileName($username) . '.json';
912
913 $content = $this->getCache($filename);
914 if ($content != null) {
915 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
916 if (time() - $this->getCacheTime(CACHE_TIMES::UUID) < $timestamp) {
917 $CACHE_TIME = $this->getCacheTime(CACHE_TIMES::UUID);
918 if (!isset($content['uuid']) || $content['uuid'] == null || $content['uuid'] == '') {
919 $CACHE_TIME = $this->getCacheTime(CACHE_TIMES::UUID_NOT_FOUND);
920 // allow for faster fail over when uuid is null/not found
921 }
922 $timestamp = array_key_exists('timestamp', $content) ? $content['timestamp'] : 0;
923 if (time() - $CACHE_TIME < $timestamp) {
924 return $content['uuid'];
925 }
926 }
927 }
928
929 $response = $this->getUrlContents($uuidURL);
930 if (isset($response['id'])) {
931 $this->debug('UUID for username fetched!');
932 $content = [
933 'timestamp' => time(),
934 'name' => $response['name'],
935 'uuid' => $response['id']
936 ];
937 $this->setFileContent($filename, json_encode($content));
938 $this->debug($username . ' => ' . $response['id']);
939 return $response['id'];
940 }
941
942 if ($this->getCacheTime(CACHE_TIMES::UUID) < self::MAX_CACHE_TIME) {
943 $this->setCacheTime(self::MAX_CACHE_TIME, CACHE_TIMES::UUID);
944 return $this->getUUID($username, $url);
945 }
946 return false;
947 }
948
949 /**
950 * @param $value
951 *
952 * @return bool|null|string
953 */
954 public function getUUIDFromVar($value) {
955 $uuid = null;
956 $type = InputType::getType($value);
957 if ($type !== null) {
958 if ($type == InputType::USERNAME) {
959 $this->debug('Input is username, fetching UUID.', false);
960 $uuid = $this->getUUID((string)$value);
961 } else if ($type == InputType::UUID) {
962 $this->debug('Input is UUID.', false);
963 $uuid = $value;
964 } else if ($type == InputType::PLAYER_OBJECT) {
965 $this->debug('Input is Player Object.', false);
966 /** @var Player $value */
967 $uuid = $value->getUUID();
968 }
969 if ($uuid === false) return null;
970 }
971 return $uuid;
972 }
973
974 /**
975 * Get the last error and status code associated with the last cURL fetch.
976 * @return null|array
977 */
978 public function getUrlError() {
979 return end($this->getUrlErrors);
980 }
981
982 /**
983 * Get all errors associated to cURL fetches in the current session.
984 * @return array
985 */
986 public function getUrlErrors() {
987 return $this->getUrlErrors;
988 }
989
990}
991
992class Utilities {
993 public static function ensureNoDashesUUID($uuid) {
994 return str_replace("-", "", $uuid);
995 }
996
997 public static function ensureDashedUUID($uuid) {
998 if (strpos($uuid, "-")) {
999 if (strlen($uuid) == 32) {
1000 return $uuid;
1001 }
1002 $uuid = Utilities::ensureNoDashesUUID($uuid);
1003 }
1004 return substr($uuid, 0, 8) . "-" . substr($uuid, 8, 12) . substr($uuid, 12, 16) . "-" . substr($uuid, 16, 20) . "-" . substr($uuid, 20, 32);
1005 }
1006
1007 public static function isUUID($input) {
1008 return is_string($input) && (strlen($input) == 32 || strlen($input) == 28);
1009 }
1010
1011 const COLOR_CHAR = '§';
1012 const MC_COLORS = [
1013 '0' => '#000000',
1014 '1' => '#0000AA',
1015 '2' => '#008000',
1016 '3' => '#00AAAA',
1017 '4' => '#AA0000',
1018 '5' => '#AA00AA',
1019 '6' => '#FFAA00',
1020 '7' => '#AAAAAA',
1021 '8' => '#555555',
1022 '9' => '#5555FF',
1023 'a' => '#3CE63C',
1024 'b' => '#3CE6E6',
1025 'c' => '#FF5555',
1026 'd' => '#FF55FF',
1027 'e' => '#FFFF55',
1028 'f' => '#FFFFFF'
1029 ];
1030
1031 const MC_COLORNAME = [
1032 "BLACK" => '§0',
1033 "DARK_BLUE" => '§1',
1034 "DARK_GREEN" => '§2',
1035 "DARK_AQUA" => '§3',
1036 "DARK_RED" => '§4',
1037 "DARK_PURPLE" => '§5',
1038 "GOLD" => '§6',
1039 "GRAY" => '§7',
1040 "DARK_GRAY" => '§8',
1041 "BLUE" => '§9',
1042 "GREEN" => '§a',
1043 "AQUA" => '§b',
1044 "RED" => '§c',
1045 "LIGHT_PURPLE" => '§d',
1046 "YELLOW" => '§e',
1047 "WHITE" => '§f',
1048 "MAGIC" => '§k',
1049 "BOLD" => '§l',
1050 "STRIKETHROUGH" => '§m',
1051 "UNDERLINE" => '§n',
1052 "ITALIC" => '§o',
1053 "RESET" => '§r'
1054 ];
1055
1056 /**
1057 * Parses MC encoded colors to HTML
1058 * @param $string
1059 * @return string
1060 */
1061 public static function parseColors($string) {
1062 if ($string == null) return null;
1063
1064 if (strpos($string, Utilities::COLOR_CHAR) === false) {
1065 return $string;
1066 }
1067 $d = explode(Utilities::COLOR_CHAR, $string);
1068 $out = '';
1069 foreach ($d as $part) {
1070 if (strlen($part) == 0) continue;
1071 $out = $out . "<span style='color:" . Utilities::MC_COLORS[substr($part, 0, 1)] . "'>" . substr($part, 1) . "</span>";
1072 }
1073 return $out;
1074 }
1075
1076 /**
1077 * Parses MC encoded colors to HTML
1078 * @param $string
1079 * @return string
1080 */
1081 public static function stripColors($string) {
1082 if ($string == null) return null;
1083 if (strpos($string, Utilities::COLOR_CHAR) === false) {
1084 return $string;
1085 }
1086 $d = explode(Utilities::COLOR_CHAR, $string);
1087 $out = '';
1088 foreach ($d as $part) {
1089 $out .= substr($part, 1);
1090 }
1091 return $out;
1092 }
1093
1094}
1095
1096class CACHE_TIMES {
1097 const OVERALL = 'overall';
1098
1099 const PLAYER = 'player';
1100 const UUID = 'uuid';
1101 const UUID_NOT_FOUND = 'uuid_not_found';
1102
1103 const GUILD = 'guild';
1104 const GUILD_NOT_FOUND = 'guild_not_found';
1105
1106 // everything else just uses OVERALL
1107
1108 public static function getAllTypes() {
1109 $obj = new \ReflectionClass ('\HypixelPHP\CACHE_TIMES');
1110 return $obj->getConstants();
1111 }
1112}
1113
1114class API_REQUESTS {
1115 const PLAYER = 'player';
1116
1117 const GUILD = 'guild';
1118 const FIND_GUILD = 'findGuild';
1119
1120 const FRIENDS = 'friends';
1121 const BOOSTERS = 'boosters';
1122 const LEADERBOARDS = 'leaderboards';
1123 const SESSION = 'session';
1124 const KEY = 'key';
1125}
1126
1127class KEYS {
1128 const PLAYER_BY_NAME = 'name';
1129 const PLAYER_BY_UUID = 'uuid';
1130 const PLAYER_BY_UNKNOWN = 'unknown';
1131
1132 public static function getPlayerKeys() {
1133 return [
1134 KEYS::PLAYER_BY_NAME,
1135 KEYS::PLAYER_BY_UUID,
1136 KEYS::PLAYER_BY_UNKNOWN
1137 ];
1138 }
1139
1140 const GUILD_BY_NAME = 'byName'; // via guild name
1141 const GUILD_BY_PLAYER_UUID = 'byUuid'; // via player uuid
1142 const GUILD_BY_PLAYER_NAME = 'byPlayer'; // via player name
1143 const GUILD_BY_PLAYER_UNKNOWN = 'unknown';
1144 const GUILD_BY_PLAYER_OBJECT = 'player'; // via Player Object, gets uuid
1145 const GUILD_BY_ID = 'id'; // via guild id
1146
1147 public static function getGuildKeys() {
1148 return [
1149 KEYS::GUILD_BY_NAME,
1150 KEYS::GUILD_BY_PLAYER_UUID,
1151 KEYS::GUILD_BY_PLAYER_NAME,
1152 KEYS::GUILD_BY_PLAYER_UNKNOWN,
1153 KEYS::GUILD_BY_PLAYER_OBJECT,
1154 KEYS::GUILD_BY_ID
1155 ];
1156 }
1157
1158 const FRIENDS_BY_NAME = 'name'; // via player uuid
1159 const FRIENDS_BY_UUID = 'uuid'; // via player name
1160 const FRIENDS_BY_PLAYER_OBJECT = 'player'; // via Player Object, gets uuid
1161
1162 public static function getFriendsKeys() {
1163 return [
1164 KEYS::FRIENDS_BY_NAME,
1165 KEYS::FRIENDS_BY_UUID,
1166 KEYS::FRIENDS_BY_PLAYER_OBJECT
1167 ];
1168 }
1169
1170 const SESSION_BY_NAME = 'name'; // via player uuid
1171 const SESSION_BY_UUID = 'uuid'; // via player name
1172 const SESSION_BY_PLAYER_OBJECT = 'player'; // via Player Object, gets uuid
1173
1174 public static function getSessionKeys() {
1175 return [
1176 KEYS::SESSION_BY_NAME,
1177 KEYS::SESSION_BY_UUID,
1178 KEYS::SESSION_BY_PLAYER_OBJECT
1179 ];
1180 }
1181}
1182
1183class InputType {
1184 const UUID = 0;
1185 const USERNAME = 1;
1186 const PLAYER_OBJECT = 2;
1187
1188 /**
1189 * Determine input type
1190 * @param $input
1191 *
1192 * @return int|null
1193 */
1194 public static function getType($input) {
1195 if ($input instanceof Player) return InputType::PLAYER_OBJECT;
1196 if (Utilities::isUUID($input)) return InputType::UUID;
1197 if (is_string($input) && strlen($input) <= 16) return InputType::USERNAME;
1198 return null;
1199 }
1200}
1201
1202/**
1203 * Class HypixelObject
1204 *
1205 * @package HypixelPHP
1206 */
1207class HypixelObject {
1208 public $JSONArray;
1209 public $api;
1210
1211 /**
1212 * @param $json
1213 * @param HypixelPHP $api
1214 */
1215 public function __construct($json, HypixelPHP $api) {
1216 $this->JSONArray = $json;
1217 $this->api = $api;
1218 if ($this->JSONArray == null) {
1219 $this->JSONArray = [];
1220 }
1221 if (!array_key_exists('extra', $this->JSONArray) || $this->JSONArray['extra'] == null) {
1222 $this->JSONArray['extra'] = [];
1223 }
1224 if (!array_key_exists('timestamp', $this->JSONArray)) {
1225 $this->JSONArray['timestamp'] = time();
1226 }
1227 }
1228
1229 public function handleNew() {
1230
1231 }
1232
1233 /**
1234 * @return array
1235 */
1236 public function getRaw() {
1237 return $this->JSONArray;
1238 }
1239
1240 public function getRecord() {
1241 return $this->JSONArray['record'];
1242 }
1243
1244 /**
1245 * @param $key
1246 * @param bool $implicit
1247 * @param null $default
1248 *
1249 * @param string $delimiter
1250 * @return array|null
1251 */
1252 public function get($key, $implicit = false, $default = null, $delimiter = '.') {
1253 if (!array_key_exists('record', $this->JSONArray)) return $default;
1254 if (!is_array($this->JSONArray['record'])) return $default;
1255 if (!$implicit) {
1256 return $this->getRecursiveValue($this->JSONArray['record'], $key, $default, $delimiter);
1257 }
1258 return in_array($key, array_keys($this->JSONArray['record'])) ? $this->JSONArray['record'][$key] : $default;
1259 }
1260
1261 public function getRecursiveValue($array, $key, $default = null, $delimiter = '.') {
1262 $return = $array;
1263 foreach (explode($delimiter, $key) as $split) {
1264 $return = isset($return[$split]) ? $return[$split] : $default;
1265 }
1266 return $return ? $return : $default;
1267 }
1268
1269 /**
1270 * @param $key
1271 * @param int $default
1272 * @return int
1273 */
1274 public function getInt($key, $default = 0) {
1275 return $this->get($key, false, $default);
1276 }
1277
1278 /**
1279 * @param $key
1280 * @return array
1281 */
1282 public function getArray($key) {
1283 return $this->get($key, true, []);
1284 }
1285
1286 /**
1287 * @return array|null
1288 */
1289 public function getID() {
1290 return $this->get('_id');
1291 }
1292
1293 /**
1294 * @return bool
1295 */
1296 public function isCached() {
1297 return abs(time() - $this->getCachedTime()) > 1;
1298 }
1299
1300 /**
1301 * @param int $extra
1302 * @return bool
1303 */
1304 public function isCacheExpired($extra = -1) {
1305 return time() - ($extra == -1 ? $this->api->getCacheTime(null, true) : $extra) > $this->getCachedTime();
1306 }
1307
1308 public function getCachedTime() {
1309 return $this->JSONArray['timestamp'];
1310 }
1311
1312 /**
1313 * @param $input
1314 */
1315 public function setExtra($input) {
1316 $anyChange = false;
1317 foreach ($input as $key => $val) {
1318 if (array_key_exists($key, $this->JSONArray['extra'])) {
1319 if ($val == null) {
1320 unset($this->JSONArray['extra'][$key]);
1321 $anyChange = true;
1322 continue;
1323 } else if ($this->JSONArray['extra'][$key] == $val) {
1324 continue;
1325 }
1326 }
1327 $this->api->debug('Extra \'' . $key . '\' set to ' . json_encode($val));
1328 $this->JSONArray['extra'][$key] = $val;
1329 $anyChange = true;
1330 }
1331 if ($anyChange) {
1332 $this->saveCache();
1333 }
1334 }
1335
1336 public function getExtra($key = null, $implicit = false, $default = null, $delimiter = '.') {
1337 if ($key != null) {
1338 if (!array_key_exists('extra', $this->JSONArray)) return $default;
1339 if (!is_array($this->JSONArray['extra'])) return $default;
1340 if (!$implicit) {
1341 return $this->getRecursiveValue($this->JSONArray['extra'], $key, $default, $delimiter);
1342 }
1343 return in_array($key, array_keys($this->JSONArray['extra'])) ? $this->JSONArray['extra'][$key] : $default;
1344 }
1345 return $this->JSONArray['extra'];
1346 }
1347
1348 public function saveCache() {
1349 if (array_key_exists('filename', $this->getExtra())) {
1350 $this->api->debug('Saving cache file', false);
1351 $this->api->setCache($this->JSONArray['extra']['filename'], $this);
1352 }
1353 }
1354
1355 public function isValid() {
1356 return true;
1357 }
1358}
1359
1360/**
1361 * Class KeyInfo
1362 *
1363 * @package HypixelPHP
1364 */
1365class KeyInfo extends HypixelObject {
1366
1367 public function getKey() {
1368 return $this->get('key');
1369 }
1370
1371}
1372
1373/**
1374 * Class Player
1375 *
1376 * @package HypixelPHP
1377 */
1378class Player extends HypixelObject {
1379 private $guild, $friends, $session;
1380
1381 public function handleNew() {
1382 $this->getAchievementPoints(true);
1383 }
1384
1385 /**
1386 * get Session of Player
1387 * @return Session|null
1388 */
1389 public function getSession() {
1390 if ($this->session == null) {
1391 $this->session = $this->api->getSession([KEYS::SESSION_BY_PLAYER_OBJECT => $this]);
1392 }
1393 return $this->session;
1394 }
1395
1396 /**
1397 * get Friends of Player
1398 * @return FriendsList|null
1399 */
1400 public function getFriends() {
1401 if ($this->friends == null) {
1402 $this->friends = $this->api->getFriends([KEYS::FRIENDS_BY_PLAYER_OBJECT => $this]);
1403 }
1404 return $this->friends;
1405 }
1406
1407 /**
1408 * get Boosters of Player
1409 * @return Booster[]
1410 */
1411 public function getBoosters() {
1412 $BOOSTERS = $this->api->getBoosters();
1413 if ($BOOSTERS != null) {
1414 return $BOOSTERS->getBoosters($this->getUUID());
1415 }
1416 return [];
1417 }
1418
1419 /**
1420 * get Guild of Player
1421 * @return Guild|null
1422 */
1423 public function getGuild() {
1424 if ($this->guild == null) {
1425 $this->guild = $this->api->getGuild([KEYS::GUILD_BY_PLAYER_OBJECT => $this]);
1426 }
1427 return $this->guild;
1428 }
1429
1430 /**
1431 * @return string
1432 */
1433 public function getName() {
1434 if ($this->get('displayname', true) != null) {
1435 return $this->get('displayname', true);
1436 } else {
1437 $aliases = $this->get('knownAliases', true, []);
1438 if (sizeof($aliases) == 0) {
1439 return $this->get('playername', true);
1440 }
1441 return end($aliases);
1442 }
1443 }
1444
1445 /**
1446 * get Formatted name of Player
1447 *
1448 * @param bool $prefix
1449 * @param bool $guildTag
1450 * @param bool $parseColors
1451 * @return string
1452 */
1453 public function getFormattedName($prefix = true, $guildTag = false, $parseColors = true) {
1454 $rank = $this->getRank(false);
1455 $out = $rank->getColor() . $this->getName();
1456 if ($prefix) {
1457 $out = ($this->getPrefix() != null ? $this->getPrefix() : $rank->getPrefix($this)) . ' ' . $this->getName();
1458 }
1459 if ($guildTag) {
1460 $out .= $this->getGuildTag() != null ? ' §7[' . $this->getGuildTag() . ']' : '';
1461 }
1462 if ($parseColors) {
1463 $outStr = Utilities::parseColors($out);
1464 } else {
1465 $outStr = Utilities::stripColors($out);
1466 }
1467 return $outStr;
1468 }
1469
1470 public function getRawFormattedName($prefix = true, $guildTag = false) {
1471 $rank = $this->getRank(false);
1472 $out = $rank->getColor() . $this->getName();
1473 if ($prefix) {
1474 $out = ($this->getPrefix() != null ? $this->getPrefix() : $rank->getPrefix($this)) . ' ' . $this->getName();
1475 }
1476 if ($guildTag) {
1477 $out .= $this->getGuildTag() != null ? ' §7[' . $this->getGuildTag() . ']' : '';
1478 }
1479 return $out;
1480 }
1481
1482 /**
1483 * Get player Guild Tag, null if no guild/tag
1484 *
1485 * @return string|null
1486 */
1487 public function getGuildTag() {
1488 $guild = $this->getGuild();
1489 if ($guild != null) {
1490 if ($guild->canTag()) {
1491 return $guild->getTag();
1492 }
1493 }
1494 return null;
1495 }
1496
1497 /**
1498 * Get player UUID
1499 *
1500 * @return string
1501 */
1502 public function getUUID() {
1503 return $this->get('uuid');
1504 }
1505
1506 /**
1507 * Get the Stats object for the player
1508 *
1509 * @return Stats
1510 */
1511 public function getStats() {
1512 return new Stats($this->getArray('stats'), $this->api);
1513 }
1514
1515 /**
1516 * Check if player has a PreEULA rank
1517 *
1518 * @return bool
1519 */
1520 public function isPreEULA() {
1521 return $this->get('packageRank', true, null) != null;
1522 }
1523
1524 /**
1525 * Get Level of player
1526 *
1527 * @param bool $zeroBased
1528 * @return int
1529 */
1530 public function getLevel($zeroBased = false) {
1531 return $this->getInt('networkLevel') + (!$zeroBased ? 1 : 0);
1532 }
1533
1534 /**
1535 * @return string|null
1536 */
1537 public function getPrefix() {
1538 return $this->get('prefix', false, null);
1539 }
1540
1541 /**
1542 * @return bool
1543 */
1544 public function isStaff() {
1545 $rank = $this->get('rank', true, 'NORMAL');
1546 if ($rank == 'NORMAL') {
1547 return false;
1548 }
1549 return true;
1550 }
1551
1552 /**
1553 * get Current Multiplier, accounts for level and Pre-EULA rank
1554 * @return int
1555 */
1556 public function getMultiplier() {
1557 if ($this->getRank(false)->getId() == RankTypes::YOUTUBER) {
1558 return RankTypes::fromID(RankTypes::YOUTUBER)->getMultiplier();
1559 }
1560 $pre = $this->getRank(true, ['packageRank']); // only old rank matters
1561 $eulaMultiplier = $pre != null ? $pre->getMultiplier() : 1;
1562 $levelMultiplier = min(floor($this->getLevel() / 25) + 1, 6);
1563 return ($eulaMultiplier > $levelMultiplier) ? $eulaMultiplier : $levelMultiplier;
1564 }
1565
1566 /**
1567 * get Rank
1568 * @param bool $package
1569 * @param array $rankKeys
1570 * @return Rank
1571 */
1572 public function getRank($package = true, $rankKeys = ['newPackageRank', 'packageRank']) {
1573 $returnRank = null;
1574 if ($package) {
1575 $returnRank = null;
1576 foreach ($rankKeys as $key) {
1577 $rank = RankTypes::fromName($this->get($key));
1578 if ($rank != null) {
1579 if ($returnRank == null) $returnRank = $rank;
1580 /** @var $rank \HypixelPHP\Rank */
1581 /** @var $returnRank \HypixelPHP\Rank */
1582 if ($rank->getId() > $returnRank->getId()) {
1583 $returnRank = $rank;
1584 }
1585 }
1586 }
1587 } else {
1588 if (!$this->isStaff()) return $this->getRank(true);
1589 $returnRank = RankTypes::fromName($this->get('rank'));
1590 }
1591 if ($returnRank == null) {
1592 $returnRank = RankTypes::fromID(RankTypes::NON_DONOR);
1593 }
1594 return $returnRank;
1595 }
1596
1597 /**
1598 * get Player achievement points
1599 * @param bool $force_update
1600 * @return int
1601 */
1602 public function getAchievementPoints($force_update = false) {
1603 if (!$force_update) {
1604 return isset($this->getExtra()['achievementPoints']) ? $this->getExtra()['achievementPoints'] : 0;
1605 }
1606
1607 $isLogging = $this->api->getOptions()['logging'];
1608 $this->api->set(['logging' => false]);
1609 $achievements = $this->api->getFileContent($this->api->getOptions()['achievements_file']);
1610 if ($achievements == null) {
1611 return 0;
1612 }
1613 $achievements = json_decode($achievements, true)['achievements'];
1614 $total = 0;
1615 $oneTime = $this->get('achievementsOneTime', false, []);
1616 $this->api->debug('Starting OneTime Achievements');
1617 foreach ($oneTime as $dbName) {
1618 $game = strtolower(substr($dbName, 0, strpos($dbName, "_")));
1619 $dbName = strtoupper(substr($dbName, strpos($dbName, "_") + 1));
1620 if (!in_array($game, array_keys($achievements))) {
1621 continue;
1622 }
1623 $this->api->debug('Achievement: ' . strtoupper(substr($dbName, strpos($dbName, "_"))));
1624 if (in_array($dbName, array_keys($achievements[$game]['one_time']))) {
1625 $this->api->debug('Achievement: ' . $dbName . ' - ' . $achievements[$game]['one_time'][$dbName]['points']);
1626 $total += $achievements[$game]['one_time'][$dbName]['points'];
1627 }
1628 }
1629 $tiered = $this->get('achievements', false, []);
1630 $this->api->debug('Starting Tiered Achievements');
1631 foreach ($tiered as $dbName => $value) {
1632 $game = strtolower(substr($dbName, 0, strpos($dbName, "_")));
1633 $dbName = strtoupper(substr($dbName, strpos($dbName, "_") + 1));
1634 if (!in_array($game, array_keys($achievements))) {
1635 continue;
1636 }
1637 $this->api->debug('Achievement: ' . $dbName);
1638 if (in_array($dbName, array_keys($achievements[$game]['tiered']))) {
1639 $tierTotal = 0;
1640 foreach ($achievements[$game]['tiered'][$dbName]['tiers'] as $tier) {
1641 if ($value >= $tier['amount']) {
1642 $this->api->debug('Tier: ' . $tier['amount'] . ' - ' . $tier['points']);
1643 $tierTotal += $tier['points'];
1644 }
1645 }
1646 $total += $tierTotal;
1647 }
1648 }
1649 $this->api->set(['logging' => $isLogging]);
1650 $this->setExtra(['achievementPoints' => $total, 'achievementTimestamp' => time()]);
1651 return $total;
1652 }
1653
1654 /**
1655 * @param $key
1656 * @param bool $implicit
1657 * @param null $default
1658 *
1659 * @param string $delimiter
1660 * @return array|float|int|mixed|null
1661 */
1662 public function get($key, $implicit = false, $default = null, $delimiter = '.') {
1663 return parent::get($key, $implicit, $default, $delimiter);
1664 }
1665
1666 public function isValid() {
1667 return is_array($this->JSONArray['record']) && sizeof($this->JSONArray['record']) > 1;
1668 }
1669}
1670
1671class RankTypes {
1672 const NON_DONOR = 1;
1673 const VIP = 2;
1674 const VIP_PLUS = 3;
1675 const MVP = 4;
1676 const MVP_PLUS = 5;
1677
1678 const ADMIN = 100;
1679 const MODERATOR = 90;
1680 const HELPER = 80;
1681 const JR_HELPER = 70;
1682 const YOUTUBER = 60;
1683
1684 /**
1685 * @param $id
1686 *
1687 * @return Rank|null
1688 */
1689 public static function fromID($id) {
1690 switch ($id) {
1691 case RankTypes::NON_DONOR:
1692 return new Rank(RankTypes::NON_DONOR, 'NON_DONOR', [
1693 'prefix' => '§7',
1694 'color' => '§7'
1695 ]);
1696 case RankTypes::VIP:
1697 return new Rank(RankTypes::VIP, 'VIP', [
1698 'prefix' => '§a[VIP]',
1699 'color' => '§a',
1700 'eulaMultiplier' => 2
1701 ]);
1702 case RankTypes::VIP_PLUS:
1703 return new Rank(RankTypes::VIP_PLUS, 'VIP_PLUS', [
1704 'prefix' => '§a[VIP§6+§a]',
1705 'color' => '§a',
1706 'eulaMultiplier' => 3
1707 ]);
1708 case RankTypes::MVP:
1709 return new Rank(RankTypes::MVP, 'MVP', [
1710 'prefix' => '§b[MVP]',
1711 'color' => '§b',
1712 'eulaMultiplier' => 4
1713 ]);
1714 case RankTypes::MVP_PLUS:
1715 return new Rank(RankTypes::MVP_PLUS, 'MVP_PLUS', [
1716 'prefix' => '§b[MVP§c+§b]',
1717 'color' => '§b',
1718 'eulaMultiplier' => 5
1719 ]);
1720 case RankTypes::YOUTUBER:
1721 return new Rank(RankTypes::YOUTUBER, 'YOUTUBER', [
1722 'prefix' => '§c[§fYOUTUBE§c]',
1723 'color' => '§6',
1724 'eulaMultiplier' => 7
1725 ]);
1726 case RankTypes::JR_HELPER:
1727 return new Rank(RankTypes::JR_HELPER, 'JR_HELPER', [
1728 'prefix' => '§9[JR HELPER]',
1729 'color' => '§9'
1730 ], true);
1731 case RankTypes::HELPER:
1732 return new Rank(RankTypes::HELPER, 'HELPER', [
1733 'prefix' => '§9[HELPER]',
1734 'color' => '§9'
1735 ], true);
1736 case RankTypes::MODERATOR:
1737 return new Rank(RankTypes::MODERATOR, 'MODERATOR', [
1738 'prefix' => '§2[MOD]',
1739 'color' => '§2'
1740 ], true);
1741 case RankTypes::ADMIN:
1742 return new Rank(RankTypes::ADMIN, 'ADMIN', [
1743 'prefix' => '§c[ADMIN]',
1744 'color' => '§c'
1745 ], true);
1746 default:
1747 return null;
1748 }
1749 }
1750
1751 public static function fromName($db) {
1752 foreach (RankTypes::getAllTypes() as $id) {
1753 $rank = RankTypes::fromID($id);
1754 if ($rank != null) {
1755 if ($rank->getName() == $db) {
1756 return $rank;
1757 }
1758 }
1759 }
1760 return null;
1761 }
1762
1763 /**
1764 * @return array
1765 */
1766 public static function getAllTypes() {
1767 $obj = new \ReflectionClass ('\HypixelPHP\RankTypes');
1768 return $obj->getConstants();
1769 }
1770}
1771
1772class Rank {
1773 private $name, $id, $options, $staff;
1774
1775 /**
1776 * @param $id
1777 * @param $name
1778 * @param $options
1779 * @param bool $staff
1780 */
1781 public function __construct($id, $name, $options, $staff = false) {
1782 $this->id = $id;
1783 $this->name = $name;
1784 $this->options = $options;
1785 $this->staff = $staff;
1786 }
1787
1788 public function getId() {
1789 return $this->id;
1790 }
1791
1792 public function getName() {
1793 return $this->name;
1794 }
1795
1796 public function getCleanName() {
1797 if ($this->name == 'NON_DONOR' || $this->name == 'NONE') return 'DEFAULT';
1798 return str_replace("_", ' ', str_replace('_PLUS', '+', $this->name));
1799 }
1800
1801 public function getOptions() {
1802 return $this->options;
1803 }
1804
1805 public function isStaff() {
1806 return $this->staff;
1807 }
1808
1809 public function getPrefix(Player $player) {
1810 if ($this->name == 'MVP_PLUS' && $player->get("rankPlusColor") != null) {
1811 return '§b[MVP' . Utilities::MC_COLORNAME[$player->get("rankPlusColor")] . '+§b]';
1812 }
1813 return isset($this->options['prefix']) ? $this->options['prefix'] : null;
1814 }
1815
1816 public function getColor() {
1817 return isset($this->options['color']) ? $this->options['color'] : null;
1818 }
1819
1820 public function getMultiplier() {
1821 return isset($this->options['eulaMultiplier']) ? $this->options['eulaMultiplier'] : 1;
1822 }
1823
1824 public function __toString() {
1825 return json_encode([$this->name => $this->options]);
1826 }
1827}
1828
1829/**
1830 * Class Stats
1831 *
1832 * @package HypixelPHP
1833 */
1834class Stats extends HypixelObject {
1835 /**
1836 * @param $json
1837 * @param HypixelPHP $api
1838 */
1839 public function __construct($json, HypixelPHP $api) {
1840 parent::__construct(['record' => $json], $api);
1841 }
1842
1843 /**
1844 * @param $game
1845 *
1846 * @return GameStats
1847 */
1848 public function getGame($game) {
1849 $game = $this->get($game, true, null);
1850 return new GameStats($game, $this->api);
1851 }
1852
1853 public function getGameFromID($id) {
1854 $gameType = GameTypes::fromID($id);
1855 if ($gameType != null) {
1856 return $this->getGame($gameType->getDb());
1857 }
1858 return null;
1859 }
1860}
1861
1862/**
1863 * Class GameStats
1864 *
1865 * @package HypixelPHP
1866 */
1867class GameStats extends HypixelObject {
1868 /**
1869 * @param $json
1870 * @param HypixelPHP $api
1871 */
1872 public function __construct($json, HypixelPHP $api) {
1873 parent::__construct(['record' => $json], $api);
1874 }
1875
1876 /**
1877 * @return array|null
1878 */
1879 public function getPackages() {
1880 return $this->getArray('packages');
1881 }
1882
1883 /**
1884 * @param $package
1885 * @return bool
1886 */
1887 public function hasPackage($package) {
1888 return in_array($package, $this->getArray('packages'));
1889 }
1890
1891 /**
1892 * @return int
1893 */
1894 public function getCoins() {
1895 return $this->getInt('coins');
1896 }
1897
1898 /**
1899 * @param $stat
1900 * @return array|null|string|int
1901 */
1902 public function getWeeklyStat($stat) {
1903 return $this->get($stat . '_' . TimeUtils::getWeeklyOscillation());
1904 }
1905
1906 /**
1907 * @param $stat
1908 * @return array|null|string|int
1909 */
1910 public function getMonthlyStat($stat) {
1911 return $this->get($stat . '_' . TimeUtils::getMonthlyOscillation());
1912 }
1913}
1914
1915/**
1916 * Class Session
1917 *
1918 * @package HypixelPHP
1919 */
1920class Session extends HypixelObject {
1921 /**
1922 * @return array
1923 */
1924 public function getPlayers() {
1925 return $this->getArray('players');
1926 }
1927
1928 /**
1929 * @return array|null
1930 */
1931 public function getGameType() {
1932 return $this->get('gameType', true);
1933 }
1934
1935 /**
1936 * @return string
1937 */
1938 public function getServer() {
1939 return $this->get('server', true);
1940 }
1941
1942 public function getUUID() {
1943 return $this->get('uuid', true);
1944 }
1945
1946 public function getPlayer() {
1947 $UUID = $this->getUUID();
1948 if ($UUID != null) {
1949 return $this->api->getPlayer([KEYS::PLAYER_BY_UUID => $UUID]);
1950 }
1951 return null;
1952 }
1953}
1954
1955/**
1956 * Class FriendsList
1957 *
1958 * @package HypixelPHP
1959 */
1960class FriendsList extends HypixelObject {
1961 private $LIST;
1962
1963 public function getUUID() {
1964 return $this->get("uuid");
1965 }
1966
1967 /**
1968 * @return Friend[]
1969 */
1970 public function getList() {
1971 if ($this->LIST == null) {
1972 $this->LIST = [];
1973 foreach ($this->getRawList() as $f) {
1974 array_push($this->LIST, new Friend($f, $this->api, $this->getUUID()));
1975 }
1976 }
1977 return $this->LIST;
1978 }
1979
1980 public function getRawList() {
1981 return $this->get('list', true, []);
1982 }
1983
1984 public function getPlayer() {
1985 if (isset($this->JSONArray['uuid'])) {
1986 return $this->api->getPlayer([KEYS::PLAYER_BY_UUID => $this->getUUID()]);
1987 }
1988 return null;
1989 }
1990}
1991
1992class Friend extends HypixelObject {
1993 public $UUID_PLAYER;
1994
1995 public function __construct($FRIEND_OBJ, $API, $UUID_PLAYER) {
1996 parent::__construct($FRIEND_OBJ, $API);
1997 $this->UUID_PLAYER = $UUID_PLAYER;
1998 }
1999
2000 /**
2001 * Returns whether or not the Player
2002 * received the friend request
2003 *
2004 * @return bool
2005 */
2006 public function wasReceiver() {
2007 return $this->JSONArray['uuidReceiver'] == $this->UUID_PLAYER;
2008 }
2009
2010 public function wasSender() {
2011 return !$this->wasReceiver();
2012 }
2013
2014 public function getOtherPlayer() {
2015 if ($this->wasReceiver()) {
2016 return $this->api->getPlayer([KEYS::PLAYER_BY_UUID => $this->JSONArray['uuidSender']]);
2017 } else {
2018 return $this->api->getPlayer([KEYS::PLAYER_BY_UUID => $this->JSONArray['uuidReceiver']]);
2019 }
2020 }
2021
2022 public function getSince() {
2023 return $this->JSONArray['started'];
2024 }
2025}
2026
2027/**
2028 * Class Guild
2029 *
2030 * @package HypixelPHP
2031 */
2032class Guild extends HypixelObject {
2033 /**
2034 * @return string
2035 */
2036 public function getName() {
2037 return $this->get('name', true, '');
2038 }
2039
2040 /**
2041 * @return bool
2042 */
2043 public function canTag() {
2044 return $this->get('canTag', true, false);
2045 }
2046
2047 /**
2048 * @return string
2049 */
2050 public function getTag() {
2051 return Utilities::parseColors($this->get('tag', true, ''));
2052 }
2053
2054 /**
2055 * @return int
2056 */
2057 public function getCoins() {
2058 return $this->getInt('coins');
2059 }
2060
2061 /**
2062 * @return MemberList
2063 */
2064 public function getMemberList() {
2065 return new MemberList($this->get('members'), $this->api);
2066 }
2067
2068 /**
2069 * @return int
2070 */
2071 public function getMaxMembers() {
2072 $total = 25;
2073 $level = $this->get('memberSizeLevel', true, -1);
2074 if ($level >= 0) {
2075 $total += 5 * $level;
2076 }
2077 return $total;
2078 }
2079
2080 /**
2081 * @return int
2082 */
2083 public function getMemberCount() {
2084 return $this->getMemberList()->getMemberCount();
2085 }
2086
2087 /**
2088 * get coin history of Guild or Player in Guild
2089 * @return array
2090 */
2091 public function getGuildCoinHistory() {
2092 $coinHistory = [];
2093 $record = $this->getRecord();
2094 foreach ($record as $key => $val) {
2095 if (strpos($key, 'dailyCoins') !== false) {
2096 $EXPLOSION = explode('-', $key);
2097 $coinHistory[$EXPLOSION[1] . '-' . ($EXPLOSION[2] + 1) . '-' . $EXPLOSION[3]] = $val;
2098 }
2099 }
2100
2101 $sortHistory = [];
2102 foreach ($coinHistory as $DATE => $AMOUNT) {
2103 array_push($sortHistory, [$DATE, $AMOUNT]);
2104 }
2105
2106 usort($sortHistory, function ($a, $b) {
2107 $ad = new DateTime($a[0]);
2108 $bd = new DateTime($b[0]);
2109
2110 if ($ad == $bd) {
2111 return 0;
2112 }
2113
2114 return $ad < $bd ? 0 : 1;
2115 });
2116
2117 return $sortHistory;
2118 }
2119}
2120
2121/**
2122 * Class MemberList
2123 *
2124 * @package HypixelPHP
2125 */
2126class MemberList extends HypixelObject {
2127 private $list;
2128 private $count;
2129
2130 /**
2131 * @param $json
2132 * @param HypixelPHP $api
2133 */
2134 public function __construct($json, $api) {
2135 parent::__construct(['record' => $json], $api);
2136
2137 $list = ["GUILDMASTER" => [], "OFFICER" => [], "MEMBER" => []];
2138 $this->count = sizeof($json);
2139 foreach ($json as $player) {
2140 $rank = $player['rank'];
2141 if (!in_array($rank, array_keys($list))) {
2142 $list[$rank] = [];
2143 }
2144
2145 $coinHistory = [];
2146 foreach ($player as $key => $val) {
2147 if (strpos($key, 'dailyCoins') !== false) {
2148 $EXPLOSION = explode('-', $key);
2149 $coinHistory[$EXPLOSION[1] . '-' . ($EXPLOSION[2] + 1) . '-' . $EXPLOSION[3]] = $val;
2150 unset($player[$key]);
2151 }
2152 }
2153 $player['coinHistory'] = $coinHistory;
2154
2155 array_push($list[$rank], new GuildMember($player, $api));
2156 }
2157 $this->list = $list;
2158 }
2159
2160 /**
2161 * @return array[string]GuildMember
2162 */
2163 public function getList() {
2164 return $this->list;
2165 }
2166
2167 /**
2168 * @return int
2169 */
2170 public function getMemberCount() {
2171 return $this->count;
2172 }
2173}
2174
2175/**
2176 * Class GuildMember
2177 *
2178 * @package HypixelPHP
2179 */
2180class GuildMember {
2181 private $coinHistory;
2182 private $uuid, $name;
2183 private $joined;
2184 private $api;
2185
2186 /**
2187 * @param $member
2188 * @param HypixelPHP $api
2189 */
2190 public function __construct($member, $api) {
2191 if (isset($member['coinHistory'])) {
2192 $this->coinHistory = $member['coinHistory'];
2193 }
2194 if (isset($member['uuid'])) {
2195 $this->uuid = $member['uuid'];
2196 }
2197 if (isset($member['name'])) {
2198 $this->name = $member['name'];
2199 }
2200 if (isset($member['joined'])) {
2201 $this->joined = $member['joined'];
2202 }
2203 $this->api = $api;
2204 }
2205
2206 /**
2207 * @return Player
2208 */
2209 public function getPlayer() {
2210 if (isset($this->uuid)) {
2211 return $this->api->getPlayer([KEYS::PLAYER_BY_UUID => $this->uuid]);
2212 } else if (isset($this->name)) {
2213 return $this->api->getPlayer([KEYS::PLAYER_BY_NAME => $this->name]);
2214 }
2215 return null;
2216 }
2217
2218 /**
2219 * @return array
2220 */
2221 public function getCoinHistory() {
2222 return $this->coinHistory;
2223 }
2224
2225 /**
2226 * @return int
2227 */
2228 public function getJoinTimeStamp() {
2229 return $this->joined;
2230 }
2231
2232 /**
2233 * @return mixed
2234 */
2235 public function getUuid() {
2236 return $this->uuid;
2237 }
2238}
2239
2240/**
2241 * Class GameTypes
2242 *
2243 * @package HypixelPHP
2244 */
2245class GameTypes {
2246 const QUAKE = 2;
2247 const WALLS = 3;
2248 const PAINTBALL = 4;
2249 const HUNGERGAMES = 5;
2250 const TNTGAMES = 6;
2251 const VAMPIREZ = 7;
2252 const WALLS3 = 13;
2253 const ARCADE = 14;
2254 const ARENA = 17;
2255 const UHC = 20;
2256 const MCGO = 21;
2257 const BATTLEGROUND = 23;
2258 const SUPER_SMASH = 24;
2259 const GINGERBREAD = 25;
2260 const HOUSING = 26;
2261 const SKYWARS = 51;
2262 const TRUE_COMBAT = 52;
2263 const SPEED_UHC = 54;
2264 const SKYCLASH = 55;
2265 const BEDWARS = 58;
2266 const DUELS = 61;
2267 const SKYBLOCK = 63;
2268 const ACH = 696969;
2269
2270 /**
2271 * @param $id
2272 *
2273 * @return GameType|null
2274 */
2275 public static function fromID($id) {
2276 switch ($id) {
2277 case GameTypes::QUAKE:
2278 return new GameType('Quake', 'Quake', 'Quake', GameTypes::QUAKE);
2279 case GameTypes::WALLS:
2280 return new GameType('Walls', 'Walls', 'Walls', GameTypes::WALLS);
2281 case GameTypes::PAINTBALL:
2282 return new GameType('Paintball', 'Paintball', 'Paintball', GameTypes::PAINTBALL);
2283 case GameTypes::HUNGERGAMES:
2284 return new GameType('HungerGames', 'Blitz Survival Games', 'BSG', GameTypes::HUNGERGAMES);
2285 case GameTypes::TNTGAMES:
2286 return new GameType('TNTGames', 'TNT Games', 'TNT Games', GameTypes::TNTGAMES);
2287 case GameTypes::VAMPIREZ:
2288 return new GameType('VampireZ', 'VampireZ', 'VampireZ', GameTypes::VAMPIREZ);
2289 case GameTypes::WALLS3:
2290 return new GameType('Walls3', 'Mega Walls', 'MW', GameTypes::WALLS3);
2291 case GameTypes::ARCADE:
2292 return new GameType('Arcade', 'Arcade', 'Arcade', GameTypes::ARCADE);
2293 case GameTypes::ARENA:
2294 return new GameType('Arena', 'Arena Brawl', 'Arena', GameTypes::ARENA);
2295 case GameTypes::UHC:
2296 return new GameType('UHC', 'UHC Champions', 'UHC', GameTypes::UHC);
2297 case GameTypes::MCGO:
2298 return new GameType('MCGO', 'Cops and Crims', 'CaC', GameTypes::MCGO);
2299 case GameTypes::BATTLEGROUND:
2300 return new GameType('Battleground', 'Warlords', 'Warlords', GameTypes::BATTLEGROUND);
2301 case GameTypes::SUPER_SMASH:
2302 return new GameType('SuperSmash', 'Smash Heroes', 'Smash Heroes', GameTypes::SUPER_SMASH);
2303 case GameTypes::GINGERBREAD:
2304 return new GameType('GingerBread', 'Turbo Kart Racers', 'TKR', GameTypes::GINGERBREAD);
2305 case GameTypes::HOUSING:
2306 return new GameType('Housing', 'Housing', 'Housing', GameTypes::HOUSING, false);
2307 case GameTypes::SKYWARS:
2308 return new GameType('SkyWars', 'SkyWars', 'SkyWars', GameTypes::SKYWARS);
2309 case GameTypes::BEDWARS:
2310 return new GameType('Bedwars', 'Bedwars', 'Bedwars', GameTypes::BEDWARS);
2311 case GameTypes::TRUE_COMBAT:
2312 return new GameType('TrueCombat', 'Crazy Walls', 'Crazy Walls', GameTypes::TRUE_COMBAT);
2313 case GameTypes::SPEED_UHC:
2314 return new GameType('SpeedUHC', 'Speed UHC', 'Speed UHC', GameTypes::SPEED_UHC);
2315 case GameTypes::SKYCLASH:
2316 return new GameType('SkyClash', 'SkyClash', 'SkyClash', GameTypes::SKYCLASH);
2317 case GameTypes::SKYBLOCK:
2318 return new GameType('SkyBlock', 'SkyBlock', 'SkyBlock', GameTypes::SKYBLOCK);
2319 case GameTypes::DUELS:
2320 return new GameType('Duels', 'Duels', 'Duels', GameTypes::DUELS);
2321 case GameTypes::ACH:
2322 return new GameType('achievements', 'achievements', 'achievements', GameTypes::ACH);
2323 default:
2324 return null;
2325 }
2326 }
2327
2328 public static function fromDbName($db) {
2329 foreach (GameTypes::getAllTypes() as $id) {
2330 $gameType = GameTypes::fromID($id);
2331 if ($gameType != null) {
2332 if ($gameType->getDb() == $db) {
2333 return $gameType;
2334 }
2335 }
2336 }
2337 return null;
2338 }
2339
2340 /**
2341 * @return array
2342 */
2343 public static function getAllTypes() {
2344 $obj = new \ReflectionClass ('\HypixelPHP\GameTypes');
2345 return $obj->getConstants();
2346 }
2347}
2348
2349/**
2350 * Class GameType
2351 *
2352 * @package HypixelPHP
2353 */
2354class GameType {
2355 private $db, $name, $short, $id, $boosters;
2356
2357 /**
2358 * @param $db
2359 * @param $name
2360 * @param $short
2361 * @param $id
2362 * @param bool $boosters
2363 */
2364 public function __construct($db, $name, $short, $id, $boosters = true) {
2365 $this->db = $db;
2366 $this->name = $name;
2367 $this->short = $short;
2368 $this->id = $id;
2369 $this->boosters = $boosters;
2370 }
2371
2372 public function getDb() {
2373 return $this->db;
2374 }
2375
2376 public function getName() {
2377 return $this->name;
2378 }
2379
2380 public function getShort() {
2381 return $this->short;
2382 }
2383
2384 public function getId() {
2385 return $this->id;
2386 }
2387
2388 public function hasBoosters() {
2389 return $this->boosters;
2390 }
2391
2392 public function toArray() {
2393 return [
2394 'id' => $this->id,
2395 'name' => $this->name,
2396 'short' => $this->short,
2397 'db' => $this->db
2398 ];
2399 }
2400}
2401
2402/**
2403 * Class Boosters
2404 *
2405 * @package HypixelPHP
2406 */
2407class Boosters extends HypixelObject {
2408 /**
2409 * @param int $gameType
2410 * @param int $max
2411 *
2412 * @return array
2413 */
2414 public function getQueue($gameType, $max = 999) {
2415 $return = [
2416 'boosters' => [],
2417 'total' => 0
2418 ];
2419 foreach ($this->JSONArray['record'] as $boosterInfo) {
2420 $booster = new Booster($boosterInfo, $this->api);
2421 if ($booster->getGameTypeID() == $gameType) {
2422 if ($return['total'] < $max) {
2423 array_push($return['boosters'], $booster);
2424 }
2425 $return['total']++;
2426 }
2427 }
2428 return $return;
2429 }
2430
2431 /**
2432 * @param $player
2433 * @return Booster[]
2434 */
2435 public function getBoosters($player) {
2436 $boosters = [];
2437 foreach ($this->JSONArray['record'] as $boosterInfo) {
2438 if (isset($boosterInfo['purchaserUuid'])) {
2439 if ($boosterInfo['purchaserUuid'] == $player) {
2440 $booster = new Booster($boosterInfo, $this->api);
2441 array_push($boosters, $booster);
2442 }
2443 }
2444 }
2445 return $boosters;
2446 }
2447}
2448
2449/**
2450 * Class Booster
2451 *
2452 * @package HypixelPHP
2453 */
2454class Booster {
2455 private $info;
2456 private $api;
2457
2458 /**
2459 * @param $info
2460 * @param HypixelPHP $api
2461 */
2462 public function __construct($info, HypixelPHP $api) {
2463 $this->info = $info;
2464 $this->api = $api;
2465 }
2466
2467 /**
2468 * @return Player
2469 */
2470 public function getOwner() {
2471 $oldTime = $this->api->getCacheTime();
2472 $this->api->setCacheTime(HypixelPHP::MAX_CACHE_TIME - 1);
2473 $player = $this->api->getPlayer([
2474 KEYS::PLAYER_BY_NAME => (isset($this->info['purchaser']) ? $this->info['purchaser'] : null),
2475 KEYS::PLAYER_BY_UUID => (isset($this->info['purchaserUuid']) ? $this->info['purchaserUuid'] : null)
2476 ]);
2477 $this->api->setCacheTime($oldTime);
2478 if ($player != null) {
2479 return $player;
2480 }
2481 return null;
2482 }
2483
2484 public function getOwnerUUID() {
2485 return isset($this->info['purchaserUuid']) ? $this->info['purchaserUuid'] : null;
2486 }
2487
2488 /**
2489 * @return int
2490 */
2491 public function getGameTypeID() {
2492 return $this->info['gameType'];
2493 }
2494
2495 /**
2496 * @return GameType|null
2497 */
2498 public function getGameType() {
2499 return GameTypes::fromID($this->info['gameType']);
2500 }
2501
2502 /**
2503 * @return bool
2504 */
2505 public function isActive() {
2506 return $this->getLength() != $this->getLength(true);
2507 }
2508
2509 /**
2510 * @param bool $original
2511 * @return int
2512 */
2513 public function getLength($original = false) {
2514 if ($original) {
2515 if (isset($this->info['originalLength'])) {
2516 return $this->info['originalLength'];
2517 }
2518 return 3600;
2519 }
2520 return $this->info['length'];
2521 }
2522
2523 /**
2524 * @return int
2525 */
2526 public function getActivateTime() {
2527 return $this->info['dateActivated'];
2528 }
2529
2530 /**
2531 * @return array
2532 */
2533 public function getInfo() {
2534 return $this->info;
2535 }
2536}
2537
2538/**
2539 * Class Leaderboards
2540 *
2541 * @package HypixelPHP
2542 */
2543class Leaderboards extends HypixelObject {
2544}
2545
2546/**
2547 * Class TimeUtils
2548 *
2549 * @package HypixelPHP
2550 */
2551class TimeUtils {
2552 /**
2553 * @return string
2554 */
2555 public static function getWeeklyOscillation() {
2556 date_default_timezone_set("America/New_York");
2557 $epoch = 1417237200000;
2558 $milli = round(microtime(true) * 1000);
2559
2560 $delta = abs($milli - $epoch);
2561 $osc = $delta / 604800000;
2562
2563 return $osc % 2 == 0 ? "a" : "b";
2564 }
2565
2566 /**
2567 * @return string
2568 */
2569 public static function getMonthlyOscillation() {
2570 date_default_timezone_set("America/New_York");
2571 $epoch = 1417410000000;
2572
2573 $dateStart = new DateTime(date("Y-m-d"));
2574 $dateEnd = new DateTime(date("Y-m-d", $epoch / 1000));
2575
2576 $diffYear = $dateEnd->format("Y") - $dateStart->format("Y");
2577 /* @var $diffYear int */
2578 $diffMonth = $diffYear * 12 + TimeUtils::getJavaMonth($dateEnd) - TimeUtils::getJavaMonth($dateStart);
2579
2580 return $diffMonth % 2 == 0 ? "a" : "b";
2581 }
2582
2583 /**
2584 * @param DateTime $date
2585 * @return int
2586 */
2587 public static function getJavaMonth(DateTime $date) {
2588 date_default_timezone_set("America/New_York");
2589 return $date->format("n") - 1;
2590 }
2591}
2592
2593// END FILE hypixelphp.php