hypixel-api-reborn 11.2.0 → 11.3.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 (101) hide show
  1. package/README.md +1 -1
  2. package/eslint.config.mjs +71 -0
  3. package/package.json +14 -20
  4. package/src/API/getAchievements.js +1 -0
  5. package/src/API/getBoosters.js +1 -0
  6. package/src/API/getChallenges.js +1 -0
  7. package/src/API/getGameCounts.js +1 -0
  8. package/src/API/getGuild.js +4 -3
  9. package/src/API/getGuildAchievements.js +1 -0
  10. package/src/API/getLeaderboards.js +1 -1
  11. package/src/API/getPlayer.js +1 -0
  12. package/src/API/getQuests.js +1 -0
  13. package/src/API/getRecentGames.js +5 -9
  14. package/src/API/getServerInfo.js +40 -37
  15. package/src/API/getStatus.js +1 -0
  16. package/src/API/getWatchdogStats.js +1 -0
  17. package/src/API/housing/getActiveHouses.js +7 -0
  18. package/src/API/housing/getHouse.js +9 -0
  19. package/src/API/housing/getPlayerHouses.js +11 -0
  20. package/src/API/index.js +6 -1
  21. package/src/API/skyblock/getAuction.js +8 -6
  22. package/src/API/skyblock/getAuctions.js +15 -12
  23. package/src/API/skyblock/getAuctionsByPlayer.js +1 -1
  24. package/src/API/skyblock/getBazaar.js +1 -3
  25. package/src/API/skyblock/getBingo.js +1 -2
  26. package/src/API/skyblock/getBingoByPlayer.js +3 -3
  27. package/src/API/skyblock/getEndedAuctions.js +1 -0
  28. package/src/API/skyblock/getFireSales.js +1 -1
  29. package/src/API/skyblock/getGarden.js +7 -0
  30. package/src/API/skyblock/getGovernment.js +1 -2
  31. package/src/API/skyblock/getMember.js +5 -2
  32. package/src/API/skyblock/getMuseum.js +1 -0
  33. package/src/API/skyblock/getNews.js +1 -0
  34. package/src/API/skyblock/getProfiles.js +5 -2
  35. package/src/Client.js +88 -16
  36. package/src/Private/rateLimit.js +7 -11
  37. package/src/Private/requests.js +12 -13
  38. package/src/Private/updater.js +2 -3
  39. package/src/Private/uuidCache.js +1 -2
  40. package/src/Private/validate.js +19 -19
  41. package/src/index.js +5 -0
  42. package/src/structures/APIIncident.js +1 -2
  43. package/src/structures/APIStatus.js +0 -1
  44. package/src/structures/Boosters/Booster.js +9 -8
  45. package/src/structures/Game.js +1 -1
  46. package/src/structures/Guild/Guild.js +19 -36
  47. package/src/structures/Guild/GuildMember.js +2 -2
  48. package/src/structures/House.js +54 -0
  49. package/src/structures/MiniGames/Arcade.js +798 -312
  50. package/src/structures/MiniGames/ArenaBrawl.js +98 -32
  51. package/src/structures/MiniGames/BedWars.js +197 -194
  52. package/src/structures/MiniGames/BlitzSurvivalGames.js +381 -129
  53. package/src/structures/MiniGames/BuildBattle.js +19 -8
  54. package/src/structures/MiniGames/CopsAndCrims.js +253 -25
  55. package/src/structures/MiniGames/Duels.js +905 -664
  56. package/src/structures/MiniGames/MegaWalls.js +390 -51
  57. package/src/structures/MiniGames/MurderMystery.js +151 -30
  58. package/src/structures/MiniGames/Paintball.js +31 -11
  59. package/src/structures/MiniGames/Pit.js +4 -5
  60. package/src/structures/MiniGames/Quakecraft.js +113 -50
  61. package/src/structures/MiniGames/SkyWars.js +528 -372
  62. package/src/structures/MiniGames/SmashHeroes.js +201 -73
  63. package/src/structures/MiniGames/SpeedUHC.js +77 -24
  64. package/src/structures/MiniGames/TNTGames.js +242 -73
  65. package/src/structures/MiniGames/TurboKartRacers.js +55 -115
  66. package/src/structures/MiniGames/UHC.js +144 -132
  67. package/src/structures/MiniGames/VampireZ.js +70 -37
  68. package/src/structures/MiniGames/Warlords.js +126 -1
  69. package/src/structures/MiniGames/WoolWars.js +60 -9
  70. package/src/structures/Pet.js +1 -1
  71. package/src/structures/Player.js +43 -128
  72. package/src/structures/PlayerCosmetics.js +5 -4
  73. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +2 -1
  74. package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -1
  75. package/src/structures/SkyBlock/News/SkyblockNews.js +15 -15
  76. package/src/structures/SkyBlock/PlayerBingo.js +7 -14
  77. package/src/structures/SkyBlock/SkyblockGarden.js +146 -0
  78. package/src/structures/SkyBlock/SkyblockInventoryItem.js +4 -28
  79. package/src/structures/SkyBlock/SkyblockMember.js +90 -228
  80. package/src/structures/SkyBlock/SkyblockPet.js +3 -4
  81. package/src/structures/SkyBlock/Static/Bingo.js +10 -11
  82. package/src/structures/SkyBlock/Static/BingoData.js +1 -1
  83. package/src/structures/Static/Achievement.js +16 -15
  84. package/src/structures/Static/AchievementTier.js +2 -2
  85. package/src/structures/Static/Quest.js +2 -2
  86. package/src/utils/Constants.js +522 -520
  87. package/src/utils/{guildExp.js → Guild.js} +42 -12
  88. package/src/utils/Player.js +112 -0
  89. package/src/utils/SkyblockUtils.js +482 -192
  90. package/src/utils/arrayTools.js +1 -1
  91. package/src/utils/divide.js +1 -1
  92. package/src/utils/index.js +2 -1
  93. package/src/utils/isGuildID.js +1 -1
  94. package/src/utils/oscillation.js +4 -2
  95. package/src/utils/removeSnakeCase.js +11 -7
  96. package/src/utils/rgbToHexColor.js +1 -1
  97. package/src/utils/romanize.js +3 -3
  98. package/src/utils/toUuid.js +4 -4
  99. package/src/utils/varInt.js +2 -2
  100. package/typings/index.d.ts +1186 -967
  101. package/src/utils/toIGN.js +0 -24
@@ -1,249 +1,620 @@
1
+ const { removeSnakeCaseString } = require('../../utils/removeSnakeCase');
1
2
  const { SkyWarsPrestigeIcons } = require('../../utils/Constants');
2
3
  const divide = require('../../utils/divide');
3
- const { removeSnakeCaseString } = require('../../utils/removeSnakeCase');
4
- const generateStatsForMode = (data, mode) => {
4
+
5
+ // eslint-disable-next-line jsdoc/require-jsdoc
6
+ function getSkyWarsPrestige(level) {
7
+ if (60 <= level) return 'Mythic';
8
+ return (
9
+ ['Iron', 'Iron', 'Gold', 'Diamond', 'Emerald', 'Sapphire', 'Ruby', 'Crystal', 'Opal', 'Amethyst', 'Rainbow'][
10
+ Math.floor(level / 5)
11
+ ] || 'Iron'
12
+ );
13
+ }
14
+
15
+ // eslint-disable-next-line jsdoc/require-jsdoc
16
+ function getSkyWarsLevel(xp) {
17
+ const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
18
+ if (15000 <= xp) return Math.floor((xp - 15000) / 10000 + 12);
19
+ const level = totalXp.findIndex((x) => 0 < x * 10 - xp);
20
+ return level;
21
+ }
22
+
23
+ // eslint-disable-next-line jsdoc/require-jsdoc
24
+ function getSkyWarsLevelProgress(xp) {
25
+ const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
26
+ const xpToNextLvl = [0, 2, 5, 8, 10, 25, 50, 100, 150, 250, 400, 500];
27
+ let percent;
28
+ let xpToNextLevel;
29
+ let currentLevelXp = xp;
30
+ if (15000 <= xp) {
31
+ currentLevelXp -= 15000;
32
+ if (0 === currentLevelXp) return { currentLevelXp: 0, xpToNextLevel: 10000, percent: 0, xpNextLevel: 10000 };
33
+ if (10000 < currentLevelXp) {
34
+ do {
35
+ currentLevelXp -= 10000;
36
+ } while (10000 <= currentLevelXp);
37
+ }
38
+ xpToNextLevel = 10000 - currentLevelXp;
39
+ percent = Math.round(currentLevelXp) / 100;
40
+ const percentRemaining = Math.round((100 - percent) * 100) / 100;
41
+ return {
42
+ currentLevelXp,
43
+ xpToNextLevel,
44
+ percent,
45
+ xpNextLevel: 10000,
46
+ percentRemaining
47
+ };
48
+ }
49
+ const totalXptoNextLevel = xpToNextLvl[totalXp.findIndex((x) => 0 < x * 10 - xp)] * 10;
50
+ for (let i = 0; i < xpToNextLvl.length; i++) {
51
+ if (0 > currentLevelXp - xpToNextLvl[i] * 10) break;
52
+ currentLevelXp -= xpToNextLvl[i] * 10;
53
+ }
54
+ xpToNextLevel = totalXptoNextLevel - currentLevelXp;
55
+ percent = Math.round((currentLevelXp / totalXptoNextLevel) * 10000) / 100;
5
56
  return {
6
- kills: data[`kills_${mode}`] || 0,
7
- deaths: data[`deaths_${mode}`] || 0,
8
- wins: data[`wins_${mode}`] || 0,
9
- losses: data[`losses_${mode}`] || 0,
10
- KDRatio: divide(data[`kills_${mode}`], data[`deaths_${mode}`]),
11
- WLRatio: divide(data[`wins_${mode}`], data[`losses_${mode}`])
57
+ currentLevelXp,
58
+ xpToNextLevel,
59
+ percent,
60
+ xpNextLevel: totalXptoNextLevel
12
61
  };
13
- };
62
+ }
63
+
64
+ class SkywarsMode {
65
+ /**
66
+ * @param {object} data Skywars data
67
+ * @param {string} gamemode Gamemode Name
68
+ */
69
+ constructor(data, gamemode) {
70
+ /**
71
+ * Kills
72
+ * @type {number}
73
+ */
74
+ this.kills = data[`kills_${gamemode}`] || 0;
75
+ /**
76
+ * Deaths
77
+ * @type {number}
78
+ */
79
+ this.deaths = data[`deaths_${gamemode}`] || 0;
80
+ /**
81
+ * KDRatio
82
+ * @type {number}
83
+ */
84
+ this.KDRatio = divide(data.kills, data.deaths);
85
+ /**
86
+ * Wins
87
+ * @type {number}
88
+ */
89
+ this.wins = data[`wins_${gamemode}`] || 0;
90
+ /**
91
+ * Losses
92
+ * @type {number}
93
+ */
94
+ this.losses = data[`losses_${gamemode}`] || 0;
95
+ /**
96
+ * WLRatio
97
+ * @type {number}
98
+ */
99
+ this.WLRatio = divide(data.wins, data.losses);
100
+ }
101
+ }
102
+ class SkywarsModeStats {
103
+ /**
104
+ * @param {object} data Skywars data
105
+ * @param {string} gamemode Gamemode Name
106
+ */
107
+ constructor(data, gamemode) {
108
+ /**
109
+ * Active Kit
110
+ * @type {string}
111
+ */
112
+ this.activeKit = data[`activeKit_${gamemode.toUpperCase()}`] || '';
113
+ /**
114
+ * Kill Streak
115
+ * @type {number}
116
+ */
117
+ this.killstreak = data[`killstreak_${gamemode}`] || 0;
118
+ /**
119
+ * Kills
120
+ * @type {number}
121
+ */
122
+ this.kills = data[`kills_${gamemode}`] || 0;
123
+ /**
124
+ * Void Kills
125
+ * @type {number}
126
+ */
127
+ this.voidKills = data[`void_kills_${gamemode}`] || 0;
128
+ /**
129
+ * Melee Kills
130
+ * @type {number}
131
+ */
132
+ this.meleeKills = data[`melee_kills_${gamemode}`] || 0;
133
+ /**
134
+ * Bow Kills
135
+ * @type {number}
136
+ */
137
+ this.bowKills = data[`bow_kills_${gamemode}`] || 0;
138
+ /**
139
+ * Mob Kills
140
+ * @type {number}
141
+ */
142
+ this.mobKills = data[`mob_kills_${gamemode}`] || 0;
143
+ /**
144
+ * Assists
145
+ * @type {number}
146
+ */
147
+ this.assists = data[`assists_${gamemode}`] || 0;
148
+ /**
149
+ * Deaths
150
+ * @type {number}
151
+ */
152
+ this.deaths = data[`deaths_${gamemode}`] || 0;
153
+ /**
154
+ * KDRatio
155
+ * @type {number}
156
+ */
157
+ this.KDRatio = divide(data.kills, data.deaths);
158
+ /**
159
+ * Wins
160
+ * @type {number}
161
+ */
162
+ this.wins = data[`wins_${gamemode}`] || 0;
163
+ /**
164
+ * Losses
165
+ * @type {number}
166
+ */
167
+ this.losses = data[`losses_${gamemode}`] || 0;
168
+ /**
169
+ * WLRatio
170
+ * @type {number}
171
+ */
172
+ this.WLRatio = divide(data.wins, data.losses);
173
+ /**
174
+ * Games Played
175
+ * @type {number}
176
+ */
177
+ this.gamesPlayed = data[`games_${gamemode}`] || 0;
178
+ /**
179
+ * Survived Players
180
+ * @type {number}
181
+ */
182
+ this.survivedPlayers = data[`survived_players_${gamemode}`] || 0;
183
+ /**
184
+ * Chests Opened
185
+ * @type {number}
186
+ */
187
+ this.chestsOpened = data[`chests_opened_${gamemode}`] || 0;
188
+ /**
189
+ * Time Played (In Seconds)
190
+ * @type {number}
191
+ */
192
+ this.timePlayed = data[`time_played_${gamemode}`] || 0;
193
+ /**
194
+ * Shard
195
+ * @type {number}
196
+ */
197
+ this.shard = data[`shard_${gamemode}`] || 0;
198
+ /**
199
+ * Longest Bow Shot
200
+ * @type {number}
201
+ */
202
+ this.longestBowShot = data[`longest_bow_shot_${gamemode}`] || 0;
203
+ /**
204
+ * Arrows Shot
205
+ * @type {number}
206
+ */
207
+ this.arrowsShot = data[`arrows_shot_${gamemode}`] || 0;
208
+ /**
209
+ * Arrows Hit
210
+ * @type {number}
211
+ */
212
+ this.arrowsHit = data[`arrows_hit_${gamemode}`] || 0;
213
+ /**
214
+ * Bow Accuracy
215
+ * @type {number}
216
+ */
217
+ this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot);
218
+ /**
219
+ * Fastest Win (In Seconds)
220
+ * @type {number}
221
+ */
222
+ this.fastestWin = data[`fastest_win_${gamemode}`] || 0;
223
+ /**
224
+ * Heads
225
+ * @type {number}
226
+ */
227
+ this.heads = data[`heads_${gamemode}`] || 0;
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Parses SkyWars Kit
233
+ */
234
+ class SkywarsKit {
235
+ /**
236
+ * Constructor
237
+ * @param {string} kit Kit
238
+ w */
239
+ constructor(kit) {
240
+ /**
241
+ * Kit data
242
+ * @private
243
+ * @type {string[] | null}
244
+ */
245
+ this.kitData = kit.match(/^kit_([a-z]+)_([a-z]+)_([a-z]+)$/);
246
+ /**
247
+ * Is this a kit
248
+ * @type {boolean}
249
+ */
250
+ this.isKit = Boolean(this.kitData);
251
+ if (!this.kitData) return;
252
+ /**
253
+ * Game mode the kit is for
254
+ * @type {KitGameModes}
255
+ */
256
+ this.gameMode = this.kitData[2];
257
+ /**
258
+ * Kit type
259
+ * @type {KitType}
260
+ */
261
+ this.kitType = this.kitData[1];
262
+ /**
263
+ * Kit name in camelCase
264
+ * @type {string}
265
+ */
266
+ this.kitName = removeSnakeCaseString(this.kitData[3]);
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Parses SkyWars Kits
272
+ */
273
+ class SkywarsKits {
274
+ /**
275
+ * Constructor
276
+ * @param {SkywarsKit[]} kits Potential Kits
277
+ w */
278
+ constructor(kits) {
279
+ this.kits = kits.map((kit) => new SkywarsKit(kit)).filter((kit) => kit.isKit);
280
+ }
281
+ /**
282
+ * Get kit by type/gameMode
283
+ * @param {KitGameModes} [gameMode] Kits in said game mode
284
+ * @param {KitType} [type] Kits corresponding to this type
285
+ * @returns {SkywarsKit[]}
286
+ w */
287
+ get(gameMode = '', type = '') {
288
+ return this.kits.filter((kit) => kit.gameMode.startsWith(gameMode) && kit.kitType.startsWith(type));
289
+ }
290
+ }
291
+ /**
292
+ * Skywars Packages - parses every package player has
293
+ */
294
+ class SkywarsPackages {
295
+ /**
296
+ * Constructor
297
+ * @param {string[]} data data from API
298
+ w */
299
+ constructor(data) {
300
+ // TODO : a lot more
301
+ /**
302
+ * Raw Packages, as received from the API
303
+ * @type {string[]}
304
+ */
305
+ this.rawPackages = data;
306
+ /**
307
+ * Cages
308
+ * @type {string[]}
309
+ */
310
+ this.cages = this.parseCages();
311
+ /**
312
+ * Kits
313
+ * @type {SkywarsKits}
314
+ */
315
+ this.kits = new SkywarsKits(data);
316
+ /**
317
+ * Achievements included in packages, under the form of name0
318
+ * @type {string[]}
319
+ */
320
+ this.achievements = this.rawPackages
321
+ .map((pkg) => pkg.match(/^([A-Za-z]+)_?achievement([0-9]?)$/))
322
+ .filter((x) => x)
323
+ .map((x) => x.slice(1).join(''));
324
+ }
325
+ /**
326
+ * Parses cages
327
+ * @returns {string[]}
328
+ w */
329
+ parseCages() {
330
+ return this.rawPackages
331
+ .map((pkg) => pkg.match(/^cage_([A-Za-z]+)-cage$/))
332
+ .filter((x) => x)
333
+ .map((x) => x[1].replace(/-[a-z]/g, (x) => x[1].toUpperCase()));
334
+ }
335
+ }
336
+
337
+ /**
338
+ * @typedef {string} KitType
339
+ * * basic
340
+ * * supporting
341
+ * * mining
342
+ * * defending
343
+ * * attacking
344
+ * * advanced
345
+ * * enderchest
346
+ */
347
+ /**
348
+ * @typedef {string} KitGameModes
349
+ * * solo
350
+ * * team
351
+ */
352
+
14
353
  /**
15
354
  * SkyWars class
16
355
  */
17
356
  class SkyWars {
18
357
  /**
19
358
  * @param {object} data SkyWars data
20
- */
359
+ w */
21
360
  constructor(data) {
22
361
  /**
23
- * Coins
362
+ * Coins
363
+ * @type {number}
364
+ */
365
+ this.coins = data.coins || 0;
366
+ /**
367
+ * Souls
368
+ * @type {number}
369
+ */
370
+ this.souls = data.souls || 0;
371
+ /**
372
+ * Tokens
373
+ * @type {number}
374
+ */
375
+ this.tokens = data.cosmetic_tokens || 0;
376
+ /**
377
+ * Experience
378
+ * @type {number}
379
+ */
380
+ this.experience = data.skywars_experience || 0;
381
+ /**
382
+ * Level
383
+ * @type {number}
384
+ */
385
+ this.level = getSkyWarsLevel(data.skywars_experience);
386
+ /**
387
+ * Level Progress
388
+ * @type {LevelProgress}
389
+ */
390
+ this.levelProgress = getSkyWarsLevelProgress(data.skywars_experience);
391
+ /**
392
+ * Formatted Level
393
+ * @type {string}
394
+ */
395
+ this.levelFormatted = data.levelFormatted
396
+ ? data.levelFormatted
397
+ .replace(/§l/gm, '**')
398
+ .replace(/§([a-f]|[1-9])/gm, '')
399
+ .replace(/§r/gm, '')
400
+ : null;
401
+ /**
402
+ * Prestige
403
+ * @type {SkyWarsPrestige}
404
+ */
405
+ this.prestige = getSkyWarsPrestige(this.level);
406
+ /**
407
+ * Prestige Icons
408
+ * @type {SkyWarsPrestigeIcons}
409
+ */
410
+ this.prestigeIcon = data.selected_prestige_icon ? SkyWarsPrestigeIcons[data.selected_prestige_icon] : null;
411
+ /**
412
+ * Opals
413
+ * @type {number}
414
+ */
415
+ this.opals = data.opals || 0;
416
+ /**
417
+ * Avarice
418
+ * @type {number}
419
+ */
420
+ this.avarice = data.avarice || 0;
421
+ /**
422
+ * Tenacity
423
+ * @type {number}
424
+ */
425
+ this.tenacity = data.tenacity || 0;
426
+ /**
427
+ * Shards
428
+ * @type {number}
429
+ */
430
+ this.shards = data.shard || 0;
431
+ /**
432
+ * Angel Of Death Level
24
433
  * @type {number}
25
434
  */
26
- this.coins = data.coins || 0;
435
+ this.angelOfDeathLevel = data.angel_of_death_level || 0;
436
+
27
437
  /**
28
- * Souls
438
+ * Killstreak
29
439
  * @type {number}
30
440
  */
31
- this.souls = data.souls || 0;
441
+ this.killstreak = data.killstreak || 0;
32
442
  /**
33
- * Tokens
443
+ * kills
34
444
  * @type {number}
35
445
  */
36
- this.tokens = data.cosmetic_tokens || 0;
446
+ this.kills = data.kills || 0;
37
447
  /**
38
- * Winstreak
448
+ * Void Kills
39
449
  * @type {number}
40
450
  */
41
- this.winstreak = data.win_streak || 0;
451
+ this.voidKills = data.void_kills || 0;
42
452
  /**
43
- * Kills
453
+ * Melee Kills
44
454
  * @type {number}
45
455
  */
46
- this.kills = data.kills || 0;
456
+ this.meleeKills = data.melee_kills || 0;
47
457
  /**
48
- * Losses
458
+ * Bow Kills
49
459
  * @type {number}
50
460
  */
51
- this.losses = data.losses || 0;
461
+ this.bowKills = data.bow_kills || 0;
462
+ /**
463
+ * Mob Kills
464
+ * @type {number}
465
+ */
466
+ this.mobKills = data.mob_kills || 0;
467
+ /**
468
+ * Assists
469
+ * @type {number}
470
+ */
471
+ this.assists = data.assists || 0;
52
472
  /**
53
473
  * Deaths
54
474
  * @type {number}
55
475
  */
56
476
  this.deaths = data.deaths || 0;
477
+ /**
478
+ * KDRatio
479
+ * @type {number}
480
+ */
481
+ this.KDRatio = divide(data.kills, data.deaths);
57
482
  /**
58
483
  * Wins
59
484
  * @type {number}
60
485
  */
61
486
  this.wins = data.wins || 0;
62
487
  /**
63
- * Heads
488
+ * Losses
64
489
  * @type {number}
65
490
  */
66
- this.heads = data.heads || 0;
491
+ this.losses = data.losses || 0;
67
492
  /**
68
- * Experience
493
+ * WLRatio
69
494
  * @type {number}
70
495
  */
71
- this.experience = data.skywars_experience || 0;
496
+ this.WLRatio = divide(data.wins, data.losses);
72
497
  /**
73
- * Level
498
+ * Games Played
74
499
  * @type {number}
75
500
  */
76
- this.level = getSkyWarsLevel(data.skywars_experience);
501
+ this.gamesPlayed = data.games || 0;
77
502
  /**
78
- * Level Progress
79
- * @type {LevelProgress}
503
+ * Survived Players
504
+ * @type {number}
80
505
  */
81
- this.levelProgress = getSkyWarsLevelProgress(data.skywars_experience);
506
+ this.survivedPlayers = data.survived_players || 0;
82
507
  /**
83
- * Formatted Level
84
- * @type {string}
508
+ * Chests Opened
509
+ * @type {number}
85
510
  */
86
- this.levelFormatted = data.levelFormatted
87
- ? data.levelFormatted
88
- .replace(/§l/gm, '**')
89
- .replace(/§([a-f]|[1-9])/gm, '')
90
- .replace(/§r/gm, '')
91
- : null;
511
+ this.chestsOpened = data.chests_opened || 0;
92
512
  /**
93
- * Prestige
94
- * @type {SkyWarsPrestige}
513
+ * Time Played (In Seconds)
514
+ * @type {number}
95
515
  */
96
- this.prestige = getSkyWarsPrestige(this.level);
516
+ this.timePlayed = data.time_played || 0;
97
517
  /**
98
- * Prestige Icons
99
- * @type {SkyWarsPrestigeIcons}
518
+ * Shard
519
+ * @type {number}
100
520
  */
101
- this.prestigeIcon = data.selected_prestige_icon ? SkyWarsPrestigeIcons[data.selected_prestige_icon] : null;
521
+ this.shard = data.shard || 0;
102
522
  /**
103
- * Games Played ( Total )
523
+ * Longest Bow Shot
104
524
  * @type {number}
105
525
  */
106
- this.playedGames =
107
- (data.games_solo || 0) +
108
- (data.games_team || 0) +
109
- (data.games_mega || 0) +
110
- (data.games_mega_doubles || 0) +
111
- (data.games_lab || 0);
526
+ this.longestBowShot = data.longest_bow_shot || 0;
112
527
  /**
113
- * Global Kill Death Ratio
528
+ * Arrows Shot
114
529
  * @type {number}
115
530
  */
116
- this.KDRatio = divide(this.kills, this.deaths);
531
+ this.arrowsShot = data.arrows_shot || 0;
117
532
  /**
118
- * Global Win Loss Ratio
533
+ * Arrows Hit
119
534
  * @type {number}
120
535
  */
121
- this.WLRatio = divide(this.wins, this.losses);
536
+ this.arrowsHit = data.arrows_hit || 0;
122
537
  /**
123
- * Opals
538
+ * Bow Accuracy
124
539
  * @type {number}
125
540
  */
126
- this.opals = data.opals || 0;
541
+ this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot);
127
542
  /**
128
- * Avarice
543
+ * Fastest Win
129
544
  * @type {number}
130
545
  */
131
- this.avarice = data.avarice || 0;
546
+ this.fastestWin = data.fastest_win || 0;
132
547
  /**
133
- * Tenacity
548
+ * Heads
134
549
  * @type {number}
135
550
  */
136
- this.tenacity = data.tenacity || 0;
551
+ this.heads = data.heads || 0;
137
552
  /**
138
- * Shards
553
+ * Blocks Placed
139
554
  * @type {number}
140
555
  */
141
- this.shards = data.shard || 0;
556
+ this.blocksPlaced = data.blocks_placed || 0;
142
557
  /**
143
- * Angel Of Death Level
558
+ * Blocks Broken
144
559
  * @type {number}
145
560
  */
146
- this.angelOfDeathLevel = data.angel_of_death_level || 0;
561
+ this.blocksBroken = data.blocks_broken || 0;
562
+ /**
563
+ * Egg Thrown
564
+ * @type {number}
565
+ */
566
+ this.eggThrown = data.egg_thrown || 0;
147
567
  /**
148
- * Shard By Mode
149
- * @type {SkyWarsShardsInMode}
568
+ * Enderpearls Thrown
569
+ * @type {number}
150
570
  */
151
- this.shardsInMode = {
152
- solo: data.shard_solo || 0,
153
- team: data.shard_team || 0,
154
- mega: (data.shard_mega || 0) + (data.shard_mega_doubles || 0),
155
- lab: data.shard_lab || 0
156
- };
571
+ this.enderpearlsThrown = data.enderpearls_thrown || 0;
572
+
157
573
  /**
158
574
  * Solo Skywars Stats
159
- * @type {SkyWarsModeExtendedStats}
160
- */
161
- this.solo = {
162
- overall: {
163
- winstreak: data.winstreak_solo || 0,
164
- playedGames: data.games_solo || 0,
165
- kills: data.kills_solo || 0,
166
- wins: data.wins_solo || 0,
167
- losses: data.losses_solo || 0,
168
- deaths: data.deaths_solo || 0,
169
- KDRatio: divide(data.kills_solo, data.deaths_solo),
170
- WLRatio: divide(data.wins_solo, data.losses_solo)
171
- },
172
- normal: generateStatsForMode(data, 'solo_normal'),
173
- insane: generateStatsForMode(data, 'solo_insane')
174
- };
575
+ * @type {SkywarsModeStats}
576
+ */
577
+ this.solo = new SkywarsModeStats(data, 'solo');
578
+ /**
579
+ * Solo Normal Stats
580
+ * @type {SkywarsMode}
581
+ */
582
+ this.soloNormal = new SkywarsMode(data, 'solo_normal');
583
+ /**
584
+ * Solo Insane Stats
585
+ * @type {SkywarsMode}
586
+ */
587
+ this.soloInsane = new SkywarsMode(data, 'solo_insane');
175
588
  /**
176
589
  * Team Skywars Stats
177
- * @type {SkyWarsModeExtendedStats}
178
- */
179
- this.team = {
180
- overall: {
181
- winstreak: data.winstreak_team || 0,
182
- playedGames: data.games_team || 0,
183
- kills: data.kills_team || 0,
184
- wins: data.wins_team || 0,
185
- losses: data.losses_team || 0,
186
- deaths: data.deaths_team || 0,
187
- KDRatio: divide(data.kills_team, data.deaths_team),
188
- WLRatio: divide(data.wins_team, data.losses_team)
189
- },
190
- normal: generateStatsForMode(data, 'team_normal'),
191
- insane: generateStatsForMode(data, 'team_insane')
192
- };
590
+ * @type {SkywarsModeStats}
591
+ */
592
+ this.team = new SkywarsModeStats(data, 'team');
593
+ /**
594
+ * Team Normal Stats
595
+ * @type {SkywarsMode}
596
+ */
597
+ this.teamNormal = new SkywarsMode(data, 'team_normal');
598
+ /**
599
+ * Team Insane Stats
600
+ * @type {SkywarsMode}
601
+ */
602
+ this.teamInsane = new SkywarsMode(data, 'team_insane');
193
603
  /**
194
604
  * Mega Skywars Stats
195
- * @type {SkyWarsMegaStats}
196
- */
197
- this.mega = {
198
- overall: {
199
- winstreak: data.winstreak_mega || 0,
200
- playedGames: (data.games_mega || 0) + (data.games_mega_doubles || 0),
201
- kills: (data.kills_mega || 0) + (data.kills_mega_doubles || 0),
202
- wins: (data.wins_mega || 0) + (data.wins_mega_doubles || 0),
203
- losses: (data.losses_mega || 0) + (data.losses_mega_doubles || 0),
204
- deaths: (data.deaths_mega || 0) + (data.deaths_mega_doubles || 0),
205
- KDRatio: divide(
206
- (data.kills_mega || 0) + (data.kills_mega_doubles || 0),
207
- (data.deaths_mega || 0) + (data.deaths_mega_doubles || 0)
208
- ),
209
- WLRatio: divide(
210
- (data.wins_mega || 0) + (data.wins_mega_doubles || 0),
211
- (data.losses_mega || 0) + (data.losses_mega_doubles || 0)
212
- )
213
- },
214
- solo: {
215
- playedGames: data.games_mega || 0,
216
- kills: data.kills_mega || 0,
217
- wins: data.wins_mega || 0,
218
- losses: data.losses_mega || 0,
219
- deaths: data.deaths_mega || 0,
220
- KDRatio: divide(data.kills_mega || 0, data.deaths_mega || 0),
221
- WLRatio: divide(data.wins_mega || 0, data.losses_mega || 0)
222
- },
223
- doubles: {
224
- playedGames: data.games_mega_doubles || 0,
225
- kills: data.kills_mega_doubles || 0,
226
- wins: data.wins_mega_doubles || 0,
227
- losses: data.losses_mega_doubles || 0,
228
- deaths: data.deaths_mega_doubles || 0,
229
- KDRatio: divide(data.kills_mega_doubles || 0, data.deaths_mega_doubles || 0),
230
- WLRatio: divide(data.wins_mega_doubles || 0, data.losses_mega_doubles || 0)
231
- }
232
- };
605
+ * @type {SkywarsMode}
606
+ */
607
+ this.mega = new SkywarsMode(data, 'mega');
608
+ /**
609
+ * Mega Doubles Skywars Stats
610
+ * @type {SkywarsMode}
611
+ */
612
+ this.megaDoubles = new SkywarsMode(data, 'mega_doubles');
233
613
  /**
234
614
  * Skywars Laboratory Stats
235
- * @type {SkyWarsTotalModeStats}
236
- */
237
- this.lab = {
238
- winstreak: data.winstreak_lab || 0,
239
- playedGames: data.games_lab || 0,
240
- kills: data.kills_lab || 0,
241
- wins: data.wins_lab || 0,
242
- losses: data.losses_lab || 0,
243
- deaths: data.deaths_lab || 0,
244
- KDRatio: divide(data.kills_lab, data.deaths_lab),
245
- WLRatio: divide(data.wins_lab, data.losses_lab)
246
- };
615
+ * @type {SkywarsMode}
616
+ */
617
+ this.lab = new SkywarsMode(data, 'lab');
247
618
  /**
248
619
  * Player Packages, can range from kits to achievement
249
620
  * @type {SkywarsPackages}
@@ -294,220 +665,5 @@ class SkyWars {
294
665
  * * 'ಠ_ಠ',
295
666
  * * '⚔'
296
667
  */
297
- /**
298
- * @typedef {Object} SkyWarsModeStats
299
- * @property {number} kills Kills
300
- * @property {number} deaths Deaths
301
- * @property {number} wins Wins
302
- * @property {number} losses Losses
303
- * @property {number} KDRatio Kill Death ratio
304
- * @property {number} WLRatio Win Loss ratio
305
- */
306
- /**
307
- * @typedef {Object} SkyWarsTotalModeStats
308
- * @property {number} winstreak Winstreak
309
- * @property {number} playedGames Played games
310
- * @property {number} kills Kills
311
- * @property {number} deaths Deaths
312
- * @property {number} wins Wins
313
- * @property {number} losses Losses
314
- * @property {number} KDRatio Kill Death ratio
315
- * @property {number} WLRatio Win Loss ratio
316
- */
317
- /**
318
- * @typedef {string} PseudoDate String date, in the format of MM-YY ( YY is 20YY )
319
- * @example `10-19` would be October 2019.
320
- */
321
- /**
322
- * @typedef {Object} SkyWarsModeExtendedStats
323
- * @property {SkyWarsTotalModeStats} overall Overall Stats
324
- * @property {SkyWarsModeStats} normal Normal Mode Stats
325
- * @property {SkyWarsModeStats} insane Insane Mode Stats
326
- */
327
- /**
328
- * @typedef {Object} SkyWarsMegaStats
329
- * @property {SkyWarsTotalModeStats} overall Overall Mega Stats
330
- * @property {SkyWarsModeStats} solo Mega Solo Stats
331
- * @property {SkyWarsModeStats} doubles Mega Doubles Stats
332
- */
333
- module.exports = SkyWars;
334
- // eslint-disable-next-line require-jsdoc
335
- function getSkyWarsPrestige(level) {
336
- if (level >= 60) return 'Mythic';
337
- return (
338
- ['Iron', 'Iron', 'Gold', 'Diamond', 'Emerald', 'Sapphire', 'Ruby', 'Crystal', 'Opal', 'Amethyst', 'Rainbow'][
339
- Math.floor(level / 5)
340
- ] || 'Iron'
341
- );
342
- }
343
- // eslint-disable-next-line require-jsdoc
344
- function getSkyWarsLevel(xp) {
345
- const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
346
- if (xp >= 15000) return Math.floor((xp - 15000) / 10000 + 12);
347
- const level = totalXp.findIndex((x) => x * 10 - xp > 0);
348
- return level; /* + (xp - (totalXp[level - 1] * 10 || 0)) / (totalXp[level] - totalXp[level - 1]) / 10*/
349
- }
350
- // eslint-disable-next-line require-jsdoc
351
- function getSkyWarsLevelProgress(xp) {
352
- const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
353
- const xpToNextLvl = [0, 2, 5, 8, 10, 25, 50, 100, 150, 250, 400, 500]; // * 10
354
- let percent;
355
- let xpToNextLevel;
356
- let currentLevelXp = xp;
357
- if (xp >= 15000) {
358
- currentLevelXp -= 15000;
359
- if (currentLevelXp === 0) return { currentLevelXp: 0, xpToNextLevel: 10000, percent: 0, xpNextLevel: 10000 };
360
- if (currentLevelXp > 10000) {
361
- do {
362
- currentLevelXp -= 10000;
363
- } while (currentLevelXp >= 10000);
364
- }
365
- xpToNextLevel = 10000 - currentLevelXp;
366
- percent = Math.round(currentLevelXp) / 100;
367
- const percentRemaining = Math.round((100 - percent) * 100) / 100;
368
- return {
369
- currentLevelXp,
370
- xpToNextLevel,
371
- percent,
372
- xpNextLevel: 10000,
373
- percentRemaining
374
- };
375
- }
376
- const totalXptoNextLevel = xpToNextLvl[totalXp.findIndex((x) => x * 10 - xp > 0)] * 10;
377
- for (let i = 0; i < xpToNextLvl.length; i++) {
378
- if (currentLevelXp - xpToNextLvl[i] * 10 < 0) break;
379
- currentLevelXp -= xpToNextLvl[i] * 10;
380
- }
381
- xpToNextLevel = totalXptoNextLevel - currentLevelXp;
382
- percent = Math.round((currentLevelXp / totalXptoNextLevel) * 10000) / 100;
383
- return {
384
- currentLevelXp,
385
- xpToNextLevel,
386
- percent,
387
- xpNextLevel: totalXptoNextLevel
388
- };
389
- }
390
- const ratingRegex = /^SkyWars_skywars_rating_(\d{1,2})_(\d{1,2})_(position|rating)$/;
391
-
392
- /**
393
- * Skywars Packages - parses every package player has
394
- */
395
- class SkywarsPackages {
396
- /**
397
- * Constructor
398
- * @param {string[]} data data from API
399
- */
400
- constructor(data) {
401
- // TODO : a lot more
402
- /**
403
- * Raw Packages, as received from the API
404
- * @type {string[]}
405
- */
406
- this.rawPackages = Array.from(data);
407
- /**
408
- * Cages
409
- * @type {string[]}
410
- */
411
- this.cages = this._parseCages();
412
- /**
413
- * Kits
414
- * @type {SkywarsKits}
415
- */
416
- this.kits = new SkywarsKits(data);
417
- /**
418
- * Achievements included in packages, under the form of name0
419
- * @type {string[]}
420
- */
421
- this.achievements = this.rawPackages
422
- .map((pkg) => pkg.match(/^([A-z]+)_?achievement([0-9]?)$/))
423
- .filter((x) => x)
424
- .map((x) => x.slice(1).join(''));
425
- }
426
- /**
427
- * Parses cages
428
- * @returns {string[]}
429
- */
430
- _parseCages() {
431
- return this.rawPackages
432
- .map((pkg) => pkg.match(/^cage_([A-z]+)-cage$/))
433
- .filter((x) => x)
434
- .map((x) => x[1].replace(/-[a-z]/g, (x) => x[1].toUpperCase()));
435
- }
436
- }
437
-
438
- /**
439
- * Parses SkyWars Kits
440
- */
441
- class SkywarsKit {
442
- /**
443
- * Constructor
444
- * @param {string} kit Kit
445
- */
446
- constructor(kit) {
447
- /**
448
- * Kit data
449
- * @private
450
- * @type {string[] | null}
451
- */
452
- this._kitData = kit.match(/^kit_([a-z]+)_([a-z]+)_([a-z]+)$/);
453
- /**
454
- * Is this a kit
455
- * @type {boolean}
456
- */
457
- this.isKit = !!this._kitData;
458
- if (!this._kitData) return;
459
- /**
460
- * Game mode the kit is for
461
- * @type {KitGameModes}
462
- */
463
- this.gameMode = this._kitData[2];
464
- /**
465
- * Kit type
466
- * @type {KitType}
467
- */
468
- this.kitType = this._kitData[1];
469
- /**
470
- * Kit name in camelCase
471
- * @type {string}
472
- */
473
- this.kitName = removeSnakeCaseString(this._kitData[3]);
474
- }
475
- }
476
-
477
- /**
478
- * Parses SkyWars Kits
479
- */
480
- class SkywarsKits {
481
- /**
482
- * Constructor
483
- * @param {SkywarsKit[]} kits Potential Kits
484
- */
485
- constructor(kits) {
486
- this.kits = kits.map((kit) => new SkywarsKit(kit)).filter((kit) => kit.isKit);
487
- }
488
- /**
489
- * Get kit by type/gameMode
490
- * @param {KitGameModes} [gameMode] Kits in said game mode
491
- * @param {KitType} [type] Kits corresponding to this type
492
- * @returns {SkywarsKit[]}
493
- */
494
- get(gameMode = '', type = '') {
495
- return this.kits.filter((kit) => kit.gameMode.startsWith(gameMode) && kit.kitType.startsWith(type));
496
- }
497
- }
498
668
 
499
- /**
500
- * @typedef {string} KitType
501
- * * basic
502
- * * supporting
503
- * * mining
504
- * * defending
505
- * * attacking
506
- * * advanced
507
- * * enderchest
508
- */
509
- /**
510
- * @typedef {string} KitGameModes
511
- * * solo
512
- * * team
513
- */
669
+ module.exports = SkyWars;