hypixel-api-reborn 11.1.0 → 11.2.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 (93) hide show
  1. package/.prettierrc +3 -3
  2. package/README.md +5 -3
  3. package/package.json +20 -18
  4. package/src/API/getAchievements.js +6 -0
  5. package/src/API/getChallenges.js +6 -0
  6. package/src/API/getGuild.js +1 -1
  7. package/src/API/getGuildAchievements.js +6 -0
  8. package/src/API/getLeaderboards.js +3 -1
  9. package/src/API/getPlayer.js +1 -1
  10. package/src/API/getQuests.js +6 -0
  11. package/src/API/getRecentGames.js +1 -1
  12. package/src/API/getServerInfo.js +3 -1
  13. package/src/API/getStatus.js +1 -1
  14. package/src/API/index.js +28 -17
  15. package/src/API/skyblock/getAuction.js +19 -0
  16. package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +6 -2
  17. package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +1 -1
  18. package/src/API/skyblock/getBingo.js +8 -0
  19. package/src/API/skyblock/getBingoByPlayer.js +14 -0
  20. package/src/API/skyblock/getFireSales.js +7 -0
  21. package/src/API/skyblock/getGovernment.js +8 -0
  22. package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +9 -3
  23. package/src/API/skyblock/getMuseum.js +14 -0
  24. package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +13 -7
  25. package/src/Client.js +88 -14
  26. package/src/Errors.js +38 -17
  27. package/src/Private/rateLimit.js +10 -2
  28. package/src/Private/requests.js +19 -7
  29. package/src/Private/updater.js +9 -5
  30. package/src/Private/uuidCache.js +23 -29
  31. package/src/Private/validate.js +20 -9
  32. package/src/index.js +9 -0
  33. package/src/structures/APIIncident.js +3 -9
  34. package/src/structures/Boosters/Booster.js +5 -5
  35. package/src/structures/Color.js +93 -48
  36. package/src/structures/Game.js +3 -1
  37. package/src/structures/Guild/Guild.js +21 -17
  38. package/src/structures/Guild/GuildMember.js +6 -6
  39. package/src/structures/Guild/GuildRank.js +2 -2
  40. package/src/structures/MiniGames/Arcade.js +22 -17
  41. package/src/structures/MiniGames/BedWars.js +152 -24
  42. package/src/structures/MiniGames/Duels.js +84 -23
  43. package/src/structures/MiniGames/MegaWalls.js +3 -1
  44. package/src/structures/MiniGames/MurderMystery.js +2 -2
  45. package/src/structures/MiniGames/Pit.js +231 -2
  46. package/src/structures/MiniGames/PitInventoryItem.js +43 -0
  47. package/src/structures/MiniGames/SkyWars.js +19 -14
  48. package/src/structures/MiniGames/SmashHeroes.js +1 -1
  49. package/src/structures/MiniGames/TNTGames.js +1 -1
  50. package/src/structures/MiniGames/UHC.js +21 -3
  51. package/src/structures/Player.js +16 -20
  52. package/src/structures/PlayerCosmetics.js +64 -10
  53. package/src/structures/ServerInfo.js +1 -1
  54. package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
  55. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +1 -0
  56. package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -0
  57. package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
  58. package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
  59. package/src/structures/SkyBlock/PlayerBingo.js +56 -0
  60. package/src/structures/SkyBlock/SkyblockInventoryItem.js +86 -18
  61. package/src/structures/SkyBlock/SkyblockMember.js +252 -144
  62. package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
  63. package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
  64. package/src/structures/SkyBlock/SkyblockPet.js +1 -0
  65. package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
  66. package/src/structures/SkyBlock/Static/Bingo.js +102 -0
  67. package/src/structures/SkyBlock/Static/BingoData.js +45 -0
  68. package/src/structures/SkyBlock/Static/Candidate.js +40 -0
  69. package/src/structures/SkyBlock/Static/FireSale.js +55 -0
  70. package/src/structures/SkyBlock/Static/Government.js +74 -0
  71. package/src/structures/SkyBlock/Static/Perk.js +24 -0
  72. package/src/structures/Static/Achievement.js +86 -0
  73. package/src/structures/Static/AchievementTier.js +33 -0
  74. package/src/structures/Static/Achievements.js +30 -0
  75. package/src/structures/Static/Challenges.js +29 -0
  76. package/src/structures/Static/GameAchievements.js +36 -0
  77. package/src/structures/Static/GameChallenges.js +40 -0
  78. package/src/structures/Static/GameQuests.js +24 -0
  79. package/src/structures/Static/GuildAchievements.js +34 -0
  80. package/src/structures/Static/Quest.js +66 -0
  81. package/src/structures/Static/Quests.js +31 -0
  82. package/src/structures/Status.js +2 -2
  83. package/src/utils/Constants.js +382 -41
  84. package/src/utils/SkyblockUtils.js +12 -7
  85. package/src/utils/guildExp.js +4 -1
  86. package/src/utils/removeSnakeCase.js +9 -2
  87. package/src/utils/romanize.js +32 -1
  88. package/src/utils/toIGN.js +6 -2
  89. package/src/utils/toUuid.js +10 -5
  90. package/typings/index.d.ts +985 -295
  91. /package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +0 -0
  92. /package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +0 -0
  93. /package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +0 -0
@@ -1,10 +1,14 @@
1
- /* eslint-disable camelcase */
2
- const { decode, getLevelByXp, getLevelByAchievement, getSlayerLevel, getMemberStats, getTrophyFishRank } = require('../../utils/SkyblockUtils');
3
- const { skyblock_year_0, skills, skills_achievements } = require('../../utils/Constants');
1
+ const {
2
+ decode,
3
+ getLevelByXp,
4
+ getSlayerLevel,
5
+ getMemberStats,
6
+ getTrophyFishRank
7
+ } = require('../../utils/SkyblockUtils');
4
8
  const SkyblockInventoryItem = require('./SkyblockInventoryItem');
5
- const SkyblockPet = require('./SkyblockPet');
6
- const objectPath = require('object-path');
7
9
  const Constants = require('../../utils/Constants');
10
+ const skyhelper = require('skyhelper-networth');
11
+ const SkyblockPet = require('./SkyblockPet');
8
12
  /**
9
13
  * Skyblock member class
10
14
  */
@@ -19,61 +23,56 @@ class SkyblockMember {
19
23
  */
20
24
  this.uuid = data.uuid;
21
25
  /**
22
- * Skyblock member's player profile<br>
26
+ * Skyblock member's player profile
23
27
  * If `fetchPlayer` option is `true`.
24
28
  * @type {Player|null}
25
29
  */
26
30
  this.player = data.m.player || null;
27
31
  /**
28
- * Skyblock member's profile name
29
- * @type {string}
32
+ * If `getMuseum` option is `true`.
33
+ * @type {object|null}
30
34
  */
31
- this.profileName = data.profileName;
35
+ this.museum = data.museum ?? null;
32
36
  /**
33
- * Timestamp when player first joined SkyBlock
34
- * @type {number}
37
+ * Profile's gamemode
38
+ * @type {string|null}
35
39
  */
36
- this.firstJoinTimestamp = data.m.first_join;
40
+ this.gameMode = data.gameMode;
37
41
  /**
38
- * Timestamp when player first joined SkyBlock as Date
39
- * @type {Date}
42
+ * Profile is selected
43
+ * @type {boolean}
40
44
  */
41
- this.firstJoinAt = new Date(data.m.first_join);
45
+ this.selected = data.selected;
42
46
  /**
43
- * Timestamp when player first joined the SkyBlock Hub
44
- * @type {number}
47
+ * Skyblock member's profile name
48
+ * @type {string}
45
49
  */
46
- this.firstJoinHubTimestamp = data.m.first_join_hub;
50
+ this.profileName = data.profileName;
47
51
  /**
48
- * Timestamp when player first joined the SkyBlock Hub as Date
49
- * @type {Date}
52
+ * Skyblock member's profile id
53
+ * @type {string}
50
54
  */
51
- this.firstJoinHubAt = new Date(this.firstJoinTimestamp + data.m.first_join_hub);
55
+ this.profileId = data.profileId;
52
56
  /**
53
- * Last save timestamp
57
+ * Timestamp when player first joined SkyBlock
54
58
  * @type {number}
55
59
  */
56
- this.lastSaveTimestamp = data.m.last_save;
60
+ this.firstJoinTimestamp = data.m.profile?.first_join;
57
61
  /**
58
- * Last save timestamp as Date
62
+ * Timestamp when player first joined SkyBlock as Date
59
63
  * @type {Date}
60
64
  */
61
- this.lastSaveAt = new Date(data.m.last_save);
65
+ this.firstJoinAt = new Date(data.m.profile?.first_join);
62
66
  /**
63
- * Last save timestamp
67
+ * Experience
64
68
  * @type {number}
65
69
  */
66
- this.lastDeathTimestamp = data.m.last_death;
67
- /**
68
- * Last death timestamp as Date
69
- * @type {Date}
70
- */
71
- this.lastDeathAt = new Date(skyblock_year_0 + data.m.last_death * 1000);
70
+ this.experience = data.m.leveling?.experience ?? 0;
72
71
  /**
73
- * Experience
72
+ * Skyblock Level
74
73
  * @type {number}
75
74
  */
76
- this.experience = data.m.leveling?.experience ?? 0;
75
+ this.level = this.experience / 100 ?? 0;
77
76
  /**
78
77
  * Heart of the Mountain - MiningSkill
79
78
  * @type {number}
@@ -89,42 +88,16 @@ class SkyblockMember {
89
88
  * @type {number}
90
89
  */
91
90
  this.highestMagicalPower = data.m.accessory_bag_storage?.highest_magical_power ?? 0;
92
- /**
93
- * Equipped armor
94
- * @return {Promise<SkyblockMemberArmor>}
95
- */
96
- this.getArmor = async () => {
97
- const base64 = data.m.inv_armor;
98
- const decoded = await decode(base64.data);
99
- const armor = {
100
- helmet: decoded[3].id ? new SkyblockInventoryItem(decoded[3]) : null,
101
- chestplate: decoded[2].id ? new SkyblockInventoryItem(decoded[2]) : null,
102
- leggings: decoded[1].id ? new SkyblockInventoryItem(decoded[1]) : null,
103
- boots: decoded[0].id ? new SkyblockInventoryItem(decoded[0]) : null
104
- };
105
- return armor;
106
- };
107
- /**
108
- * Wardrobe contents
109
- * @return {Promise<SkyblockMemberItem[]>}
110
- */
111
- this.getWardrobe = async () => {
112
- const base64 = data.m?.wardrobe_contents?.data;
113
- if (!base64) return [];
114
- const decoded = await decode(base64);
115
- const armor = decoded.filter((item) => Object.keys(item).length !== 0).map((item) => new SkyblockInventoryItem(item));
116
- return armor;
117
- };
118
91
  /**
119
92
  * Collected fairy souls
120
93
  * @type {number}
121
94
  */
122
- this.fairySouls = data.m.fairy_souls_collected || 0;
95
+ this.fairySouls = data.m?.fairy_soul?.total_collected ?? 0;
123
96
  /**
124
97
  * Amount of fairy soul exchanges
125
98
  * @type {number}
126
99
  */
127
- this.fairyExchanges = data.m.fairyExchanges || 0;
100
+ this.fairyExchanges = data.m?.fairy_soul?.fairy_exchanges ?? 0;
128
101
  /**
129
102
  * Skyblock member skills
130
103
  * @type {SkyblockMemberSkills}
@@ -150,27 +123,74 @@ class SkyblockMember {
150
123
  * @type {object}
151
124
  */
152
125
  this.collections = data.m.collection ? data.m.collection : null;
126
+ /**
127
+ * Skyblock coins in purse
128
+ * @type {number}
129
+ */
130
+ this.purse = data.m?.currencies?.coin_purse ?? 0;
131
+ /**
132
+ * Skyblock member stats
133
+ * @type {SkyblockMemberStats}
134
+ */
135
+ this.stats = data.m.player_stats ? getMemberStats(data.m.player_stats) : null;
136
+ /**
137
+ * Skyblock pets
138
+ * @type {SkyblockPet[]}
139
+ */
140
+ this.pets = data.m?.pets_data?.pets ? data.m.pets_data.pets.map((pet) => new SkyblockPet(pet)) : [];
141
+ /**
142
+ * Skyblock jacob data
143
+ * @type {jacobData}
144
+ */
145
+ this.jacob = getJacobData(data);
146
+ /**
147
+ * Equipped armor
148
+ * @return {Promise<SkyblockMemberArmor>}
149
+ */
150
+ this.getArmor = async () => {
151
+ const base64 = data.m.inventory.inv_armor;
152
+ const decoded = await decode(base64.data);
153
+ const armor = {
154
+ helmet: decoded[3].id ? new SkyblockInventoryItem(decoded[3]) : null,
155
+ chestplate: decoded[2].id ? new SkyblockInventoryItem(decoded[2]) : null,
156
+ leggings: decoded[1].id ? new SkyblockInventoryItem(decoded[1]) : null,
157
+ boots: decoded[0].id ? new SkyblockInventoryItem(decoded[0]) : null
158
+ };
159
+ return armor;
160
+ };
161
+ /**
162
+ * Wardrobe contents
163
+ * @return {Promise<SkyblockMemberItem[]>}
164
+ */
165
+ this.getWardrobe = async () => {
166
+ const base64 = data.m?.inventory?.wardrobe_contents?.data;
167
+ if (!base64) return [];
168
+ const decoded = await decode(base64);
169
+ const armor = decoded
170
+ .filter((item) => Object.keys(item).length !== 0)
171
+ .map((item) => new SkyblockInventoryItem(item));
172
+ return armor;
173
+ };
153
174
  /**
154
175
  * Skyblock member enderchest
155
176
  * @return {Promise<SkyblockInventoryItem[]>}
156
177
  */
157
178
  this.getEnderChest = async () => {
158
- const chest = data.m.ender_chest_contents;
179
+ let chest = data.m.inventory.ender_chest_contents;
159
180
  if (!chest) return [];
160
181
 
161
182
  try {
162
- const enderChest = await decode(chest.data);
163
-
183
+ chest = await decode(chest.data);
164
184
  const edited = [];
165
- for (let i = 0; i < enderChest.length; i++) {
166
- if (!enderChest[i].id) {
185
+ for (let i = 0; i < chest.length; i++) {
186
+ if (!chest[i].id) {
167
187
  continue;
168
188
  }
169
- edited.push(new SkyblockInventoryItem(enderChest[i]));
189
+ edited.push(new SkyblockInventoryItem(chest[i]));
170
190
  }
171
191
  return edited;
172
192
  } catch (e) {
173
- return e;
193
+ return [];
174
194
  }
175
195
  };
176
196
  /**
@@ -178,7 +198,7 @@ class SkyblockMember {
178
198
  * @return {Promise<SkyblockInventoryItem[]>}
179
199
  */
180
200
  this.getInventory = async () => {
181
- let inventory = data.m.inv_contents;
201
+ let inventory = data.m.inventory.inv_contents;
182
202
  if (!inventory) return [];
183
203
 
184
204
  try {
@@ -192,43 +212,23 @@ class SkyblockMember {
192
212
  }
193
213
  return edited;
194
214
  } catch (e) {
195
- return e;
215
+ return [];
196
216
  }
197
217
  };
198
- /**
199
- * Skyblock coins in purse
200
- * @type {number}
201
- */
202
- this.purse = data.m.coin_purse || 0;
203
- /**
204
- * Skyblock member stats
205
- * @type {SkyblockMemberStats}
206
- */
207
- this.stats = data.m.stats ? getMemberStats(data.m.stats) : null;
208
- /**
209
- * Skyblock pets
210
- * @type {SkyblockPet[]}
211
- */
212
- this.pets = data.m.pets ? data.m.pets.map((pet) => new SkyblockPet(pet)) : [];
213
- /**
214
- * Skyblock jacob data
215
- * @type {jacobData}
216
- */
217
- this.jacob = getJacobData(data);
218
218
  /**
219
219
  * Skyblock Member pet score
220
220
  * @return {number}
221
221
  */
222
222
  this.getPetScore = () => {
223
223
  const highestRarity = {};
224
- for (const pet of data.m.pets) {
224
+ for (const pet of data.m.pets_data.pets) {
225
225
  if (!(pet.type in highestRarity) || Constants.pet_score[pet.tier] > highestRarity[pet.type]) {
226
226
  highestRarity[pet.type] = Constants.pet_score[pet.tier];
227
227
  }
228
228
  }
229
229
 
230
230
  const highestLevel = {};
231
- for (const pet of data.m.pets) {
231
+ for (const pet of data.m.pets_data.pets) {
232
232
  const maxLevel = pet.type === 'GOLDEN_DRAGON' ? 200 : 100;
233
233
  const petLevel = getPetLevel(pet.exp, pet.tier, maxLevel);
234
234
 
@@ -241,7 +241,69 @@ class SkyblockMember {
241
241
  }
242
242
  }
243
243
 
244
- return Object.values(highestRarity).reduce((a, b) => a + b, 0) + Object.values(highestLevel).reduce((a, b) => a + b, 0);
244
+ return (
245
+ Object.values(highestRarity).reduce((a, b) => a + b, 0) + Object.values(highestLevel).reduce((a, b) => a + b, 0)
246
+ );
247
+ };
248
+ /**
249
+ * Skyblock member equipment
250
+ * @return {Promise<SkyblockMemberEquipment>}
251
+ */
252
+ this.getEquipment = async () => {
253
+ let equipment = data.m.inventory.equipment_contents;
254
+ if (!equipment) return [];
255
+
256
+ try {
257
+ equipment = await decode(equipment.data);
258
+ const playerEquipment = {
259
+ gauntlet: equipment[3].id ? new SkyblockInventoryItem(equipment[3]) : null,
260
+ belt: equipment[2].id ? new SkyblockInventoryItem(equipment[2]) : null,
261
+ cloak: equipment[1].id ? new SkyblockInventoryItem(equipment[1]) : null,
262
+ necklace: equipment[0].id ? new SkyblockInventoryItem(equipment[0]) : null
263
+ };
264
+ return playerEquipment;
265
+ } catch (e) {
266
+ return [];
267
+ }
268
+ };
269
+ /**
270
+ * Skyblock member Personal Vault
271
+ * @return {Promise<SkyblockInventoryItem[]>}
272
+ */
273
+ this.getPersonalVault = async () => {
274
+ let vault = data.m.inventory.personal_vault_contents;
275
+ if (!vault) return [];
276
+
277
+ try {
278
+ vault = await decode(vault.data);
279
+ const edited = [];
280
+ for (let i = 0; i < vault.length; i++) {
281
+ if (!vault[i].id) {
282
+ continue;
283
+ }
284
+ edited.push(new SkyblockInventoryItem(vault[i]));
285
+ }
286
+ return edited;
287
+ } catch (e) {
288
+ return [];
289
+ }
290
+ };
291
+ /**
292
+ * Skyblock member networth (Credit to skyhelper-networth package)
293
+ * @return {Promise<skyhelper.NetworthResult>}
294
+ */
295
+ this.getNetworth = async () => {
296
+ try {
297
+ const nw = await skyhelper.getNetworth(data.m, data.banking.balance ?? 0, {
298
+ onlyNetworth: true,
299
+ v2Endpoint: true,
300
+ cache: true,
301
+ museumData: data.museum?.raw ?? {}
302
+ });
303
+ return nw;
304
+ } catch (e) {
305
+ return [];
306
+ }
245
307
  };
246
308
  }
247
309
  /**
@@ -255,20 +317,25 @@ class SkyblockMember {
255
317
  // eslint-disable-next-line require-jsdoc
256
318
  function getSkills(data) {
257
319
  const skillsObject = {};
258
- if (!objectPath.has(data, 'experience_skill_foraging')) {
259
- if (data.player) {
260
- for (const [skill, achievement] of Object.entries(skills_achievements)) {
261
- skillsObject[skill] = getLevelByAchievement(data.player.achievements[achievement], skill);
262
- }
263
- skillsObject.usedAchievementApi = true;
264
- return skillsObject;
265
- }
266
- return null;
267
- }
268
- for (const skill of skills) {
269
- skillsObject[skill] = getLevelByXp(data[`experience_skill_${skill}`], skill, skill === 'farming' ? (data.jacob2 && data.jacob2.perks && data.jacob2.perks.farming_level_cap) || 0 : null);
270
- }
271
- if (data.player) skillsObject.usedAchievementApi = false;
320
+ skillsObject['combat'] = getLevelByXp(data?.player_data?.experience?.SKILL_COMBAT ?? 0, 'combat');
321
+ skillsObject['farming'] = getLevelByXp(
322
+ data?.player_data?.experience?.SKILL_FARMING ?? 0,
323
+ 'farming',
324
+ data?.m?.jacobs_contest?.perks?.farming_level_cap ?? 0 + 50
325
+ );
326
+ skillsObject['fishing'] = getLevelByXp(data?.player_data?.experience?.SKILL_FISHING ?? 0, 'fishing');
327
+ skillsObject['mining'] = getLevelByXp(data?.player_data?.experience?.SKILL_MINING ?? 0, 'mining');
328
+ skillsObject['foraging'] = getLevelByXp(data?.player_data?.experience?.SKILL_FORAGING ?? 0, 'foraging');
329
+ skillsObject['enchanting'] = getLevelByXp(data?.player_data?.experience?.SKILL_ENCHANTING ?? 0, 'enchanting');
330
+ skillsObject['alchemy'] = getLevelByXp(data?.player_data?.experience?.SKILL_ALCHEMY ?? 0, 'alchemy');
331
+ skillsObject['carpentry'] = getLevelByXp(data?.player_data?.experience?.SKILL_CARPENTRY ?? 0, 'carpentry');
332
+ skillsObject['runecrafting'] = getLevelByXp(data?.player_data?.experience?.SKILL_RUNECRAFTING ?? 0, 'runecrafting');
333
+ skillsObject['taming'] = getLevelByXp(data?.player_data?.experience?.SKILL_TAMING ?? 0, 'taming');
334
+ skillsObject['social'] = getLevelByXp(data?.player_data?.experience?.SKILL_SOCIAL ?? 0, 'social');
335
+ const levels = Object.values(skillsObject)
336
+ .filter((skill) => skill.cosmetic !== true)
337
+ .map((skill) => skill.level);
338
+ skillsObject['average'] = levels.reduce((a, b) => a + b, 0) / levels.length;
272
339
  return skillsObject;
273
340
  }
274
341
  // eslint-disable-next-line require-jsdoc
@@ -329,39 +396,52 @@ function getBestiaryLevel(userProfile) {
329
396
 
330
397
  // eslint-disable-next-line require-jsdoc
331
398
  function getSlayer(data) {
332
- if (!objectPath.has(data, 'slayer_bosses')) {
333
- return null;
334
- }
399
+ if (!data?.slayer?.slayer_bosses) return;
335
400
  return {
336
- zombie: getSlayerLevel(data.slayer_bosses.zombie),
337
- spider: getSlayerLevel(data.slayer_bosses.spider),
338
- wolf: getSlayerLevel(data.slayer_bosses.wolf),
339
- enderman: getSlayerLevel(data.slayer_bosses.enderman),
340
- blaze: getSlayerLevel(data.slayer_bosses.blaze),
341
- vampire: getSlayerLevel(data.slayer_bosses.vampire)
401
+ zombie: getSlayerLevel(data?.slayer?.slayer_bosses?.zombie),
402
+ spider: getSlayerLevel(data?.slayer?.slayer_bosses?.spider),
403
+ wolf: getSlayerLevel(data?.slayer?.slayer_bosses?.wolf),
404
+ enderman: getSlayerLevel(data?.slayer?.slayer_bosses?.enderman),
405
+ blaze: getSlayerLevel(data?.slayer?.slayer_bosses?.blaze),
406
+ vampire: getSlayerLevel(data?.slayer?.slayer_bosses?.vampire)
342
407
  };
343
408
  }
344
409
  // eslint-disable-next-line require-jsdoc
345
410
  function getDungeons(data) {
346
- if (!objectPath.has(data, 'dungeons')) {
347
- return null;
348
- }
349
411
  return {
350
412
  types: {
351
- catacombs: getLevelByXp(data.dungeons.dungeon_types.catacombs ? data.dungeons.dungeon_types.catacombs.experience : null, 'dungeons')
413
+ catacombs: getLevelByXp(
414
+ data.dungeons?.dungeon_types?.catacombs ? data.dungeons.dungeon_types.catacombs.experience : null,
415
+ 'dungeons'
416
+ )
352
417
  },
353
418
  classes: {
354
- healer: getLevelByXp(data.dungeons.player_classes.healer ? data.dungeons.player_classes.healer.experience : null, 'dungeons'),
355
- mage: getLevelByXp(data.dungeons.player_classes.mage ? data.dungeons.player_classes.mage.experience : null, 'dungeons'),
356
- berserk: getLevelByXp(data.dungeons.player_classes.berserk ? data.dungeons.player_classes.berserk.experience : null, 'dungeons'),
357
- archer: getLevelByXp(data.dungeons.player_classes.archer ? data.dungeons.player_classes.archer.experience : null, 'dungeons'),
358
- tank: getLevelByXp(data.dungeons.player_classes.tank ? data.dungeons.player_classes.tank.experience : null, 'dungeons')
419
+ healer: getLevelByXp(
420
+ data.dungeons?.player_classes?.healer ? data.dungeons.player_classes.healer.experience : null,
421
+ 'dungeons'
422
+ ),
423
+ mage: getLevelByXp(
424
+ data.dungeons?.player_classes?.mage ? data.dungeons.player_classes.mage.experience : null,
425
+ 'dungeons'
426
+ ),
427
+ berserk: getLevelByXp(
428
+ data.dungeons?.player_classes?.berserk ? data.dungeons.player_classes.berserk.experience : null,
429
+ 'dungeons'
430
+ ),
431
+ archer: getLevelByXp(
432
+ data.dungeons?.player_classes?.archer ? data.dungeons.player_classes.archer.experience : null,
433
+ 'dungeons'
434
+ ),
435
+ tank: getLevelByXp(
436
+ data.dungeons?.player_classes?.tank ? data.dungeons.player_classes.tank.experience : null,
437
+ 'dungeons'
438
+ )
359
439
  }
360
440
  };
361
441
  }
362
442
  // eslint-disable-next-line require-jsdoc
363
443
  function getJacobData(data) {
364
- if (!data.m.jacob2) {
444
+ if (!data.m.jacobs_contest) {
365
445
  return {
366
446
  medals: {
367
447
  bronze: 0,
@@ -370,17 +450,28 @@ function getJacobData(data) {
370
450
  },
371
451
  perks: {
372
452
  doubleDrops: 0,
373
- farmingLevelCap: 0
453
+ farmingLevelCap: 0,
454
+ personalBests: false
374
455
  },
375
456
  contests: {}
376
457
  };
377
458
  }
378
459
  return {
379
- medals: data.m.jacob2.medals_inv
380
- ? { bronze: data.m.jacob2.medals_inv.bronze || 0, silver: data.m.jacob2.medals_inv.silver || 0, gold: data.m.jacob2.medals_inv.gold || 0 }
460
+ medals: data.m.jacobs_contest.medals_inv
461
+ ? {
462
+ bronze: data.m.jacobs_contest.medals_inv.bronze || 0,
463
+ silver: data.m.jacobs_contest.medals_inv.silver || 0,
464
+ gold: data.m.jacobs_contest.medals_inv.gold || 0
465
+ }
381
466
  : { bronze: 0, silver: 0, gold: 0 },
382
- perks: data.m.jacob2.perks ? { doubleDrops: data.m.jacob2.perks.doubleDrops || 0, farmingLevelCap: data.m.jacob2.perks.farmingLevelCap || 0 } : { doubleDrops: 0, farmingLevelCap: 0 },
383
- contests: data.m.jacob2.contests || {}
467
+ perks: data.m.jacobs_contest.perks
468
+ ? {
469
+ doubleDrops: data.m.jacobs_contest.perks.double_drops || 0,
470
+ farmingLevelCap: data.m.jacobs_contest.perks.farming_level_cap || 0,
471
+ personalBests: data.m.jacobs_contest.perks.personal_bests || false
472
+ }
473
+ : { doubleDrops: 0, farmingLevelCap: 0, personalBests: false },
474
+ contests: data.m.jacobs_contest.contests || {}
384
475
  };
385
476
  }
386
477
  // eslint-disable-next-line require-jsdoc
@@ -427,7 +518,14 @@ function getPetLevel(petExp, offsetRarity, maxLevel) {
427
518
  };
428
519
  }
429
520
  /**
430
- * @typedef {object} SkyblockMemberArmor Equipped armor
521
+ * @typedef {object} SkyblockMemberEquipment
522
+ * @property {SkyblockInventoryItem|null} gauntlet Gauntlet
523
+ * @property {SkyblockInventoryItem|null} belt Belt
524
+ * @property {SkyblockInventoryItem|null} cloak Cloak
525
+ * @property {SkyblockInventoryItem|null} necklace Necklace
526
+ */
527
+ /**
528
+ * @typedef {object} SkyblockMemberArmor
431
529
  * @property {SkyblockInventoryItem|null} helmet Helmet
432
530
  * @property {SkyblockInventoryItem|null} chestplate Chestplate
433
531
  * @property {SkyblockInventoryItem|null} leggings Leggings
@@ -435,16 +533,18 @@ function getPetLevel(petExp, offsetRarity, maxLevel) {
435
533
  */
436
534
  /**
437
535
  * @typedef {object} SkyblockMemberSkills
536
+ * @property {SkyblockSkillLevel} combat Combat skill
438
537
  * @property {SkyblockSkillLevel} farming Farming skill
538
+ * @property {SkyblockSkillLevel} fishing Fishing skill
439
539
  * @property {SkyblockSkillLevel} mining Mining skill
440
- * @property {SkyblockSkillLevel} combat Combat skill
441
540
  * @property {SkyblockSkillLevel} foraging Foraging skills
442
- * @property {SkyblockSkillLevel} fishing Fishing skill
443
541
  * @property {SkyblockSkillLevel} enchanting Enchanting skill
444
542
  * @property {SkyblockSkillLevel} alchemy Alchemy skill
445
- * @property {SkyblockSkillLevel} taming Taming skill
446
543
  * @property {SkyblockSkillLevel} carpentry Carpentry skill
447
544
  * @property {SkyblockSkillLevel} runecrafting Runecrafting skill
545
+ * @property {SkyblockSkillLevel} taming Taming skill
546
+ * @property {SkyblockSkillLevel} social Social skill
547
+ * @property {number} average Average skill level
448
548
  */
449
549
  /**
450
550
  * @typedef {object} SkyblockSkillLevel
@@ -457,12 +557,15 @@ function getPetLevel(petExp, offsetRarity, maxLevel) {
457
557
  * @property {number} xpCurrent Current XP
458
558
  * @property {number} xpForNext XP for next level
459
559
  * @property {number} progress Progress
560
+ * @property {boolean} cosmetic Cosmetic
460
561
  */
461
562
  /**
462
563
  * @typedef {object} SkyblockMemberSlayer
463
- * @property {SkyblockMemberSlayerLevel} zombie
464
- * @property {SkyblockMemberSlayerLevel} spider
465
- * @property {SkyblockMemberSlayerLevel} wolf
564
+ * @property {SkyblockMemberSlayerLevel} zombie Zombie
565
+ * @property {SkyblockMemberSlayerLevel} spider Spider
566
+ * @property {SkyblockMemberSlayerLevel} wolf Wolf
567
+ * @property {SkyblockMemberSlayerLevel} blaze Blaze
568
+ * @property {SkyblockMemberSlayerLevel} vampire Vampire
466
569
  */
467
570
  /**
468
571
  * @typedef {object} SkyblockMemberSlayerLevel
@@ -471,12 +574,13 @@ function getPetLevel(petExp, offsetRarity, maxLevel) {
471
574
  * @property {number} tier2 Tier 2
472
575
  * @property {number} tier3 Tier 3
473
576
  * @property {number} tier4 Tier 4
577
+ * @property {number} tier5 Tier 5
474
578
  * @property {number} level Level
475
579
  */
476
580
  /**
477
581
  * @typedef {object} SkyblockMemberDungeons
478
- * @property {object} types Dungeons types
479
- * @property {object} classes Dungeons classes
582
+ * @property {SkyblockMemberDungeonsTypes} types Dungeons types
583
+ * @property {SkyblockMemberDungeonsClasses} classes Dungeons classes
480
584
  */
481
585
  /**
482
586
  * @typedef {object} SkyblockMemberDungeonsTypes
@@ -806,15 +910,19 @@ function getPetLevel(petExp, offsetRarity, maxLevel) {
806
910
  * @property {number|undefined} petMilestoneOresMined
807
911
  * @property {number|undefined} petMilestoneSeaCreaturesKilled
808
912
  */
913
+ /**
914
+ * @typedef {object} jacobDataPerks
915
+ * @property {number} doubleDrops Double drops
916
+ * @property {number} farmingLevelCap Farming level cap
917
+ * @property {boolean} personalBests Personal Bests
918
+ */
809
919
  /**
810
920
  * @typedef {object} jacobData
811
921
  * @property {object} medals Medals
812
922
  * @property {number} medals.bronze Bronze medals
813
923
  * @property {number} medals.silver Silver medals
814
924
  * @property {number} medals.gold Gold medals
815
- * @property {object} perks Perks
816
- * @property {number} perks.doubleDrops Double drops
817
- * @property {number} perks.farmingLevelCap Farming level cap
925
+ * @property {jacobDataPerks} perks Perks
818
926
  * @property {object} contests Contests
819
927
  */
820
928
  module.exports = SkyblockMember;
@@ -0,0 +1,60 @@
1
+ const SkyblockMuseumItem = require('./SkyblockMuseumItem');
2
+ const { decode } = require('../../utils/SkyblockUtils');
3
+ /**
4
+ * Skyblock Museum class
5
+ */
6
+ class SkyblockMuseum {
7
+ /**
8
+ * @param {object} data Skyblock member data
9
+ */
10
+ constructor(data) {
11
+ /**
12
+ * Raw data
13
+ * @type {object}
14
+ */
15
+ this.raw = data.m.members?.[data.uuid] ?? {};
16
+ /**
17
+ * Normal Items
18
+ * @returns {SkyblockMuseumItem[]}
19
+ */
20
+ this.getItems = async () => {
21
+ const keys = Object.keys(data.m.members[data.uuid].items);
22
+ const items = [];
23
+ for (const key of keys) {
24
+ const decoded = await decode(data.m.members[data.uuid].items[key].items.data);
25
+ items.push(
26
+ new SkyblockMuseumItem({
27
+ decoded: decoded,
28
+ borrowing: data.m.members[data.uuid].items[key].borrowing ?? false,
29
+ featuredSlot: data.m.members[data.uuid].items[key].featured_slot ?? null,
30
+ donatedTime: data.m.members[data.uuid].items[key].donated_time,
31
+ name: key.toLowerCase().replace(/_/g, ' ')
32
+ })
33
+ );
34
+ }
35
+ return items;
36
+ };
37
+ /**
38
+ * Special items
39
+ * @returns {SkyblockMuseumItem[]}
40
+ */
41
+ this.getSpecial = async () => {
42
+ const items = [];
43
+ for (const item of data.m.members[data.uuid].special) {
44
+ const decoded = await decode(item.items.data);
45
+ items.push(
46
+ new SkyblockMuseumItem({
47
+ decoded: decoded,
48
+ borrowing: item.borrowing ?? false,
49
+ featuredSlot: item.featured_slot ?? null,
50
+ donatedTime: item.donated_time,
51
+ name: null
52
+ })
53
+ );
54
+ }
55
+ return items;
56
+ };
57
+ }
58
+ }
59
+
60
+ module.exports = SkyblockMuseum;