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.
- package/.prettierrc +3 -3
- package/README.md +5 -3
- package/package.json +20 -18
- package/src/API/getAchievements.js +6 -0
- package/src/API/getChallenges.js +6 -0
- package/src/API/getGuild.js +1 -1
- package/src/API/getGuildAchievements.js +6 -0
- package/src/API/getLeaderboards.js +3 -1
- package/src/API/getPlayer.js +1 -1
- package/src/API/getQuests.js +6 -0
- package/src/API/getRecentGames.js +1 -1
- package/src/API/getServerInfo.js +3 -1
- package/src/API/getStatus.js +1 -1
- package/src/API/index.js +28 -17
- package/src/API/skyblock/getAuction.js +19 -0
- package/src/API/skyblock/{getSkyblockAuctions.js → getAuctions.js} +6 -2
- package/src/API/skyblock/{getSkyblockAuctionsByPlayer.js → getAuctionsByPlayer.js} +1 -1
- package/src/API/skyblock/getBingo.js +8 -0
- package/src/API/skyblock/getBingoByPlayer.js +14 -0
- package/src/API/skyblock/getFireSales.js +7 -0
- package/src/API/skyblock/getGovernment.js +8 -0
- package/src/API/skyblock/{getSkyblockMember.js → getMember.js} +9 -3
- package/src/API/skyblock/getMuseum.js +14 -0
- package/src/API/skyblock/{getSkyblockProfiles.js → getProfiles.js} +13 -7
- package/src/Client.js +88 -14
- package/src/Errors.js +38 -17
- package/src/Private/rateLimit.js +10 -2
- package/src/Private/requests.js +19 -7
- package/src/Private/updater.js +9 -5
- package/src/Private/uuidCache.js +23 -29
- package/src/Private/validate.js +20 -9
- package/src/index.js +9 -0
- package/src/structures/APIIncident.js +3 -9
- package/src/structures/Boosters/Booster.js +5 -5
- package/src/structures/Color.js +93 -48
- package/src/structures/Game.js +3 -1
- package/src/structures/Guild/Guild.js +21 -17
- package/src/structures/Guild/GuildMember.js +6 -6
- package/src/structures/Guild/GuildRank.js +2 -2
- package/src/structures/MiniGames/Arcade.js +22 -17
- package/src/structures/MiniGames/BedWars.js +152 -24
- package/src/structures/MiniGames/Duels.js +84 -23
- package/src/structures/MiniGames/MegaWalls.js +3 -1
- package/src/structures/MiniGames/MurderMystery.js +2 -2
- package/src/structures/MiniGames/Pit.js +231 -2
- package/src/structures/MiniGames/PitInventoryItem.js +43 -0
- package/src/structures/MiniGames/SkyWars.js +19 -14
- package/src/structures/MiniGames/SmashHeroes.js +1 -1
- package/src/structures/MiniGames/TNTGames.js +1 -1
- package/src/structures/MiniGames/UHC.js +21 -3
- package/src/structures/Player.js +16 -20
- package/src/structures/PlayerCosmetics.js +64 -10
- package/src/structures/ServerInfo.js +1 -1
- package/src/structures/SkyBlock/Auctions/Auction.js +3 -1
- package/src/structures/SkyBlock/Auctions/AuctionInfo.js +1 -0
- package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -0
- package/src/structures/SkyBlock/Auctions/Bid.js +1 -0
- package/src/structures/SkyBlock/Auctions/PartialAuction.js +1 -0
- package/src/structures/SkyBlock/PlayerBingo.js +56 -0
- package/src/structures/SkyBlock/SkyblockInventoryItem.js +86 -18
- package/src/structures/SkyBlock/SkyblockMember.js +252 -144
- package/src/structures/SkyBlock/SkyblockMuseum.js +60 -0
- package/src/structures/SkyBlock/SkyblockMuseumItem.js +54 -0
- package/src/structures/SkyBlock/SkyblockPet.js +1 -0
- package/src/structures/SkyBlock/SkyblockProfile.js +37 -23
- package/src/structures/SkyBlock/Static/Bingo.js +102 -0
- package/src/structures/SkyBlock/Static/BingoData.js +45 -0
- package/src/structures/SkyBlock/Static/Candidate.js +40 -0
- package/src/structures/SkyBlock/Static/FireSale.js +55 -0
- package/src/structures/SkyBlock/Static/Government.js +74 -0
- package/src/structures/SkyBlock/Static/Perk.js +24 -0
- package/src/structures/Static/Achievement.js +86 -0
- package/src/structures/Static/AchievementTier.js +33 -0
- package/src/structures/Static/Achievements.js +30 -0
- package/src/structures/Static/Challenges.js +29 -0
- package/src/structures/Static/GameAchievements.js +36 -0
- package/src/structures/Static/GameChallenges.js +40 -0
- package/src/structures/Static/GameQuests.js +24 -0
- package/src/structures/Static/GuildAchievements.js +34 -0
- package/src/structures/Static/Quest.js +66 -0
- package/src/structures/Static/Quests.js +31 -0
- package/src/structures/Status.js +2 -2
- package/src/utils/Constants.js +382 -41
- package/src/utils/SkyblockUtils.js +12 -7
- package/src/utils/guildExp.js +4 -1
- package/src/utils/removeSnakeCase.js +9 -2
- package/src/utils/romanize.js +32 -1
- package/src/utils/toIGN.js +6 -2
- package/src/utils/toUuid.js +10 -5
- package/typings/index.d.ts +985 -295
- /package/src/API/skyblock/{getSkyblockBazaar.js → getBazaar.js} +0 -0
- /package/src/API/skyblock/{getEndedSkyblockAuctions.js → getEndedAuctions.js} +0 -0
- /package/src/API/skyblock/{getSkyblockNews.js → getNews.js} +0 -0
|
@@ -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;
|
|
@@ -12,27 +12,55 @@ class SkyblockProfile {
|
|
|
12
12
|
* Skyblock profile ID
|
|
13
13
|
* @type {string}
|
|
14
14
|
*/
|
|
15
|
-
this.profileId = data.
|
|
15
|
+
this.profileId = data.profileId;
|
|
16
16
|
/**
|
|
17
17
|
* Skyblock profile name
|
|
18
18
|
* @type {string}
|
|
19
19
|
*/
|
|
20
|
-
this.profileName = data.
|
|
20
|
+
this.profileName = data.profileName;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @type {
|
|
22
|
+
* Profile's gamemode
|
|
23
|
+
* @type {string|null}
|
|
24
24
|
*/
|
|
25
|
-
this.
|
|
25
|
+
this.gameMode = data.gameMode;
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @type {
|
|
27
|
+
* Profile's banking
|
|
28
|
+
* @type {object}
|
|
29
29
|
*/
|
|
30
|
-
this.
|
|
30
|
+
this.banking = data.banking;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
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,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bingo class
|
|
3
|
+
*/
|
|
4
|
+
class Bingo {
|
|
5
|
+
/**
|
|
6
|
+
* Constructor
|
|
7
|
+
* @param {Object} data data
|
|
8
|
+
* @param {number} position Position
|
|
9
|
+
*/
|
|
10
|
+
constructor(data, position = 0) {
|
|
11
|
+
/**
|
|
12
|
+
* Name of this bingo goal
|
|
13
|
+
* @type {string}
|
|
14
|
+
*/
|
|
15
|
+
this.name = data.name;
|
|
16
|
+
/**
|
|
17
|
+
* string ID (code name)
|
|
18
|
+
* @type {string}
|
|
19
|
+
*/
|
|
20
|
+
this.id = data.id;
|
|
21
|
+
const [row, column] = parsePosition(position);
|
|
22
|
+
/**
|
|
23
|
+
* 1-indexed row
|
|
24
|
+
* @type {number|null}
|
|
25
|
+
*/
|
|
26
|
+
this.row = row;
|
|
27
|
+
/**
|
|
28
|
+
* 1-indexed colmun
|
|
29
|
+
* @type {number|null}
|
|
30
|
+
*/
|
|
31
|
+
this.column = column;
|
|
32
|
+
/**
|
|
33
|
+
* Bingo lore, with color codes
|
|
34
|
+
* @type {string}
|
|
35
|
+
*/
|
|
36
|
+
this.rawLore = data.lore;
|
|
37
|
+
/**
|
|
38
|
+
* Bingo lore in plain text
|
|
39
|
+
* @type {string}
|
|
40
|
+
*/
|
|
41
|
+
this.lore = data.lore?.replace?.(/§([1-9]|[a-l])|§/gm, '') || null;
|
|
42
|
+
/**
|
|
43
|
+
* Only available for TIERED bingos
|
|
44
|
+
* Shows you the requirement for each tier of this achievement
|
|
45
|
+
* @type {number[]}
|
|
46
|
+
*/
|
|
47
|
+
this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : null;
|
|
48
|
+
/**
|
|
49
|
+
* Only available for TIERED bingos
|
|
50
|
+
* Difference between each tier requirement, if it is constant
|
|
51
|
+
* @type {number|null}
|
|
52
|
+
*/
|
|
53
|
+
this.tierStep = this.#getTierStep();
|
|
54
|
+
/**
|
|
55
|
+
* Only available for ONE_TIERED bingos
|
|
56
|
+
* @type {number|null}
|
|
57
|
+
*/
|
|
58
|
+
this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null;
|
|
59
|
+
/**
|
|
60
|
+
* Type of Bingo
|
|
61
|
+
* ONE_TIME means the goal doesn't have a specific amount
|
|
62
|
+
* ONE_TIER means the goal specifies 1 amount to achieve
|
|
63
|
+
* TIERED means the goal specifies more than 1 amount to achieve
|
|
64
|
+
* @type {'ONE_TIME'|'ONE_TIER'|'TIERED'}
|
|
65
|
+
*/
|
|
66
|
+
this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* As string
|
|
70
|
+
* BEWARE this returns ID to assure compatibility with PlayerBingo
|
|
71
|
+
* @return {string}
|
|
72
|
+
*/
|
|
73
|
+
toString() {
|
|
74
|
+
return this.id;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Gets tier step, if constant
|
|
78
|
+
* @private
|
|
79
|
+
* @returns {number|null}
|
|
80
|
+
*/
|
|
81
|
+
#getTierStep() {
|
|
82
|
+
if (this.type !== 'TIERED') return null;
|
|
83
|
+
// No step possible
|
|
84
|
+
if (this.tiers.length < 2) return null;
|
|
85
|
+
const hypotheticStep = this.tiers[1] - this.tiers[0];
|
|
86
|
+
// Check if every 2 elements have the same step
|
|
87
|
+
const isConstant = this.tiers.slice(1).every((el, index) => {
|
|
88
|
+
return hypotheticStep === this.tiers[index - 1] - el;
|
|
89
|
+
});
|
|
90
|
+
if (!isConstant) return null;
|
|
91
|
+
return hypotheticStep;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// eslint-disable-next-line require-jsdoc
|
|
96
|
+
function parsePosition(position) {
|
|
97
|
+
const x = (position % 5) + 1;
|
|
98
|
+
const y = Math.floor(position / 5) + 1;
|
|
99
|
+
return [x, y];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
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 || this.goals.length < 1) 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,86 @@
|
|
|
1
|
+
const AchievementTier = require('./AchievementTier');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Achievement Class
|
|
5
|
+
*/
|
|
6
|
+
class Achievement {
|
|
7
|
+
/**
|
|
8
|
+
* constructor
|
|
9
|
+
* @param {string} achievementName Name of achievement
|
|
10
|
+
* @param {Object} data
|
|
11
|
+
*/
|
|
12
|
+
constructor(achievementName, data) {
|
|
13
|
+
/**
|
|
14
|
+
* Name of achievement, trimmed trailing spaces
|
|
15
|
+
* @type {string}
|
|
16
|
+
*/
|
|
17
|
+
this.name = data.name.trim();
|
|
18
|
+
/**
|
|
19
|
+
* Code name of achievement
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
22
|
+
this.codeName = achievementName;
|
|
23
|
+
/**
|
|
24
|
+
* Description, trimmed trailing spaces
|
|
25
|
+
* @type {string}
|
|
26
|
+
*/
|
|
27
|
+
this.description = data.description.trim();
|
|
28
|
+
/**
|
|
29
|
+
* Type of achievement
|
|
30
|
+
* @type {'ONE_TIME'|'TIERED'}
|
|
31
|
+
*/
|
|
32
|
+
this.type = data.tiers ? 'TIERED' : 'ONE_TIME';
|
|
33
|
+
/**
|
|
34
|
+
* ONLY AVAILABLE IN PERSONAL ONE TIME ACHIEVEMENTS, last checked April 26th
|
|
35
|
+
* Unlock rate of this achievement
|
|
36
|
+
* Local : Fraction of players that have played the game and gotten this achievement (0 to 1 inclusive)
|
|
37
|
+
* Global : Fraction of players that have played Hypixel and gotten this achievement (0 to 1 inclusive)
|
|
38
|
+
* ...percentage : In percentage (0 to 100 inclusive)
|
|
39
|
+
* @type {Record<'local'|'localPercentage'|'global'|'globalPercentage', number>|null}
|
|
40
|
+
*/
|
|
41
|
+
this.rarity = {
|
|
42
|
+
local: parseFloat(data.gamePercentUnlocked) || 0,
|
|
43
|
+
localPercentage: parseFloat(data.gamePercentUnlocked) * 100 || 0,
|
|
44
|
+
global: data.globalPercentUnlocked,
|
|
45
|
+
globalPercentage: parseFloat(data.globalPercentUnlocked) * 100 || 0
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* ONLY AVAILABLE FOR TIERED
|
|
49
|
+
* @type {AchievementTier|null}
|
|
50
|
+
*/
|
|
51
|
+
this.tierInformation = this.type === 'TIERED' ? new AchievementTier(data.tiers) : null;
|
|
52
|
+
|
|
53
|
+
const { totalPoints, totalAmount } = this.type === 'TIERED' ? collectAll(this.tierInformation) : {};
|
|
54
|
+
/**
|
|
55
|
+
* Total points worth (sum of all tiers if tiered)
|
|
56
|
+
* This is always 0 for Guild Achievements
|
|
57
|
+
* @type {number}
|
|
58
|
+
*/
|
|
59
|
+
this.points = this.type === 'ONE_TIME' ? parseInt(data.points, 10) : totalPoints;
|
|
60
|
+
/**
|
|
61
|
+
* Total amount required to reach max tier, only for tiered
|
|
62
|
+
* @type {number|null}
|
|
63
|
+
*/
|
|
64
|
+
this.totalAmountRequired = this.type === 'TIERED' ? totalAmount : null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* As string
|
|
68
|
+
* @return {string}
|
|
69
|
+
*/
|
|
70
|
+
toString() {
|
|
71
|
+
return this.achievementName;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// eslint-disable-next-line require-jsdoc
|
|
76
|
+
function collectAll(data) {
|
|
77
|
+
const mTier = data.maxTier;
|
|
78
|
+
let totalPoints = 0;
|
|
79
|
+
let totalAmount = 0;
|
|
80
|
+
for (let i = 1; i <= mTier; i++) {
|
|
81
|
+
totalPoints += data.getTier(i).pointsRewarded;
|
|
82
|
+
totalAmount += data.getTier(i).amountRequired;
|
|
83
|
+
}
|
|
84
|
+
return { totalPoints, totalAmount };
|
|
85
|
+
}
|
|
86
|
+
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;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const GameAchievements = require('./GameAchievements.js');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Achievement class
|
|
5
|
+
*/
|
|
6
|
+
class Achievements {
|
|
7
|
+
/**
|
|
8
|
+
* @param {object} data data
|
|
9
|
+
*/
|
|
10
|
+
constructor(data) {
|
|
11
|
+
/**
|
|
12
|
+
* Last time this resource was updated
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
|
|
16
|
+
/**
|
|
17
|
+
* Last time this resource was updated, as Date
|
|
18
|
+
* @type {Date|null}
|
|
19
|
+
*/
|
|
20
|
+
this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
|
|
21
|
+
/**
|
|
22
|
+
* @type {Record<StaticGameNames, GameAchievements>}
|
|
23
|
+
*/
|
|
24
|
+
this.achievementsPerGame = Object.fromEntries(
|
|
25
|
+
Object.entries(data.achievements).map(([game, data]) => [game, new GameAchievements(game, data)])
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = Achievements;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const GameChallenges = require('./GameChallenges.js');
|
|
2
|
+
/**
|
|
3
|
+
* Achievement class
|
|
4
|
+
*/
|
|
5
|
+
class Challenges {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} data data
|
|
8
|
+
*/
|
|
9
|
+
constructor(data) {
|
|
10
|
+
/**
|
|
11
|
+
* Last time this resource was updated
|
|
12
|
+
* @type {number}
|
|
13
|
+
*/
|
|
14
|
+
this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10);
|
|
15
|
+
/**
|
|
16
|
+
* Last time this resource was updated, as Date
|
|
17
|
+
* @type {Date|null}
|
|
18
|
+
*/
|
|
19
|
+
this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp);
|
|
20
|
+
/**
|
|
21
|
+
* @type {Record<StaticGameNames, GameChallenges>}
|
|
22
|
+
*/
|
|
23
|
+
this.challengesPerGame = Object.fromEntries(
|
|
24
|
+
Object.entries(data.challenges).map(([game, data]) => [game, new GameChallenges(game, data)])
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = Challenges;
|