aboutsummaryrefslogtreecommitdiff
path: root/build/hypixelCached.js
diff options
context:
space:
mode:
Diffstat (limited to 'build/hypixelCached.js')
-rw-r--r--build/hypixelCached.js227
1 files changed, 227 insertions, 0 deletions
diff --git a/build/hypixelCached.js b/build/hypixelCached.js
new file mode 100644
index 0000000..c874089
--- /dev/null
+++ b/build/hypixelCached.js
@@ -0,0 +1,227 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fetchProfileName = exports.fetchProfile = exports.fetchProfileUuid = exports.fetchSkyblockProfiles = exports.fetchPlayer = exports.usernameFromUser = exports.uuidFromUser = void 0;
+const node_cache_1 = __importDefault(require("node-cache"));
+const mojang = __importStar(require("./mojang"));
+const hypixel = __importStar(require("./hypixel"));
+const util_1 = require("./util");
+/**
+Hypixel... but with caching
+All the caching in this project is done here!
+*/
+// cache usernames for 4 hours
+const usernameCache = new node_cache_1.default({
+ stdTTL: 60 * 60 * 4,
+ checkperiod: 60,
+ useClones: false,
+});
+const basicProfilesCache = new node_cache_1.default({
+ stdTTL: 60 * 10,
+ checkperiod: 60,
+ useClones: false,
+});
+const playerCache = new node_cache_1.default({
+ stdTTL: 60,
+ checkperiod: 10,
+ useClones: false,
+});
+const profileCache = new node_cache_1.default({
+ stdTTL: 30,
+ checkperiod: 10,
+ useClones: false,
+});
+const profilesCache = new node_cache_1.default({
+ stdTTL: 60 * 3,
+ checkperiod: 10,
+ useClones: false,
+});
+const profileNameCache = new node_cache_1.default({
+ stdTTL: 60 * 60,
+ checkperiod: 60,
+ useClones: false,
+});
+/**
+ * Fetch the uuid from a user
+ * @param user A user can be either a uuid or a username
+ */
+async function uuidFromUser(user) {
+ if (usernameCache.has(util_1.undashUuid(user)))
+ // check if the uuid is a key
+ return util_1.undashUuid(user);
+ // check if the username is a value
+ const uuidToUsername = usernameCache.mget(usernameCache.keys());
+ for (const [uuid, username] of Object.entries(uuidToUsername)) {
+ if (user.toLowerCase() === username.toLowerCase())
+ return uuid;
+ }
+ // not cached, actually fetch mojang api now
+ let { uuid, username } = await mojang.mojangDataFromUser(user);
+ // remove dashes from the uuid so its more normal
+ uuid = util_1.undashUuid(uuid);
+ usernameCache.set(uuid, username);
+ return uuid;
+}
+exports.uuidFromUser = uuidFromUser;
+/**
+ * Fetch the username from a user
+ * @param user A user can be either a uuid or a username
+ */
+async function usernameFromUser(user) {
+ if (usernameCache.has(util_1.undashUuid(user))) {
+ return usernameCache.get(util_1.undashUuid(user));
+ }
+ let { uuid, username } = await mojang.mojangDataFromUser(user);
+ uuid = util_1.undashUuid(uuid);
+ usernameCache.set(uuid, username);
+ return username;
+}
+exports.usernameFromUser = usernameFromUser;
+async function fetchPlayer(user) {
+ const playerUuid = await uuidFromUser(user);
+ if (playerCache.has(playerUuid)) {
+ console.log('cache hit! fetchPlayer', playerUuid);
+ return playerCache.get(playerUuid);
+ }
+ const cleanPlayer = await hypixel.sendCleanApiRequest({
+ path: 'player',
+ args: { uuid: playerUuid }
+ });
+ playerCache.set(playerUuid, cleanPlayer);
+ return cleanPlayer;
+}
+exports.fetchPlayer = fetchPlayer;
+async function fetchSkyblockProfiles(playerUuid) {
+ if (profilesCache.has(playerUuid)) {
+ console.log('cache hit! fetchSkyblockProfiles', playerUuid);
+ return profilesCache.get(playerUuid);
+ }
+ const profiles = await hypixel.sendCleanApiRequest({
+ path: 'skyblock/profiles',
+ args: {
+ uuid: playerUuid
+ }
+ });
+ const basicProfiles = [];
+ // create the basicProfiles array
+ for (const profile of profiles) {
+ const basicProfile = {
+ name: profile.name,
+ uuid: profile.uuid,
+ members: profile.members.map(m => {
+ return {
+ uuid: m.uuid,
+ username: m.username,
+ first_join: m.first_join,
+ last_save: m.last_save
+ };
+ })
+ };
+ basicProfiles.push(basicProfile);
+ }
+ // cache the profiles
+ profilesCache.set(playerUuid, basicProfiles);
+ return basicProfiles;
+}
+exports.fetchSkyblockProfiles = fetchSkyblockProfiles;
+/** Fetch an array of `BasicProfile`s */
+async function fetchBasicProfiles(user) {
+ const playerUuid = await uuidFromUser(user);
+ if (basicProfilesCache.has(playerUuid)) {
+ console.log('cache hit! fetchBasicProfiles');
+ return basicProfilesCache.get(playerUuid);
+ }
+ const player = await fetchPlayer(playerUuid);
+ const profiles = player.profiles;
+ basicProfilesCache.set(playerUuid, profiles);
+ console.log(player);
+ // cache the profile names and uuids to profileNameCache because we can
+ for (const profile of profiles)
+ profileNameCache.set(`${playerUuid}.${profile.uuid}`, profile.name);
+ return profiles;
+}
+/**
+ * Fetch a profile UUID from its name and user
+ * @param user A username or uuid
+ * @param profile A profile name or profile uuid
+ */
+async function fetchProfileUuid(user, profile) {
+ const profiles = await fetchBasicProfiles(user);
+ const profileUuid = util_1.undashUuid(profile);
+ for (const p of profiles) {
+ if (p.name.toLowerCase() === profileUuid.toLowerCase())
+ return util_1.undashUuid(p.uuid);
+ else if (util_1.undashUuid(p.uuid) === util_1.undashUuid(profileUuid))
+ return util_1.undashUuid(p.uuid);
+ }
+}
+exports.fetchProfileUuid = fetchProfileUuid;
+/**
+ * Fetch an entire profile from the user and profile data
+ * @param user A username or uuid
+ * @param profile A profile name or profile uuid
+ */
+async function fetchProfile(user, profile) {
+ const profileUuid = await fetchProfileUuid(user, profile);
+ if (profileCache.has(profileUuid)) {
+ console.log('cache hit! fetchProfile');
+ // we have the profile cached, return it :)
+ return profileCache.get(profileUuid);
+ }
+ const profileName = await fetchProfileName(user, profile);
+ const cleanProfile = await hypixel.sendCleanApiRequest({
+ path: 'skyblock/profile',
+ args: {
+ profile: profileUuid
+ }
+ });
+ // we know the name from fetchProfileName, so set it here
+ cleanProfile.name = profileName;
+ profileCache.set(profileUuid, cleanProfile);
+ return cleanProfile;
+}
+exports.fetchProfile = fetchProfile;
+/**
+ * Fetch the name of a profile from the user and profile uuid
+ * @param user A player uuid or username
+ * @param profile A profile uuid or name
+ */
+async function fetchProfileName(user, profile) {
+ // we're fetching the profile and player uuid again in case we were given a name, but it's cached so it's not much of a problem
+ const profileUuid = await fetchProfileUuid(user, profile);
+ const playerUuid = await uuidFromUser(user);
+ if (profileNameCache.has(`${playerUuid}.${profileUuid}`)) {
+ // Return the profile name if it's cached
+ console.log('cache hit! fetchProfileName');
+ return profileNameCache.get(`${playerUuid}.${profileUuid}`);
+ }
+ const basicProfiles = await fetchBasicProfiles(playerUuid);
+ let profileName;
+ for (const basicProfile of basicProfiles)
+ if (basicProfile.uuid === playerUuid)
+ profileName = basicProfile.name;
+ profileNameCache.set(`${playerUuid}.${profileUuid}`, profileName);
+ return profileName;
+}
+exports.fetchProfileName = fetchProfileName;