hypixel-api-reborn 11.2.0 → 11.3.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/README.md +1 -1
- package/eslint.config.mjs +71 -0
- package/package.json +14 -20
- package/src/API/getAchievements.js +1 -0
- package/src/API/getBoosters.js +1 -0
- package/src/API/getChallenges.js +1 -0
- package/src/API/getGameCounts.js +1 -0
- package/src/API/getGuild.js +4 -3
- package/src/API/getGuildAchievements.js +1 -0
- package/src/API/getLeaderboards.js +1 -1
- package/src/API/getPlayer.js +1 -0
- package/src/API/getQuests.js +1 -0
- package/src/API/getRecentGames.js +5 -9
- package/src/API/getServerInfo.js +40 -37
- package/src/API/getStatus.js +1 -0
- package/src/API/getWatchdogStats.js +1 -0
- package/src/API/housing/getActiveHouses.js +7 -0
- package/src/API/housing/getHouse.js +9 -0
- package/src/API/housing/getPlayerHouses.js +11 -0
- package/src/API/index.js +6 -1
- package/src/API/skyblock/getAuction.js +8 -6
- package/src/API/skyblock/getAuctions.js +15 -12
- package/src/API/skyblock/getAuctionsByPlayer.js +1 -1
- package/src/API/skyblock/getBazaar.js +1 -3
- package/src/API/skyblock/getBingo.js +1 -2
- package/src/API/skyblock/getBingoByPlayer.js +3 -3
- package/src/API/skyblock/getEndedAuctions.js +1 -0
- package/src/API/skyblock/getFireSales.js +1 -1
- package/src/API/skyblock/getGarden.js +7 -0
- package/src/API/skyblock/getGovernment.js +1 -2
- package/src/API/skyblock/getMember.js +5 -2
- package/src/API/skyblock/getMuseum.js +1 -0
- package/src/API/skyblock/getNews.js +1 -0
- package/src/API/skyblock/getProfiles.js +5 -2
- package/src/Client.js +88 -16
- package/src/Private/rateLimit.js +7 -11
- package/src/Private/requests.js +12 -13
- package/src/Private/updater.js +2 -3
- package/src/Private/uuidCache.js +1 -2
- package/src/Private/validate.js +19 -19
- package/src/index.js +5 -0
- package/src/structures/APIIncident.js +1 -2
- package/src/structures/APIStatus.js +0 -1
- package/src/structures/Boosters/Booster.js +9 -8
- package/src/structures/Game.js +1 -1
- package/src/structures/Guild/Guild.js +19 -36
- package/src/structures/Guild/GuildMember.js +2 -2
- package/src/structures/House.js +54 -0
- package/src/structures/MiniGames/Arcade.js +798 -312
- package/src/structures/MiniGames/ArenaBrawl.js +98 -32
- package/src/structures/MiniGames/BedWars.js +197 -194
- package/src/structures/MiniGames/BlitzSurvivalGames.js +381 -129
- package/src/structures/MiniGames/BuildBattle.js +19 -8
- package/src/structures/MiniGames/CopsAndCrims.js +253 -25
- package/src/structures/MiniGames/Duels.js +905 -664
- package/src/structures/MiniGames/MegaWalls.js +390 -51
- package/src/structures/MiniGames/MurderMystery.js +151 -30
- package/src/structures/MiniGames/Paintball.js +31 -11
- package/src/structures/MiniGames/Pit.js +4 -5
- package/src/structures/MiniGames/Quakecraft.js +113 -50
- package/src/structures/MiniGames/SkyWars.js +528 -372
- package/src/structures/MiniGames/SmashHeroes.js +201 -73
- package/src/structures/MiniGames/SpeedUHC.js +77 -24
- package/src/structures/MiniGames/TNTGames.js +242 -73
- package/src/structures/MiniGames/TurboKartRacers.js +55 -115
- package/src/structures/MiniGames/UHC.js +144 -132
- package/src/structures/MiniGames/VampireZ.js +70 -37
- package/src/structures/MiniGames/Warlords.js +126 -1
- package/src/structures/MiniGames/WoolWars.js +60 -9
- package/src/structures/Pet.js +1 -1
- package/src/structures/Player.js +43 -128
- package/src/structures/PlayerCosmetics.js +5 -4
- package/src/structures/SkyBlock/Auctions/AuctionInfo.js +2 -1
- package/src/structures/SkyBlock/Auctions/BaseAuction.js +1 -1
- package/src/structures/SkyBlock/News/SkyblockNews.js +15 -15
- package/src/structures/SkyBlock/PlayerBingo.js +7 -14
- package/src/structures/SkyBlock/SkyblockGarden.js +146 -0
- package/src/structures/SkyBlock/SkyblockInventoryItem.js +4 -28
- package/src/structures/SkyBlock/SkyblockMember.js +90 -228
- package/src/structures/SkyBlock/SkyblockPet.js +3 -4
- package/src/structures/SkyBlock/Static/Bingo.js +10 -11
- package/src/structures/SkyBlock/Static/BingoData.js +1 -1
- package/src/structures/Static/Achievement.js +16 -15
- package/src/structures/Static/AchievementTier.js +2 -2
- package/src/structures/Static/Quest.js +2 -2
- package/src/utils/Constants.js +522 -520
- package/src/utils/{guildExp.js → Guild.js} +42 -12
- package/src/utils/Player.js +112 -0
- package/src/utils/SkyblockUtils.js +482 -192
- package/src/utils/arrayTools.js +1 -1
- package/src/utils/divide.js +1 -1
- package/src/utils/index.js +2 -1
- package/src/utils/isGuildID.js +1 -1
- package/src/utils/oscillation.js +4 -2
- package/src/utils/removeSnakeCase.js +11 -7
- package/src/utils/rgbToHexColor.js +1 -1
- package/src/utils/romanize.js +3 -3
- package/src/utils/toUuid.js +4 -4
- package/src/utils/varInt.js +2 -2
- package/typings/index.d.ts +1186 -967
- package/src/utils/toIGN.js +0 -24
|
@@ -4,6 +4,7 @@ module.exports = async function (query, profileId) {
|
|
|
4
4
|
const SkyblockMuseum = require('../../structures/SkyBlock/SkyblockMuseum');
|
|
5
5
|
if (!query) throw new Error(Errors.NO_NICKNAME_UUID);
|
|
6
6
|
query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI);
|
|
7
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
7
8
|
const res = await this._makeRequest(`/skyblock/museum?uuid=${query}&profile=${profileId}`);
|
|
8
9
|
if (res.raw) return res;
|
|
9
10
|
return new SkyblockMuseum({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const SkyblockNews = require('../../structures/SkyBlock/News/SkyblockNews');
|
|
2
2
|
module.exports = async function () {
|
|
3
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
3
4
|
const res = await this._makeRequest('/skyblock/news');
|
|
4
5
|
if (res.raw) return res;
|
|
5
6
|
return res.items.map((i) => new SkyblockNews(i));
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
const Errors = require('../../Errors');
|
|
2
2
|
const toUuid = require('../../utils/toUuid');
|
|
3
3
|
const getPlayer = require('../getPlayer');
|
|
4
|
-
module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false }) {
|
|
4
|
+
module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false, getGarden: false }) {
|
|
5
5
|
const SkyblockProfile = require('../../structures/SkyBlock/SkyblockProfile');
|
|
6
|
-
const getSkyblockMuseum = require('
|
|
6
|
+
const getSkyblockMuseum = require('./getMuseum');
|
|
7
|
+
const getSkyblockGarden = require('./getGarden');
|
|
7
8
|
if (!query) throw new Error(Errors.NO_NICKNAME_UUID);
|
|
8
9
|
query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI);
|
|
10
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
9
11
|
const res = await this._makeRequest(`/skyblock/profiles?uuid=${query}`);
|
|
10
12
|
if (res.raw) return res;
|
|
11
13
|
if (!res.profiles || !res.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES);
|
|
@@ -37,6 +39,7 @@ module.exports = async function (query, options = { fetchPlayer: false, getMuseu
|
|
|
37
39
|
banking: res.profiles[i].banking,
|
|
38
40
|
communityUpgrades: res.profiles[i].community_upgrades,
|
|
39
41
|
museum: options.getMuseum ? await getSkyblockMuseum.call(this, query, res.profiles[i].profile_id) : null,
|
|
42
|
+
garden: options.getGarden ? await getSkyblockGarden.call(this, res.profiles[i].profile_id) : null,
|
|
40
43
|
selected: res.profiles[i].selected,
|
|
41
44
|
members: res.profiles[i].members
|
|
42
45
|
});
|
package/src/Client.js
CHANGED
|
@@ -1,13 +1,39 @@
|
|
|
1
|
-
/* eslint-disable require-jsdoc */
|
|
2
|
-
/* eslint-disable max-len */
|
|
3
|
-
const validate = new (require('./Private/validate'))();
|
|
4
1
|
const rateLimit = new (require('./Private/rateLimit'))();
|
|
5
|
-
const
|
|
2
|
+
const validate = new (require('./Private/validate'))();
|
|
6
3
|
const updater = new (require('./Private/updater'))();
|
|
4
|
+
const Requests = require('./Private/requests');
|
|
5
|
+
const EventEmitter = require('events');
|
|
7
6
|
const Errors = require('./Errors');
|
|
8
7
|
const API = require('./API/index');
|
|
9
|
-
const EventEmitter = require('events');
|
|
10
8
|
const clients = [];
|
|
9
|
+
|
|
10
|
+
/* eslint-disable */
|
|
11
|
+
const Player = require('./structures/Player');
|
|
12
|
+
const Guild = require('./structures/Guild/Guild');
|
|
13
|
+
const WatchdogStats = require('./structures/Watchdog/Stats');
|
|
14
|
+
const Booster = require('./structures/Boosters/Booster');
|
|
15
|
+
const SkyblockProfile = require('./structures/SkyBlock/SkyblockProfile');
|
|
16
|
+
const SkyblockMember = require('./structures/SkyBlock/SkyblockMember');
|
|
17
|
+
const SkyblockMuseum = require('./structures/SkyBlock/SkyblockMuseum');
|
|
18
|
+
const SkyblockGarden = require('./structures/SkyBlock/SkyblockGarden');
|
|
19
|
+
const APIStatus = require('./structures/APIStatus');
|
|
20
|
+
const Leaderboard = require('./structures/Leaderboard');
|
|
21
|
+
const ServerInfo = require('./structures/ServerInfo');
|
|
22
|
+
const RecentGame = require('./structures/RecentGame');
|
|
23
|
+
const Status = require('./structures/Status');
|
|
24
|
+
const Auction = require('./structures/SkyBlock/Auctions/Auction');
|
|
25
|
+
const AuctionInfo = require('./structures/SkyBlock/Auctions/AuctionInfo');
|
|
26
|
+
const PartialAuction = require('./structures/SkyBlock/Auctions/PartialAuction');
|
|
27
|
+
const Product = require('./structures/SkyBlock/Bazzar/Product');
|
|
28
|
+
const BingoData = require('./structures/SkyBlock/Static/BingoData');
|
|
29
|
+
const PlayerBingo = require('./structures/SkyBlock/PlayerBingo');
|
|
30
|
+
const GovernmentData = require('./structures/SkyBlock/Static/Government');
|
|
31
|
+
const FireSale = require('./structures/SkyBlock/Static/FireSale');
|
|
32
|
+
const SkyblockNews = require('./structures/SkyBlock/News/SkyblockNews');
|
|
33
|
+
const GameCounts = require('./structures/GameCounts');
|
|
34
|
+
const House = require('./structures/House.js');
|
|
35
|
+
/* eslint-enable */
|
|
36
|
+
|
|
11
37
|
/**
|
|
12
38
|
* Client class
|
|
13
39
|
*/
|
|
@@ -30,12 +56,13 @@ class Client extends EventEmitter {
|
|
|
30
56
|
this.key = validate.validateKey(key);
|
|
31
57
|
this.options = validate.parseOptions(options);
|
|
32
58
|
validate.validateOptions(this.options);
|
|
33
|
-
|
|
59
|
+
|
|
34
60
|
for (const func in API) {
|
|
35
61
|
Client.prototype[func] = (...args) => {
|
|
36
62
|
const lastArg = args[args.length - 1];
|
|
37
63
|
return API[func].apply(
|
|
38
64
|
{
|
|
65
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
39
66
|
_makeRequest: this._makeRequest.bind(this, validate.cacheSuboptions(lastArg) ? lastArg : {}),
|
|
40
67
|
...this
|
|
41
68
|
},
|
|
@@ -68,8 +95,8 @@ class Client extends EventEmitter {
|
|
|
68
95
|
*/
|
|
69
96
|
async _makeRequest(options, url, useRateLimitManager = true) {
|
|
70
97
|
if (!url) return;
|
|
71
|
-
if (
|
|
72
|
-
return Object.assign(await this.requests.cache.get(url), { raw:
|
|
98
|
+
if ('/key' !== url && !options.noCacheCheck && (await this.requests.cache.has(url))) {
|
|
99
|
+
return Object.assign(await this.requests.cache.get(url), { raw: Boolean(options.raw) });
|
|
73
100
|
}
|
|
74
101
|
if (useRateLimitManager) await rateLimit.rateLimitManager();
|
|
75
102
|
this.emit('outgoingRequest', url, { ...options, headers: { ...options.headers, ...this.options.headers } });
|
|
@@ -77,12 +104,13 @@ class Client extends EventEmitter {
|
|
|
77
104
|
...options,
|
|
78
105
|
headers: { ...options.headers, ...this.options.headers }
|
|
79
106
|
});
|
|
107
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
80
108
|
if (this.options.syncWithHeaders) rateLimit.sync(result._headers);
|
|
81
109
|
return result;
|
|
82
110
|
}
|
|
83
111
|
/**
|
|
84
112
|
* Emitted when rate limiter is ready. ( You don't have to wait for this event to emit UNLESS you are planning to do data scraping which means spamming requests )
|
|
85
|
-
* @event
|
|
113
|
+
* @event ready
|
|
86
114
|
* @name Client#ready
|
|
87
115
|
* @example
|
|
88
116
|
* // This example gets player's uuid.
|
|
@@ -94,14 +122,14 @@ class Client extends EventEmitter {
|
|
|
94
122
|
*/
|
|
95
123
|
/**
|
|
96
124
|
* Emitted when a request is going to be sent
|
|
97
|
-
* @event
|
|
125
|
+
* @event outgoingRequest
|
|
98
126
|
* @name Client#outgoingRequest
|
|
99
127
|
* @param {string} url URL
|
|
100
128
|
* @param {object} [options] Options, if any
|
|
101
129
|
*/
|
|
102
130
|
/**
|
|
103
131
|
* Emitted when there is a warning.
|
|
104
|
-
* @event
|
|
132
|
+
* @event warn
|
|
105
133
|
* @name Client#warn
|
|
106
134
|
* @param {string} error Warning Message
|
|
107
135
|
*/
|
|
@@ -140,7 +168,7 @@ class Client extends EventEmitter {
|
|
|
140
168
|
* Allows you to get statistics of hypixel guild
|
|
141
169
|
* @method
|
|
142
170
|
* @name Client#getGuild
|
|
143
|
-
* @param {id|name|player} searchParameter Search for guild by id, name or player (if player is in guild)
|
|
171
|
+
* @param {'id'|'name'|'player'} searchParameter Search for guild by id, name or player (if player is in guild)
|
|
144
172
|
* @param {string} query Guild ID, Guild name or player uuid/nickname
|
|
145
173
|
* @param {MethodOptions} [options={}] Method options
|
|
146
174
|
* @return {Promise<Guild>}
|
|
@@ -226,6 +254,24 @@ class Client extends EventEmitter {
|
|
|
226
254
|
* const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log);
|
|
227
255
|
* console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
|
|
228
256
|
*/
|
|
257
|
+
/**
|
|
258
|
+
* Allows you to get a player's skyblock member data from all their profiles
|
|
259
|
+
* @method
|
|
260
|
+
* @name Client#getSkyblockGarden
|
|
261
|
+
* @param {string} profileId Profile id of the garden you want
|
|
262
|
+
* @param {MethodOptions} [options={}] Method options
|
|
263
|
+
* @return {Promise<SkyblockGarden>}
|
|
264
|
+
* @example
|
|
265
|
+
* hypixel.getSkyblockMember('StavZDev').then(member => {
|
|
266
|
+
* // 'Cucumber' - profile name
|
|
267
|
+
* console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
|
|
268
|
+
* }).catch(e => {
|
|
269
|
+
* console.log(e);
|
|
270
|
+
* })
|
|
271
|
+
* @example
|
|
272
|
+
* const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log);
|
|
273
|
+
* console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4'
|
|
274
|
+
*/
|
|
229
275
|
/**
|
|
230
276
|
* Allows you to get a player's skyblock profile museum
|
|
231
277
|
* @method
|
|
@@ -347,7 +393,8 @@ class Client extends EventEmitter {
|
|
|
347
393
|
* console.log(products[0].productId); // INK_SACK:3
|
|
348
394
|
* })
|
|
349
395
|
* .catch(console.log);
|
|
350
|
-
*/
|
|
396
|
+
*/
|
|
397
|
+
/**
|
|
351
398
|
* Allows you to get bingo data
|
|
352
399
|
* @method
|
|
353
400
|
* @name Client#getSkyblockBingo
|
|
@@ -376,6 +423,29 @@ class Client extends EventEmitter {
|
|
|
376
423
|
* @param {MethodOptions} [options={}] Options
|
|
377
424
|
* @return {Promise<FireSale[]>}
|
|
378
425
|
*/
|
|
426
|
+
/**
|
|
427
|
+
* Get a array of active houses
|
|
428
|
+
* @method
|
|
429
|
+
* @name Client#getActiveHouses
|
|
430
|
+
* @param {MethodOptions} [options={}] Options
|
|
431
|
+
* @return {Promise<House[]>}
|
|
432
|
+
*/
|
|
433
|
+
/**
|
|
434
|
+
* Get a array of houses for a user
|
|
435
|
+
* @method
|
|
436
|
+
* @name Client#getPlayerHouses
|
|
437
|
+
* @param {string} query UUID / IGN of player
|
|
438
|
+
* @param {MethodOptions} [options={}] Options
|
|
439
|
+
* @return {Promise<House[]>}
|
|
440
|
+
*/
|
|
441
|
+
/**
|
|
442
|
+
* Get a house
|
|
443
|
+
* @method
|
|
444
|
+
* @name Client#getHouse
|
|
445
|
+
* @param {string} query House UUID
|
|
446
|
+
* @param {MethodOptions} [options={}] Options
|
|
447
|
+
* @return {Promise<House>}
|
|
448
|
+
*/
|
|
379
449
|
/**
|
|
380
450
|
* Allows you to get skyblock news
|
|
381
451
|
* @method
|
|
@@ -415,7 +485,7 @@ class Client extends EventEmitter {
|
|
|
415
485
|
* @prop {number} [hypixelCacheTime=60] Amount of time in seconds to cache the hypixel api requests.
|
|
416
486
|
* @prop {number} [mojangCacheTime=600] Amount of time in seconds to cache the mojang api requests.
|
|
417
487
|
* @prop {CacheHandler} [cacheHandler] Custom Cache Handler
|
|
418
|
-
* @prop {AUTO|HARD|NONE} [rateLimit='AUTO'] Rate limit mode.
|
|
488
|
+
* @prop {'AUTO'|'HARD'|'NONE'} [rateLimit='AUTO'] Rate limit mode.
|
|
419
489
|
* @prop {boolean} [syncWithHeaders=false] Sync with headers rate limit information. Usually not necessary nor recommended ( because of latency )
|
|
420
490
|
* @prop {number} [keyLimit=60] Key limit of your key.
|
|
421
491
|
* @prop {number} [cacheSize=-1] The amount how many results will be cached. (`-1` for infinity)
|
|
@@ -424,6 +494,7 @@ class Client extends EventEmitter {
|
|
|
424
494
|
* @prop {boolean} [checkForUpdates=true] Enable/Disable check for new version of hypixel-api-reborn.
|
|
425
495
|
* @prop {boolean|string} [useThirdPartyAPI=false] Enable/Disable Mojang Third Party API
|
|
426
496
|
*/
|
|
497
|
+
// eslint-disable-next-line no-unused-vars
|
|
427
498
|
const defaultCache = require('./Private/defaultCache.js');
|
|
428
499
|
/**
|
|
429
500
|
* @typedef {defaultCache} Cache
|
|
@@ -449,11 +520,12 @@ const defaultCache = require('./Private/defaultCache.js');
|
|
|
449
520
|
*/
|
|
450
521
|
/**
|
|
451
522
|
* @typedef {object} SkyblockMethodOptions
|
|
452
|
-
* @property {boolean} [
|
|
453
|
-
* @property {boolean} [getMuseum=false] Raw data
|
|
523
|
+
* @property {boolean} [raw=false] Raw data
|
|
454
524
|
* @property {boolean} [noCacheCheck=false] Disable/Enable cache checking
|
|
455
525
|
* @property {boolean} [noCaching=false] Disable/Enable writing to cache
|
|
456
526
|
* @property {?boolean} [fetchPlayer=false] Disable/Enable player profile request for each member
|
|
527
|
+
* @property {?boolean} [getMuseum=false] Disable/Enable player museum request for each member
|
|
528
|
+
* @property {?boolean} [getGarden=false] Disable/Enable player garden request for each member
|
|
457
529
|
* @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided.
|
|
458
530
|
*/
|
|
459
531
|
/**
|
package/src/Private/rateLimit.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
-
/* eslint-disable camelcase */
|
|
3
1
|
const Errors = require('../Errors');
|
|
4
2
|
|
|
5
|
-
/* eslint-disable require-jsdoc */
|
|
6
3
|
class RateLimit {
|
|
7
4
|
constructor() {
|
|
8
5
|
this.initialized = 0;
|
|
@@ -12,12 +9,11 @@ class RateLimit {
|
|
|
12
9
|
if (!this.initialized) return;
|
|
13
10
|
this.requests++;
|
|
14
11
|
this.requestQueue.unshift(Date.now());
|
|
15
|
-
if (this.options.rateLimit
|
|
16
|
-
if (this.options.rateLimit
|
|
12
|
+
if ('NONE' === this.options.rateLimit || !this.requestQueue.length) return;
|
|
13
|
+
if ('AUTO' === this.options.rateLimit && this.requests <= this.options.keyLimit / 2) return;
|
|
17
14
|
const cooldown = this.computeCooldownTime();
|
|
18
15
|
this.requestQueue[0] = Date.now() + cooldown;
|
|
19
|
-
await new Promise((r) => setTimeout(r, cooldown), true);
|
|
20
|
-
return;
|
|
16
|
+
return await new Promise((r) => setTimeout(r, cooldown), true);
|
|
21
17
|
}
|
|
22
18
|
|
|
23
19
|
sync(data) {
|
|
@@ -45,7 +41,7 @@ class RateLimit {
|
|
|
45
41
|
|
|
46
42
|
reset() {
|
|
47
43
|
this.requests = this.requests - this.options.keyLimit;
|
|
48
|
-
if (this.requests
|
|
44
|
+
if (0 > this.requests) this.requests = 0;
|
|
49
45
|
this.lastResetHappenedAt = Date.now();
|
|
50
46
|
this.resetTimer = setTimeout(this.reset.bind(this), 300000);
|
|
51
47
|
this.requestQueue = this.requestQueue.filter((x) => x >= Date.now());
|
|
@@ -58,13 +54,13 @@ class RateLimit {
|
|
|
58
54
|
init(keyInfo, options, client) {
|
|
59
55
|
this.options = options;
|
|
60
56
|
this.requests = 0;
|
|
61
|
-
this.cooldownTime = 300000 / this.options.keyLimit;
|
|
57
|
+
this.cooldownTime = 300000 / this.options.keyLimit;
|
|
62
58
|
this.requestQueue = [];
|
|
63
59
|
this.client = client;
|
|
64
60
|
return keyInfo
|
|
65
61
|
.then((info) => {
|
|
66
62
|
this.requests = info.requestsInPastMin;
|
|
67
|
-
this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000;
|
|
63
|
+
this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000;
|
|
68
64
|
this.resetTimer = setTimeout(this.rateLimitMonitor.bind(this), 1000 * info.resetsAfter);
|
|
69
65
|
this.initialized = 1;
|
|
70
66
|
})
|
|
@@ -82,6 +78,6 @@ module.exports = RateLimit;
|
|
|
82
78
|
/**
|
|
83
79
|
* @typedef {Object} RLOptions
|
|
84
80
|
* @property {number} keyLimit Max request of key per min
|
|
85
|
-
* @property {NONE|AUTO|HARD} rateLimit rate limit mode
|
|
81
|
+
* @property {'NONE'|'AUTO'|'HARD'} rateLimit rate limit mode
|
|
86
82
|
* @property {boolean} syncWithHeaders Sync rate limits with headers
|
|
87
83
|
*/
|
package/src/Private/requests.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
/* eslint-disable require-jsdoc */
|
|
2
1
|
const requireFetch = !globalThis.fetch;
|
|
3
2
|
const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
|
4
3
|
const fetch = requireFetch ? externalFetch : globalThis.fetch;
|
|
5
4
|
const BASE_URL = 'https://api.hypixel.net/v2';
|
|
6
|
-
const Errors = require('../Errors');
|
|
7
5
|
const Cache = require('./defaultCache');
|
|
8
|
-
const
|
|
6
|
+
const Errors = require('../Errors');
|
|
9
7
|
|
|
10
8
|
class Requests {
|
|
11
9
|
constructor(client, cache) {
|
|
@@ -19,7 +17,7 @@ class Requests {
|
|
|
19
17
|
* @type {externalFetch.Response|Response}
|
|
20
18
|
*/
|
|
21
19
|
const res = await fetch(BASE_URL + endpoint, options);
|
|
22
|
-
if (res.status
|
|
20
|
+
if (500 <= res.status && 528 > res.status) {
|
|
23
21
|
throw new Error(
|
|
24
22
|
Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`)
|
|
25
23
|
);
|
|
@@ -27,20 +25,21 @@ class Requests {
|
|
|
27
25
|
const parsedRes = await res.json().catch(() => {
|
|
28
26
|
throw new Error(Errors.INVALID_RESPONSE_BODY);
|
|
29
27
|
});
|
|
30
|
-
if (res.status
|
|
28
|
+
if (400 === res.status) {
|
|
31
29
|
throw new Error(
|
|
32
30
|
Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || '')
|
|
33
31
|
);
|
|
34
32
|
}
|
|
35
|
-
if (res.status
|
|
36
|
-
if (res.status
|
|
37
|
-
if (res.status
|
|
38
|
-
if (res.status
|
|
39
|
-
if (!parsedRes.success) {
|
|
33
|
+
if (403 === res.status) throw new Error(Errors.INVALID_API_KEY);
|
|
34
|
+
if (422 === res.status) throw new Error(Errors.UNEXPECTED_ERROR);
|
|
35
|
+
if (429 === res.status) throw new Error(Errors.RATE_LIMIT_EXCEEDED);
|
|
36
|
+
if (200 !== res.status) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText));
|
|
37
|
+
if (!parsedRes.success && !endpoint.startsWith('/housing')) {
|
|
40
38
|
throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.cause));
|
|
41
39
|
}
|
|
40
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
42
41
|
parsedRes._headers = res.headers;
|
|
43
|
-
parsedRes.raw =
|
|
42
|
+
parsedRes.raw = Boolean(options.raw);
|
|
44
43
|
if (options.noCaching) return parsedRes;
|
|
45
44
|
// split by question mark : first part is /path, remove /
|
|
46
45
|
if (this.client.options.cache && this.client.options.cacheFilter(endpoint.split('?')[0].slice(1))) {
|
|
@@ -49,7 +48,7 @@ class Requests {
|
|
|
49
48
|
}
|
|
50
49
|
await this.cached.delete(endpoint);
|
|
51
50
|
await this.cached.set(endpoint, parsedRes);
|
|
52
|
-
if (this.client.options.hypixelCacheTime
|
|
51
|
+
if (0 <= this.client.options.hypixelCacheTime) {
|
|
53
52
|
setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.hypixelCacheTime);
|
|
54
53
|
}
|
|
55
54
|
}
|
|
@@ -70,7 +69,7 @@ class Requests {
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
validateCustomCache(cache) {
|
|
73
|
-
return
|
|
72
|
+
return Boolean(cache.set && cache.get && cache.delete && cache.keys);
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
package/src/Private/updater.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable require-jsdoc */
|
|
2
1
|
/* eslint-disable no-console */
|
|
3
2
|
const requireFetch = !globalThis.fetch;
|
|
4
3
|
const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
|
@@ -12,7 +11,7 @@ class Updater {
|
|
|
12
11
|
const metadata = await request.json();
|
|
13
12
|
const latest = metadata['dist-tags'].latest;
|
|
14
13
|
const compare = this.compare(version, latest);
|
|
15
|
-
if (
|
|
14
|
+
if (-1 === compare) {
|
|
16
15
|
console.log(
|
|
17
16
|
`New version of hypixel-api-reborn is available! Current version: ${version}, Latest version: ${latest}`
|
|
18
17
|
);
|
|
@@ -21,7 +20,7 @@ class Updater {
|
|
|
21
20
|
compare(a, b) {
|
|
22
21
|
const pa = a.split('.');
|
|
23
22
|
const pb = b.split('.');
|
|
24
|
-
for (let i = 0;
|
|
23
|
+
for (let i = 0; 3 > i; i++) {
|
|
25
24
|
const na = Number(pa[i]);
|
|
26
25
|
const nb = Number(pb[i]);
|
|
27
26
|
if (na > nb) return 1;
|
package/src/Private/uuidCache.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable require-jsdoc */
|
|
2
1
|
const requireFetch = !globalThis.fetch;
|
|
3
2
|
const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
|
|
4
3
|
const fetch = requireFetch ? externalFetch : globalThis.fetch;
|
|
@@ -12,7 +11,7 @@ module.exports = async (url, query, cacheTime) => {
|
|
|
12
11
|
const res = await fetch(url);
|
|
13
12
|
const data = await res.json();
|
|
14
13
|
// Don't cache 4xx
|
|
15
|
-
if (res.status
|
|
14
|
+
if (400 <= res.status) {
|
|
16
15
|
return {
|
|
17
16
|
status: res.status,
|
|
18
17
|
id: null,
|
package/src/Private/validate.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable require-jsdoc */
|
|
2
1
|
const Errors = require('../Errors');
|
|
3
2
|
const { isStrArray, strToArray } = require('../utils/arrayTools');
|
|
4
3
|
/**
|
|
@@ -12,17 +11,17 @@ class Validation {
|
|
|
12
11
|
* @private
|
|
13
12
|
*/
|
|
14
13
|
validateOptions(options) {
|
|
15
|
-
if (typeof options.hypixelCacheTime
|
|
16
|
-
if (typeof options.mojangCacheTime
|
|
17
|
-
if (typeof options.cacheSize
|
|
18
|
-
if (typeof options.rateLimit
|
|
14
|
+
if ('number' !== typeof options.hypixelCacheTime) throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
|
|
15
|
+
if ('number' !== typeof options.mojangCacheTime) throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER);
|
|
16
|
+
if ('number' !== typeof options.cacheSize) throw new Error(Errors.CACHE_LIMIT_MUST_BE_A_NUMBER);
|
|
17
|
+
if ('string' !== typeof options.rateLimit || !['AUTO', 'HARD', 'NONE'].includes(options.rateLimit)) {
|
|
19
18
|
throw new Error(Errors.INVALID_RATE_LIMIT_OPTION);
|
|
20
19
|
}
|
|
21
|
-
if (typeof options.keyLimit
|
|
22
|
-
if (typeof options.syncWithHeaders
|
|
23
|
-
if (typeof options.headers
|
|
24
|
-
if (typeof options.silent
|
|
25
|
-
if (typeof options.checkForUpdates
|
|
20
|
+
if ('number' !== typeof options.keyLimit) throw new Error(Errors.INVALID_KEY_LIMIT_OPTION);
|
|
21
|
+
if ('boolean' !== typeof options.syncWithHeaders) throw new Error(Errors.INVALID_HEADER_SYNC_OPTION);
|
|
22
|
+
if ('object' !== typeof options.headers) throw new Error(Errors.INVALID_HEADERS);
|
|
23
|
+
if ('boolean' !== typeof options.silent) throw new Error(Errors.INVALID_SILENT_OPTION);
|
|
24
|
+
if ('boolean' !== typeof options.checkForUpdates) throw new Error(Errors.INVALID_UPDATE_OPTION);
|
|
26
25
|
if (!['boolean', 'string'].includes(typeof options.useThirdPartyAPI)) {
|
|
27
26
|
throw new Error(Errors.INVALID_THIRD_PARTY_API_OPTION);
|
|
28
27
|
}
|
|
@@ -35,19 +34,20 @@ class Validation {
|
|
|
35
34
|
* @private
|
|
36
35
|
*/
|
|
37
36
|
parseOptions(options) {
|
|
38
|
-
if (
|
|
37
|
+
if ('object' !== typeof options || null === options) throw new Error(Errors.OPTIONS_MUST_BE_AN_OBJECT);
|
|
39
38
|
return {
|
|
40
39
|
cache: options.cache ?? true,
|
|
41
40
|
hypixelCacheTime: options.hypixelCacheTime ?? 60,
|
|
42
41
|
mojangCacheTime: options.mojangCacheTime ?? 600,
|
|
43
|
-
cacheSize: (options.cacheSize
|
|
42
|
+
cacheSize: (-1 === options.cacheSize ? Infinity : options.cacheSize) || Infinity,
|
|
44
43
|
cacheFilter:
|
|
45
|
-
|
|
44
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
45
|
+
'function' === typeof options.cacheFilter ? options.cacheFilter : this._handleFilter(options.cacheFilter),
|
|
46
46
|
rateLimit: options.rateLimit ?? 'AUTO',
|
|
47
47
|
keyLimit: options.keyLimit ?? 60,
|
|
48
|
-
syncWithHeaders:
|
|
48
|
+
syncWithHeaders: Boolean(options.syncWithHeaders),
|
|
49
49
|
headers: options.headers ?? {},
|
|
50
|
-
silent:
|
|
50
|
+
silent: Boolean(options.silent),
|
|
51
51
|
checkForUpdates: options.checkForUpdates ?? true,
|
|
52
52
|
useThirdPartyAPI: options.useThirdPartyAPI ?? false
|
|
53
53
|
};
|
|
@@ -61,7 +61,7 @@ class Validation {
|
|
|
61
61
|
*/
|
|
62
62
|
validateKey(key) {
|
|
63
63
|
if (!key) throw new Error(Errors.NO_API_KEY);
|
|
64
|
-
if (typeof key
|
|
64
|
+
if ('string' !== typeof key) throw new Error(Errors.KEY_MUST_BE_A_STRING);
|
|
65
65
|
return key;
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -72,7 +72,7 @@ class Validation {
|
|
|
72
72
|
* @private
|
|
73
73
|
*/
|
|
74
74
|
cacheSuboptions(input) {
|
|
75
|
-
if (
|
|
75
|
+
if ('object' !== typeof input || null === input) return false;
|
|
76
76
|
if (!input.noCacheCheck && !input.noCaching && !input.raw) return false;
|
|
77
77
|
return true;
|
|
78
78
|
}
|
|
@@ -85,7 +85,7 @@ class Validation {
|
|
|
85
85
|
*/
|
|
86
86
|
_handleFilter(filter) {
|
|
87
87
|
if (!filter) return () => true;
|
|
88
|
-
if (typeof filter
|
|
88
|
+
if ('object' === typeof filter && !Array.isArray(filter)) {
|
|
89
89
|
if (filter.whitelist && isStrArray(filter.whitelist)) return (x) => strToArray(filter.whitelist).includes(x);
|
|
90
90
|
if (filter.blacklist && isStrArray(filter.blacklist)) return (x) => !strToArray(filter.blacklist).includes(x);
|
|
91
91
|
throw new Error(Errors.CACHE_FILTER_INVALID);
|
|
@@ -102,7 +102,7 @@ class Validation {
|
|
|
102
102
|
*/
|
|
103
103
|
validateNodeVersion() {
|
|
104
104
|
const nodeVersion = parseInt(process.version.match(/v(\d{2})\.\d{1,}\.\d+/)[1], 10);
|
|
105
|
-
if (
|
|
105
|
+
if (12 > nodeVersion) throw new Error(Errors.NODE_VERSION_ERR);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
module.exports = Validation;
|
package/src/index.js
CHANGED
|
@@ -29,6 +29,7 @@ module.exports = {
|
|
|
29
29
|
/* SkyBlock */
|
|
30
30
|
SkyblockProfile: require('./structures/SkyBlock/SkyblockProfile.js'),
|
|
31
31
|
SkyblockMember: require('./structures/SkyBlock/SkyblockMember.js'),
|
|
32
|
+
SkyblockGarden: require('./structures/SkyBlock/SkyblockGarden.js'),
|
|
32
33
|
SkyblockInventoryItem: require('./structures/SkyBlock/SkyblockInventoryItem.js'),
|
|
33
34
|
SkyblockPet: require('./structures/SkyBlock/SkyblockPet'),
|
|
34
35
|
GovernmentData: require('./structures/SkyBlock/Static/Government.js'),
|
|
@@ -54,6 +55,9 @@ module.exports = {
|
|
|
54
55
|
/* Booster */
|
|
55
56
|
Booster: require('./structures/Boosters/Booster.js'),
|
|
56
57
|
|
|
58
|
+
/* House */
|
|
59
|
+
House: require('./structures/House.js'),
|
|
60
|
+
|
|
57
61
|
/* MiniGames */
|
|
58
62
|
Arcade: require('./structures/MiniGames/Arcade.js'),
|
|
59
63
|
ArenaBrawl: require('./structures/MiniGames/ArenaBrawl.js'),
|
|
@@ -65,6 +69,7 @@ module.exports = {
|
|
|
65
69
|
MegaWalls: require('./structures/MiniGames/MegaWalls.js'),
|
|
66
70
|
MurderMystery: require('./structures/MiniGames/MurderMystery.js'),
|
|
67
71
|
Paintball: require('./structures/MiniGames/Paintball.js'),
|
|
72
|
+
Pit: require('./structures/MiniGames/Pit.js'),
|
|
68
73
|
Quakecraft: require('./structures/MiniGames/Quakecraft.js'),
|
|
69
74
|
SkyWars: require('./structures/MiniGames/SkyWars.js'),
|
|
70
75
|
SmashHeroes: require('./structures/MiniGames/SmashHeroes.js'),
|
|
@@ -16,7 +16,7 @@ class APIIncident {
|
|
|
16
16
|
* Timestamp when investigation was started as Date object
|
|
17
17
|
* @type {object|null}
|
|
18
18
|
*/
|
|
19
|
-
this.start = new Date(data.pubDate)
|
|
19
|
+
this.start = data.pubDate ? new Date(data.pubDate) : null;
|
|
20
20
|
/**
|
|
21
21
|
* Formatted timestamp when investigation was started
|
|
22
22
|
* @type {string|null}
|
|
@@ -56,7 +56,6 @@ class APIIncident {
|
|
|
56
56
|
* Whether the incident is resolved/completed or not
|
|
57
57
|
* @author linearaccelerator
|
|
58
58
|
* @type {boolean}
|
|
59
|
-
* @version >6.0.1
|
|
60
59
|
*/
|
|
61
60
|
this.isResolved = this.HTMLContent.includes('Resolved -') || this.HTMLContent.includes('Completed -');
|
|
62
61
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
const Game = require('../Game');
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
4
|
+
function parseType(data) {
|
|
5
|
+
if (true === data.stacked) return 'STACKED';
|
|
6
|
+
if (!data.stacked) return 'QUEUED';
|
|
7
|
+
return 'ACTIVE';
|
|
8
|
+
}
|
|
9
|
+
|
|
2
10
|
/**
|
|
3
11
|
* Booster class
|
|
4
12
|
*/
|
|
@@ -63,7 +71,7 @@ class Booster {
|
|
|
63
71
|
* Works by checking if date.length is negative
|
|
64
72
|
* @type {boolean}
|
|
65
73
|
*/
|
|
66
|
-
this.expired = data.length
|
|
74
|
+
this.expired = 0 > data.length;
|
|
67
75
|
}
|
|
68
76
|
/**
|
|
69
77
|
* Beautiful format
|
|
@@ -73,11 +81,4 @@ class Booster {
|
|
|
73
81
|
return `${this.purchaser}'s booster in ${this.game}`;
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
|
-
|
|
77
|
-
// eslint-disable-next-line require-jsdoc
|
|
78
|
-
function parseType(data) {
|
|
79
|
-
if (data.stacked === true) return 'STACKED';
|
|
80
|
-
if (!data.stacked) return 'QUEUED';
|
|
81
|
-
return 'ACTIVE';
|
|
82
|
-
}
|
|
83
84
|
module.exports = Booster;
|