skyhelper-networth
Version:
SkyHelper's Networth Calculation for Hypixel SkyBlock
245 lines (220 loc) • 8.93 kB
JavaScript
const { setItems, itemsBackupLoaded } = require('../constants/itemsMap');
const { ItemsError } = require('../helper/errors');
const { sleep } = require('../helper/functions');
const axios = require('axios');
class NetworthManager {
#cachePrices;
#cachePricesTime;
#pricesRetries;
#itemsRetries;
#itemsInterval;
#onlyNetworth;
#sortItems;
#stackItems;
#includeItemData;
#itemsIntervalInstance;
/**
* Create a new NetworthManager instance. This class is a singleton and should be accessed through the networthManager instance
* @param {Object} options - Options for the NetworthManager
* @param {boolean | number} [options.cachePrices=true] - Whether to cache the prices for a time after fetching them or fetch them every time.
* @param {number} [options.cachePricesTime=1000 * 60 * 5] - The amount of time to cache the prices in milliseconds
* @param {number} [options.pricesRetries=3] - The amount of retries to fetch the prices when failing to fetch them
* @param {number} [options.itemsRetries=3] - The amount of retries to fetch the items when failing to fetch them
* @param {number} [options.itemsInterval=1000 * 60 * 60 * 12] - The interval to fetch the items from the Hypixel API
* @param {boolean} [options.onlyNetworth=false] - Whether to only return the total networth or the items as well
* @param {boolean} [options.sortItems=true] - Whether to sort items by price
* @param {boolean} [options.stackItems=true] - Whether to stack items with the same name and price
* @param {boolean} [options.includeItemData=false] - Whether to include the item data as a property in the item object
*/
constructor({ cachePrices, pricesRetries, cachePricesTime, itemsRetries, itemsInterval, onlyNetworth, sortItems, stackItems, includeItemData } = {}) {
if (NetworthManager.instance) {
return NetworthManager.instance;
}
NetworthManager.instance = this;
this.#cachePrices = cachePrices || true;
this.#pricesRetries = pricesRetries || 3;
this.#cachePricesTime = cachePricesTime || 1000 * 60 * 5;
this.#itemsRetries = itemsRetries || 3;
this.#itemsInterval = itemsInterval || 1000 * 60 * 60 * 12;
this.#onlyNetworth = onlyNetworth || false;
this.#sortItems = sortItems || true;
this.#stackItems = stackItems || true;
this.#includeItemData = includeItemData || false;
this.itemsPromise = this.updateItems(this.#itemsRetries);
this.#itemsIntervalInstance = setInterval(() => {
this.updateItems(this.#itemsRetries);
}, this.#itemsInterval);
}
/**
* Whether to cache the prices for time after fetching them or fetch them every time. Default: true
* @param {boolean | number} cachePrices
* @returns {NetworthManager} The NetworthManager instance
*/
setCachePrices(cachePrices) {
this.#cachePrices = cachePrices;
return this;
}
/**
* The amount of retries to fetch the prices when failing to fetch them. Default: 3
* @param {number} pricesRetries
* @returns {NetworthManager} The NetworthManager instance
*/
setPricesRetries(pricesRetries) {
this.#pricesRetries = pricesRetries;
return this;
}
/**
* The amount of time to cache the prices in milliseconds. Default: 1000 * 60 * 5 (5 minutes)
* @param {number} cachePricesTime
* @returns {NetworthManager} The NetworthManager instance
*/
setCachePricesTime(cachePricesTime) {
this.#cachePricesTime = cachePricesTime;
return this;
}
/**
* The amount of retries to fetch the items endpoint from the Hypixel API when failing to fetch them. Default: 3
* @param {number} itemsRetries
* @returns {NetworthManager} The NetworthManager instance
*/
setItemsRetries(itemsRetries) {
this.#itemsRetries = itemsRetries;
return this;
}
/**
* The interval in milliseconds to fetch the items from the Hypixel API. Default: 1000 * 60 * 60 * 12 (12 hours)
* @param {number} itemsInterval
* @returns {NetworthManager} The NetworthManager instance
*/
setItemsInterval(itemsInterval) {
this.#itemsInterval = itemsInterval;
clearInterval(this.#itemsIntervalInstance);
this.#itemsIntervalInstance = setInterval(() => {
this.updateItems(this.#itemsRetries);
}, this.#itemsInterval);
return this;
}
/**
* Whether to only return the total networth or the items as well. Default: false
* @param {boolean} onlyNetworth
* @returns {NetworthManager} The NetworthManager instance
*/
setOnlyNetworth(onlyNetworth) {
this.#onlyNetworth = onlyNetworth;
return this;
}
/**
* Whether to sort items by price. Default: true
* @param {boolean} sortItems
* @returns {NetworthManager} The NetworthManager instance
*/
setSortItems(sortItems) {
this.#sortItems = sortItems;
return this;
}
/**
* Whether to stack items with the same attributes and price. Default: true
* @param {boolean} stackItems
* @returns {NetworthManager} The NetworthManager instance
*/
setStackItems(stackItems) {
this.#stackItems = stackItems;
return this;
}
/**
* Whether to include the item data as a property in the item object. Default: false
* @param {boolean} includeItemData
* @returns {NetworthManager} The NetworthManager instance
*/
setIncludeItemData(includeItemData) {
this.#includeItemData = includeItemData;
return this;
}
/**
* Manually update the items from the Hypixel API
* @param {number} [retries = 3] The amount of retries to fetch the items when failing to fetch them
* @param {number} [retryInterval = 1000] The interval in milliseconds to fetch the items from the Hypixel API when failing to fetch them
* @param {number} [currentRetry = 0] The current retry count
*/
async updateItems(retries = 3, retryInterval = 1000, currentRetry = 0) {
try {
const response = await axios.get('https://api.hypixel.net/v2/resources/skyblock/items', {
timeout: 5000,
});
const items = response?.data?.items;
if (!items) {
if (currentRetry >= retries) throw new ItemsError('Failed to retrieve items');
console.warn(`[SKYHELPER-NETWORTH] Failed to retrieve items. Retrying (${retries - currentRetry} attempt(s) left)...`);
await sleep(retryInterval);
return await this.updateItems(retries, retryInterval, currentRetry + 1);
}
setItems(items);
return;
} catch (err) {
const error = `[SKYHELPER-NETWORTH] ${
axios.isAxiosError(err) ? `Failed to retrieve items with status code ${err?.response?.status || 'Unknown'}.` : `Failed to retrieve items: ${err}.`
}`;
if (currentRetry >= retries) {
if (itemsBackupLoaded) return console.warn(`${error} Using backup items...`);
else throw new ItemsError(error);
}
console.warn(`${error} Retrying (${retries - currentRetry} attempt(s) left)...`);
await sleep(retryInterval);
return await this.updateItems(retries, retryInterval, currentRetry + 1);
}
}
/**
* Get the cache prices value
* @returns {boolean} The cache prices value
*/
getCachePrices() {
return this.#cachePrices;
}
/**
* Get the prices retries value
* @returns {number} The prices retries value
*/
getPricesRetries() {
return this.#pricesRetries;
}
/**
* Get the cache prices time value
* @returns {number} The cache prices time value
*/
getCachePricesTime() {
return this.#cachePricesTime;
}
/**
* Get the only networth value
* @returns {boolean} The only networth value
*/
getOnlyNetworth() {
return this.#onlyNetworth;
}
/**
* Get the include item data value
* @returns {boolean} The include item data value
*/
getIncludeItemData() {
return this.#includeItemData;
}
/**
* Get the sort items value
* @returns {boolean} The sort items value
*/
getSortItems() {
return this.#sortItems;
}
/**
* Get the stack items value
* @returns {boolean} The stack items value
*/
getStackItems() {
return this.#stackItems;
}
}
/**
* The NetworthManager instance. This class is a singleton and should be accessed through this instance
*/
const networthManager = new NetworthManager();
module.exports = networthManager;