diff --git a/src/cachetimes.js b/src/cachetimes.js new file mode 100644 index 0000000000..7c2da39780 --- /dev/null +++ b/src/cachetimes.js @@ -0,0 +1,47 @@ +import credentials from "./credentials.js"; + +/** + * Check if a resource is expired based on the cache time + * @param {number} unixMs Unix timestamp in milliseconds + * @param {number} cacheTime The cache time in seconds + * @returns {boolean} Whether the cache is expired + */ +export function isCacheExpired(unixMs, cacheTime) { + return Date.now() - unixMs > cacheTime * 1000; +} + +/** + * Check if a profile cache is expired based on the configured cache time + * @param {number} unixMs Unix timestamp in milliseconds + * @returns {boolean} Whether the cache is expired + */ +export function isProfileCacheExpired(unixMs) { + return isCacheExpired(unixMs, credentials.cacheSeconds.profiles); +} + +/** + * Check if a museum cache is expired based on the configured cache time + * @param {number} unixMs Unix timestamp in milliseconds + * @returns {boolean} Whether the cache is expired + */ +export function isMuseumCacheExpired(unixMs) { + return isCacheExpired(unixMs, credentials.cacheSeconds.museum); +} + +/** + * Check if a guild cache is expired based on the configured cache time + * @param {number} unixMs Unix timestamp in milliseconds + * @returns {boolean} Whether the cache is expired + */ +export function isGuildCacheExpired(unixMs) { + return isCacheExpired(unixMs, credentials.cacheSeconds.guild); +} + +/** + * Check if a bingo profile cache is expired based on the configured cache time + * @param {number} unixMs Unix timestamp in milliseconds + * @returns {boolean} Whether the cache is expired + */ +export function isBingoProfileCacheExpired(unixMs) { + return isCacheExpired(unixMs, credentials.cacheSeconds.bingoProfiles); +} diff --git a/src/credentials.js b/src/credentials.js index 91eaec0a3c..41a3be2151 100644 --- a/src/credentials.js +++ b/src/credentials.js @@ -19,6 +19,12 @@ const defaultCredentials = { get session_secret() { return randomBytes(32).toString("hex"); }, + cacheSeconds: { + profiles: 60 * 5, // 5 minutes + bingoProfile: 60 * 5, // 5 minutes + museum: 60 * 30, // 30 minutes + guild: 60 * 60 * 24, // 24 hours + }, }; /** @@ -50,6 +56,15 @@ for (const key in defaultCredentials) { CREDENTIALS[key] = defaultCredentials[key]; hasBeenModified = true; } + + if (typeof defaultCredentials[key] === "object") { + for (const subKey in defaultCredentials[key]) { + if (CREDENTIALS[key][subKey] == undefined) { + CREDENTIALS[key][subKey] = defaultCredentials[key][subKey]; + hasBeenModified = true; + } + } + } } if (hasBeenModified) { @@ -72,4 +87,20 @@ if (process.env.DISCORD_WEBHOOK) { CREDENTIALS.discord_webhook = process.env.DISCORD_WEBHOOK; } +if (process.env.CACHE_PROFILES && isFinite(parseInt(process.env.CACHE_PROFILES))) { + CREDENTIALS.cacheSeconds.profiles = parseInt(process.env.CACHE_PROFILES); +} + +if (process.env.CACHE_MUSEUM && isFinite(parseInt(process.env.CACHE_MUSEUM))) { + CREDENTIALS.cacheSeconds.museum = parseInt(process.env.CACHE_MUSEUM); +} + +if (process.env.CACHE_GUILD && isFinite(parseInt(process.env.CACHE_GUILD))) { + CREDENTIALS.cacheSeconds.guild = parseInt(process.env.CACHE_GUILD); +} + +if (process.env.CACHE_BINGO_PROFILE && isFinite(parseInt(process.env.CACHE_BINGO_PROFILE))) { + CREDENTIALS.cacheSeconds.bingoProfile = parseInt(process.env.CACHE_BINGO_PROFILE); +} + export default CREDENTIALS; diff --git a/src/lib.js b/src/lib.js index e429adb89f..61d0680c8c 100644 --- a/src/lib.js +++ b/src/lib.js @@ -4,6 +4,7 @@ import axios from "axios"; import * as constants from "./constants.js"; import credentials from "./credentials.js"; +import * as cacheTimes from "./cachetimes.js"; import * as helper from "./helper.js"; import * as stats from "./stats.js"; import { SkyCryptError } from "./constants/error.js"; @@ -255,8 +256,6 @@ export async function getProfile( let profileObject = await db.collection("profileStore").findOne({ uuid: sanitize(paramPlayer) }); - let lastCachedSave = 0; - if (profileObject) { const profileData = db .collection("profileCache") @@ -276,13 +275,9 @@ export async function getProfile( let response = null; - lastCachedSave = Math.max(profileObject.last_update, Date.now() || 0); + const lastCachedSave = profileObject.last_update; - if ( - !options.cacheOnly && - ((Date.now() - lastCachedSave > 190 * 1000 && Date.now() - lastCachedSave < 300 * 1000) || - Date.now() - profileObject.last_update >= 300 * 1000) - ) { + if (!options.cacheOnly && (cacheTimes.isProfileCacheExpired(lastCachedSave) || lastCachedSave === 0)) { try { profileObject.last_update = Date.now(); response = await retry( @@ -504,12 +499,7 @@ export async function getBingoProfile( }; const lastCachedSave = profileData.last_save ?? 0; - if ( - (!options.cacheOnly && - ((Date.now() - lastCachedSave > 190 * 1000 && Date.now() - lastCachedSave < 300 * 1000) || - Date.now() - profileData.last_save >= 300 * 1000)) || - lastCachedSave === 0 - ) { + if (!options.cacheOnly && (cacheTimes.isBingoProfileCacheExpired(lastCachedSave) || lastCachedSave === 0)) { try { const response = await retry( async () => { @@ -565,7 +555,7 @@ export async function getMuseum( } let museumData = await db.collection("museumCache").findOne({ profile_id: profileID }); - if (!options.cacheOnly && (museumData == undefined || museumData.last_save < Date.now() - 1000 * 60 * 30)) { + if (!options.cacheOnly && (museumData == undefined || cacheTimes.isMuseumCacheExpired(museumData.last_save))) { try { const params = { key: credentials.hypixel_api_key, @@ -616,7 +606,7 @@ export async function getGuild( const timeStarted = Date.now(); let output = await db.collection("guildCache").findOne({ uuid: paramPlayer }); - if (!options.cacheOnly && (!output || output.last_updated < Date.now() - 1000 * 60 * 60 * 24)) { + if (!options.cacheOnly && (!output || cacheTimes.isGuildCacheExpired(output.last_updated))) { try { const params = { key: credentials.hypixel_api_key,