hypixel-api-reborn 8.3.0 → 10.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 (47) hide show
  1. package/README.md +2 -2
  2. package/package.json +9 -9
  3. package/src/API/getAPIStatus.js +2 -1
  4. package/src/API/getBoosters.js +1 -0
  5. package/src/API/getFriends.js +1 -0
  6. package/src/API/getGameCounts.js +1 -0
  7. package/src/API/getGuild.js +4 -2
  8. package/src/API/getKeyInfo.js +1 -0
  9. package/src/API/getLeaderboards.js +1 -0
  10. package/src/API/getPlayer.js +18 -3
  11. package/src/API/getRankedSkyWars.js +11 -0
  12. package/src/API/getRecentGames.js +1 -0
  13. package/src/API/getStatus.js +1 -0
  14. package/src/API/getWatchdogStats.js +1 -0
  15. package/src/API/index.js +23 -9
  16. package/src/API/skyblock/getEndedSkyblockAuctions.js +1 -0
  17. package/src/API/skyblock/getSkyblockAuctionsByPlayer.js +1 -0
  18. package/src/API/skyblock/getSkyblockBazaar.js +1 -0
  19. package/src/API/skyblock/getSkyblockMember.js +1 -0
  20. package/src/API/skyblock/getSkyblockNews.js +1 -0
  21. package/src/API/skyblock/getSkyblockProfiles.js +1 -0
  22. package/src/Client.js +57 -13
  23. package/src/Errors.js +3 -1
  24. package/src/Private/defaultCache.js +78 -0
  25. package/src/Private/rateLimit.js +4 -4
  26. package/src/Private/requests.js +24 -9
  27. package/src/Private/updater.js +45 -0
  28. package/src/Private/validate.js +6 -4
  29. package/src/structures/Game.js +3 -3
  30. package/src/structures/Guild/Guild.js +7 -1
  31. package/src/structures/MiniGames/Arcade.js +8 -8
  32. package/src/structures/MiniGames/BedWars.js +22 -0
  33. package/src/structures/MiniGames/Duels.js +291 -60
  34. package/src/structures/MiniGames/SkyWars.js +14 -6
  35. package/src/structures/MiniGames/SkyWarsRanked.js +45 -0
  36. package/src/structures/MiniGames/TurboKartRacers.js +130 -0
  37. package/src/structures/Player.js +15 -23
  38. package/src/structures/ServerInfo.js +1 -1
  39. package/src/structures/SkyBlock/News/SkyblockNews.js +4 -4
  40. package/src/structures/SkyBlock/SkyblockInventoryItem.js +29 -1
  41. package/src/structures/SkyBlock/SkyblockMember.js +25 -13
  42. package/src/utils/Constants.js +14 -0
  43. package/src/utils/index.js +13 -9
  44. package/src/utils/rgbToHexColor.js +8 -0
  45. package/src/utils/romanize.js +13 -0
  46. package/src/utils/varInt.js +1 -1
  47. package/typings/index.d.ts +423 -358
@@ -1,39 +1,41 @@
1
1
  /* eslint-disable max-len */
2
2
  const divide = require('../../utils/divide');
3
+ const romanize = require('../../utils/romanize');
4
+ // eslint-disable-next-line camelcase
5
+ const { duels_divisions } = require('../../utils/Constants');
6
+
3
7
  /**
4
- * @param {string} string
5
- * @return {string}
8
+ * @param {object<string,any>} data
9
+ * @param {string|null} mode
10
+ * @returns {string|undefined}
6
11
  */
7
- function capitalize (string) {
8
- return string.charAt(0).toUpperCase() + string.slice(1);
12
+ function getDivision (data, mode) {
13
+ for (const div of duels_divisions.slice().reverse()) {
14
+ const prestige = data[`${mode ? mode : 'all_modes'}_${div.key}_title_prestige`];
15
+ if (prestige !== undefined) {
16
+ return `${div.name} ${romanize(prestige)}`;
17
+ }
18
+ }
19
+ return null;
9
20
  }
10
- const numerals = {
11
- 1: 'I',
12
- 2: 'II',
13
- 3: 'III',
14
- 4: 'IV',
15
- 5: 'V',
16
- 6: 'VI',
17
- 7: 'VII',
18
- 8: 'VIII',
19
- 9: 'IX',
20
- 10: 'X'
21
- };
22
21
  /**
23
- * @param {object} data
24
- * @return {string|null}
22
+ * @param {object<string,any>} data
23
+ * @return {{kills:number,deaths:number}}
25
24
  */
26
- function cosmeticTitlePrestige (data) {
27
- if (data.active_cosmetictitle === 'custom') {
28
- if (!data.equipped_custom_titles) return null;
29
- return `${data.equipped_custom_titles.replace([0-9a-fl]{1}/g, '')}`;
30
- }
31
- if (data.active_cosmetictitle) {
32
- const prestige = data[`${data.active_cosmetictitle.split('_').reverse().join('_')}_title_prestige`] || 1;
33
- return `${capitalize(data.active_cosmetictitle.split('_')[1])} ${capitalize(data.active_cosmetictitle.split('_')[0])} ${numerals[prestige]}`;
34
- } else {
35
- return null;
25
+ function getTotalKillsDeaths (data) {
26
+ let totalDeaths = 0;
27
+ let totalKills = 0;
28
+ for (const [k, v] of Object.entries(data)) {
29
+ if (k.includes('deaths') && k !== 'deaths') {
30
+ totalDeaths += v;
31
+ } else if (k.includes('kills') && k !== 'kills') {
32
+ totalKills += v;
33
+ }
36
34
  }
35
+ return {
36
+ kills: totalKills,
37
+ deaths: totalDeaths
38
+ };
37
39
  }
38
40
  /**
39
41
  * Duels class
@@ -49,20 +51,20 @@ class Duels {
49
51
  */
50
52
  this.coins = data.coins || 0;
51
53
  /**
52
- * Cosmetic title
54
+ * All modes division
53
55
  * @type {string|null}
54
56
  */
55
- this.title = cosmeticTitlePrestige(data);
57
+ this.division = getDivision(data);
56
58
  /**
57
59
  * Kills
58
60
  * @type {number}
59
61
  */
60
- this.kills = data.kills || 0;
62
+ this.kills = getTotalKillsDeaths(data).kills;
61
63
  /**
62
64
  * Deaths
63
65
  * @type {number}
64
66
  */
65
- this.deaths = data.deaths || 0;
67
+ this.deaths = getTotalKillsDeaths(data).deaths;
66
68
  /**
67
69
  * Kill Death ratio
68
70
  * @type {number}
@@ -88,13 +90,25 @@ class Duels {
88
90
  * @type {number}
89
91
  */
90
92
  this.playedGames = data.games_played_duels || 0;
93
+ /**
94
+ * Current winstreak
95
+ * @type {number}
96
+ */
97
+ this.winstreak = data.current_winstreak || 0;
98
+ /**
99
+ * Best overall winstreak
100
+ * @type {number}
101
+ */
102
+ this.bestWinstreak = data.best_overall_winstreak || 0;
91
103
  /**
92
104
  * UHC duels stats
93
105
  * @type {DuelsUHC}
94
106
  */
95
107
  this.uhc = {
96
108
  'overall': {
97
- winstreak: (data.current_winstreak_mode_uhc_duel || 0) + (data.current_winstreak_mode_uhc_doubles || 0) + (data.current_winstreak_mode_uhc_four || 0) + (data.current_winstreak_mode_uhc_meetup || 0),
109
+ division: getDivision(data, 'uhc'),
110
+ winstreak: data.current_uhc_winstreak || 0,
111
+ bestWinstreak: data.best_uhc_winstreak || 0,
98
112
  kills: (data.uhc_duel_kills || 0) + (data.uhc_doubles_kills || 0) + (data.uhc_four_kills || 0) + (data.uhc_meetup_kills || 0),
99
113
  deaths: (data.uhc_duel_deaths || 0) + (data.uhc_doubles_deaths || 0) + (data.uhc_four_deaths || 0) + (data.uhc_meetup_deaths || 0),
100
114
  KDRatio: divide((data.uhc_duel_kills || 0) + (data.uhc_doubles_kills || 0) + (data.uhc_four_kills || 0) + (data.uhc_meetup_kills || 0), (data.uhc_duel_deaths || 0) + (data.uhc_doubles_deaths || 0) + (data.uhc_four_deaths || 0) + (data.uhc_meetup_deaths || 0)),
@@ -104,7 +118,9 @@ class Duels {
104
118
  playedGames: (data.uhc_duel_rounds_played || 0) + (data.uhc_doubles_rounds_played || 0) + (data.uhc_four_rounds_played || 0) + (data.uhc_meetup_rounds_played || 0)
105
119
  },
106
120
  '1v1': {
121
+ division: getDivision(data, 'uhc'),
107
122
  winstreak: data.current_winstreak_mode_uhc_duel || 0,
123
+ bestWinstreak: data.best_winstreak_mode_uhc_duel || 0,
108
124
  kills: data.uhc_duel_kills || 0,
109
125
  deaths: data.uhc_duel_deaths || 0,
110
126
  KDRatio: divide(data.uhc_duel_kills, data.uhc_duel_deaths),
@@ -114,7 +130,9 @@ class Duels {
114
130
  playedGames: data.uhc_duel_rounds_played || 0
115
131
  },
116
132
  '2v2': {
133
+ division: getDivision(data, 'uhc'),
117
134
  winstreak: data.current_winstreak_mode_uhc_doubles || 0,
135
+ bestWinstreak: data.best_winstreak_mode_uhc_doubles || 0,
118
136
  kills: data.uhc_doubles_kills || 0,
119
137
  deaths: data.uhc_doubles_deaths || 0,
120
138
  KDRatio: divide(data.uhc_doubles_kills, data.uhc_doubles_deaths),
@@ -124,7 +142,9 @@ class Duels {
124
142
  playedGames: data.uhc_doubles_rounds_played || 0
125
143
  },
126
144
  '4v4': {
145
+ division: getDivision(data, 'uhc'),
127
146
  winstreak: data.current_winstreak_mode_uhc_four || 0,
147
+ bestWinstreak: data.best_winstreak_mode_uhc_four || 0,
128
148
  kills: data.uhc_four_kills || 0,
129
149
  deaths: data.uhc_four_deaths || 0,
130
150
  KDRatio: divide(data.uhc_four_kills, data.uhc_four_deaths),
@@ -134,7 +154,9 @@ class Duels {
134
154
  playedGames: data.uhc_four_rounds_played || 0
135
155
  },
136
156
  'meetup': {
157
+ division: getDivision(data, 'uhc'),
137
158
  winstreak: data.current_winstreak_mode_uhc_meetup || 0,
159
+ bestWinstreak: data.best_winstreak_mode_uhc_meetup || 0,
138
160
  kills: data.uhc_meetup_kills || 0,
139
161
  deaths: data.uhc_meetup_deaths || 0,
140
162
  KDRatio: divide(data.uhc_meetup_kills, data.uhc_meetup_deaths),
@@ -144,8 +166,64 @@ class Duels {
144
166
  playedGames: data.uhc_meetup_rounds_played || 0
145
167
  }
146
168
  };
169
+ /**
170
+ * @type {DuelsParkour}
171
+ */
172
+ this.parkour = {
173
+ division: getDivision(data, 'parkour'),
174
+ deaths: data.parkour_eight_deaths || 0,
175
+ wins: data.parkour_eight_wins || 0,
176
+ losses: data.parkour_eight_losses || 0,
177
+ WLRatio: divide(data.parkour_eight_wins, data.parkour_eight_losses),
178
+ playedGames: data.parkour_eight_rounds_played || 0
179
+ };
180
+ /**
181
+ * @type {DuelsBoxing}
182
+ */
183
+ this.boxing = {
184
+ division: getDivision(data, 'boxing'),
185
+ kills: data.boxing_duel_kills || 0,
186
+ wins: data.boxing_duel_wins || 0,
187
+ losses: data.boxing_duel_losses || 0,
188
+ WLRatio: divide(data.boxing_duel_wins, data.boxing_duel_losses),
189
+ playedGames: data.boxing_duel_rounds_played || 0,
190
+ meleeSwings: data.boxing_duel_melee_swings || 0,
191
+ meleeHits: data.boxing_duel_melee_hits || 0
192
+ };
193
+ /**
194
+ * @type {DuelsBowspleef}
195
+ */
196
+ this.bowspleef = {
197
+ division: getDivision(data, 'tnt_games'),
198
+ winstreak: data.current_tnt_games_winstreak || 0,
199
+ bestWinstreak: data.best_tnt_games_winstreak || 0,
200
+ bowShots: data.bowspleef_duel_bow_shots || 0,
201
+ deaths: data.bowspleef_duel_deaths || 0,
202
+ wins: data.bowspleef_duel_wins || 0,
203
+ losses: data.bowspleef_duel_losses || 0,
204
+ WLRatio: divide((data.bowspleef_duel_wins || 0), (data.bowspleef_duel_losses || 0)),
205
+ playedGames: data.bowspleef_duel_rounds_played || 0
206
+ };
207
+ /**
208
+ * @type {DuelsArena}
209
+ */
210
+ this.arena = {
211
+ kills: data.duel_arena_kills || 0,
212
+ deaths: data.duel_arena_deaths || 0,
213
+ KDRatio: divide(data.duel_arena_kills, data.duel_arena_deaths),
214
+ wins: data.duel_arena_wins || 0,
215
+ losses: data.duel_arena_losses || 0,
216
+ WLRatio: divide(data.duel_arena_wins, data.duel_arena_losses),
217
+ playedGames: data.duel_arena_rounds_played || 0
218
+ };
219
+ /**
220
+ * MegaWalls duels stats
221
+ * @type {DuelsModeStats}
222
+ */
147
223
  this.megawalls = {
224
+ division: getDivision(data, 'mega_walls'),
148
225
  winstreak: data.current_winstreak_mode_mw_duel || 0,
226
+ bestWinstreak: data.best_winstreak_mode_mw_duel || 0,
149
227
  kills: data.mw_duel_kills || 0,
150
228
  deaths: data.mw_duel_deaths || 0,
151
229
  KDRatio: divide(data.mw_duel_kills, data.mw_duel_deaths),
@@ -160,7 +238,9 @@ class Duels {
160
238
  */
161
239
  this.op = {
162
240
  'overall': {
163
- winstreak: (data.current_winstreak_mode_op_duel || 0) + (data.current_winstreak_mode_op_doubles || 0),
241
+ division: getDivision(data, 'op'),
242
+ winstreak: data.current_op_winstreak || 0,
243
+ bestWinstreak: data.best_op_winstreak || 0,
164
244
  kills: (data.op_duel_kills || 0) + (data.op_doubles_kills || 0),
165
245
  deaths: (data.op_duel_deaths || 0) + (data.op_doubles_deaths || 0),
166
246
  KDRatio: divide((data.op_duel_kills || 0) + (data.op_doubles_kills || 0), (data.op_duel_deaths || 0) + (data.op_doubles_deaths || 0)),
@@ -170,7 +250,9 @@ class Duels {
170
250
  playedGames: (data.op_duel_rounds_played || 0) + (data.op_doubles_rounds_played || 0)
171
251
  },
172
252
  '1v1': {
253
+ division: getDivision(data, 'op'),
173
254
  winstreak: data.current_winstreak_mode_op_duel || 0,
255
+ bestWinstreak: data.best_winstreak_mode_op_duel || 0,
174
256
  kills: data.op_duel_kills || 0,
175
257
  deaths: data.op_duel_deaths || 0,
176
258
  KDRatio: divide(data.op_duel_kills, data.op_duel_deaths),
@@ -180,7 +262,9 @@ class Duels {
180
262
  playedGames: data.op_duel_rounds_played || 0
181
263
  },
182
264
  '2v2': {
265
+ division: getDivision(data, 'op'),
183
266
  winstreak: data.current_winstreak_mode_op_doubles || 0,
267
+ bestWinstreak: data.best_winstreak_mode_op_doubles || 0,
184
268
  kills: data.op_doubles_kills || 0,
185
269
  deaths: data.op_doubles_deaths || 0,
186
270
  KDRatio: divide(data.op_doubles_kills, data.op_doubles_deaths),
@@ -196,17 +280,21 @@ class Duels {
196
280
  */
197
281
  this.skywars = {
198
282
  'overall': {
199
- winstreak: (data.current_winstreak_mode_sw_duel || 0) + (data.current_winstreak_mode_sw_doubles || 0),
200
- kills: (data.sw_duel_kills || 0) + (data.sw_doubles_kills || 0),
201
- deaths: (data.sw_duel_deaths || 0) + (data.sw_doubles_deaths || 0),
283
+ division: getDivision(data, 'skywars'),
284
+ winstreak: data.current_skywars_winstreak || 0,
285
+ bestWinstreak: data.best_skywars_winstreak || 0,
286
+ kills: ((data.sw_duel_kills || 0) + (data.sw_doubles_kills || 0)),
287
+ deaths: ((data.sw_duel_deaths || 0) + (data.sw_doubles_deaths || 0)),
202
288
  KDRatio: divide((data.sw_duel_kills || 0) + (data.sw_doubles_kills || 0), (data.sw_duel_deaths || 0) + (data.sw_doubles_deaths || 0)),
203
- wins: (data.sw_duel_wins || 0) + (data.sw_doubles_wins || 0),
204
- losses: (data.sw_duel_losses || 0) + (data.sw_doubles_losses || 0),
289
+ wins: ((data.sw_duel_wins || 0) + (data.sw_doubles_wins || 0)),
290
+ losses: ((data.sw_duel_losses || 0) + (data.sw_doubles_losses || 0)),
205
291
  WLRatio: divide((data.sw_duel_wins || 0) + (data.sw_doubles_wins || 0), (data.sw_duel_losses || 0) + (data.sw_doubles_losses || 0)),
206
292
  playedGames: (data.sw_duel_rounds_played || 0) + (data.sw_doubles_rounds_played || 0)
207
293
  },
208
294
  '1v1': {
295
+ division: getDivision(data, 'skywars'),
209
296
  winstreak: data.current_winstreak_mode_sw_duel || 0,
297
+ bestWinstreak: data.best_winstreak_mode_sw_duel || 0,
210
298
  kills: data.sw_duel_kills || 0,
211
299
  deaths: data.sw_duel_deaths || 0,
212
300
  KDRatio: divide(data.sw_duel_kills, data.sw_duel_deaths),
@@ -216,7 +304,9 @@ class Duels {
216
304
  playedGames: data.sw_duel_rounds_played || 0
217
305
  },
218
306
  '2v2': {
307
+ division: getDivision(data, 'skywars'),
219
308
  winstreak: data.current_winstreak_mode_sw_doubles || 0,
309
+ bestWinstreak: data.best_winstreak_mode_sw_doubles || 0,
220
310
  kills: data.sw_doubles_kills || 0,
221
311
  deaths: data.sw_doubles_deaths || 0,
222
312
  KDRatio: divide(data.sw_doubles_kills, data.sw_doubles_deaths),
@@ -231,7 +321,9 @@ class Duels {
231
321
  * @type {DuelsModeStats}
232
322
  */
233
323
  this.sumo = {
324
+ division: getDivision(data, 'sumo'),
234
325
  winstreak: data.current_winstreak_mode_sumo_duel || 0,
326
+ bestWinstreak: data.best_winstreak_mode_sumo_duel || 0,
235
327
  kills: data.sumo_duel_kills || 0,
236
328
  deaths: data.sumo_duel_deaths || 0,
237
329
  KDRatio: divide(data.sumo_duel_kills, data.sumo_duel_deaths),
@@ -245,7 +337,9 @@ class Duels {
245
337
  * @type {DuelsModeStats}
246
338
  */
247
339
  this.classic = {
340
+ division: getDivision(data, 'classic'),
248
341
  winstreak: data.current_winstreak_mode_classic_duel || 0,
342
+ bestWinstreak: data.best_winstreak_mode_classic_duel || 0,
249
343
  kills: data.classic_duel_kills || 0,
250
344
  deaths: data.classic_duel_deaths || 0,
251
345
  KDRatio: divide(data.classic_duel_kills, data.classic_duel_deaths),
@@ -259,7 +353,9 @@ class Duels {
259
353
  * @type {DuelsModeStats}
260
354
  */
261
355
  this.combo = {
356
+ division: getDivision(data, 'combo'),
262
357
  winstreak: data.current_winstreak_mode_combo_duel || 0,
358
+ bestWinstreak: data.best_winstreak_mode_combo_duel || 0,
263
359
  kills: data.combo_duel_kills || 0,
264
360
  deaths: data.combo_duel_deaths || 0,
265
361
  KDRatio: divide(data.combo_duel_kills, data.combo_duel_deaths),
@@ -274,44 +370,100 @@ class Duels {
274
370
  */
275
371
  this.bridge = {
276
372
  'overall': {
277
- winstreak: (data.current_winstreak_mode_bridge_duel || 0) + (data.current_winstreak_mode_bridge_doubles || 0) + (data.current_winstreak_mode_bridge_four || 0),
278
- kills: ((data.bridge_duel_kills || data.bridge_duel_bridge_kills) || 0) + ((data.bridge_doubles_kills || data.bridge_doubles_bridge_kills) || 0) + ((data.bridge_four_kills || data.bridge_four_bridge_kills) || 0),
279
- deaths: ((data.bridge_duel_deaths || data.bridge_duel_bridge_deaths) || 0) + ((data.bridge_doubles_deaths || data.bridge_doubles_bridge_deaths) || 0) + ((data.bridge_four_deaths || data.bridge_four_bridge_deaths) || 0),
280
- KDRatio: divide(((data.bridge_duel_kills || data.bridge_duel_bridge_kills) || 0) + ((data.bridge_doubles_kills || data.bridge_doubles_bridge_kills) || 0) + ((data.bridge_four_kills || data.bridge_four_bridge_kills) || 0), ((data.bridge_duel_deaths || data.bridge_duel_bridge_deaths) || 0) + ((data.bridge_doubles_deaths || data.bridge_doubles_bridge_deaths) || 0) + ((data.bridge_four_deaths || data.bridge_four_bridge_deaths) || 0)),
281
- wins: (data.bridge_duel_wins || 0) + (data.bridge_doubles_wins || 0) + (data.bridge_four_wins || 0),
282
- losses: (data.bridge_duel_losses || 0) + (data.bridge_doubles_losses || 0) + (data.bridge_four_losses || 0),
283
- WLRatio: divide((data.bridge_duel_wins || 0) + (data.bridge_doubles_wins || 0) + (data.bridge_four_wins || 0), (data.bridge_duel_losses || 0) + (data.bridge_doubles_losses || 0) + (data.bridge_four_losses || 0)),
284
- playedGames: (data.bridge_duel_rounds_played || 0) + (data.bridge_doubles_rounds_played || 0) + (data.bridge_four_rounds_played || 0)
373
+ division: getDivision(data, 'bridge'),
374
+ winstreak: data.current_bridge_winstreak || 0,
375
+ bestWinstreak: data.best_bridge_winstreak || 0,
376
+ kills: ((data.bridge_duel_bridge_kills || 0) + (data.bridge_doubles_bridge_kills || 0) + (data.bridge_2v2v2v2_bridge_kills || 0) + (data.bridge_3v3v3v3_bridge_kills || 0) + (data.bridge_four_bridge_kills || 0) + (data.bridge_threes_bridge_kills || 0) + (data.capture_threes_bridge_kills || 0)),
377
+ deaths: ((data.bridge_duel_bridge_deaths || 0) + (data.bridge_doubles_bridge_deaths || 0) + (data.bridge_2v2v2v2_bridge_deaths || 0) + (data.bridge_3v3v3v3_bridge_deaths || 0) + (data.bridge_four_bridge_deaths || 0) + (data.bridge_threes_bridge_deaths || 0) + (data.capture_threes_bridge_deaths || 0)),
378
+ KDRatio: divide(((data.bridge_duel_bridge_kills || 0) + (data.bridge_doubles_bridge_kills || 0) + (data.bridge_2v2v2v2_bridge_kills || 0) + (data.bridge_3v3v3v3_bridge_kills || 0) + (data.bridge_four_bridge_kills || 0) + (data.bridge_threes_bridge_kills || 0) + (data.capture_threes_bridge_kills || 0)), ((data.bridge_duel_bridge_deaths || 0) + (data.bridge_doubles_bridge_deaths || 0) + (data.bridge_2v2v2v2_bridge_deaths || 0) + (data.bridge_3v3v3v3_bridge_deaths || 0) + (data.bridge_four_bridge_deaths || 0) + (data.bridge_threes_bridge_deaths || 0) + (data.capture_threes_bridge_deaths || 0))),
379
+ wins: ((data.bridge_duel_wins || 0) + (data.bridge_doubles_wins || 0) + (data.bridge_2v2v2v2_wins || 0) + (data.bridge_3v3v3v3_wins || 0) + (data.bridge_four_wins || 0) + (data.bridge_threes_bridge_wins || 0) + (data.capture_threes_wins || 0)),
380
+ losses: ((data.bridge_duel_losses || 0) + (data.bridge_doubles_losses || 0) + (data.bridge_2v2v2v2_losses || 0) + (data.bridge_3v3v3v3_losses || 0) + (data.bridge_four_losses || 0) + (data.bridge_threes_bridge_losses || 0) + (data.capture_threes_bridge_losses || 0)),
381
+ WLRatio: divide(((data.bridge_duel_wins || 0) + (data.bridge_doubles_wins || 0) + (data.bridge_2v2v2v2_wins || 0) + (data.bridge_3v3v3v3_wins || 0) + (data.bridge_four_wins || 0) + (data.bridge_threes_bridge_wins || 0) + (data.capture_threes_wins || 0)), ((data.bridge_duel_losses || 0) + (data.bridge_doubles_losses || 0) + (data.bridge_2v2v2v2_losses || 0) + (data.bridge_3v3v3v3_losses || 0) + (data.bridge_four_losses || 0) + (data.bridge_threes_bridge_losses || 0) + (data.capture_threes_bridge_losses || 0))),
382
+ playedGames: ((data.bridge_duel_rounds_played || 0) + (data.bridge_doubles_rounds_played || 0) + (data.bridge_2v2v2v2_rounds_played || 0) + (data.bridge_3v3v3v3_rounds_played || 0) + (data.bridge_four_rounds_played || 0) + (data.bridge_threes_bridge_rounds_played || 0) + (data.capture_threes_rounds_played || 0))
285
383
  },
286
384
  '1v1': {
385
+ division: getDivision(data, 'bridge'),
287
386
  winstreak: data.current_winstreak_mode_bridge_duel || 0,
288
- kills: (data.bridge_duel_kills || data.bridge_duel_bridge_kills) || 0,
289
- deaths: (data.bridge_duel_deaths || data.bridge_duel_bridge_deaths) || 0,
290
- KDRatio: divide((data.bridge_duel_kills || data.bridge_duel_bridge_kills), (data.bridge_duel_deaths || data.bridge_duel_bridge_deaths)),
387
+ bestWinstreak: data.best_winstreak_mode_bridge_duel || 0,
388
+ kills: data.bridge_duel_bridge_kills || 0,
389
+ deaths: data.bridge_duel_bridge_deaths || 0,
390
+ KDRatio: divide(data.bridge_duel_bridge_kills, data.bridge_duel_bridge_deaths),
291
391
  wins: data.bridge_duel_wins || 0,
292
392
  losses: data.bridge_duel_losses || 0,
293
393
  WLRatio: divide(data.bridge_duel_wins, data.bridge_duel_losses),
294
394
  playedGames: data.bridge_duel_rounds_played || 0
295
395
  },
296
396
  '2v2': {
397
+ division: getDivision(data, 'bridge'),
297
398
  winstreak: data.current_winstreak_mode_bridge_doubles || 0,
298
- kills: (data.bridge_doubles_kills || data.bridge_doubles_bridge_kills) || 0,
299
- deaths: (data.bridge_doubles_deaths || data.bridge_doubles_bridge_deaths) || 0,
300
- KDRatio: divide((data.bridge_doubles_kills || data.bridge_doubles_bridge_kills), (data.bridge_doubles_deaths || data.bridge_doubles_bridge_deaths)),
399
+ bestWinstreak: data.best_winstreak_mode_bridge_doubles || 0,
400
+ kills: data.bridge_doubles_bridge_kills || 0,
401
+ deaths: data.bridge_doubles_bridge_deaths || 0,
402
+ KDRatio: divide(data.bridge_doubles_bridge_kills, data.bridge_doubles_bridge_deaths),
301
403
  wins: data.bridge_doubles_wins || 0,
302
404
  losses: data.bridge_doubles_losses || 0,
303
405
  WLRatio: divide(data.bridge_doubles_wins, data.bridge_doubles_losses),
304
406
  playedGames: data.bridge_doubles_rounds_played || 0
305
407
  },
408
+ '3v3': {
409
+ division: getDivision(data, 'bridge'),
410
+ winstreak: data.current_winstreak_mode_bridge_threes || 0,
411
+ bestWinstreak: data.best_winstreak_mode_bridge_threes || 0,
412
+ kills: data.bridge_threes_bridge_kills || 0,
413
+ deaths: data.bridge_threes_bridge_deaths || 0,
414
+ KDRatio: divide(data.bridge_threes_bridge_kills, data.bridge_threes_bridge_deaths),
415
+ wins: data.bridge_threes_wins || 0,
416
+ losses: data.bridge_threes_losses || 0,
417
+ WLRatio: divide(data.bridge_threes_wins, data.bridge_threes_losses),
418
+ playedGames: data.bridge_threes_rounds_played || 0
419
+ },
420
+ '2v2v2v2': {
421
+ division: getDivision(data, 'bridge'),
422
+ winstreak: data.current_winstreak_mode_bridge_2v2v2v2 || 0,
423
+ bestWinstreak: data.best_winstreak_mode_bridge_2v2v2v2 || 0,
424
+ kills: data.bridge_2v2v2v2_bridge_kills || 0,
425
+ deaths: data.bridge_2v2v2v2_bridge_deaths || 0,
426
+ KDRatio: divide(data.bridge_2v2v2v2_bridge_kills, data.bridge_2v2v2v2_bridge_deaths),
427
+ wins: data.bridge_2v2v2v2_wins || 0,
428
+ losses: data.bridge_2v2v2v2_losses || 0,
429
+ WLRatio: divide(data.bridge_2v2v2v2_wins, data.bridge_2v2v2v2_losses),
430
+ playedGames: data.bridge_2v2v2v2_rounds_played || 0
431
+ },
432
+ '3v3v3v3': {
433
+ division: getDivision(data, 'bridge'),
434
+ winstreak: data.current_winstreak_mode_bridge_3v3v3v3 || 0,
435
+ bestWinstreak: data.best_winstreak_mode_bridge_3v3v3v3 || 0,
436
+ kills: data.bridge_3v3v3v3_bridge_kills || 0,
437
+ deaths: data.bridge_3v3v3v3_bridge_deaths || 0,
438
+ KDRatio: divide(data.bridge_3v3v3v3_bridge_kills, data.bridge_3v3v3v3_bridge_deaths),
439
+ wins: data.bridge_3v3v3v3_wins || 0,
440
+ losses: data.bridge_3v3v3v3_losses || 0,
441
+ WLRatio: divide(data.bridge_3v3v3v3_wins, data.bridge_3v3v3v3_losses),
442
+ playedGames: data.bridge_3v3v3v3_rounds_played || 0
443
+ },
306
444
  '4v4': {
445
+ division: getDivision(data, 'bridge'),
307
446
  winstreak: data.current_winstreak_mode_bridge_four || 0,
308
- kills: (data.bridge_four_kills || data.bridge_four_bridge_kills) || 0,
309
- deaths: (data.bridge_four_deaths || data.bridge_four_bridge_deaths) || 0,
310
- KDRatio: divide((data.bridge_four_kills || data.bridge_four_bridge_kills), (data.bridge_four_deaths || data.bridge_four_bridge_deaths)),
447
+ bestWinstreak: data.best_winstreak_mode_bridge_four || 0,
448
+ kills: data.bridge_four_bridge_kills || 0,
449
+ deaths: data.bridge_four_bridge_deaths || 0,
450
+ KDRatio: divide(data.bridge_four_bridge_kills, data.bridge_four_bridge_deaths),
311
451
  wins: data.bridge_four_wins || 0,
312
452
  losses: data.bridge_four_losses || 0,
313
453
  WLRatio: divide(data.bridge_four_wins, data.bridge_four_losses),
314
454
  playedGames: data.bridge_four_rounds_played || 0
455
+ },
456
+ // eslint-disable-next-line quote-props
457
+ ctf: {
458
+ division: getDivision(data, 'bridge'),
459
+ kills: data.capture_threes_bridge_kills || 0,
460
+ deaths: data.capture_threes_bridge_deaths || 0,
461
+ KDRatio: divide(data.capture_threes_bridge_kills, data.capture_threes_bridge_deaths),
462
+ wins: data.capture_threes_wins || 0,
463
+ losses: data.capture_threes_losses || 0,
464
+ WLRatio: divide(data.capture_threes_wins, data.capture_threes_losses),
465
+ captures: data.capture_threes_captures || 0,
466
+ playedGames: data.capture_threes_rounds_played || 0
315
467
  }
316
468
  };
317
469
  /**
@@ -319,7 +471,9 @@ class Duels {
319
471
  * @type {DuelsModeStats}
320
472
  */
321
473
  this.blitz = {
474
+ division: getDivision(data, 'blitz'),
322
475
  winstreak: data.current_winstreak_mode_blitz_duel || 0,
476
+ bestWinstreak: data.best_winstreak_mode_blitz_duel || 0,
323
477
  kills: data.blitz_duel_kills || 0,
324
478
  deaths: data.blitz_duel_deaths || 0,
325
479
  KDRatio: divide(data.blitz_duel_kills, data.blitz_duel_deaths),
@@ -333,7 +487,9 @@ class Duels {
333
487
  * @type {DuelsModeStats}
334
488
  */
335
489
  this.nodebuff = {
490
+ division: getDivision(data, 'no_debuff'),
336
491
  winstreak: data.current_winstreak_mode_potion_duel || 0,
492
+ bestWinstreak: data.best_winstreak_mode_potion_duel || 0,
337
493
  kills: data.potion_duel_kills || 0,
338
494
  deaths: data.potion_duel_deaths || 0,
339
495
  KDRatio: divide(data.potion_duel_kills, data.potion_duel_deaths),
@@ -347,7 +503,9 @@ class Duels {
347
503
  * @type {DuelsModeStats}
348
504
  */
349
505
  this.bow = {
506
+ division: getDivision(data, 'bow'),
350
507
  winstreak: data.current_winstreak_mode_bow_duel || 0,
508
+ bestWinstreak: data.best_winstreak_mode_bow_duel || 0,
351
509
  kills: data.bow_duel_kills || 0,
352
510
  deaths: data.bow_duel_deaths || 0,
353
511
  KDRatio: divide(data.bow_duel_kills, data.bow_duel_deaths),
@@ -360,7 +518,76 @@ class Duels {
360
518
  }
361
519
  /**
362
520
  * @typedef {object} DuelsModeStats
521
+ * @property {number|undefined} winstreak Current winstreak
522
+ * @property {number|undefined} bestWinstreak Best winstreak
523
+ * @property {string|null} division Division
524
+ * @property {number} kills Kills
525
+ * @property {number} deaths Deaths
526
+ * @property {number} wins Wins
527
+ * @property {number} losses Losses
528
+ * @property {number} KDRatio Kill/Death ratio
529
+ * @property {number} WLRatio Win/Loss ratio
530
+ * @property {number} playedGames Played games
531
+ */
532
+ /**
533
+ * @typedef {object} BridgeModeStats
534
+ * @property {number|undefined} winstreak Current winstreak
535
+ * @property {number|undefined} bestWinstreak Best winstreak
536
+ * @property {string|null} division Division
537
+ * @property {number} kills Kills
538
+ * @property {number} deaths Deaths
539
+ * @property {number} wins Wins
540
+ * @property {number} losses Losses
541
+ * @property {number} KDRatio Kill/Death ratio
542
+ * @property {number} WLRatio Win/Loss ratio
543
+ * @property {number} playedGames Played games
544
+ * @property {number} goals Goals
545
+ */
546
+ /**
547
+ * @typedef {object} DuelsBowspleef
548
+ * @property {string|null} division Division
363
549
  * @property {number} winstreak Winstreak
550
+ * @property {number} bestWinstreak Best winstreak
551
+ * @property {number} bowShots Bow shots
552
+ * @property {number} deaths Deaths
553
+ * @property {number} wins Wins
554
+ * @property {number} losses Losses
555
+ * @property {number} WLRatio Win/Loss ratio
556
+ * @property {number} playedGames Played games
557
+ */
558
+ /**
559
+ * @typedef {object} BridgeCTFModeStats
560
+ * @property {string|null} division Division
561
+ * @property {number} kills Kills
562
+ * @property {number} deaths Deaths
563
+ * @property {number} wins Wins
564
+ * @property {number} losses Losses
565
+ * @property {number} KDRatio Kill/Death ratio
566
+ * @property {number} WLRatio Win/Loss ratio
567
+ * @property {number} playedGames Played games
568
+ * @property {number} captures Captures
569
+ */
570
+ /**
571
+ * @typedef {object} DuelsParkour
572
+ * @property {number} deaths Deaths
573
+ * @property {number} wins Wins
574
+ * @property {number} losses Losses
575
+ * @property {number} WLRatio Win/Loss ratio
576
+ * @property {number} playedGames Played games
577
+ */
578
+ /**
579
+ * @typedef {object} DuelsBoxing
580
+ * @property {string} division Division
581
+ * @property {number} kills Kills
582
+ * @property {number} wins Wins
583
+ * @property {number} losses Losses
584
+ * @property {number} WLRatio Win/Loss ratio
585
+ * @property {number} playedGames Played games
586
+ * @property {number} meleeSwings Melee swings
587
+ * @property {number} meleeHits Melee hits
588
+ */
589
+ /**
590
+ * @typedef {object} DuelsArena
364
591
  * @property {number} kills Kills
365
592
  * @property {number} deaths Deaths
366
593
  * @property {number} wins Wins
@@ -391,9 +618,13 @@ class Duels {
391
618
  */
392
619
  /**
393
620
  * @typedef {object} DuelsBridge
394
- * @property {DuelsModeStats} overall Overall The Bridge duel stats
395
- * @property {DuelsModeStats} '1v1' The Bridge Duel 1v1 stats
396
- * @property {DuelsModeStats} '2v2' The Bridge Duel 2v2 stats
397
- * @property {DuelsModeStats} '4v4' The Bridge Duel 4v4 stats
621
+ * @property {BridgeModeStats} overall Overall The Bridge duel stats
622
+ * @property {BridgeModeStats} '1v1' The Bridge Duel 1v1 stats
623
+ * @property {BridgeModeStats} '2v2' The Bridge Duel 2v2 stats
624
+ * @property {BridgeModeStats} '3v3' The Bridge Duel 3v3 stats
625
+ * @property {BridgeModeStats} '4v4' The Bridge Duel 4v4 stats
626
+ * @property {BridgeModeStats} '2v2v2v2' The Bridge Duel 2v2v2v2 stats
627
+ * @property {BridgeModeStats} '3v3v3v3' The Bridge Duel 3v3v3v3 stats
628
+ * @property {BridgeCTFModeStats} ctf The Bridge Capture The Flag duel 3v3 stats
398
629
  */
399
630
  module.exports = Duels;
@@ -17,8 +17,9 @@ const generateStatsForMode = (data, mode) => {
17
17
  class SkyWars {
18
18
  /**
19
19
  * @param {object} data SkyWars data
20
+ * @param {object|null} extraRSWData Extra Ranked Skywars data, if any
20
21
  */
21
- constructor (data) {
22
+ constructor (data, extraRSWData) {
22
23
  /**
23
24
  * Coins
24
25
  * @type {number}
@@ -204,7 +205,7 @@ class SkyWars {
204
205
  deaths: data.deaths_ranked || 0,
205
206
  KDRatio: divide(data.kills_ranked, data.deaths_ranked),
206
207
  WLRatio: divide(data.wins_ranked, data.losses_ranked),
207
- ratings: getRankedPositions(data)
208
+ ratings: getRankedPositions(data, extraRSWData)
208
209
  };
209
210
  /**
210
211
  * Mega Skywars Stats
@@ -417,19 +418,26 @@ const ratingRegex = /^SkyWars_skywars_rating_(\d{1,2})_(\d{1,2})_(position|ratin
417
418
  /**
418
419
  * gets ratings & positions on the leaderboard
419
420
  * @param {Object} data data
421
+ * @param {Object|null} extraRSWData extra data to be attached
420
422
  * @returns {SkywarsRankedStats} some map
421
423
  */
422
- function getRankedPositions (data) {
424
+ function getRankedPositions (data, extraRSWData) {
423
425
  const map = new Map();
424
426
  const keys = Object.keys(data).map((key) => key.match(ratingRegex)).filter((x) => x);
425
427
  for (const key of keys) {
426
- const computedKey = `${(key[1].length - 1 ? '' : '0')}${key[1]}-${key[2]}`;
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);
427
433
  map.set(computedKey, {
428
434
  ...map.get(computedKey),
429
- [key[3]]: parseInt(data[key[0]], 10) || 0,
430
- date: new Date(new Date(1000 * 60 * 60 * 5).setFullYear(2000 + parseInt(key[2], 10), parseInt(key[1], 10) - 1, 1))
435
+ 'seasonKey': computedKey,
436
+ [type]: parseInt(data[property], 10) || 0,
437
+ 'date': new Date(initDate.setFullYear(2000 + year, month - 1, 1))
431
438
  });
432
439
  }
440
+ if (extraRSWData) map.set(extraRSWData.seasonKey, extraRSWData);
433
441
  return map;
434
442
  }
435
443
 
@@ -0,0 +1,45 @@
1
+ /**
2
+ * SkyWars Ranked class
3
+ */
4
+ class SkyWarsRanked {
5
+ /**
6
+ * @param {object} data
7
+ */
8
+ constructor (data) {
9
+ /**
10
+ * Ranked season key (e.g. 7_21 - July 2021)
11
+ * @type {string}
12
+ */
13
+ this.seasonKey = data.key;
14
+ /**
15
+ * Current position
16
+ * @type {number}
17
+ */
18
+ this.position = data.position;
19
+ /**
20
+ * Current rating
21
+ * @type {number}
22
+ */
23
+ this.rating = data.score;
24
+ /**
25
+ * Season key parsed as date, should usually be current season
26
+ * @type {Date}
27
+ */
28
+ this.date = getDateFromKey(this.seasonKey);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Gets date from season key
34
+ * @param {string} key Season Key
35
+ * @return {Date|null}
36
+ */
37
+ function getDateFromKey(key) {
38
+ const initDate = new Date(1000 * 60 * 60 * 5);
39
+ const [month, year] = key.split('_').map(Number);
40
+ // month needs to be 0 indexed cuz js :)
41
+ if (isNaN(month) || isNaN(year) || month > 11) return null;
42
+ return new Date(initDate.setFullYear(2000 + year, month - 1, 1));
43
+ }
44
+
45
+ module.exports = SkyWarsRanked;