hypixel-api-reborn 9.0.3 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.prettierrc +13 -0
  2. package/README.md +28 -16
  3. package/package.json +60 -58
  4. package/src/API/getAPIStatus.js +8 -7
  5. package/src/API/getBoosters.js +6 -5
  6. package/src/API/getGameCounts.js +6 -5
  7. package/src/API/getGuild.js +18 -17
  8. package/src/API/getLeaderboards.js +13 -12
  9. package/src/API/getPlayer.js +22 -26
  10. package/src/API/getRecentGames.js +18 -17
  11. package/src/API/getServerInfo.js +66 -77
  12. package/src/API/getStatus.js +8 -7
  13. package/src/API/getWatchdogStats.js +6 -5
  14. package/src/API/index.js +19 -9
  15. package/src/API/skyblock/getEndedSkyblockAuctions.js +10 -9
  16. package/src/API/skyblock/getSkyblockAuctions.js +64 -64
  17. package/src/API/skyblock/getSkyblockAuctionsByPlayer.js +11 -10
  18. package/src/API/skyblock/getSkyblockBazaar.js +10 -9
  19. package/src/API/skyblock/getSkyblockMember.js +28 -24
  20. package/src/API/skyblock/getSkyblockNews.js +6 -5
  21. package/src/API/skyblock/getSkyblockProfiles.js +44 -40
  22. package/src/Client.js +406 -430
  23. package/src/Errors.js +44 -38
  24. package/src/Private/defaultCache.js +77 -0
  25. package/src/Private/rateLimit.js +79 -98
  26. package/src/Private/requests.js +65 -39
  27. package/src/Private/updater.js +45 -42
  28. package/src/Private/uuidCache.js +37 -33
  29. package/src/Private/validate.js +97 -97
  30. package/src/index.js +82 -83
  31. package/src/structures/APIIncident.js +78 -78
  32. package/src/structures/APIStatus.js +47 -47
  33. package/src/structures/Boosters/Booster.js +83 -87
  34. package/src/structures/Color.js +129 -129
  35. package/src/structures/Game.js +164 -160
  36. package/src/structures/GameCounts.js +151 -151
  37. package/src/structures/Guild/Guild.js +204 -218
  38. package/src/structures/Guild/GuildMember.js +66 -66
  39. package/src/structures/Guild/GuildRank.js +48 -48
  40. package/src/structures/ItemBytes.js +33 -36
  41. package/src/structures/Leaderboard.js +31 -31
  42. package/src/structures/MiniGames/Arcade.js +567 -569
  43. package/src/structures/MiniGames/ArenaBrawl.js +52 -56
  44. package/src/structures/MiniGames/BedWars.js +423 -329
  45. package/src/structures/MiniGames/BlitzSurvivalGames.js +172 -148
  46. package/src/structures/MiniGames/BuildBattle.js +53 -53
  47. package/src/structures/MiniGames/CopsAndCrims.js +90 -90
  48. package/src/structures/MiniGames/Duels.js +694 -460
  49. package/src/structures/MiniGames/MegaWalls.js +137 -137
  50. package/src/structures/MiniGames/MurderMystery.js +93 -93
  51. package/src/structures/MiniGames/Paintball.js +67 -67
  52. package/src/structures/MiniGames/Pit.js +19 -19
  53. package/src/structures/MiniGames/Quakecraft.js +101 -101
  54. package/src/structures/MiniGames/SkyWars.js +508 -559
  55. package/src/structures/MiniGames/SmashHeroes.js +144 -151
  56. package/src/structures/MiniGames/SpeedUHC.js +115 -57
  57. package/src/structures/MiniGames/TNTGames.js +116 -116
  58. package/src/structures/MiniGames/TurboKartRacers.js +201 -71
  59. package/src/structures/MiniGames/UHC.js +164 -143
  60. package/src/structures/MiniGames/VampireZ.js +60 -60
  61. package/src/structures/MiniGames/Walls.js +52 -52
  62. package/src/structures/MiniGames/Warlords.js +62 -62
  63. package/src/structures/MiniGames/WoolWars.js +123 -0
  64. package/src/structures/Pet.js +96 -97
  65. package/src/structures/Pets.js +64 -64
  66. package/src/structures/Player.js +433 -453
  67. package/src/structures/PlayerCosmetics.js +100 -95
  68. package/src/structures/RecentGame.js +57 -57
  69. package/src/structures/ServerInfo.js +78 -78
  70. package/src/structures/SkyBlock/Auctions/Auction.js +104 -104
  71. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +54 -54
  72. package/src/structures/SkyBlock/Auctions/BaseAuction.js +45 -45
  73. package/src/structures/SkyBlock/Auctions/Bid.js +48 -48
  74. package/src/structures/SkyBlock/Auctions/PartialAuction.js +25 -25
  75. package/src/structures/SkyBlock/Bazzar/Order.js +38 -38
  76. package/src/structures/SkyBlock/Bazzar/Product.js +53 -53
  77. package/src/structures/SkyBlock/News/SkyblockNews.js +60 -68
  78. package/src/structures/SkyBlock/SkyblockInventoryItem.js +124 -102
  79. package/src/structures/SkyBlock/SkyblockMember.js +820 -675
  80. package/src/structures/SkyBlock/SkyblockPet.js +71 -71
  81. package/src/structures/SkyBlock/SkyblockProfile.js +60 -60
  82. package/src/structures/Status.js +41 -41
  83. package/src/structures/Watchdog/Stats.js +36 -36
  84. package/src/utils/Constants.js +2789 -795
  85. package/src/utils/SkyblockUtils.js +208 -164
  86. package/src/utils/arrayTools.js +4 -4
  87. package/src/utils/divide.js +5 -5
  88. package/src/utils/guildExp.js +57 -67
  89. package/src/utils/index.js +13 -9
  90. package/src/utils/isGuildID.js +3 -3
  91. package/src/utils/isUUID.js +5 -5
  92. package/src/utils/oscillation.js +15 -23
  93. package/src/utils/removeSnakeCase.js +22 -35
  94. package/src/utils/rgbToHexColor.js +8 -0
  95. package/src/utils/romanize.js +11 -0
  96. package/src/utils/toIGN.js +20 -20
  97. package/src/utils/toUuid.js +19 -19
  98. package/src/utils/varInt.js +17 -21
  99. package/typings/index.d.ts +3532 -2625
  100. package/src/API/getFriends.js +0 -13
  101. package/src/API/getKeyInfo.js +0 -9
  102. package/src/API/getRankedSkyWars.js +0 -10
  103. package/src/structures/Friend.js +0 -38
  104. package/src/structures/KeyInfo.js +0 -42
  105. package/src/structures/MiniGames/SkyWarsRanked.js +0 -45
@@ -1,453 +1,433 @@
1
- const SkyWars = require('./MiniGames/SkyWars');
2
- const BedWars = require('./MiniGames/BedWars');
3
- const UHC = require('./MiniGames/UHC');
4
- const SpeedUHC = require('./MiniGames/SpeedUHC');
5
- const MurderMystery = require('./MiniGames/MurderMystery');
6
- const Duels = require('./MiniGames/Duels');
7
- const BuildBattle = require('./MiniGames/BuildBattle');
8
- const MegaWalls = require('./MiniGames/MegaWalls');
9
- const CopsAndCrims = require('./MiniGames/CopsAndCrims');
10
- const TNTGames = require('./MiniGames/TNTGames');
11
- const SmashHeroes = require('./MiniGames/SmashHeroes');
12
- const VampireZ = require('./MiniGames/VampireZ');
13
- const BlitzSurvivalGames = require('./MiniGames/BlitzSurvivalGames');
14
- const ArenaBrawl = require('./MiniGames/ArenaBrawl');
15
- const Arcade = require('./MiniGames/Arcade');
16
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
- const Pit = require('./MiniGames/Pit');
18
- const Color = require('./Color');
19
- const Game = require('./Game');
20
- const PlayerCosmetics = require('./PlayerCosmetics');
21
- const { recursive } = require('../utils/removeSnakeCase');
22
- const TurboKartRacers = require('./MiniGames/TurboKartRacers');
23
- const Paintball = require('./MiniGames/Paintball');
24
- const Quakecraft = require('./MiniGames/Quakecraft');
25
- const Walls = require('./MiniGames/Walls');
26
- const Warlords = require('./MiniGames/Warlords');
27
- /**
28
- * Player class
29
- */
30
- class Player {
31
- /**
32
- * @param {object} data Player data
33
- * @param {Record<string, any>} extraPayload extra data requested alongside player
34
- */
35
- constructor (data, extraPayload) {
36
- /**
37
- * Player nickname
38
- * @type {string}
39
- */
40
- this.nickname = data.displayname;
41
- /**
42
- * Player UUID
43
- * @type {string}
44
- */
45
- this.uuid = data.uuid;
46
- /**
47
- * Player nickname history known to Hypixel
48
- * @type {Array<string>}
49
- */
50
- this.history = data.knownAliases;
51
- /**
52
- * Player rank
53
- * @type {PlayerRank}
54
- */
55
- this.rank = getRank(data);
56
- /**
57
- * Player minecraft version
58
- * @type {string|null}
59
- */
60
- this.mcVersion = data.mcVersionRp || null;
61
- /**
62
- * Current chat channel, usually ALL, PARTY, or GUILD
63
- * @type {string|null}
64
- */
65
- this.channel = data.channel || null;
66
- /**
67
- * Timestamp when player last logged in
68
- * @type {number}
69
- */
70
- this.firstLoginTimestamp = data.firstLogin || null;
71
- /**
72
- * Timestamp when player last logged in as Date
73
- * @type {Date}
74
- */
75
- this.firstLogin = data.firstLogin ? new Date(data.firstLogin) : null;
76
- /**
77
- * Player's recently played game
78
- * @type {Game|null}
79
- */
80
- this.lastLoginTimestamp = data.lastLogin || null;
81
- /**
82
- * Timestamp when player first logged in
83
- * @type {number}
84
- */
85
- this.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;
86
- /**
87
- * Timestamp when player last logged out as Date
88
- * @type {Date}
89
- */
90
- this.lastLogoutTimestamp = data.lastLogout || null;
91
- /**
92
- * Timestamp when player first logged in as Date
93
- * @type {Date}
94
- */
95
- this.lastLogout = data.lastLogout ? new Date(data.lastLogout) : null;
96
- /**
97
- * Recently played game
98
- * @type {Game|null}
99
- */
100
- this.recentlyPlayedGame = data.mostRecentGameType ? new Game(data.mostRecentGameType) : null;
101
- /**
102
- * Player's plus color (must be a MVP+ rank)
103
- * @type {Color|null}
104
- */
105
- this.plusColor = this.rank === 'MVP+' || this.rank === 'MVP++' ? (data.rankPlusColor ? new Color(data.rankPlusColor) : null) : null;
106
- /**
107
- * MVP++ prefix color
108
- * @type {Color|null}
109
- */
110
- this.prefixColor = this.rank === 'MVP++' ? (data.monthlyRankColor ? new Color(data.monthlyRankColor) : new Color('GOLD')) : null;
111
- /**
112
- * Player karma
113
- * @type {number}
114
- */
115
- this.karma = data.karma || 0;
116
- /**
117
- * Player achievements
118
- * @type {Object}
119
- */
120
- this.achievements = recursive(data.achievements);
121
- /**
122
- * Player achievement points
123
- * @type {number}
124
- */
125
- this.achievementPoints = data.achievementPoints || 0;
126
- /**
127
- * Player total experience
128
- * @type {number}
129
- */
130
- this.totalExperience = data.networkExp || 0;
131
- /**
132
- * Player level
133
- * @type {number}
134
- */
135
- this.level = getPlayerLevel(this.totalExperience) || 0;
136
- /**
137
- * Player social media, if any
138
- * @type {Array<PlayerSocialMedia>}
139
- */
140
- this.socialMedia = getSocialMedia(data.socialMedia) || [];
141
- /**
142
- * Amount of gift bundles sent
143
- * @type {number}
144
- */
145
- this.giftBundlesSent = data.giftingMeta ? data.giftingMeta.realBundlesGiven || 0 : null;
146
- /**
147
- * Amount of gift bundles received
148
- * @type {number}
149
- */
150
- this.giftBundlesReceived = data.giftingMeta ? data.giftingMeta.realBundlesReceived || 0 : null;
151
- /**
152
- * Amount of gifts sent
153
- * @type {number}
154
- */
155
- this.giftsSent = data.giftingMeta ? data.giftingMeta.giftsGiven || 0 : null;
156
- /**
157
- * Is player online?
158
- * @type {boolean}
159
- */
160
- this.isOnline = this.lastLoginTimestamp > this.lastLogoutTimestamp;
161
- /**
162
- * Last time player claimed the daily reward
163
- * @type {Date | null}
164
- */
165
- this.lastDailyReward = new Date(data.lastAdsenseGenerateTime) || null;
166
- /**
167
- * Last time player claimed the daily reward, as timestamp
168
- * @type {number | null}
169
- */
170
- this.lastDailyRewardTimestamp = data.lastAdsenseGenerateTime || null;
171
- /**
172
- * Total amount of Daily Rewards
173
- * @type {number | null}
174
- */
175
- this.totalRewards = data.totalRewards || null;
176
- /**
177
- * Total amount of Daily Rewards claimed
178
- * @type {number | null}
179
- */
180
- this.totalDailyRewards = data.totalDailyRewards || null;
181
- /**
182
- * Honestly no clue what this is specifically
183
- * @type {number | null}
184
- */
185
- this.rewardStreak = data.rewardStreak || null;
186
- /**
187
- * Current Daily Rewards streak
188
- * @type {number | null}
189
- */
190
- this.rewardScore = data.rewardScore || null;
191
- /**
192
- * Highest Daily Rewards streak
193
- * @type {number | null}
194
- */
195
- this.rewardHighScore = data.rewardHighScore || null;
196
- /**
197
- * Player leveling progress.
198
- * @type {LevelProgress}
199
- */
200
- this.levelProgress = playerLevelProgress(data);
201
- /**
202
- * Player's Guild if requested in options
203
- * @type {Guild|null}
204
- */
205
- this.guild = extraPayload?.guild || null;
206
- /**
207
- * Recent Games if requested in options
208
- * @type {RecentGame[]|null}
209
- */
210
- this.recentGames = extraPayload?.recentGames || null;
211
- /**
212
- * Player stats for each mini-game
213
- * @type {PlayerStats}
214
- */
215
- this.stats = (data.stats ? {
216
- skywars: (data.stats.SkyWars ? new SkyWars(data.stats.SkyWars, extraPayload?.rankedSW || null) : null),
217
- bedwars: (data.stats.Bedwars ? new BedWars(data.stats.Bedwars) : null),
218
- uhc: (data.stats.UHC ? new UHC(data.stats.UHC) : null),
219
- speeduhc: (data.stats.SpeedUHC ? new SpeedUHC(data.stats.SpeedUHC) : null),
220
- murdermystery: (data.stats.MurderMystery ? new MurderMystery(data.stats.MurderMystery) : null),
221
- duels: (data.stats.Duels ? new Duels(data.stats.Duels) : null),
222
- buildbattle: (data.stats.BuildBattle ? new BuildBattle(data.stats.BuildBattle) : null),
223
- megawalls: (data.stats.Walls3 ? new MegaWalls(data.stats.Walls3) : null),
224
- copsandcrims: (data.stats.MCGO ? new CopsAndCrims(data.stats.MCGO) : null),
225
- tntgames: (data.stats.TNTGames ? new TNTGames(data.stats.TNTGames) : null),
226
- smashheroes: (data.stats.SuperSmash ? new SmashHeroes(data.stats.SuperSmash) : null),
227
- vampirez: (data.stats.VampireZ ? new VampireZ(data.stats.VampireZ) : null),
228
- blitzsg: (data.stats.HungerGames ? new BlitzSurvivalGames(data.stats.HungerGames) : null),
229
- arena: (data.stats.Arena ? new ArenaBrawl(data.stats.Arena) : null),
230
- arcade: (data.stats.Arcade ? new Arcade({...data.stats.Arcade, ...data.achievements}) : null),
231
- paintball: (data.stats.Paintball ? new Paintball(data.stats.Paintball) : null),
232
- quakecraft: (data.stats.Quake ? new Quakecraft(data.stats.Quake) : null),
233
- turbokartracers: (data.stats.GingerBread ? new TurboKartRacers(data.stats.GingerBread) : null),
234
- walls: (data.stats.Walls ? new Walls(data.stats.Walls) : null),
235
- warlords: (data.stats.Battleground ? new Warlords(data.stats.Battleground) : null),
236
- pit: null
237
- } : null);
238
- /**
239
- * User's current language
240
- * @type {string}
241
- * @default ENGLISH Default to english
242
- */
243
- this.userLanguage = data.userLanguage || 'ENGLISH';
244
- /**
245
- * Claimed Leveling Rewards
246
- * @type {number[]}
247
- */
248
- this.claimedLevelingRewards = parseClaimedRewards(data) || [];
249
- /**
250
- * Global Cosmetics a player owns
251
- * @type {PlayerCosmetics}
252
- */
253
- this.globalCosmetics = new PlayerCosmetics(data) || null;
254
- /**
255
- * Time at which the ranks were purchased. Can be all null if bought a long time ago, and some values can be null if player bought directly a rank above that
256
- * @type {RanksPurchaseTime}
257
- */
258
- this.ranksPurchaseTime = {
259
- 'VIP': data.levelUp_VIP ? new Date(data.levelUp_VIP) : null,
260
- 'VIP_PLUS': data.levelUp_VIP_PLUS ? new Date(data.levelUp_VIP_PLUS) : null,
261
- 'MVP': data.levelUp_MVP ? new Date(data.levelUp_MVP) : null,
262
- 'MVP_PLUS': data.levelUp_MVP_PLUS ? new Date(data.levelUp_MVP_PLUS) : null
263
- };
264
- }
265
- /**
266
- * Player Name ( at least last known to hypixel )
267
- * @return {string}
268
- */
269
- toString () {
270
- return this.nickname;
271
- }
272
- }
273
-
274
- /**
275
- * @async
276
- * @description Get player's rank
277
- * @param {object} player
278
- * @return {string}
279
- */
280
- function getRank (player) {
281
- let rank;
282
- if (player.prefix) {
283
- rank = player.prefix.replace(/§[0-9|a-z]|\[|\]/g, '');
284
- } else if (player.rank && player.rank !== 'NORMAL') {
285
- switch (player.rank) {
286
- case 'MODERATOR':
287
- rank = 'Moderator';
288
- break;
289
- case 'YOUTUBER':
290
- rank = 'YouTube';
291
- break;
292
- case 'HELPER':
293
- rank = 'Helper';
294
- break;
295
- case 'ADMIN':
296
- rank = 'Admin';
297
- break;
298
- }
299
- } else {
300
- switch (player.newPackageRank) {
301
- case 'MVP_PLUS':
302
- rank = player.monthlyPackageRank && player.monthlyPackageRank === 'SUPERSTAR' ? 'MVP++' : 'MVP+';
303
- break;
304
- case 'MVP':
305
- rank = 'MVP';
306
- break;
307
- case 'VIP_PLUS':
308
- rank = 'VIP+';
309
- break;
310
- case 'VIP':
311
- rank = 'VIP';
312
- break;
313
- default:
314
- rank = player.monthlyPackageRank && player.monthlyPackageRank === 'SUPERSTAR' ? 'MVP++' : 'Default';
315
- }
316
- }
317
- return rank;
318
- }
319
- /**
320
- * @param {number} exp
321
- * @return {number} Level rounded to the nearest cent
322
- */
323
- function getPlayerLevel (exp) {
324
- const base = 10000;
325
- const growth = 2500;
326
- const reversePqPrefix = -(base - 0.5 * growth) / growth;
327
- const reverseConst = reversePqPrefix * reversePqPrefix;
328
- const growthDivides2 = 2 / growth;
329
- const num = 1 + reversePqPrefix + Math.sqrt(reverseConst + growthDivides2 * exp);
330
- const level = Math.round(num * 100) / 100;
331
- return level;
332
- }
333
- /**
334
- * @description EXP to next player level.
335
- * @param {object} player
336
- * @returns {number}
337
- */
338
- function xpToNextLevel (player) {
339
- const lvl = getPlayerLevel(player.networkExp);
340
- const xpToNext = (2500 * Math.floor(lvl)) + 5000;
341
- if (player.networkExp < 10000) return 10000;
342
- return xpToNext;
343
- }
344
- /**
345
- * @param {Player} player
346
- * @returns {number}
347
- */
348
- function levelToXP (player) {
349
- let level = Number(Math.floor(getPlayerLevel(player.networkExp)));
350
- level = level - 1;
351
- const xp = 1250 * level ** 2 + 8750 * level;
352
- return xp;
353
- }
354
- /**
355
- * Player Network level Progress
356
- * @param {Object} player player data
357
- * @returns {{xpToNext:number,currentXP:number,percent:number,remainingXP:number,percentRemaining:number}}
358
- */
359
- function playerLevelProgress (player) {
360
- const xpFromLevel = levelToXP(player);
361
- let currentXP = (player.networkExp - xpFromLevel);
362
- const xpToNext = xpToNextLevel(player);
363
- const remainingXP = (xpToNext - currentXP) + 2500;
364
- currentXP = currentXP - 2500;
365
- const percent = (Math.round(((currentXP / xpToNext) * 100) * 100) / 100);
366
- const percentRemaining = Math.round((100 - percent) * 100) / 100;
367
- return {
368
- xpToNext,
369
- currentXP,
370
- remainingXP,
371
- percent,
372
- percentRemaining
373
- };
374
- }
375
- /**
376
- * @param {object} data
377
- * @return {Array<{name:string,link:string,id:string}>}
378
- */
379
- function getSocialMedia (data) {
380
- if (!data) return null;
381
- const links = data.links;
382
- const formattedNames = ['Twitter', 'YouTube', 'Instagram', 'Twitch', 'Hypixel', 'Discord'];
383
- const upperNames = ['TWITTER', 'YOUTUBE', 'INSTAGRAM', 'TWITCH', 'HYPIXEL', 'DISCORD'];
384
- if (!links) return null;
385
- return Object.keys(links).map((x) => upperNames.indexOf(x)).filter((x) => x !== -1).map((x) => ({ name: formattedNames[x], link: links[upperNames[x]], id: upperNames[x] }));
386
- }
387
- /**
388
- *
389
- * @param {object} data
390
- * @returns {number[]}
391
- */
392
- function parseClaimedRewards (data) {
393
- if (!data) return null;
394
- return Object.keys(data).map((x) => x.match(/levelingReward_(\d+)/)).filter((x) => x).map((x) => parseInt(x[1], 10));
395
- }
396
- /**
397
- * @typedef {string} PlayerRank
398
- * * `Default`
399
- * * `VIP`
400
- * * `VIP+`
401
- * * `MVP`
402
- * * `MVP+`
403
- * * `MVP++`
404
- * * `Helper`
405
- * * `Moderator`
406
- * * `Admin`
407
- * * `YouTube`
408
- */
409
- /**
410
- * @typedef {Object} PlayerSocialMedia
411
- * Player social media object
412
- * @property {string} name Twitter, YouTube, Instagram, Twitch, Hypixel, Discord
413
- * @property {string} link Link to social media
414
- * @property {string} id TWITTER, YOUTUBE, INSTRAGRAM, TWITCH, HYPIXEL, DISCORD
415
- */
416
- /**
417
- * @typedef {Object|null} PlayerStats
418
- * Player stats for each mini-game. `null` if player has no stats.
419
- * <br>
420
- * Usage: `<Player>.stats.skywars`
421
- * @property {SkyWars|null} skywars SkyWars
422
- * @property {BedWars|null} bedwars BedWars
423
- * @property {UHC|null} uhc UHC
424
- * @property {SpeedUHC|null} speedUHC Speed UHC
425
- * @property {MurderMystery|null} murdermystery Murder Mystery
426
- * @property {Duels|null} duels Duels
427
- * @property {BuildBattle|null} buildbattle BuildBattle
428
- * @property {MegaWalls|null} megawalls MegaWalls
429
- * @property {CopsAndCrims|null} copsandcrims Cops and Crims
430
- * @property {TNTGames|null} tntgames The TNT Games
431
- * @property {SmashHeroes|null} smashheroes Smash Heroes
432
- * @property {VampireZ|null} vampirez VampireZ
433
- * @property {BlitzSurvivalGames|null} blitzsg Blitz Survival Games
434
- * @property {ArenaBrawl|null} arena Arena Brawl
435
- * @property {Arcade|null} arcade Arcade
436
- */
437
- /**
438
- * @typedef {Object} RanksPurchaseTime
439
- * Time at which ranks were purchased. Beware, even if a player has MVP+(+), every value here *could* be null
440
- * @property {Date|null} VIP VIP rank
441
- * @property {Date|null} VIP_PLUS VIP+ rank
442
- * @property {Date|null} MVP MVP rank
443
- * @property {Date|null} MVP_PLUS MVP+ rank
444
- */
445
- /**
446
- * @typedef {Object} LevelProgress
447
- * @property {number} xpToNext Total XP to a player's next level.
448
- * @property {number} remainingXP XP to the player's next level.
449
- * @property {number} currentXP XP the player current has.
450
- * @property {number} percent Player level progress as a percentage.
451
- * @property {number} percentRemaining Remaining percentage of the percent value.
452
- */
453
- module.exports = Player;
1
+ const SkyWars = require('./MiniGames/SkyWars');
2
+ const BedWars = require('./MiniGames/BedWars');
3
+ const UHC = require('./MiniGames/UHC');
4
+ const SpeedUHC = require('./MiniGames/SpeedUHC');
5
+ const MurderMystery = require('./MiniGames/MurderMystery');
6
+ const Duels = require('./MiniGames/Duels');
7
+ const BuildBattle = require('./MiniGames/BuildBattle');
8
+ const MegaWalls = require('./MiniGames/MegaWalls');
9
+ const CopsAndCrims = require('./MiniGames/CopsAndCrims');
10
+ const TNTGames = require('./MiniGames/TNTGames');
11
+ const SmashHeroes = require('./MiniGames/SmashHeroes');
12
+ const VampireZ = require('./MiniGames/VampireZ');
13
+ const BlitzSurvivalGames = require('./MiniGames/BlitzSurvivalGames');
14
+ const ArenaBrawl = require('./MiniGames/ArenaBrawl');
15
+ const Arcade = require('./MiniGames/Arcade');
16
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
+ const Pit = require('./MiniGames/Pit');
18
+ const Color = require('./Color');
19
+ const Game = require('./Game');
20
+ const PlayerCosmetics = require('./PlayerCosmetics');
21
+ const { recursive } = require('../utils/removeSnakeCase');
22
+ const TurboKartRacers = require('./MiniGames/TurboKartRacers');
23
+ const Paintball = require('./MiniGames/Paintball');
24
+ const Quakecraft = require('./MiniGames/Quakecraft');
25
+ const Walls = require('./MiniGames/Walls');
26
+ const Warlords = require('./MiniGames/Warlords');
27
+ const WoolWars = require('./MiniGames/WoolWars');
28
+ /**
29
+ * Player class
30
+ */
31
+ class Player {
32
+ /**
33
+ * @param {object} data Player data
34
+ * @param {Record<string, any>} extraPayload extra data requested alongside player
35
+ */
36
+ constructor(data, extraPayload) {
37
+ /**
38
+ * Player nickname
39
+ * @type {string}
40
+ */
41
+ this.nickname = data.displayname;
42
+ /**
43
+ * Player UUID
44
+ * @type {string}
45
+ */
46
+ this.uuid = data.uuid;
47
+ /**
48
+ * Player nickname history known to Hypixel
49
+ * @type {Array<string>}
50
+ */
51
+ this.history = data.knownAliases;
52
+ /**
53
+ * Player rank
54
+ * @type {PlayerRank}
55
+ */
56
+ this.rank = getRank(data);
57
+ /**
58
+ * Player minecraft version
59
+ * @type {string|null}
60
+ */
61
+ this.mcVersion = data.mcVersionRp || null;
62
+ /**
63
+ * Current chat channel, usually ALL, PARTY, or GUILD
64
+ * @type {string|null}
65
+ */
66
+ this.channel = data.channel || null;
67
+ /**
68
+ * Timestamp when player last logged in
69
+ * @type {number|null}
70
+ */
71
+ this.firstLoginTimestamp = data.firstLogin || null;
72
+ /**
73
+ * Timestamp when player last logged in as Date
74
+ * @type {Date|null}
75
+ */
76
+ this.firstLogin = data.firstLogin ? new Date(data.firstLogin) : null;
77
+ /**
78
+ * Player's recently played game
79
+ * @type {Game|null}
80
+ */
81
+ this.lastLoginTimestamp = data.lastLogin || null;
82
+ /**
83
+ * Timestamp when player first logged in
84
+ * @type {number|null}
85
+ */
86
+ this.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;
87
+ /**
88
+ * Timestamp when player last logged out as Date
89
+ * @type {Date|null}
90
+ */
91
+ this.lastLogoutTimestamp = data.lastLogout || null;
92
+ /**
93
+ * Timestamp when player first logged in as Date
94
+ * @type {Date|null}
95
+ */
96
+ this.lastLogout = data.lastLogout ? new Date(data.lastLogout) : null;
97
+ /**
98
+ * Recently played game
99
+ * @type {Game|null}
100
+ */
101
+ this.recentlyPlayedGame = data.mostRecentGameType ? new Game(data.mostRecentGameType) : null;
102
+ /**
103
+ * Player's plus color (must be a MVP+ rank)
104
+ * @type {Color|null}
105
+ */
106
+ this.plusColor = this.rank === 'MVP+' || this.rank === 'MVP++' ? (data.rankPlusColor ? new Color(data.rankPlusColor) : new Color('RED')) : null;
107
+ /**
108
+ * MVP++ prefix color
109
+ * @type {Color|null}
110
+ */
111
+ this.prefixColor = this.rank === 'MVP++' ? (data.monthlyRankColor ? new Color(data.monthlyRankColor) : new Color('GOLD')) : null;
112
+ /**
113
+ * Player karma
114
+ * @type {number}
115
+ */
116
+ this.karma = data.karma || 0;
117
+ /**
118
+ * Player achievements
119
+ * @type {Object}
120
+ */
121
+ this.achievements = recursive(data.achievements);
122
+ /**
123
+ * Player achievement points
124
+ * @type {number}
125
+ */
126
+ this.achievementPoints = data.achievementPoints || 0;
127
+ /**
128
+ * Player total experience
129
+ * @type {number}
130
+ */
131
+ this.totalExperience = data.networkExp || 0;
132
+ /**
133
+ * Player level
134
+ * @type {number}
135
+ */
136
+ this.level = getPlayerLevel(this.totalExperience) || 0;
137
+ /**
138
+ * Player social media, if any
139
+ * @type {Array<PlayerSocialMedia>}
140
+ */
141
+ this.socialMedia = getSocialMedia(data.socialMedia) || [];
142
+ /**
143
+ * Amount of gift bundles sent
144
+ * @type {number}
145
+ */
146
+ this.giftBundlesSent = data.giftingMeta ? data.giftingMeta.realBundlesGiven || 0 : null;
147
+ /**
148
+ * Amount of gift bundles received
149
+ * @type {number}
150
+ */
151
+ this.giftBundlesReceived = data.giftingMeta ? data.giftingMeta.realBundlesReceived || 0 : null;
152
+ /**
153
+ * Amount of gifts sent
154
+ * @type {number}
155
+ */
156
+ this.giftsSent = data.giftingMeta ? data.giftingMeta.giftsGiven || 0 : null;
157
+ /**
158
+ * Is player online?
159
+ * @type {boolean}
160
+ */
161
+ this.isOnline = this.lastLoginTimestamp > this.lastLogoutTimestamp;
162
+ /**
163
+ * Last time player claimed the daily reward
164
+ * @type {Date | null}
165
+ */
166
+ this.lastDailyReward = new Date(data.lastAdsenseGenerateTime) || null;
167
+ /**
168
+ * Last time player claimed the daily reward, as timestamp
169
+ * @type {number | null}
170
+ */
171
+ this.lastDailyRewardTimestamp = data.lastAdsenseGenerateTime || null;
172
+ /**
173
+ * Total amount of Daily Rewards
174
+ * @type {number | null}
175
+ */
176
+ this.totalRewards = data.totalRewards || null;
177
+ /**
178
+ * Total amount of Daily Rewards claimed
179
+ * @type {number | null}
180
+ */
181
+ this.totalDailyRewards = data.totalDailyRewards || null;
182
+ /**
183
+ * Honestly no clue what this is specifically
184
+ * @type {number | null}
185
+ */
186
+ this.rewardStreak = data.rewardStreak || null;
187
+ /**
188
+ * Current Daily Rewards streak
189
+ * @type {number | null}
190
+ */
191
+ this.rewardScore = data.rewardScore || null;
192
+ /**
193
+ * Highest Daily Rewards streak
194
+ * @type {number | null}
195
+ */
196
+ this.rewardHighScore = data.rewardHighScore || null;
197
+ /**
198
+ * Player leveling progress.
199
+ * @type {LevelProgress}
200
+ */
201
+ this.levelProgress = playerLevelProgress(data);
202
+ /**
203
+ * Player's Guild if requested in options
204
+ * @type {Guild|null}
205
+ */
206
+ this.guild = extraPayload?.guild || null;
207
+ /**
208
+ * Recent Games if requested in options
209
+ * @type {RecentGame[]|null}
210
+ */
211
+ this.recentGames = extraPayload?.recentGames || null;
212
+ /**
213
+ * Player stats for each mini-game
214
+ * @type {PlayerStats}
215
+ */
216
+ this.stats = data.stats
217
+ ? {
218
+ skywars: data.stats.SkyWars ? new SkyWars(data.stats.SkyWars) : null,
219
+ bedwars: data.stats.Bedwars ? new BedWars(data.stats.Bedwars) : null,
220
+ uhc: data.stats.UHC ? new UHC(data.stats.UHC) : null,
221
+ speeduhc: data.stats.SpeedUHC ? new SpeedUHC(data.stats.SpeedUHC) : null,
222
+ murdermystery: data.stats.MurderMystery ? new MurderMystery(data.stats.MurderMystery) : null,
223
+ duels: data.stats.Duels ? new Duels(data.stats.Duels) : null,
224
+ buildbattle: data.stats.BuildBattle ? new BuildBattle(data.stats.BuildBattle) : null,
225
+ megawalls: data.stats.Walls3 ? new MegaWalls(data.stats.Walls3) : null,
226
+ copsandcrims: data.stats.MCGO ? new CopsAndCrims(data.stats.MCGO) : null,
227
+ tntgames: data.stats.TNTGames ? new TNTGames(data.stats.TNTGames) : null,
228
+ smashheroes: data.stats.SuperSmash ? new SmashHeroes(data.stats.SuperSmash) : null,
229
+ vampirez: data.stats.VampireZ ? new VampireZ(data.stats.VampireZ) : null,
230
+ blitzsg: data.stats.HungerGames ? new BlitzSurvivalGames(data.stats.HungerGames) : null,
231
+ arena: data.stats.Arena ? new ArenaBrawl(data.stats.Arena) : null,
232
+ arcade: data.stats.Arcade ? new Arcade({ ...data.stats.Arcade, ...data.achievements }) : null,
233
+ paintball: data.stats.Paintball ? new Paintball(data.stats.Paintball) : null,
234
+ quakecraft: data.stats.Quake ? new Quakecraft(data.stats.Quake) : null,
235
+ turbokartracers: data.stats.GingerBread ? new TurboKartRacers(data.stats.GingerBread) : null,
236
+ walls: data.stats.Walls ? new Walls(data.stats.Walls) : null,
237
+ warlords: data.stats.Battleground ? new Warlords(data.stats.Battleground) : null,
238
+ woolwars: data.stats.WoolGames ? new WoolWars(data.stats.WoolGames) : null,
239
+ pit: null
240
+ }
241
+ : null;
242
+ /**
243
+ * User's current language
244
+ * @type {string}
245
+ * @default ENGLISH Default to english
246
+ */
247
+ this.userLanguage = data.userLanguage || 'ENGLISH';
248
+ /**
249
+ * Claimed Leveling Rewards
250
+ * @type {number[]}
251
+ */
252
+ this.claimedLevelingRewards = parseClaimedRewards(data) || [];
253
+ /**
254
+ * Global Cosmetics a player owns
255
+ * @type {PlayerCosmetics}
256
+ */
257
+ this.globalCosmetics = new PlayerCosmetics(data) || null;
258
+ /**
259
+ * Time at which the ranks were purchased. Can be all null if bought a long time ago, and some values can be null if player bought directly a rank above that
260
+ * @type {RanksPurchaseTime}
261
+ */
262
+ this.ranksPurchaseTime = {
263
+ VIP: data.levelUp_VIP ? new Date(data.levelUp_VIP) : null,
264
+ VIP_PLUS: data.levelUp_VIP_PLUS ? new Date(data.levelUp_VIP_PLUS) : null,
265
+ MVP: data.levelUp_MVP ? new Date(data.levelUp_MVP) : null,
266
+ MVP_PLUS: data.levelUp_MVP_PLUS ? new Date(data.levelUp_MVP_PLUS) : null
267
+ };
268
+ }
269
+ /**
270
+ * Player Name ( at least last known to hypixel )
271
+ * @return {string}
272
+ */
273
+ toString() {
274
+ return this.nickname;
275
+ }
276
+ }
277
+
278
+ // eslint-disable-next-line require-jsdoc
279
+ function getRank(player) {
280
+ let rank;
281
+ if (player.prefix) {
282
+ rank = player.prefix.replace(/§[0-9|a-z]|\[|\]/g, '');
283
+ } else if (player.rank && player.rank !== 'NORMAL') {
284
+ switch (player.rank) {
285
+ case 'YOUTUBER':
286
+ rank = 'YouTube';
287
+ break;
288
+ case 'GAME_MASTER':
289
+ rank = 'Game Master';
290
+ break;
291
+ case 'ADMIN':
292
+ rank = 'Admin';
293
+ break;
294
+ }
295
+ } else {
296
+ switch (player.newPackageRank) {
297
+ case 'MVP_PLUS':
298
+ rank = player.monthlyPackageRank && player.monthlyPackageRank === 'SUPERSTAR' ? 'MVP++' : 'MVP+';
299
+ break;
300
+ case 'MVP':
301
+ rank = 'MVP';
302
+ break;
303
+ case 'VIP_PLUS':
304
+ rank = 'VIP+';
305
+ break;
306
+ case 'VIP':
307
+ rank = 'VIP';
308
+ break;
309
+ default:
310
+ rank = player.monthlyPackageRank && player.monthlyPackageRank === 'SUPERSTAR' ? 'MVP++' : 'Default';
311
+ }
312
+ }
313
+ return rank;
314
+ }
315
+ // eslint-disable-next-line require-jsdoc
316
+ function getPlayerLevel(exp) {
317
+ const base = 10000;
318
+ const growth = 2500;
319
+ const reversePqPrefix = -(base - 0.5 * growth) / growth;
320
+ const reverseConst = reversePqPrefix * reversePqPrefix;
321
+ const growthDivides2 = 2 / growth;
322
+ const num = 1 + reversePqPrefix + Math.sqrt(reverseConst + growthDivides2 * exp);
323
+ const level = Math.round(num * 100) / 100;
324
+ return level;
325
+ }
326
+ // eslint-disable-next-line require-jsdoc
327
+ function xpToNextLevel(player) {
328
+ const lvl = getPlayerLevel(player.networkExp);
329
+ const xpToNext = 2500 * Math.floor(lvl) + 5000;
330
+ if (player.networkExp < 10000) return 10000;
331
+ return xpToNext;
332
+ }
333
+ // eslint-disable-next-line require-jsdoc
334
+ function levelToXP(player) {
335
+ let level = Number(Math.floor(getPlayerLevel(player.networkExp)));
336
+ level = level - 1;
337
+ const xp = 1250 * level ** 2 + 8750 * level;
338
+ return xp;
339
+ }
340
+ // eslint-disable-next-line require-jsdoc
341
+ function playerLevelProgress(player) {
342
+ const xpFromLevel = levelToXP(player);
343
+ let currentXP = player.networkExp - xpFromLevel;
344
+ const xpToNext = xpToNextLevel(player);
345
+ const remainingXP = xpToNext - currentXP + 2500;
346
+ currentXP = currentXP - 2500;
347
+ const percent = Math.round((currentXP / xpToNext) * 100 * 100) / 100;
348
+ const percentRemaining = Math.round((100 - percent) * 100) / 100;
349
+ return {
350
+ xpToNext,
351
+ currentXP,
352
+ remainingXP,
353
+ percent,
354
+ percentRemaining
355
+ };
356
+ }
357
+ // eslint-disable-next-line require-jsdoc
358
+ function getSocialMedia(data) {
359
+ if (!data) return null;
360
+ const links = data.links;
361
+ const formattedNames = ['Twitter', 'YouTube', 'Instagram', 'Twitch', 'Hypixel', 'Discord'];
362
+ const upperNames = ['TWITTER', 'YOUTUBE', 'INSTAGRAM', 'TWITCH', 'HYPIXEL', 'DISCORD'];
363
+ if (!links) return null;
364
+ return Object.keys(links)
365
+ .map((x) => upperNames.indexOf(x))
366
+ .filter((x) => x !== -1)
367
+ .map((x) => ({ name: formattedNames[x], link: links[upperNames[x]], id: upperNames[x] }));
368
+ }
369
+ // eslint-disable-next-line require-jsdoc
370
+ function parseClaimedRewards(data) {
371
+ if (!data) return null;
372
+ return Object.keys(data)
373
+ .map((x) => x.match(/levelingReward_(\d+)/))
374
+ .filter((x) => x)
375
+ .map((x) => parseInt(x[1], 10));
376
+ }
377
+ /**
378
+ * @typedef {string} PlayerRank
379
+ * * `Default`
380
+ * * `VIP`
381
+ * * `VIP+`
382
+ * * `MVP`
383
+ * * `MVP+`
384
+ * * `MVP++`
385
+ * * `Game Master`
386
+ * * `Admin`
387
+ * * `YouTube`
388
+ */
389
+ /**
390
+ * @typedef {Object} PlayerSocialMedia
391
+ * Player social media object
392
+ * @property {string} name Twitter, YouTube, Instagram, Twitch, Hypixel, Discord
393
+ * @property {string} link Link to social media
394
+ * @property {string} id TWITTER, YOUTUBE, INSTRAGRAM, TWITCH, HYPIXEL, DISCORD
395
+ */
396
+ /**
397
+ * @typedef {Object|null} PlayerStats
398
+ * Player stats for each mini-game. `null` if player has no stats.
399
+ * <br>
400
+ * Usage: `<Player>.stats.skywars`
401
+ * @property {SkyWars|null} skywars SkyWars
402
+ * @property {BedWars|null} bedwars BedWars
403
+ * @property {UHC|null} uhc UHC
404
+ * @property {SpeedUHC|null} speedUHC Speed UHC
405
+ * @property {MurderMystery|null} murdermystery Murder Mystery
406
+ * @property {Duels|null} duels Duels
407
+ * @property {BuildBattle|null} buildbattle BuildBattle
408
+ * @property {MegaWalls|null} megawalls MegaWalls
409
+ * @property {CopsAndCrims|null} copsandcrims Cops and Crims
410
+ * @property {TNTGames|null} tntgames The TNT Games
411
+ * @property {SmashHeroes|null} smashheroes Smash Heroes
412
+ * @property {VampireZ|null} vampirez VampireZ
413
+ * @property {BlitzSurvivalGames|null} blitzsg Blitz Survival Games
414
+ * @property {ArenaBrawl|null} arena Arena Brawl
415
+ * @property {Arcade|null} arcade Arcade
416
+ */
417
+ /**
418
+ * @typedef {Object} RanksPurchaseTime
419
+ * Time at which ranks were purchased. Beware, even if a player has MVP+(+), every value here *could* be null
420
+ * @property {Date|null} VIP VIP rank
421
+ * @property {Date|null} VIP_PLUS VIP+ rank
422
+ * @property {Date|null} MVP MVP rank
423
+ * @property {Date|null} MVP_PLUS MVP+ rank
424
+ */
425
+ /**
426
+ * @typedef {Object} LevelProgress
427
+ * @property {number} xpToNext Total XP to a player's next level.
428
+ * @property {number} remainingXP XP to the player's next level.
429
+ * @property {number} currentXP XP the player current has.
430
+ * @property {number} percent Player level progress as a percentage.
431
+ * @property {number} percentRemaining Remaining percentage of the percent value.
432
+ */
433
+ module.exports = Player;