hypixel-api-reborn 10.0.0 → 11.0.1

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 -8
  5. package/src/API/getBoosters.js +6 -6
  6. package/src/API/getGameCounts.js +6 -6
  7. package/src/API/getGuild.js +18 -18
  8. package/src/API/getLeaderboards.js +13 -13
  9. package/src/API/getPlayer.js +22 -27
  10. package/src/API/getRecentGames.js +18 -18
  11. package/src/API/getServerInfo.js +66 -77
  12. package/src/API/getStatus.js +8 -8
  13. package/src/API/getWatchdogStats.js +6 -6
  14. package/src/API/index.js +19 -23
  15. package/src/API/skyblock/getEndedSkyblockAuctions.js +10 -10
  16. package/src/API/skyblock/getSkyblockAuctions.js +64 -64
  17. package/src/API/skyblock/getSkyblockAuctionsByPlayer.js +11 -11
  18. package/src/API/skyblock/getSkyblockBazaar.js +10 -10
  19. package/src/API/skyblock/getSkyblockMember.js +28 -25
  20. package/src/API/skyblock/getSkyblockNews.js +6 -6
  21. package/src/API/skyblock/getSkyblockProfiles.js +44 -41
  22. package/src/Client.js +406 -450
  23. package/src/Errors.js +44 -39
  24. package/src/Private/defaultCache.js +77 -78
  25. package/src/Private/rateLimit.js +79 -98
  26. package/src/Private/requests.js +65 -54
  27. package/src/Private/updater.js +45 -45
  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 -351
  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 -630
  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 -176
  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 -449
  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 -130
  79. package/src/structures/SkyBlock/SkyblockMember.js +820 -687
  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 -809
  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 -13
  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 -8
  95. package/src/utils/romanize.js +11 -13
  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 -2644
  100. package/src/API/getFriends.js +0 -14
  101. package/src/API/getKeyInfo.js +0 -10
  102. package/src/API/getRankedSkyWars.js +0 -11
  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,559 +1,508 @@
1
- const { SkyWarsPrestigeIcons } = require('../../utils/Constants');
2
- const divide = require('../../utils/divide');
3
- const { removeSnakeCaseString } = require('../../utils/removeSnakeCase');
4
- const generateStatsForMode = (data, mode) => {
5
- 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}`])
12
- };
13
- };
14
- /**
15
- * SkyWars class
16
- */
17
- class SkyWars {
18
- /**
19
- * @param {object} data SkyWars data
20
- * @param {object|null} extraRSWData Extra Ranked Skywars data, if any
21
- */
22
- constructor (data, extraRSWData) {
23
- /**
24
- * Coins
25
- * @type {number}
26
- */
27
- this.coins = data.coins || 0;
28
- /**
29
- * Souls
30
- * @type {number}
31
- */
32
- this.souls = data.souls || 0;
33
- /**
34
- * Tokens
35
- * @type {number}
36
- */
37
- this.tokens = data.cosmetic_tokens || 0;
38
- /**
39
- * Winstreak
40
- * @type {number}
41
- */
42
- this.winstreak = data.win_streak || 0;
43
- /**
44
- * Kills
45
- * @type {number}
46
- */
47
- this.kills = data.kills || 0;
48
- /**
49
- * Losses
50
- * @type {number}
51
- */
52
- this.losses = data.losses || 0;
53
- /**
54
- * Deaths
55
- * @type {number}
56
- */
57
- this.deaths = data.deaths || 0;
58
- /**
59
- * Wins
60
- * @type {number}
61
- */
62
- this.wins = data.wins || 0;
63
- /**
64
- * Loot Chests
65
- * @type {number}
66
- */
67
- this.lootChests = data.skywars_chests || 0;
68
- /**
69
- * Opened Loot Chests
70
- * @type {number}
71
- */
72
- this.openedLootChests = data.SkyWars_openedChests || 0;
73
- /**
74
- * Heads
75
- * @type {number}
76
- */
77
- this.heads = data.heads || 0;
78
- /**
79
- * Experience
80
- * @type {number}
81
- */
82
- this.experience = data.skywars_experience || 0;
83
- /**
84
- * Level
85
- * @type {number}
86
- */
87
- this.level = getSkyWarsLevel(data.skywars_experience);
88
- /**
89
- * Level Progress
90
- * @type {LevelProgress}
91
- */
92
- this.levelProgress = getSkyWarsLevelProgress(data.skywars_experience);
93
- /**
94
- * Formatted Level
95
- * @type {string}
96
- */
97
- this.levelFormatted = data.levelFormatted ? (data.levelFormatted.replace(/§l/gm, '**').replace(/§([a-f]|[1-9])/gm, '').replace(/§r/gm, '')) : null;
98
- /**
99
- * Prestige
100
- * @type {SkyWarsPrestige}
101
- */
102
- this.prestige = getSkyWarsPrestige(this.level);
103
- /**
104
- * Prestige Icons
105
- * @type {SkyWarsPrestigeIcons}
106
- */
107
- this.prestigeIcon = data.selected_prestige_icon ? SkyWarsPrestigeIcons[data.selected_prestige_icon] : null;
108
- /**
109
- * Games Played ( Total )
110
- * @type {number}
111
- */
112
- this.playedGames = (data.games_solo || 0) + (data.games_team || 0) + (data.games_ranked || 0) + (data.games_mega || 0) + (data.games_mega_doubles || 0) + (data.games_lab || 0);
113
- /**
114
- * Global Kill Death Ratio
115
- * @type {number}
116
- */
117
- this.KDRatio = divide(this.kills, this.deaths);
118
- /**
119
- * Global Win Loss Ratio
120
- * @type {number}
121
- */
122
- this.WLRatio = divide(this.wins, this.losses);
123
- /**
124
- * Opals
125
- * @type {number}
126
- */
127
- this.opals = data.opals || 0;
128
- /**
129
- * Avarice
130
- * @type {number}
131
- */
132
- this.avarice = data.avarice || 0;
133
- /**
134
- * Tenacity
135
- * @type {number}
136
- */
137
- this.tenacity = data.tenacity || 0;
138
- /**
139
- * Shards
140
- * @type {number}
141
- */
142
- this.shards = data.shard || 0;
143
- /**
144
- * Angel Of Death Level
145
- * @type {number}
146
- */
147
- this.angelOfDeathLevel = data.angel_of_death_level || 0;
148
- /**
149
- * Shard By Mode
150
- * @type {SkyWarsShardsInMode}
151
- */
152
- this.shardsInMode = {
153
- solo: data.shard_solo || 0,
154
- team: data.shard_team || 0,
155
- ranked: data.shard_ranked || 0,
156
- mega: (data.shard_mega || 0) + (data.shard_mega_doubles || 0),
157
- lab: data.shard_lab || 0
158
- };
159
- /**
160
- * Solo Skywars Stats
161
- * @type {SkyWarsModeExtendedStats}
162
- */
163
- this.solo = {
164
- overall: {
165
- winstreak: data.winstreak_solo || 0,
166
- playedGames: data.games_solo || 0,
167
- kills: data.kills_solo || 0,
168
- wins: data.wins_solo || 0,
169
- losses: data.losses_solo || 0,
170
- deaths: data.deaths_solo || 0,
171
- KDRatio: divide(data.kills_solo, data.deaths_solo),
172
- WLRatio: divide(data.wins_solo, data.losses_solo)
173
- },
174
- normal: generateStatsForMode(data, 'solo_normal'),
175
- insane: generateStatsForMode(data, 'solo_insane')
176
- };
177
- /**
178
- * Team Skywars Stats
179
- * @type {SkyWarsModeExtendedStats}
180
- */
181
- this.team = {
182
- overall: {
183
- winstreak: data.winstreak_team || 0,
184
- playedGames: data.games_team || 0,
185
- kills: data.kills_team || 0,
186
- wins: data.wins_team || 0,
187
- losses: data.losses_team || 0,
188
- deaths: data.deaths_team || 0,
189
- KDRatio: divide(data.kills_team, data.deaths_team),
190
- WLRatio: divide(data.wins_team, data.losses_team)
191
- },
192
- normal: generateStatsForMode(data, 'team_normal'),
193
- insane: generateStatsForMode(data, 'team_insane')
194
- };
195
- /**
196
- * Ranked Skywars Stats
197
- * @type {SkyWarsTotalModeStats}
198
- */
199
- this.ranked = {
200
- winstreak: data.winstreak_ranked || 0,
201
- playedGames: data.games_ranked || 0,
202
- kills: data.kills_ranked || 0,
203
- wins: data.wins_ranked || 0,
204
- losses: data.losses_ranked || 0,
205
- deaths: data.deaths_ranked || 0,
206
- KDRatio: divide(data.kills_ranked, data.deaths_ranked),
207
- WLRatio: divide(data.wins_ranked, data.losses_ranked),
208
- ratings: getRankedPositions(data, extraRSWData)
209
- };
210
- /**
211
- * Mega Skywars Stats
212
- * @type {SkyWarsMegaStats}
213
- */
214
- this.mega = {
215
- overall: {
216
- winstreak: data.winstreak_mega || 0,
217
- playedGames: (data.games_mega || 0) + (data.games_mega_doubles || 0),
218
- kills: (data.kills_mega || 0) + (data.kills_mega_doubles || 0),
219
- wins: (data.wins_mega || 0) + (data.wins_mega_doubles || 0),
220
- losses: (data.losses_mega || 0) + (data.losses_mega_doubles || 0),
221
- deaths: (data.deaths_mega || 0) + (data.deaths_mega_doubles || 0),
222
- KDRatio: divide(((data.kills_mega || 0) + (data.kills_mega_doubles || 0)), ((data.deaths_mega || 0) + (data.deaths_mega_doubles || 0))),
223
- WLRatio: divide(((data.wins_mega || 0) + (data.wins_mega_doubles || 0)), ((data.losses_mega || 0) + (data.losses_mega_doubles || 0)))
224
- },
225
- solo: {
226
- playedGames: data.games_mega || 0,
227
- kills: data.kills_mega || 0,
228
- wins: data.wins_mega || 0,
229
- losses: data.losses_mega || 0,
230
- deaths: data.deaths_mega || 0,
231
- KDRatio: divide(data.kills_mega || 0, data.deaths_mega || 0),
232
- WLRatio: divide(data.wins_mega || 0, data.losses_mega || 0)
233
- },
234
- doubles: {
235
- playedGames: data.games_mega_doubles || 0,
236
- kills: data.kills_mega_doubles || 0,
237
- wins: data.wins_mega_doubles || 0,
238
- losses: data.losses_mega_doubles || 0,
239
- deaths: data.deaths_mega_doubles || 0,
240
- KDRatio: divide(data.kills_mega_doubles || 0, data.deaths_mega_doubles || 0),
241
- WLRatio: divide(data.wins_mega_doubles || 0, data.losses_mega_doubles || 0)
242
- }
243
- };
244
- /**
245
- * Skywars Laboratory Stats
246
- * @type {SkyWarsTotalModeStats}
247
- */
248
- this.lab = {
249
- winstreak: data.winstreak_lab || 0,
250
- playedGames: data.games_lab || 0,
251
- kills: data.kills_lab || 0,
252
- wins: data.wins_lab || 0,
253
- losses: data.losses_lab || 0,
254
- deaths: data.deaths_lab || 0,
255
- KDRatio: divide(data.kills_lab, data.deaths_lab),
256
- WLRatio: divide(data.wins_lab, data.losses_lab)
257
- };
258
- /**
259
- * Player Packages, can range from kits to achievement
260
- * @type {SkywarsPackages}
261
- */
262
- this.packages = new SkywarsPackages(data.packages || []);
263
- }
264
- }
265
- /**
266
- * @typedef {string} SkyWarsPrestige
267
- * * `Iron`
268
- * * `Iron`
269
- * * `Gold`
270
- * * `Diamond`
271
- * * `Emerald`
272
- * * `Sapphire`
273
- * * `Ruby`
274
- * * `Crystal`
275
- * * `Opal`
276
- * * `Amethyst`
277
- * * `Rainbow`
278
- * * `Mythic`
279
- */
280
- /**
281
- * @typedef {string} SkyWarsPrestigeIcons
282
- * * ''
283
- * * ''
284
- * * ''
285
- * * '',
286
- * * '',
287
- * * '',
288
- * * '',
289
- * * '',
290
- * * '',
291
- * * '',
292
- * * '',
293
- * * '',
294
- * * '',
295
- * * '✙',
296
- * * '❤️',
297
- * * '☠',
298
- * * '✦',
299
- * * '✌',
300
- * * '❦',
301
- * * '✵',
302
- * * '❣',
303
- * * '☯',
304
- * * '✺',
305
- * * 'ಠ_ಠ',
306
- * * '⚔'
307
- */
308
- /**
309
- * @typedef {Object} SkyWarsModeStats
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 {Object} SkyWarsTotalModeStats
319
- * @property {number} winstreak Winstreak
320
- * @property {number} playedGames Played games
321
- * @property {number} kills Kills
322
- * @property {number} deaths Deaths
323
- * @property {number} wins Wins
324
- * @property {number} losses Losses
325
- * @property {number} KDRatio Kill Death ratio
326
- * @property {number} WLRatio Win Loss ratio
327
- */
328
- /**
329
- * @typedef {Object} SkywarsRankedStats
330
- * @extends SkywarsTotalModeStats
331
- * @property {Map<PseudoDate,SkywarsRankData>} ratings Ratings & leaderboard positions
332
- */
333
- /**
334
- * @typedef {Object} SkywarsRankData
335
- * @property {number} rating Rating of player ( if not found, this is set to 0 )
336
- * @property {number} position Position of player ( if not found, this is set to 0 )
337
- * @property {Date} date Parsed date
338
- */
339
- /**
340
- * @typedef {string} PseudoDate String date, in the format of MM-YY ( YY is 20YY )
341
- * @example `10-19` would be October 2019.
342
- */
343
- /**
344
- * @typedef {Object} SkyWarsModeExtendedStats
345
- * @property {SkyWarsTotalModeStats} overall Overall Stats
346
- * @property {SkyWarsModeStats} normal Normal Mode Stats
347
- * @property {SkyWarsModeStats} insane Insane Mode Stats
348
- */
349
- /**
350
- * @typedef {Object} SkyWarsMegaStats
351
- * @property {SkyWarsTotalModeStats} overall Overall Mega Stats
352
- * @property {SkyWarsModeStats} solo Mega Solo Stats
353
- * @property {SkyWarsModeStats} doubles Mega Doubles Stats
354
- */
355
- module.exports = SkyWars;
356
- /**
357
- * @param {number} level
358
- * @return {string}
359
- */
360
- function getSkyWarsPrestige (level) {
361
- if (level >= 60) return 'Mythic';
362
- return ['Iron', 'Iron', 'Gold', 'Diamond', 'Emerald', 'Sapphire', 'Ruby', 'Crystal', 'Opal', 'Amethyst', 'Rainbow'][Math.floor(level / 5)] || 'Iron';
363
- }
364
- /**
365
- * @param {number} xp
366
- * @return {number}
367
- */
368
- function getSkyWarsLevel (xp) {
369
- const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
370
- if (xp >= 15000) return Math.floor((xp - 15000) / 10000 + 12);
371
- const level = totalXp.findIndex((x) => x * 10 - xp > 0);
372
- return level; /* + (xp - (totalXp[level - 1] * 10 || 0)) / (totalXp[level] - totalXp[level - 1]) / 10*/
373
- }
374
- /**
375
- * @param {number} xp
376
- * @return {{xpToNextLevel:number,percent:number,xpNextLevel:number}}
377
- */
378
- function getSkyWarsLevelProgress (xp) {
379
- const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
380
- const xpToNextLvl = [0, 2, 5, 8, 10, 25, 50, 100, 150, 250, 400, 500]; // * 10
381
- let percent;
382
- let xpToNextLevel;
383
- let currentLevelXp = xp;
384
- if (xp >= 15000) {
385
- currentLevelXp -= 15000;
386
- if (currentLevelXp === 0) return { currentLevelXp: 0, xpToNextLevel: 10000, percent: 0, xpNextLevel: 10000 };
387
- if (currentLevelXp > 10000) {
388
- do {
389
- currentLevelXp -= 10000;
390
- } while (currentLevelXp >= 10000);
391
- }
392
- xpToNextLevel = 10000 - currentLevelXp;
393
- percent = (Math.round(currentLevelXp) / 100);
394
- const percentRemaining = Math.round((100 - percent) * 100) / 100;
395
- return {
396
- currentLevelXp,
397
- xpToNextLevel,
398
- percent,
399
- xpNextLevel: 10000,
400
- percentRemaining
401
- };
402
- }
403
- const totalXptoNextLevel = xpToNextLvl[totalXp.findIndex((x) => x * 10 - xp > 0)] * 10;
404
- for (let i = 0; i < xpToNextLvl.length; i++) {
405
- if ((currentLevelXp - xpToNextLvl[i] * 10) < 0) break;
406
- currentLevelXp -= xpToNextLvl[i] * 10;
407
- }
408
- xpToNextLevel = totalXptoNextLevel - currentLevelXp;
409
- percent = (Math.round((currentLevelXp / totalXptoNextLevel) * 10000) / 100);
410
- return {
411
- currentLevelXp,
412
- xpToNextLevel,
413
- percent,
414
- xpNextLevel: totalXptoNextLevel
415
- };
416
- }
417
- const ratingRegex = /^SkyWars_skywars_rating_(\d{1,2})_(\d{1,2})_(position|rating)$/;
418
- /**
419
- * gets ratings & positions on the leaderboard
420
- * @param {Object} data data
421
- * @param {Object|null} extraRSWData extra data to be attached
422
- * @returns {SkywarsRankedStats} some map
423
- */
424
- function getRankedPositions (data, extraRSWData) {
425
- const map = new Map();
426
- const keys = Object.keys(data).map((key) => key.match(ratingRegex)).filter((x) => x);
427
- for (const key of keys) {
428
- let [property, month, year, type] = key;
429
- month = parseInt(month, 10);
430
- year = parseInt(year, 10);
431
- const computedKey = `${month}_${year}`;
432
- const initDate = new Date(1000 * 60 * 60 * 5);
433
- map.set(computedKey, {
434
- ...map.get(computedKey),
435
- 'seasonKey': computedKey,
436
- [type]: parseInt(data[property], 10) || 0,
437
- 'date': new Date(initDate.setFullYear(2000 + year, month - 1, 1))
438
- });
439
- }
440
- if (extraRSWData) map.set(extraRSWData.seasonKey, extraRSWData);
441
- return map;
442
- }
443
-
444
- /**
445
- * Skywars Packages - parses every package player has
446
- */
447
- class SkywarsPackages {
448
- /**
449
- * Constructor
450
- * @param {string[]} data data from API
451
- */
452
- constructor (data) {
453
- // TODO : a lot more
454
- /**
455
- * Raw Packages, as received from the API
456
- * @type {string[]}
457
- */
458
- this.rawPackages = Array.from(data);
459
- /**
460
- * Cages
461
- * @type {string[]}
462
- */
463
- this.cages = this._parseCages();
464
- /**
465
- * Kits
466
- * @type {SkywarsKits}
467
- */
468
- this.kits = new SkywarsKits(data);
469
- /**
470
- * Achievements included in packages, under the form of name0
471
- * @type {string[]}
472
- */
473
- this.achievements = this.rawPackages.map((pkg) => pkg.match(/^([A-z]+)_?achievement([0-9]?)$/)).filter((x) => x).map((x) => x.slice(1).join(''));
474
- }
475
- /**
476
- * Parses cages
477
- * @returns {string[]}
478
- */
479
- _parseCages () {
480
- return this.rawPackages.map((pkg) => pkg.match(/^cage_([A-z]+)-cage$/)).filter((x) => x).map((x) => x[1].replace(/-[a-z]/g, (x) => x[1].toUpperCase()));
481
- }
482
- }
483
-
484
- /**
485
- * Parses SkyWars Kits
486
- */
487
- class SkywarsKit {
488
- /**
489
- * Constructor
490
- * @param {string} kit Kit
491
- */
492
- constructor (kit) {
493
- /**
494
- * Kit data
495
- * @private
496
- * @type {string[] | null}
497
- */
498
- this._kitData = kit.match(/^kit_([a-z]+)_([a-z]+)_([a-z]+)$/);
499
- /**
500
- * Is this a kit
501
- * @type {boolean}
502
- */
503
- this.isKit = !!this._kitData;
504
- if (!this._kitData) return;
505
- /**
506
- * Game mode the kit is for
507
- * @type {KitGameModes}
508
- */
509
- this.gameMode = this._kitData[2];
510
- /**
511
- * Kit type
512
- * @type {KitType}
513
- */
514
- this.kitType = this._kitData[1];
515
- /**
516
- * Kit name in camelCase
517
- * @type {string}
518
- */
519
- this.kitName = removeSnakeCaseString(this._kitData[3]);
520
- }
521
- }
522
-
523
- /**
524
- * Parses SkyWars Kits
525
- */
526
- class SkywarsKits {
527
- /**
528
- * Constructor
529
- * @param {SkywarsKit[]} kits Potential Kits
530
- */
531
- constructor (kits) {
532
- this.kits = kits.map((kit) => new SkywarsKit(kit)).filter((kit) => kit.isKit);
533
- }
534
- /**
535
- * Get kit by type/gameMode
536
- * @param {KitGameModes} [gameMode] Kits in said game mode
537
- * @param {KitType} [type] Kits corresponding to this type
538
- * @returns {SkywarsKit[]}
539
- */
540
- get (gameMode = '', type = '') {
541
- return this.kits.filter((kit) => (kit.gameMode.startsWith(gameMode) && kit.kitType.startsWith(type)));
542
- }
543
- }
544
-
545
- /**
546
- * @typedef {string} KitType
547
- * * basic
548
- * * supporting
549
- * * mining
550
- * * defending
551
- * * attacking
552
- * * advanced
553
- * * enderchest
554
- */
555
- /**
556
- * @typedef {string} KitGameModes
557
- * * solo
558
- * * team
559
- */
1
+ const { SkyWarsPrestigeIcons } = require('../../utils/Constants');
2
+ const divide = require('../../utils/divide');
3
+ const { removeSnakeCaseString } = require('../../utils/removeSnakeCase');
4
+ const generateStatsForMode = (data, mode) => {
5
+ 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}`])
12
+ };
13
+ };
14
+ /**
15
+ * SkyWars class
16
+ */
17
+ class SkyWars {
18
+ /**
19
+ * @param {object} data SkyWars data
20
+ */
21
+ constructor(data) {
22
+ /**
23
+ * Coins
24
+ * @type {number}
25
+ */
26
+ this.coins = data.coins || 0;
27
+ /**
28
+ * Souls
29
+ * @type {number}
30
+ */
31
+ this.souls = data.souls || 0;
32
+ /**
33
+ * Tokens
34
+ * @type {number}
35
+ */
36
+ this.tokens = data.cosmetic_tokens || 0;
37
+ /**
38
+ * Winstreak
39
+ * @type {number}
40
+ */
41
+ this.winstreak = data.win_streak || 0;
42
+ /**
43
+ * Kills
44
+ * @type {number}
45
+ */
46
+ this.kills = data.kills || 0;
47
+ /**
48
+ * Losses
49
+ * @type {number}
50
+ */
51
+ this.losses = data.losses || 0;
52
+ /**
53
+ * Deaths
54
+ * @type {number}
55
+ */
56
+ this.deaths = data.deaths || 0;
57
+ /**
58
+ * Wins
59
+ * @type {number}
60
+ */
61
+ this.wins = data.wins || 0;
62
+ /**
63
+ * Loot Chests
64
+ * @type {number}
65
+ */
66
+ this.lootChests = data.skywars_chests || 0;
67
+ /**
68
+ * Opened Loot Chests
69
+ * @type {number}
70
+ */
71
+ this.openedLootChests = data.SkyWars_openedChests || 0;
72
+ /**
73
+ * Heads
74
+ * @type {number}
75
+ */
76
+ this.heads = data.heads || 0;
77
+ /**
78
+ * Experience
79
+ * @type {number}
80
+ */
81
+ this.experience = data.skywars_experience || 0;
82
+ /**
83
+ * Level
84
+ * @type {number}
85
+ */
86
+ this.level = getSkyWarsLevel(data.skywars_experience);
87
+ /**
88
+ * Level Progress
89
+ * @type {LevelProgress}
90
+ */
91
+ this.levelProgress = getSkyWarsLevelProgress(data.skywars_experience);
92
+ /**
93
+ * Formatted Level
94
+ * @type {string}
95
+ */
96
+ this.levelFormatted = data.levelFormatted
97
+ ? data.levelFormatted
98
+ .replace(/§l/gm, '**')
99
+ .replace(/§([a-f]|[1-9])/gm, '')
100
+ .replace(/§r/gm, '')
101
+ : null;
102
+ /**
103
+ * Prestige
104
+ * @type {SkyWarsPrestige}
105
+ */
106
+ this.prestige = getSkyWarsPrestige(this.level);
107
+ /**
108
+ * Prestige Icons
109
+ * @type {SkyWarsPrestigeIcons}
110
+ */
111
+ this.prestigeIcon = data.selected_prestige_icon ? SkyWarsPrestigeIcons[data.selected_prestige_icon] : null;
112
+ /**
113
+ * Games Played ( Total )
114
+ * @type {number}
115
+ */
116
+ this.playedGames = (data.games_solo || 0) + (data.games_team || 0) + (data.games_mega || 0) + (data.games_mega_doubles || 0) + (data.games_lab || 0);
117
+ /**
118
+ * Global Kill Death Ratio
119
+ * @type {number}
120
+ */
121
+ this.KDRatio = divide(this.kills, this.deaths);
122
+ /**
123
+ * Global Win Loss Ratio
124
+ * @type {number}
125
+ */
126
+ this.WLRatio = divide(this.wins, this.losses);
127
+ /**
128
+ * Opals
129
+ * @type {number}
130
+ */
131
+ this.opals = data.opals || 0;
132
+ /**
133
+ * Avarice
134
+ * @type {number}
135
+ */
136
+ this.avarice = data.avarice || 0;
137
+ /**
138
+ * Tenacity
139
+ * @type {number}
140
+ */
141
+ this.tenacity = data.tenacity || 0;
142
+ /**
143
+ * Shards
144
+ * @type {number}
145
+ */
146
+ this.shards = data.shard || 0;
147
+ /**
148
+ * Angel Of Death Level
149
+ * @type {number}
150
+ */
151
+ this.angelOfDeathLevel = data.angel_of_death_level || 0;
152
+ /**
153
+ * Shard By Mode
154
+ * @type {SkyWarsShardsInMode}
155
+ */
156
+ this.shardsInMode = {
157
+ solo: data.shard_solo || 0,
158
+ team: data.shard_team || 0,
159
+ mega: (data.shard_mega || 0) + (data.shard_mega_doubles || 0),
160
+ lab: data.shard_lab || 0
161
+ };
162
+ /**
163
+ * Solo Skywars Stats
164
+ * @type {SkyWarsModeExtendedStats}
165
+ */
166
+ this.solo = {
167
+ overall: {
168
+ winstreak: data.winstreak_solo || 0,
169
+ playedGames: data.games_solo || 0,
170
+ kills: data.kills_solo || 0,
171
+ wins: data.wins_solo || 0,
172
+ losses: data.losses_solo || 0,
173
+ deaths: data.deaths_solo || 0,
174
+ KDRatio: divide(data.kills_solo, data.deaths_solo),
175
+ WLRatio: divide(data.wins_solo, data.losses_solo)
176
+ },
177
+ normal: generateStatsForMode(data, 'solo_normal'),
178
+ insane: generateStatsForMode(data, 'solo_insane')
179
+ };
180
+ /**
181
+ * Team Skywars Stats
182
+ * @type {SkyWarsModeExtendedStats}
183
+ */
184
+ this.team = {
185
+ overall: {
186
+ winstreak: data.winstreak_team || 0,
187
+ playedGames: data.games_team || 0,
188
+ kills: data.kills_team || 0,
189
+ wins: data.wins_team || 0,
190
+ losses: data.losses_team || 0,
191
+ deaths: data.deaths_team || 0,
192
+ KDRatio: divide(data.kills_team, data.deaths_team),
193
+ WLRatio: divide(data.wins_team, data.losses_team)
194
+ },
195
+ normal: generateStatsForMode(data, 'team_normal'),
196
+ insane: generateStatsForMode(data, 'team_insane')
197
+ };
198
+ /**
199
+ * Mega Skywars Stats
200
+ * @type {SkyWarsMegaStats}
201
+ */
202
+ this.mega = {
203
+ overall: {
204
+ winstreak: data.winstreak_mega || 0,
205
+ playedGames: (data.games_mega || 0) + (data.games_mega_doubles || 0),
206
+ kills: (data.kills_mega || 0) + (data.kills_mega_doubles || 0),
207
+ wins: (data.wins_mega || 0) + (data.wins_mega_doubles || 0),
208
+ losses: (data.losses_mega || 0) + (data.losses_mega_doubles || 0),
209
+ deaths: (data.deaths_mega || 0) + (data.deaths_mega_doubles || 0),
210
+ KDRatio: divide((data.kills_mega || 0) + (data.kills_mega_doubles || 0), (data.deaths_mega || 0) + (data.deaths_mega_doubles || 0)),
211
+ WLRatio: divide((data.wins_mega || 0) + (data.wins_mega_doubles || 0), (data.losses_mega || 0) + (data.losses_mega_doubles || 0))
212
+ },
213
+ solo: {
214
+ playedGames: data.games_mega || 0,
215
+ kills: data.kills_mega || 0,
216
+ wins: data.wins_mega || 0,
217
+ losses: data.losses_mega || 0,
218
+ deaths: data.deaths_mega || 0,
219
+ KDRatio: divide(data.kills_mega || 0, data.deaths_mega || 0),
220
+ WLRatio: divide(data.wins_mega || 0, data.losses_mega || 0)
221
+ },
222
+ doubles: {
223
+ playedGames: data.games_mega_doubles || 0,
224
+ kills: data.kills_mega_doubles || 0,
225
+ wins: data.wins_mega_doubles || 0,
226
+ losses: data.losses_mega_doubles || 0,
227
+ deaths: data.deaths_mega_doubles || 0,
228
+ KDRatio: divide(data.kills_mega_doubles || 0, data.deaths_mega_doubles || 0),
229
+ WLRatio: divide(data.wins_mega_doubles || 0, data.losses_mega_doubles || 0)
230
+ }
231
+ };
232
+ /**
233
+ * Skywars Laboratory Stats
234
+ * @type {SkyWarsTotalModeStats}
235
+ */
236
+ this.lab = {
237
+ winstreak: data.winstreak_lab || 0,
238
+ playedGames: data.games_lab || 0,
239
+ kills: data.kills_lab || 0,
240
+ wins: data.wins_lab || 0,
241
+ losses: data.losses_lab || 0,
242
+ deaths: data.deaths_lab || 0,
243
+ KDRatio: divide(data.kills_lab, data.deaths_lab),
244
+ WLRatio: divide(data.wins_lab, data.losses_lab)
245
+ };
246
+ /**
247
+ * Player Packages, can range from kits to achievement
248
+ * @type {SkywarsPackages}
249
+ */
250
+ this.packages = new SkywarsPackages(data.packages || []);
251
+ }
252
+ }
253
+ /**
254
+ * @typedef {string} SkyWarsPrestige
255
+ * * `Iron`
256
+ * * `Iron`
257
+ * * `Gold`
258
+ * * `Diamond`
259
+ * * `Emerald`
260
+ * * `Sapphire`
261
+ * * `Ruby`
262
+ * * `Crystal`
263
+ * * `Opal`
264
+ * * `Amethyst`
265
+ * * `Rainbow`
266
+ * * `Mythic`
267
+ */
268
+ /**
269
+ * @typedef {string} SkyWarsPrestigeIcons
270
+ * * '⋆'
271
+ * * '★'
272
+ * * '☆'
273
+ * * '⁕',
274
+ * * '✶',
275
+ * * '✳',
276
+ * * '✴',
277
+ * * '✷',
278
+ * * '❋',
279
+ * * '✼',
280
+ * * '❂',
281
+ * * '❁',
282
+ * * '',
283
+ * * '',
284
+ * * '❤️',
285
+ * * '',
286
+ * * '',
287
+ * * '',
288
+ * * '',
289
+ * * '',
290
+ * * '',
291
+ * * '',
292
+ * * '',
293
+ * * 'ಠ_ಠ',
294
+ * * ''
295
+ */
296
+ /**
297
+ * @typedef {Object} SkyWarsModeStats
298
+ * @property {number} kills Kills
299
+ * @property {number} deaths Deaths
300
+ * @property {number} wins Wins
301
+ * @property {number} losses Losses
302
+ * @property {number} KDRatio Kill Death ratio
303
+ * @property {number} WLRatio Win Loss ratio
304
+ */
305
+ /**
306
+ * @typedef {Object} SkyWarsTotalModeStats
307
+ * @property {number} winstreak Winstreak
308
+ * @property {number} playedGames Played games
309
+ * @property {number} kills Kills
310
+ * @property {number} deaths Deaths
311
+ * @property {number} wins Wins
312
+ * @property {number} losses Losses
313
+ * @property {number} KDRatio Kill Death ratio
314
+ * @property {number} WLRatio Win Loss ratio
315
+ */
316
+ /**
317
+ * @typedef {string} PseudoDate String date, in the format of MM-YY ( YY is 20YY )
318
+ * @example `10-19` would be October 2019.
319
+ */
320
+ /**
321
+ * @typedef {Object} SkyWarsModeExtendedStats
322
+ * @property {SkyWarsTotalModeStats} overall Overall Stats
323
+ * @property {SkyWarsModeStats} normal Normal Mode Stats
324
+ * @property {SkyWarsModeStats} insane Insane Mode Stats
325
+ */
326
+ /**
327
+ * @typedef {Object} SkyWarsMegaStats
328
+ * @property {SkyWarsTotalModeStats} overall Overall Mega Stats
329
+ * @property {SkyWarsModeStats} solo Mega Solo Stats
330
+ * @property {SkyWarsModeStats} doubles Mega Doubles Stats
331
+ */
332
+ module.exports = SkyWars;
333
+ // eslint-disable-next-line require-jsdoc
334
+ function getSkyWarsPrestige(level) {
335
+ if (level >= 60) return 'Mythic';
336
+ return ['Iron', 'Iron', 'Gold', 'Diamond', 'Emerald', 'Sapphire', 'Ruby', 'Crystal', 'Opal', 'Amethyst', 'Rainbow'][Math.floor(level / 5)] || 'Iron';
337
+ }
338
+ // eslint-disable-next-line require-jsdoc
339
+ function getSkyWarsLevel(xp) {
340
+ const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
341
+ if (xp >= 15000) return Math.floor((xp - 15000) / 10000 + 12);
342
+ const level = totalXp.findIndex((x) => x * 10 - xp > 0);
343
+ return level; /* + (xp - (totalXp[level - 1] * 10 || 0)) / (totalXp[level] - totalXp[level - 1]) / 10*/
344
+ }
345
+ // eslint-disable-next-line require-jsdoc
346
+ function getSkyWarsLevelProgress(xp) {
347
+ const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500];
348
+ const xpToNextLvl = [0, 2, 5, 8, 10, 25, 50, 100, 150, 250, 400, 500]; // * 10
349
+ let percent;
350
+ let xpToNextLevel;
351
+ let currentLevelXp = xp;
352
+ if (xp >= 15000) {
353
+ currentLevelXp -= 15000;
354
+ if (currentLevelXp === 0) return { currentLevelXp: 0, xpToNextLevel: 10000, percent: 0, xpNextLevel: 10000 };
355
+ if (currentLevelXp > 10000) {
356
+ do {
357
+ currentLevelXp -= 10000;
358
+ } while (currentLevelXp >= 10000);
359
+ }
360
+ xpToNextLevel = 10000 - currentLevelXp;
361
+ percent = Math.round(currentLevelXp) / 100;
362
+ const percentRemaining = Math.round((100 - percent) * 100) / 100;
363
+ return {
364
+ currentLevelXp,
365
+ xpToNextLevel,
366
+ percent,
367
+ xpNextLevel: 10000,
368
+ percentRemaining
369
+ };
370
+ }
371
+ const totalXptoNextLevel = xpToNextLvl[totalXp.findIndex((x) => x * 10 - xp > 0)] * 10;
372
+ for (let i = 0; i < xpToNextLvl.length; i++) {
373
+ if (currentLevelXp - xpToNextLvl[i] * 10 < 0) break;
374
+ currentLevelXp -= xpToNextLvl[i] * 10;
375
+ }
376
+ xpToNextLevel = totalXptoNextLevel - currentLevelXp;
377
+ percent = Math.round((currentLevelXp / totalXptoNextLevel) * 10000) / 100;
378
+ return {
379
+ currentLevelXp,
380
+ xpToNextLevel,
381
+ percent,
382
+ xpNextLevel: totalXptoNextLevel
383
+ };
384
+ }
385
+ const ratingRegex = /^SkyWars_skywars_rating_(\d{1,2})_(\d{1,2})_(position|rating)$/;
386
+
387
+ /**
388
+ * Skywars Packages - parses every package player has
389
+ */
390
+ class SkywarsPackages {
391
+ /**
392
+ * Constructor
393
+ * @param {string[]} data data from API
394
+ */
395
+ constructor(data) {
396
+ // TODO : a lot more
397
+ /**
398
+ * Raw Packages, as received from the API
399
+ * @type {string[]}
400
+ */
401
+ this.rawPackages = Array.from(data);
402
+ /**
403
+ * Cages
404
+ * @type {string[]}
405
+ */
406
+ this.cages = this._parseCages();
407
+ /**
408
+ * Kits
409
+ * @type {SkywarsKits}
410
+ */
411
+ this.kits = new SkywarsKits(data);
412
+ /**
413
+ * Achievements included in packages, under the form of name0
414
+ * @type {string[]}
415
+ */
416
+ this.achievements = this.rawPackages
417
+ .map((pkg) => pkg.match(/^([A-z]+)_?achievement([0-9]?)$/))
418
+ .filter((x) => x)
419
+ .map((x) => x.slice(1).join(''));
420
+ }
421
+ /**
422
+ * Parses cages
423
+ * @returns {string[]}
424
+ */
425
+ _parseCages() {
426
+ return this.rawPackages
427
+ .map((pkg) => pkg.match(/^cage_([A-z]+)-cage$/))
428
+ .filter((x) => x)
429
+ .map((x) => x[1].replace(/-[a-z]/g, (x) => x[1].toUpperCase()));
430
+ }
431
+ }
432
+
433
+ /**
434
+ * Parses SkyWars Kits
435
+ */
436
+ class SkywarsKit {
437
+ /**
438
+ * Constructor
439
+ * @param {string} kit Kit
440
+ */
441
+ constructor(kit) {
442
+ /**
443
+ * Kit data
444
+ * @private
445
+ * @type {string[] | null}
446
+ */
447
+ this._kitData = kit.match(/^kit_([a-z]+)_([a-z]+)_([a-z]+)$/);
448
+ /**
449
+ * Is this a kit
450
+ * @type {boolean}
451
+ */
452
+ this.isKit = !!this._kitData;
453
+ if (!this._kitData) return;
454
+ /**
455
+ * Game mode the kit is for
456
+ * @type {KitGameModes}
457
+ */
458
+ this.gameMode = this._kitData[2];
459
+ /**
460
+ * Kit type
461
+ * @type {KitType}
462
+ */
463
+ this.kitType = this._kitData[1];
464
+ /**
465
+ * Kit name in camelCase
466
+ * @type {string}
467
+ */
468
+ this.kitName = removeSnakeCaseString(this._kitData[3]);
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Parses SkyWars Kits
474
+ */
475
+ class SkywarsKits {
476
+ /**
477
+ * Constructor
478
+ * @param {SkywarsKit[]} kits Potential Kits
479
+ */
480
+ constructor(kits) {
481
+ this.kits = kits.map((kit) => new SkywarsKit(kit)).filter((kit) => kit.isKit);
482
+ }
483
+ /**
484
+ * Get kit by type/gameMode
485
+ * @param {KitGameModes} [gameMode] Kits in said game mode
486
+ * @param {KitType} [type] Kits corresponding to this type
487
+ * @returns {SkywarsKit[]}
488
+ */
489
+ get(gameMode = '', type = '') {
490
+ return this.kits.filter((kit) => kit.gameMode.startsWith(gameMode) && kit.kitType.startsWith(type));
491
+ }
492
+ }
493
+
494
+ /**
495
+ * @typedef {string} KitType
496
+ * * basic
497
+ * * supporting
498
+ * * mining
499
+ * * defending
500
+ * * attacking
501
+ * * advanced
502
+ * * enderchest
503
+ */
504
+ /**
505
+ * @typedef {string} KitGameModes
506
+ * * solo
507
+ * * team
508
+ */