hypixel-api-reborn 11.1.0 → 11.2.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 (113) hide show
  1. package/.prettierrc +3 -3
  2. package/README.md +6 -4
  3. package/eslint.config.mjs +71 -0
  4. package/package.json +21 -25
  5. package/src/API/getAchievements.js +7 -0
  6. package/src/API/getBoosters.js +1 -0
  7. package/src/API/getChallenges.js +7 -0
  8. package/src/API/getGameCounts.js +1 -0
  9. package/src/API/getGuild.js +5 -4
  10. package/src/API/getGuildAchievements.js +7 -0
  11. package/src/API/getLeaderboards.js +4 -2
  12. package/src/API/getPlayer.js +2 -1
  13. package/src/API/getQuests.js +7 -0
  14. package/src/API/getRecentGames.js +6 -10
  15. package/src/API/getServerInfo.js +42 -37
  16. package/src/API/getStatus.js +2 -1
  17. package/src/API/getWatchdogStats.js +1 -0
  18. package/src/API/index.js +28 -17
  19. package/src/API/skyblock/getAuction.js +21 -0
  20. package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +19 -12
  21. package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +2 -2
  22. package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +1 -3
  23. package/src/API/skyblock/getBingo.js +7 -0
  24. package/src/API/skyblock/getBingoByPlayer.js +14 -0
  25. package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +1 -0
  26. package/src/API/skyblock/getFireSales.js +7 -0
  27. package/src/API/skyblock/getGovernment.js +7 -0
  28. package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +10 -3
  29. package/src/API/skyblock/getMuseum.js +15 -0
  30. package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +1 -0
  31. package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +14 -7
  32. package/src/Client.js +127 -25
  33. package/src/Errors.js +38 -17
  34. package/src/Private/rateLimit.js +17 -13
  35. package/src/Private/requests.js +27 -16
  36. package/src/Private/updater.js +11 -8
  37. package/src/Private/uuidCache.js +23 -30
  38. package/src/Private/validate.js +33 -22
  39. package/src/index.js +9 -0
  40. package/src/structures/APIIncident.js +4 -11
  41. package/src/structures/APIStatus.js +0 -1
  42. package/src/structures/Boosters/Booster.js +14 -13
  43. package/src/structures/Color.js +93 -48
  44. package/src/structures/Game.js +4 -2
  45. package/src/structures/Guild/Guild.js +35 -48
  46. package/src/structures/Guild/GuildMember.js +8 -8
  47. package/src/structures/Guild/GuildRank.js +2 -2
  48. package/src/structures/MiniGames/Arcade.js +242 -235
  49. package/src/structures/MiniGames/ArenaBrawl.js +11 -11
  50. package/src/structures/MiniGames/BedWars.js +262 -131
  51. package/src/structures/MiniGames/BlitzSurvivalGames.js +24 -23
  52. package/src/structures/MiniGames/CopsAndCrims.js +1 -0
  53. package/src/structures/MiniGames/Duels.js +92 -33
  54. package/src/structures/MiniGames/MegaWalls.js +3 -1
  55. package/src/structures/MiniGames/MurderMystery.js +2 -2
  56. package/src/structures/MiniGames/Pit.js +230 -2
  57. package/src/structures/MiniGames/PitInventoryItem.js +43 -0
  58. package/src/structures/MiniGames/SkyWars.js +211 -195
  59. package/src/structures/MiniGames/SmashHeroes.js +37 -35
  60. package/src/structures/MiniGames/SpeedUHC.js +17 -4
  61. package/src/structures/MiniGames/TNTGames.js +1 -1
  62. package/src/structures/MiniGames/UHC.js +33 -14
  63. package/src/structures/MiniGames/WoolWars.js +6 -5
  64. package/src/structures/Pet.js +1 -1
  65. package/src/structures/Player.js +26 -121
  66. package/src/structures/PlayerCosmetics.js +67 -12
  67. package/src/structures/ServerInfo.js +1 -1
  68. package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
  69. package/src/structures/SkyBlock/Auctions/AuctionInfo.js +3 -1
  70. package/src/structures/SkyBlock/Auctions/BaseAuction.js +2 -1
  71. package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
  72. package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
  73. package/src/structures/SkyBlock/News/SkyblockNews.js +15 -15
  74. package/src/structures/SkyBlock/PlayerBingo.js +49 -0
  75. package/src/structures/SkyBlock/SkyblockInventoryItem.js +76 -32
  76. package/src/structures/SkyBlock/SkyblockMember.js +252 -289
  77. package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
  78. package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
  79. package/src/structures/SkyBlock/SkyblockPet.js +3 -3
  80. package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
  81. package/src/structures/SkyBlock/Static/Bingo.js +101 -0
  82. package/src/structures/SkyBlock/Static/BingoData.js +45 -0
  83. package/src/structures/SkyBlock/Static/Candidate.js +40 -0
  84. package/src/structures/SkyBlock/Static/FireSale.js +55 -0
  85. package/src/structures/SkyBlock/Static/Government.js +74 -0
  86. package/src/structures/SkyBlock/Static/Perk.js +24 -0
  87. package/src/structures/Static/Achievement.js +87 -0
  88. package/src/structures/Static/AchievementTier.js +33 -0
  89. package/src/structures/Static/Achievements.js +30 -0
  90. package/src/structures/Static/Challenges.js +29 -0
  91. package/src/structures/Static/GameAchievements.js +36 -0
  92. package/src/structures/Static/GameChallenges.js +40 -0
  93. package/src/structures/Static/GameQuests.js +24 -0
  94. package/src/structures/Static/GuildAchievements.js +34 -0
  95. package/src/structures/Static/Quest.js +66 -0
  96. package/src/structures/Static/Quests.js +31 -0
  97. package/src/structures/Status.js +2 -2
  98. package/src/utils/Constants.js +384 -543
  99. package/src/utils/{guildExp.js → Guild.js} +46 -13
  100. package/src/utils/Player.js +112 -0
  101. package/src/utils/SkyblockUtils.js +448 -186
  102. package/src/utils/arrayTools.js +1 -1
  103. package/src/utils/divide.js +1 -1
  104. package/src/utils/index.js +2 -1
  105. package/src/utils/isGuildID.js +1 -1
  106. package/src/utils/oscillation.js +4 -2
  107. package/src/utils/removeSnakeCase.js +19 -8
  108. package/src/utils/rgbToHexColor.js +1 -1
  109. package/src/utils/romanize.js +35 -4
  110. package/src/utils/toUuid.js +12 -7
  111. package/src/utils/varInt.js +2 -2
  112. package/typings/index.d.ts +1246 -446
  113. package/src/utils/toIGN.js +0 -20
@@ -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;
@@ -0,0 +1,54 @@
1
+ const SkyblockInventoryItem = require('./SkyblockInventoryItem');
2
+ /**
3
+ * Item class
4
+ */
5
+ class SkyblockMuseumItem {
6
+ /**
7
+ * @param {object} data Item data
8
+ */
9
+ constructor(data) {
10
+ /**
11
+ * Item name
12
+ * @type {string|null}
13
+ **/
14
+ this.name = data.name;
15
+ /**
16
+ * Item
17
+ * @type {SkyblockInventoryItem}
18
+ */
19
+ this.items = [];
20
+ data.decoded.forEach((item) => {
21
+ if (!item.tag) return;
22
+ this.items.push(new SkyblockInventoryItem(item));
23
+ });
24
+ /**
25
+ * Donated Time
26
+ * @type {number}
27
+ */
28
+ this.donatedTime = data.donatedTime;
29
+ /**
30
+ * Donated Time as Date
31
+ * @type {Date}
32
+ */
33
+ this.donatedTimeAt = new Date(data.donatedTime);
34
+ /**
35
+ * Borrowing
36
+ * @type {boolean}
37
+ */
38
+ this.borrowing = data.borrowing;
39
+ /**
40
+ * Featured Slot
41
+ * @type {string|null}
42
+ */
43
+ this.featuredSlot = data.featuredSlot;
44
+ }
45
+ /**
46
+ * Item Name
47
+ * @return {string}
48
+ */
49
+ toString() {
50
+ return this.name;
51
+ }
52
+ }
53
+
54
+ module.exports = SkyblockMuseumItem;
@@ -1,5 +1,4 @@
1
- // eslint-disable-next-line camelcase
2
- const { pet_score } = require('../../utils/Constants');
1
+ const { petScore } = require('../../utils/Constants');
3
2
  /**
4
3
  * Skyblock Pet class
5
4
  */
@@ -38,7 +37,8 @@ class SkyblockPet {
38
37
  * Skyblock Pet score
39
38
  * @type {number}
40
39
  */
41
- this.petScore = pet_score[data.tier] || 0;
40
+
41
+ this.petScore = petScore[data.tier] || 0;
42
42
  /**
43
43
  * Skyblock Pet held item
44
44
  * @type {string|null}
@@ -12,27 +12,55 @@ class SkyblockProfile {
12
12
  * Skyblock profile ID
13
13
  * @type {string}
14
14
  */
15
- this.profileId = data.profile_id;
15
+ this.profileId = data.profileId;
16
16
  /**
17
17
  * Skyblock profile name
18
18
  * @type {string}
19
19
  */
20
- this.profileName = data.profile_name;
20
+ this.profileName = data.profileName;
21
21
  /**
22
- * Skyblock profile members
23
- * @type {SkyblockMember[]}
22
+ * Profile's gamemode
23
+ * @type {string|null}
24
24
  */
25
- this.members = edit(data.members, this.profileName).map((m) => new SkyblockMember(m));
25
+ this.gameMode = data.gameMode;
26
26
  /**
27
- * Queried player's member stats
28
- * @type {SkyblockMember}
27
+ * Profile's banking
28
+ * @type {object}
29
29
  */
30
- this.me = this.members.find((x) => x.uuid === data.me);
30
+ this.banking = data.banking;
31
31
  /**
32
- * Is the profile selected
32
+ * Profile's community upgrades
33
+ * @type {object}
34
+ */
35
+ this.communityUpgrades = data.communityUpgrades;
36
+ /**
37
+ * Profile is selected
33
38
  * @type {boolean}
34
39
  */
35
40
  this.selected = data.selected;
41
+ /**
42
+ * Skyblock profile members
43
+ * @type {SkyblockMember[]}
44
+ */
45
+ this.members = Object.keys(data.members).map(
46
+ (uuid) =>
47
+ new SkyblockMember({
48
+ uuid: uuid,
49
+ profileId: this.profileId,
50
+ profileName: this.profileName,
51
+ gameMode: this.gameMode,
52
+ m: data.members[uuid],
53
+ banking: this.banking,
54
+ communityUpgrades: this.communityUpgrades,
55
+ museum: null,
56
+ selected: this.selected
57
+ })
58
+ );
59
+ /**
60
+ * Queried player's member stats
61
+ * @type {SkyblockMember}
62
+ */
63
+ this.me = this.members.find((x) => x.uuid === data.uuid);
36
64
  }
37
65
  /**
38
66
  * Profile Name
@@ -43,18 +71,4 @@ class SkyblockProfile {
43
71
  }
44
72
  }
45
73
 
46
- // eslint-disable-next-line require-jsdoc
47
- function edit(members, profileName) {
48
- const edited = [];
49
- Object.keys(members).forEach((k) => {
50
- const m = members[k];
51
- edited.push({
52
- uuid: k,
53
- profileName,
54
- m
55
- });
56
- });
57
- return edited;
58
- }
59
-
60
74
  module.exports = SkyblockProfile;
@@ -0,0 +1,101 @@
1
+ // eslint-disable-next-line jsdoc/require-jsdoc
2
+ function parsePosition(position) {
3
+ const x = (position % 5) + 1;
4
+ const y = Math.floor(position / 5) + 1;
5
+ return [x, y];
6
+ }
7
+ /**
8
+ * Bingo class
9
+ */
10
+ class Bingo {
11
+ /**
12
+ * Constructor
13
+ * @param {Object} data data
14
+ * @param {number} position Position
15
+ */
16
+ constructor(data, position = 0) {
17
+ /**
18
+ * Name of this bingo goal
19
+ * @type {string}
20
+ */
21
+ this.name = data.name;
22
+ /**
23
+ * string ID (code name)
24
+ * @type {string}
25
+ */
26
+ this.id = data.id;
27
+ const [row, column] = parsePosition(position);
28
+ /**
29
+ * 1-indexed row
30
+ * @type {number|null}
31
+ */
32
+ this.row = row;
33
+ /**
34
+ * 1-indexed colmun
35
+ * @type {number|null}
36
+ */
37
+ this.column = column;
38
+ /**
39
+ * Bingo lore, with color codes
40
+ * @type {string}
41
+ */
42
+ this.rawLore = data.lore;
43
+ /**
44
+ * Bingo lore in plain text
45
+ * @type {string}
46
+ */
47
+ this.lore = data.lore?.replace?.(/§([1-9]|[a-l])|§/gm, '') || null;
48
+ /**
49
+ * Only available for TIERED bingos
50
+ * Shows you the requirement for each tier of this achievement
51
+ * @type {number[]}
52
+ */
53
+ this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : null;
54
+ /**
55
+ * Only available for TIERED bingos
56
+ * Difference between each tier requirement, if it is constant
57
+ * @type {number|null}
58
+ */
59
+ this.tierStep = this.getTierStep();
60
+ /**
61
+ * Only available for ONE_TIERED bingos
62
+ * @type {number|null}
63
+ */
64
+ this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null;
65
+ /**
66
+ * Type of Bingo
67
+ * ONE_TIME means the goal doesn't have a specific amount
68
+ * ONE_TIER means the goal specifies 1 amount to achieve
69
+ * TIERED means the goal specifies more than 1 amount to achieve
70
+ * @type {'ONE_TIME'|'ONE_TIER'|'TIERED'}
71
+ */
72
+ this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME';
73
+ }
74
+ /**
75
+ * As string
76
+ * BEWARE this returns ID to assure compatibility with PlayerBingo
77
+ * @return {string}
78
+ */
79
+ toString() {
80
+ return this.id;
81
+ }
82
+ /**
83
+ * Gets tier step, if constant
84
+ * @private
85
+ * @returns {number|null}
86
+ */
87
+ getTierStep() {
88
+ if ('TIERED' !== this.type) return null;
89
+ // No step possible
90
+ if (2 > this.tiers.length) return null;
91
+ const hypotheticStep = this.tiers[1] - this.tiers[0];
92
+ // Check if every 2 elements have the same step
93
+ const isConstant = this.tiers.slice(1).every((el, index) => {
94
+ return hypotheticStep === this.tiers[index - 1] - el;
95
+ });
96
+ if (!isConstant) return null;
97
+ return hypotheticStep;
98
+ }
99
+ }
100
+
101
+ module.exports = Bingo;
@@ -0,0 +1,45 @@
1
+ const Bingo = require('./Bingo.js');
2
+
3
+ /**
4
+ * SB Bingo Class
5
+ */
6
+ class BingoData {
7
+ /**
8
+ * constructor
9
+ * @param {Object} data
10
+ */
11
+ constructor(data) {
12
+ /**
13
+ * Last time this resource was updated
14
+ * @type {number}
15
+ */
16
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
17
+ /**
18
+ * Last time this resource was updated, as Date
19
+ * @type {Date|null}
20
+ */
21
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
22
+ /**
23
+ * Bingo ID
24
+ * @type {number|null}
25
+ */
26
+ this.id = parseInt(data.id, 10) || null;
27
+ /**
28
+ * Goals
29
+ * @type {Bingo[]|null}
30
+ */
31
+ this.goals = Array.isArray(data.goals) ? data.goals.map((goal, index) => new Bingo(goal, index)) : null;
32
+ }
33
+ /**
34
+ * Gets a goal on the bingo table by row and column
35
+ * @param {number} column Column number (starts at 1)
36
+ * @param {number} row Row number (starts at 1)
37
+ * @returns {Bingo|undefined}
38
+ */
39
+ getGoal(column, row) {
40
+ if (!this.goals || 1 > this.goals.length) return;
41
+ return this.goals.find((goal) => goal.row === row && goal.column === column);
42
+ }
43
+ }
44
+
45
+ module.exports = BingoData;
@@ -0,0 +1,40 @@
1
+ const Perk = require('./Perk');
2
+ /**
3
+ * Candidate class
4
+ */
5
+ class Candidate {
6
+ /**
7
+ * Constructor
8
+ * @param {Object} data data
9
+ * @param {boolean} [isMayor=false] if this candidate is the current mayor
10
+ */
11
+ constructor(data, isMayor = false) {
12
+ /**
13
+ * Mayor's name
14
+ * @type {string}
15
+ */
16
+ this.name = data.name;
17
+ /**
18
+ * Mayor's Key Benefit (in 1 word)
19
+ * @type {string}
20
+ */
21
+ this.keyBenefit = data.key;
22
+ /**
23
+ * Perks
24
+ * @type {Perk[]}
25
+ */
26
+ this.perks = data.perks.map((x) => new Perk(x));
27
+ /**
28
+ * If this candidate is the current mayor
29
+ * @type {boolean}
30
+ */
31
+ this.isMayor = isMayor || false;
32
+ /**
33
+ * The number of votes received by this candidate
34
+ * @type {number}
35
+ */
36
+ this.votesReceived = parseInt(data.votes, 10) || 0;
37
+ }
38
+ }
39
+
40
+ module.exports = Candidate;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SB Fire Sale
3
+ */
4
+ class FireSale {
5
+ /**
6
+ * constructor
7
+ * @param {Object} data
8
+ */
9
+ constructor(data) {
10
+ /**
11
+ * Item ID
12
+ * @type {string|null}
13
+ */
14
+ this.itemId = data.item_id || null;
15
+ /**
16
+ * Start Timestamp as a unix
17
+ * @type {number}
18
+ */
19
+ this.startTimestamp = parseInt(data.start, 10);
20
+ /**
21
+ * Start Date
22
+ * @type {Date}
23
+ */
24
+ this.startAt = new Date(this.startTimestamp);
25
+ /**
26
+ * End Timestamp as a unix
27
+ * @type {number}
28
+ */
29
+ this.endTimestamp = parseInt(data.end, 10);
30
+ /**
31
+ * End Date
32
+ * @type {Date}
33
+ */
34
+ this.endAt = new Date(this.endTimestamp);
35
+ /**
36
+ * Amount of items being sold
37
+ * @type {number}
38
+ */
39
+ this.amount = data.amount || 0;
40
+ /**
41
+ * Price
42
+ * @type {number}
43
+ */
44
+ this.price = data.price || 0;
45
+ }
46
+ /**
47
+ * Item Id
48
+ * @return {string|null}
49
+ */
50
+ toString() {
51
+ return this.itemId;
52
+ }
53
+ }
54
+
55
+ module.exports = FireSale;
@@ -0,0 +1,74 @@
1
+ const Candidate = require('./Candidate');
2
+
3
+ /**
4
+ * SB Government Class
5
+ */
6
+ class GovernmentData {
7
+ /**
8
+ * constructor
9
+ * @param {Object} data
10
+ */
11
+ constructor(data) {
12
+ /**
13
+ * Last time this resource was updated
14
+ * @type {number}
15
+ */
16
+ this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
17
+ /**
18
+ * Last time this resource was updated, as Date
19
+ * @type {Date|null}
20
+ */
21
+ this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
22
+ const lastElectionResults = data.mayor.election.candidates.map((x) => new Candidate(x, x.name === data.mayor.name));
23
+ /**
24
+ * A map of last election results for each candidate
25
+ * Sorted ascendingly by votes received
26
+ * @type {Map<string, Candidate>}
27
+ */
28
+ this.lastElectionResults = new Map(
29
+ lastElectionResults
30
+ .sort((a, b) => a.votesReceived - b.votesReceived)
31
+ .reverse()
32
+ .map((x) => [x.name, x])
33
+ );
34
+ /**
35
+ * The mayor
36
+ * @type {Candidate}
37
+ */
38
+ this.mayor = this.lastElectionResults.get(data.mayor.name);
39
+ /**
40
+ * The year the mayor will be running for
41
+ * @type {number}
42
+ */
43
+ this.runningYear = parseInt(data.mayor.election.year, 10) || 0;
44
+ const thisElection = data.current?.candidates.map((x) => new Candidate(x, x.name === data.mayor.name)) || null;
45
+ /**
46
+ * Current elections, valid for next year
47
+ * Sorted ascendingly by votes received
48
+ * RESULTS MIGHT BE TEMPORARY
49
+ * @type {Map<string, Candidate>|null}
50
+ */
51
+ this.currentElectionResults = thisElection
52
+ ? new Map(
53
+ thisElection
54
+ .sort((a, b) => a.votesReceived - b.votesReceived)
55
+ .reverse()
56
+ .map((x) => [x.name, x])
57
+ )
58
+ : null;
59
+ /**
60
+ * The year the current election will be effective for
61
+ * @type {number|null}
62
+ */
63
+ this.currentElectionFor = parseInt(data.current?.year, 10) || null;
64
+ }
65
+ /**
66
+ * Current Mayor
67
+ * @return {string}
68
+ */
69
+ toString() {
70
+ return this.mayor.name;
71
+ }
72
+ }
73
+
74
+ module.exports = GovernmentData;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Candidate class
3
+ */
4
+ class Perk {
5
+ /**
6
+ * Constructor
7
+ * @param {Object} data data
8
+ * @param {boolean} [isMayor=false] if this candidate is the current mayor
9
+ */
10
+ constructor(data) {
11
+ /**
12
+ * Perk's Name
13
+ * @type {string}
14
+ */
15
+ this.name = data.name;
16
+ /**
17
+ * Perk's Description
18
+ * @type {string}
19
+ */
20
+ this.description = data.description;
21
+ }
22
+ }
23
+
24
+ module.exports = Perk;
@@ -0,0 +1,87 @@
1
+ const AchievementTier = require('./AchievementTier');
2
+
3
+ // eslint-disable-next-line jsdoc/require-jsdoc
4
+ function collectAll(data) {
5
+ const mTier = data.maxTier;
6
+ let totalPoints = 0;
7
+ let totalAmount = 0;
8
+ for (let i = 1; i <= mTier; i++) {
9
+ totalPoints += data.getTier(i).pointsRewarded;
10
+ totalAmount += data.getTier(i).amountRequired;
11
+ }
12
+ return { totalPoints, totalAmount };
13
+ }
14
+
15
+ /**
16
+ * Achievement Class
17
+ */
18
+ class Achievement {
19
+ /**
20
+ * constructor
21
+ * @param {string} achievementName Name of achievement
22
+ * @param {Object} data
23
+ */
24
+ constructor(achievementName, data) {
25
+ /**
26
+ * Name of achievement, trimmed trailing spaces
27
+ * @type {string}
28
+ */
29
+ this.name = data.name.trim();
30
+ /**
31
+ * Code name of achievement
32
+ * @type {string}
33
+ */
34
+ this.codeName = achievementName;
35
+ /**
36
+ * Description, trimmed trailing spaces
37
+ * @type {string}
38
+ */
39
+ this.description = data.description.trim();
40
+ /**
41
+ * Type of achievement
42
+ * @type {'ONE_TIME'|'TIERED'}
43
+ */
44
+ this.type = data.tiers ? 'TIERED' : 'ONE_TIME';
45
+ /**
46
+ * ONLY AVAILABLE IN PERSONAL ONE TIME ACHIEVEMENTS, last checked April 26th
47
+ * Unlock rate of this achievement
48
+ * Local : Fraction of players that have played the game and gotten this achievement (0 to 1 inclusive)
49
+ * Global : Fraction of players that have played Hypixel and gotten this achievement (0 to 1 inclusive)
50
+ * ...percentage : In percentage (0 to 100 inclusive)
51
+ * @type {Record<'local'|'localPercentage'|'global'|'globalPercentage', number>|null}
52
+ */
53
+ this.rarity = {
54
+ local: parseFloat(data.gamePercentUnlocked) || 0,
55
+ localPercentage: parseFloat(data.gamePercentUnlocked) * 100 || 0,
56
+ global: data.globalPercentUnlocked,
57
+ globalPercentage: parseFloat(data.globalPercentUnlocked) * 100 || 0
58
+ };
59
+ /**
60
+ * ONLY AVAILABLE FOR TIERED
61
+ * @type {AchievementTier|null}
62
+ */
63
+ this.tierInformation = 'TIERED' === this.type ? new AchievementTier(data.tiers) : null;
64
+
65
+ const { totalPoints, totalAmount } = 'TIERED' === this.type ? collectAll(this.tierInformation) : {};
66
+ /**
67
+ * Total points worth (sum of all tiers if tiered)
68
+ * This is always 0 for Guild Achievements
69
+ * @type {number}
70
+ */
71
+ this.points = 'ONE_TIME' === this.type ? parseInt(data.points, 10) : totalPoints;
72
+ /**
73
+ * Total amount required to reach max tier, only for tiered
74
+ * @type {number|null}
75
+ */
76
+ this.totalAmountRequired = 'TIERED' === this.type ? totalAmount : null;
77
+ }
78
+ /**
79
+ * As string
80
+ * @return {string}
81
+ */
82
+ toString() {
83
+ return this.achievementName;
84
+ }
85
+ }
86
+
87
+ module.exports = Achievement;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * AchievementTier class
3
+ */
4
+ class AchievementTier {
5
+ /**
6
+ * @param {Record<string, number>} data
7
+ */
8
+ constructor(data) {
9
+ /**
10
+ * Maximum tier reachable
11
+ * getTier will be take any integer from 1 to this number (inclusive)
12
+ * @type {number}
13
+ */
14
+ this.maxTier = data.length;
15
+ // Still make sure it is well sorted
16
+ this.tierInfo = data.sort(({ tier: tierA }, { tier: tierB }) => Number(tierA) - Number(tierB));
17
+ }
18
+ /**
19
+ * Gets information for tier
20
+ * @param {number} tier Tier number (1-indexed!)
21
+ * @returns {Record<'pointsRewarded'|'amountRequired', number>}
22
+ */
23
+ getTier(tier) {
24
+ const index = tier - 1;
25
+ const info = this.tierInfo[index];
26
+ return {
27
+ pointsRewarded: parseInt(info.points, 10) || 0,
28
+ amountRequired: parseInt(info.amount, 10) || 0
29
+ };
30
+ }
31
+ }
32
+
33
+ module.exports = AchievementTier;