diff --git a/package.json b/package.json index 3b7bd4d..da63102 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@sveltejs/adapter-auto": "^3.0.1", "@sveltejs/adapter-node": "^2.0.2", "@sveltejs/kit": "2.0.6", + "@types/lodash": "^4.14.202", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "autoprefixer": "^10.4.16", @@ -50,6 +51,7 @@ "eslint-plugin-deprecation": "^2.0.0", "flowbite": "^1.8.1", "flowbite-svelte": "^0.39.3", + "lodash": "^4.17.21", "mongodb": "^6.3.0", "redis": "^4.6.12", "tailwind-merge": "^1.14.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfad930..ec86d04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ dependencies: flowbite-svelte: specifier: ^0.39.3 version: 0.39.3(svelte@4.2.8) + lodash: + specifier: ^4.17.21 + version: 4.17.21 mongodb: specifier: ^6.3.0 version: 6.3.0 @@ -43,6 +46,9 @@ devDependencies: '@sveltejs/kit': specifier: 2.0.6 version: 2.0.6(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.10) + '@types/lodash': + specifier: ^4.14.202 + version: 4.14.202 '@typescript-eslint/eslint-plugin': specifier: ^5.62.0 version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.56.0)(typescript@5.1.6) @@ -754,6 +760,10 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} + dev: true + /@types/node@20.10.5: resolution: {integrity: sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==} dependencies: @@ -2459,7 +2469,6 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} diff --git a/src/constants/misc.ts b/src/constants/misc.ts index 3e496d2..a9c6e53 100644 --- a/src/constants/misc.ts +++ b/src/constants/misc.ts @@ -34,3 +34,43 @@ export const ESSENCE = { head: '/head/67c41930f8ff0f2b0430e169ae5f38e984df1244215705c6f173862844543e9d' } }; + +export const EXPERIMENTS = { + games: { + simon: { + name: 'Chronomatron' + }, + numbers: { + name: 'Ultrasequencer' + }, + pairings: { + name: 'Superpairs' + } + }, + tiers: [ + { + name: 'Beginner', + icon: 'INK_SACK:12' + }, + { + name: 'High', + icon: 'INK_SACK:10' + }, + { + name: 'Grand', + icon: 'INK_SACK:11' + }, + { + name: 'Supreme', + icon: 'INK_SACK:14' + }, + { + name: 'Transcendent', + icon: 'INK_SACK:1' + }, + { + name: 'Metaphysical', + icon: 'INK_SACK:13' + } + ] +}; diff --git a/src/db/mongo/collections.d.ts b/src/db/mongo/collections.d.ts index ed617cb..0a58b7c 100644 --- a/src/db/mongo/collections.d.ts +++ b/src/db/mongo/collections.d.ts @@ -23,6 +23,7 @@ export interface StoredProfileMemberData { currencies?: SkyblockPlayerCurrencies; collections?: Record; mining?: SkyBlockMiningData; + enchanting?: SkyblockEnchantingData; unparsed?: Partial; } diff --git a/src/lib/stats.ts b/src/lib/stats.ts index 770d116..ed77a5c 100644 --- a/src/lib/stats.ts +++ b/src/lib/stats.ts @@ -9,7 +9,8 @@ export function getStats(profile: SkyBlockProfile, player: HypixelPlayerData, uu skills: stats.getSkills(userProfile, player, profile.members), currencies: stats.getCurrencies(userProfile, profile), slayers: stats.getSlayers(userProfile), - mining: stats.getMining(userProfile, player) + mining: stats.getMining(userProfile, player), + enchanting: stats.getEnchanting(userProfile) // unparsed: userProfile }; diff --git a/src/lib/stats/enchanting.ts b/src/lib/stats/enchanting.ts new file mode 100644 index 0000000..66128de --- /dev/null +++ b/src/lib/stats/enchanting.ts @@ -0,0 +1,55 @@ +import type { Experimentation, SkyBlockProfileMember, SkyblockExperimentTier } from '$types/hypixel'; +import { EXPERIMENTS } from '$constants'; +import _ from 'lodash'; + +export function getEnchanting(userProfile: Partial) { + if (!userProfile.experimentation) return; + + return { + unlocked: !!userProfile.experimentation, + experiments: userProfile.experimentation + ? Object.fromEntries( + Object.keys(EXPERIMENTS.games) + .filter((game) => game in (userProfile.experimentation as Experimentation)) + .map((game) => { + const gameConstants = EXPERIMENTS.games[game as keyof typeof EXPERIMENTS.games]; + const gameData = (userProfile.experimentation as Experimentation)[ + game as keyof typeof userProfile.experimentation + ] as Record; + + const output = { + name: gameConstants.name, + stats: {} as Record, + tiers: {} as Record + }; + + for (const key in gameData) { + if (key.startsWith('attempts') || key.startsWith('claims') || key.startsWith('best_score')) { + const statArray = key.split('_'); + const tierValue = parseInt(statArray.pop() as string); + const tier = + game === 'numbers' ? tierValue + 2 : game === 'simon' ? Math.min(tierValue + 1, 5) : tierValue; + + const tierInfo = _.cloneDeep(EXPERIMENTS.tiers[tier]); + if (output.tiers[tier as keyof typeof output.tiers] === undefined) output.tiers[tier] = tierInfo; + + const stat = statArray.join('_'); + Object.assign(output.tiers[tier], { + [stat]: gameData[key] + }); + continue; + } + if (key == 'last_attempt' || key == 'last_claimed') { + if (gameData[key] <= 0) continue; + output.stats[key] = gameData[key]; + continue; + } + output.stats[key] = gameData[key]; + } + + return [game, output]; + }) + ) + : undefined + }; +} diff --git a/src/lib/stats/index.ts b/src/lib/stats/index.ts index 79fdf36..9ef42fe 100644 --- a/src/lib/stats/index.ts +++ b/src/lib/stats/index.ts @@ -2,3 +2,4 @@ export * from '$lib/stats/skills'; export * from '$lib/stats/currencies'; export * from '$lib/stats/slayer'; export * from '$lib/stats/mining'; +export * from '$lib/stats/enchanting'; diff --git a/src/types/processed/stats.d.ts b/src/types/processed/stats.d.ts index d4f7a9f..42b6cb1 100644 --- a/src/types/processed/stats.d.ts +++ b/src/types/processed/stats.d.ts @@ -3,3 +3,4 @@ export * from './stats/slayer'; export * from './stats/rank'; export * from './stats/inventory'; export * from './stats/mining'; +export * from './stats/enchanting'; diff --git a/src/types/processed/stats/enchanting.d.ts b/src/types/processed/stats/enchanting.d.ts new file mode 100644 index 0000000..1b19498 --- /dev/null +++ b/src/types/processed/stats/enchanting.d.ts @@ -0,0 +1,23 @@ +export type SkyblockExperimentTier = { + name: string; + icon: string; + attempts?: number; + claims?: number; + best_score?: number; +}; + +export type SkyblockEnchantingData = { + unlocked: boolean; + experiments?: Record< + string, + { + name: string; + stats: { + last_claimed?: number; + last_attempt?: number; + bonus_clicks?: number; + }; + tiers: Record; + } + >; +};