import z from "zod" function bedwarsModeStats() { const ids = [ "eight_one", "eight_two", "four_three", "four_four", "two_four", "eight_two_rush", "four_four_rush", "eight_two_ultimate", "four_four_ultimate", "eight_two_lucky", "four_four_lucky", "eight_two_voidless", "four_four_voidless", "eight_two_armed", "four_four_armed", "four_four_swap", "four_four_underworld", "castle" ] as const const stats = [ "winstreak", "kills_bedwars", "deaths_bedwars", "final_kills_bedwars", "final_deaths_bedwars", "wins_bedwars", "losses_bedwars", "beds_broken_bedwars", "beds_lost_bedwars" ] as const const entries = new Map>() const winstreak = new Map>() for (const id of ids) { for (const stat of stats) { if (stat === "winstreak") { winstreak.set(`${id}_${stat}`, z.number().optional()) } else { entries.set(`${id}_${stat}`, z.number().default(0)) } } } type Modes = typeof ids[number] type Stats = Exclude return { all: Object.fromEntries(entries) as Record<`${Modes}_${Stats}`, z.ZodDefault>, winstreak: Object.fromEntries(winstreak) as Record<`${Modes}_winstreak`, z.ZodOptional> } } export const bedwarsStatsSchema = z.looseObject({ Experience: z.number().default(0), coins: z.number().default(0), winstreak: z.number().optional(), kills_bedwars: z.number().default(0), deaths_bedwars: z.number().default(0), final_kills_bedwars: z.number().default(0), final_deaths_bedwars: z.number().default(0), wins_bedwars: z.number().default(0), losses_bedwars: z.number().default(0), beds_broken_bedwars: z.number().default(0), beds_lost_bedwars: z.number().default(0), total_challenges_completed: z.number().default(0), iron_resources_collected_bedwars: z.number().default(0), gold_resources_collected_bedwars: z.number().default(0), diamond_resources_collected_bedwars: z.number().default(0), emerald_resources_collected_bedwars: z.number().default(0), _items_purchased_bedwars: z.number().default(0), slumber: z.looseObject({ tickets: z.number().default(0), bag_type: z.string().optional(), total_tickets_earned: z.number().default(0), doublers: z.number().default(0), room: z.record(z.string(), z.boolean()).optional() }).optional(), ...bedwarsModeStats().all, ...bedwarsModeStats().winstreak }) function skywarsModeStats() { const ids = [ "solo_normal", "solo_insane", "team_normal", "team_insane", "mega", "mega_doubles", "ranked_normal" ] as const const stats = [ "kills", "deaths", "wins", "losses" ] as const const entries = new Map>() for (const id of ids) { for (const stat of stats) { entries.set(`${stat}_${id}`, z.number().default(0)) } } return Object.fromEntries(entries) as Record<`${typeof stats[number]}_${typeof ids[number]}`, z.ZodDefault> } export const skywarsStatsSchema = z.looseObject({ skywars_experience: z.number().default(0), selected_prestige_icon: z.string().optional(), kills: z.number().default(0), deaths: z.number().default(0), assists: z.number().default(0), wins: z.number().default(0), losses: z.number().default(0), cosmetic_tokens: z.number().default(0), coins: z.number().default(0), blocks_placed: z.number().default(0), blocks_broken: z.number().default(0), chests_opened: z.number().default(0), arrows_hit: z.number().default(0), arrows_shot: z.number().default(0), melee_kills: z.number().default(0), void_kills: z.number().default(0), bow_kills: z.number().default(0), mobs_kills: z.number().default(0), enderpearls_thrown: z.number().default(0), egg_thrown: z.number().default(0), wins_lab: z.number().default(0), heads: z.number().default(0), angel_of_death_level: z.number().default(0), angels_offering: z.number().default(0), souls_gathered: z.number().default(0), souls: z.number().default(0), paid_souls: z.number().default(0), soul_well: z.number().default(0), packages: z.array(z.string()), shard: z.number().default(0), opals: z.number().default(0), heads_eww: z.number().default(0), heads_yucky: z.number().default(0), heads_meh: z.number().default(0), heads_decent: z.number().default(0), heads_salty: z.number().default(0), heads_tasty: z.number().default(0), heads_succulent: z.number().default(0), heads_sweet: z.number().default(0), heads_divine: z.number().default(0), heads_heavenly: z.number().default(0), head_collection: z.looseObject({ prestigious: z.array(z.object({ username: z.string().nullable().default(null), timestamp: z.number(), mode: z.string(), sacrifice: z.string() })) }).optional(), ...skywarsModeStats() }) function duelsModeStats() { const ids = [ "uhc_duel", "uhc_doubles", "uhc_four", "uhc_meetup", "op_duel", "op_doubles", "sw_duel", "sw_doubles", "bow_duel", "blitz_duel", "mw_duel", "mw_doubles", "sumo_duel", "bowspleef_duel", "spleef_duel", "parkour_eight", "boxing_duel", "classic_duel", "classic_doubles", "potion_duel", "combo_duel", "duel_arena", "quake_duel", "bedwars_two_one_duels", "bedwars_two_one_duels_rush" ] as const const bridgeIds = [ "bridge_duel", "bridge_doubles", "bridge_threes", "bridge_four", "bridge_2v2v2v2", "bridge_3v3v3v3" ] as const const bridgeStats = [ "bridge_kills", "bridge_deaths", "goals" ] as const const stats = [ "kills", "deaths", "wins", "losses", "melee_swings", "melee_hits", "bow_shots", "bow_hits", "current_winstreak_mode", "best_winstreak_mode" ] as const const entries = new Map>() const ws = new Map>() const bestWs = new Map>() const bridge = new Map>() for (const id of ids) { for (const stat of stats) { if (stat === "current_winstreak_mode") { ws.set(`${stat}_${id}`, z.number().optional()) } else if (stat === "best_winstreak_mode") { bestWs.set(`${stat}_${id}`, z.number().optional()) } else { entries.set(`${id}_${stat}`, z.number().default(0)) } } } const combined = [...stats, ...bridgeStats] for (const id of bridgeIds) { for (const stat of combined) { if (stat === "bridge_kills" || stat === "bridge_deaths" || stat === "goals") { bridge.set(`${id}_${stat}`, z.number().default(0)) } else if (stat === "best_winstreak_mode") { ws.set(`${stat}_${id}`, z.number().optional()) } else if (stat === "current_winstreak_mode") { ws.set(`${stat}_${id}`, z.number().optional()) } else { entries.set(`${id}_${stat}`, z.number().default(0)) } } } type Modes = typeof ids[number] type BridgeModes = typeof bridgeIds[number] type Stats = Exclude type BridgeStats = typeof bridgeStats[number] return { all: Object.fromEntries(entries) as Record<`${Modes | BridgeModes}_${Stats}`, z.ZodDefault>, ws: Object.fromEntries(ws) as Record<`current_winstreak_mode_${Modes | BridgeModes}`, z.ZodOptional>, bestWs: Object.fromEntries(bestWs) as Record<`best_winstreak_mode_${Modes | BridgeModes}`, z.ZodOptional>, bridge: Object.fromEntries(bridge) as Record<`${BridgeModes}_${BridgeStats}`, z.ZodDefault> } } function devisionTitles() { const devisions = [ "all_modes", "uhc", "op", "skywars", "bow", "blitz", "mega_walls", "sumo", "tnt_games", "parkour", "boxing", "classic", "no_debuff", "combo", "bridge" ] as const const titles = [ "rookie", "iron", "gold", "diamond", "master", "legend", "grandmaster", "godlike", "celestial", "divine", "ascended" ] as const const entries = new Map>() for (const div of devisions) { for (const title of titles) { entries.set(`${div}_${title}_title_prestige`, z.number().default(-1)) } } return Object.fromEntries(entries) as Record<`${typeof devisions[number]}_${typeof titles[number]}_title_prestige`, z.ZodDefault> } export const duelsStatsSchema = z.looseObject({ wins: z.number().default(0), losses: z.number().default(0), coins: z.number().default(0), kills: z.number().default(0), deaths: z.number().default(0), melee_swings: z.number().default(0), melee_hits: z.number().default(0), bow_shots: z.number().default(0), bow_hits: z.number().default(0), current_winstreak: z.number().optional(), best_overall_winstreak: z.number().optional(), ...devisionTitles(), ...duelsModeStats().all, ...duelsModeStats().ws, ...duelsModeStats().bestWs, ...duelsModeStats().bridge }) function murderMysteryModeStats() { const ids = [ "MURDER_CLASSIC", "MURDER_ASSASSINS", "MURDER_DOUBLE_UP", "MURDER_HARDCORE", "MURDER_SHOWDOWN" ] as const const stats = [ "kills", "bow_kills", "knife_kills", "thrown_knife_kills", "wins", "games", "coins_pickedup" ] as const const entries = new Map>() for (const id of ids) { for (const stat of stats) { entries.set(`${stat}_${id}`, z.number().default(0)) } } return Object.fromEntries(entries) as Record<`${typeof stats[number]}_${typeof ids[number]}`, z.ZodDefault> } export const murderMysteryStatsSchema = z.looseObject({ kills: z.number().default(0), deaths: z.number().default(0), wins: z.number().default(0), losses: z.number().default(0), coins: z.number().default(0), games: z.number().default(0), bow_kills: z.number().default(0), knife_kills: z.number().default(0), coins_pickedup: z.number().default(0), kills_as_murderer: z.number().default(0), thrown_knife_kills: z.number().default(0), active_knife_skin: z.string().optional(), quickest_detective_win_time_seconds: z.number().default(0), quickest_murderer_win_time_seconds: z.number().default(0), kills_as_infected_MURDER_INFECTION: z.number().default(0), kills_as_survivor_MURDER_INFECTION: z.number().default(0), kills_MURDER_INFECTION: z.number().default(0), wins_MURDER_INFECTION: z.number().default(0), games_MURDER_INFECTION: z.number().default(0), total_time_survived_seconds_MURDER_INFECTION: z.number().default(0), coins_pickedup_MURDER_INFECTION: z.number().default(0), ...murderMysteryModeStats() }) export const buildBattleStatsSchema = z.looseObject({ wins: z.number().default(0), score: z.number().default(0), coins: z.number().default(0), games_played: z.number().default(0), correct_guesses: z.number().default(0), super_votes: z.number().default(0), wins_solo_normal: z.number().default(0), wins_teams_normal: z.number().default(0), wins_guess_the_build: z.number().default(0), wins_solo_pro: z.number().default(0), wins_speed_builders: z.number().default(0), wins_solo_normal_latest: z.number().default(0), wins_teams_normal_latest: z.number().default(0), wins_guess_the_build_latest: z.number().default(0), wins_solo_pro_latest: z.number().default(0), wins_speed_builders_latest: z.number().default(0) }) function uhcModesStats() { const ids = [ "solo", "red_vs_blue", "no_diamonds", "vanilla_doubles", "brawl", "solo_brawl", "duo_brawl" ] as const const stats = [ "wins", "kills", "deaths", "heads_eaten" ] as const const entries = new Map>() for (const id of ids) { for (const stat of stats) { entries.set(`${stat}_${id}`, z.number().default(0)) } } return Object.fromEntries(entries) as Record<`${typeof stats[number]}_${typeof ids[number]}`, z.ZodDefault> } export const uhcSchema = z.looseObject({ kills: z.number().default(0), deaths: z.number().default(0), wins: z.number().default(0), heads_eaten: z.number().default(0), score: z.number().default(0), coins: z.number().default(0), ultimates_crafted: z.number().default(0), ultimates_crafted_solo: z.number().default(0), ...uhcModesStats() }) export const pitStats = z.looseObject({ pit_stats_ptl: z.looseObject({ kills: z.number().default(0), deaths: z.number().default(0), cash_earned: z.number().default(0), playtime_minutes: z.number().default(0), assists: z.number().default(0), max_streak: z.number().default(0), damage_dealt: z.number().default(0), damage_received: z.number().default(0), melee_damage_dealt: z.number().default(0), melee_damage_received: z.number().default(0), bow_damage_dealt: z.number().default(0), bow_damage_received: z.number().default(0), sword_hits: z.number().default(0), left_clicks: z.number().default(0), arrow_hits: z.number().default(0), arrows_fired: z.number().default(0), contracts_completed: z.number().default(0), jumped_into_pit: z.number().default(0), launched_by_launchers: z.number().default(0) }), profile: z.looseObject({ prestiges: z.array(z.looseObject({ index: z.number(), xp_on_prestige: z.number(), timestamp: z.number() })).optional(), xp: z.number().default(0), cash: z.number().default(0), renown: z.number().default(0) }) }).transform(({ profile, pit_stats_ptl, ...rest }) => ({ profile, ...pit_stats_ptl, ...rest }))