commit d94c5c6cc057853b70f8b96cc813ed8a736cc1f2 Author: yhqe Date: Sun Jun 28 11:30:57 2026 -0500 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e5aa1c --- /dev/null +++ b/.gitignore @@ -0,0 +1,60 @@ +# Node +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnp/ +.pnp.js +dist/ +build/ +out/ +coverage/ + +# pnpm (keep pnpm-lock.yaml) +pnpm-debug.log* + +# Logs +logs/ +*.log + +# Environment +.env +.env.* + +# Editor directories and files +.vscode/ +.idea/ +*.suo +*.ntvs* +*.njsproj +*.sln + +# Python +__pycache__/ +*.py[cod] +*$py.class +venv/ +.venv/ +env/ +pip-wheel-metadata/ +*.egg-info/ +.pytest_cache/ +.mypy_cache/ +.coverage +htmlcov/ + +# Secrets and keys +*.pem +*.key +*.crt +secrets.* + +# OS files +.DS_Store +Thumbs.db +Desktop.ini +ehthumbs.db + +# Misc caches +.cache/ +.parcel-cache/ diff --git a/EXCLUSIVES.md b/EXCLUSIVES.md new file mode 100644 index 0000000..583e779 --- /dev/null +++ b/EXCLUSIVES.md @@ -0,0 +1,106 @@ +ALL EXCLUSIVE AND OG ITEMS THAT ARE SUPPOSED TO BE LABELED MYTHIC IN THE SKIN CHECK! +Season 1 exclusives +Season 2 Battle Pass exclusives +Promotional exclusives (Samsung, Nintendo, PlayStation, Xbox, Twitch Prime, Intel, NVIDIA, etc.) +Founder exclusives +Tournament exclusives +Creator/Search for Survivors exclusives +Limited-time challenge exclusives + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +OG Skins +Renegade Raider +Aerial Assault Trooper +Black Knight +Blue Squire +Royale Knight +Sparkle Specialist +The Reaper +Elite Agent +Omega (fully upgraded) +Purple Skull Trooper +Pink Ghoul Trooper +Exclusive Skins +Galaxy +IKONIK +Glow +Wonder +Honor Guard +Eon +Dark Vertex +Double Helix +Neo Versa +Royale Bomber +Wildcat +Stealth Reflex +Reflex (original) +Rogue Spider Knight +Huntmaster Saber +Surf Strider +Blue Team Leader +Blue Striker +Carbon Commando +Prodigy +Cloud Striker +Fixer +Point Patroller +Trailblazer +OG Pickaxes +Raider's Revenge +Aerial Assault One +AC/DC +Trusty No. 2 +Party Animal +OG / Exclusive Emotes +Fresh +Rambunctious +Tidy +Floss +Take the L +Orange Justice +Ride the Pony +Pony Up +Scenario +Evasive Maneuvers +Widow's Pirouette +Hot Marat +Kiss the Cup +Rare Banners +Battle Bus Banner +Alpha Tester Banner +Founder's Banners +Frostnite 128 Banner +FNCS Champion Banners +World Cup Finalist Banners +Fall Skirmish Banner +Summer Skirmish Banner +Galaxy Banner +IKONIK Banner +Glow Banner +Wonder Banner +Honor Guard Banner +EON Banner +Dark Vertex Banner +Double Helix Banner +Neo Versa Banner +Wildcat Banner +Search for Survivors Creator Banners +PewDiePie Banner +VanossGaming Banner +Muselk Banner +Jesse Cox Banner +Dhalucard Banner +Folagor03 Banner +Ionix_TV Banner +JesusAVGN Banner +OrkPod Banner +Rare Emoticons +Founder Emoticons +Galaxy Emoticon +IKONIK Emoticon +Glow Emoticon +Wonder Emoticon +Honor Guard Emoticon +Twitch Prime Emoticons +Early Battle Pass Emoticons \ No newline at end of file diff --git a/assets/BurbankBigCondensed-Black.ttf b/assets/BurbankBigCondensed-Black.ttf new file mode 100644 index 0000000..af695a7 Binary files /dev/null and b/assets/BurbankBigCondensed-Black.ttf differ diff --git a/assets/Fortnite_Master_Exclusive_List.txt b/assets/Fortnite_Master_Exclusive_List.txt new file mode 100644 index 0000000..ddb798a --- /dev/null +++ b/assets/Fortnite_Master_Exclusive_List.txt @@ -0,0 +1,178 @@ +FORTNITE OG / EXCLUSIVE / PROMOTIONAL / STW / CREATOR BANNER MASTER LIST + +======================== YOUTUBER / CREATOR BANNERS +======================== - PewDiePie Banner - VanossGaming Banner - +Muselk Banner - Jesse Cox Banner - Dhalucard Banner - Folagor03 Banner - +Ionix_TV Banner - JesusAVGN Banner - OrkPod Banner + +======================== SAVE THE WORLD EXCLUSIVE BANNERS +======================== - Founder’s Banner - Ultimate Founder’s +Banner - Challenge the Horde Banner - Horde Bash Banner - Frostnite +Banner - Frostnite 128 Banner - Hit the Road Banner - Endurance Banner - +Mythic Storm King Banner - Survive the Storm Banner - Canny Valley +Endurance Banner - Plankerton Endurance Banner - Stonewood Endurance +Banner - Twine Peaks Endurance Banner + +======================== OG SKINS ======================== - Renegade +Raider - Aerial Assault Trooper - Black Knight - Blue Squire - Royale +Knight - Sparkle Specialist - The Reaper - Elite Agent - Omega (Max +Lights) - Carbide (Max Lights) - Purple Skull Trooper - Pink Ghoul +Trooper + +======================== EXCLUSIVE SKINS ======================== - +Galaxy - IKONIK - Glow - Honor Guard - Wonder - EON - Dark Vertex - +Double Helix - Neo Versa - Royale Bomber - Wildcat - Reflex - Stealth +Reflex - Rogue Spider Knight - Huntmaster Saber - Blue Team Leader - +Blue Striker - Carbon Commando - Prodigy - Cloud Striker - Fixer - Point +Patroller - Trailblazer - Havoc - Rose Team Leader - Warpaint + +======================== EXCLUSIVE PICKAXES ======================== - +Raider’s Revenge - Aerial Assault One - Merry Mint Axe - Stellar Axe - +Resonator - Razor Edge - Pinpoint - Angular Axe - Tenderizer - AC/DC - +Trusty No. 2 - Party Animal + +======================== EXCLUSIVE EMOTES ======================== - +Scenario - Levitate - Pony Up - Ride The Pony - Fresh - Rambunctious - +Tidy - Floss - Take The L - Orange Justice - Evasive Maneuvers - Widow’s +Pirouette - Hot Marat - Kiss The Cup + +======================== SAMSUNG GALAXY BUNDLE +======================== - Galaxy - Galactic Disc - Stellar Axe - +Discovery + +======================== IKONIK BUNDLE ======================== - +IKONIK - Scenario + +======================== GLOW BUNDLE ======================== - Glow - +Levitate + +======================== EON BUNDLE ======================== - EON - +Resonator - Aurora + +======================== DARK VERTEX BUNDLE ======================== - +Dark Vertex - Dark Deflector - Razor Edge - Dark Forerunner + +======================== DOUBLE HELIX BUNDLE ======================== - +Double Helix - Telemetry - Pinpoint - Rotor + +======================== NEO VERSA BUNDLE ======================== - Neo +Versa - Neo Phrenzy + +======================== ROYALE BOMBER BUNDLE ======================== - +Royale Bomber - Royale Air + +======================== REFLEX BUNDLE ======================== - +Reflex - Response Unit - Angular Axe - Pivot + +======================== STEALTH REFLEX BUNDLE +======================== - Stealth Reflex - Stealth Response Unit + +======================== WILDCAT BUNDLE ======================== - +Wildcat - Sleek Strike + +======================== ROGUE SPIDER KNIGHT BUNDLE +======================== - Rogue Spider Knight - Time Keeper + +======================== FOUNDER EXCLUSIVES ======================== - +Rose Team Leader - Warpaint - Pony Up - Founder’s Umbrella - Founder’s +Gliders - Founder’s Pickaxes - Founder’s Banners + +======================== RARE BANNERS ======================== - Alpha +Tester Banner - Battle Bus Banner - Founder’s Banner - FNCS Champion +Banner - World Cup Banner - Fall Skirmish Banner - Summer Skirmish +Banner - Galaxy Banner - IKONIK Banner - Glow Banner - Wonder Banner - +Honor Guard Banner - EON Banner - Dark Vertex Banner - Double Helix +Banner - Neo Versa Banner - Wildcat Banner + + +extra stuff IGNORE THAT IT SAYS MISSING JUST ADD THEM TO EITHER OG OR EXCLUSIVE LIST + + +Missing Exclusive Skins +Honor Guard +Wonder +Surf Strider +Gildedguy +Tart Tycoon +Various FNCS reward skins/styles +Platform-exclusive reskins +Crew Pack exclusive legacy styles +Missing Pickaxes +Crowbar (High Stakes) +Instigator +Founder-exclusive pickaxes +STW event pickaxes +Galaxy Cup pickaxes +Tournament reward pickaxes +Missing Gliders +Snowflake Umbrella +Mako +Founder's Gliders +Exclusive bundle gliders +Tournament gliders +Missing Banners +Many Search for Survivors creator banners +Alpha Tester variants +Early STW event banners +Dungeon banners +Ventures banners +Holiday event banners +Tournament placement banners +Missing Emoticons +Founder emoticons +Samsung emoticons +Wonder emoticons +Honor Guard emoticons +Twitch Prime emoticons +Early Battle Pass emoticons +Missing Wraps +Stealth Black +Magma +Star Scout +Competitive reward wraps +Platform-exclusive wraps +Missing Sprays +Tournament sprays +World Cup sprays +FNCS sprays +STW sprays +Missing Loading Screens +Galaxy loading screens +Wildcat loading screens +Tournament loading screens +STW exclusive loading screens +Missing Back Blings + +There are dozens of exclusive back blings tied to: + +Samsung bundles +Xbox bundles +Nintendo bundles +PlayStation bundles +Founder packs +Twitch Prime packs +Intel/NVIDIA promotions +Missing OG Progression Items +Max Omega Lights +Max Carbide Lights +Corrupted Scratch levels +Golden Peely +Fully Enlightened Chapter 2 skins +Holo Foil Marvel skins +Rainbow Foil Marvel skins +Gold Agent styles +Missing STW Exclusives + +This is a huge category: + +Founder heroes +Founder schematics +Founder banners +Event banners +Challenge the Horde rewards +Survive the Storm rewards +Frostnite rewards +Endurance rewards +Mythic Storm King rewards + +If your goal is a checker that's com diff --git a/assets/font_test.png b/assets/font_test.png new file mode 100644 index 0000000..c07c837 Binary files /dev/null and b/assets/font_test.png differ diff --git a/checker/.gitignore b/checker/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/checker/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/checker/README.md b/checker/README.md new file mode 100644 index 0000000..d60cdd3 --- /dev/null +++ b/checker/README.md @@ -0,0 +1,27 @@ +![test](https://cdn.discordapp.com/attachments/1285541629016670300/1320374781333340211/logo.png?ex=67695e57&is=67680cd7&hm=e5962535a2d6b7864a4a81e87fe51422356ecc85fecbb96ab88b7250e390245c&) + +Provably-Safe Telegram Fortnite Skin Checker Bot +- single handedly developed by @xhexago on telegram and discord + +Setup Guide(Windows): +- install Python 3.11.4 from https://www.python.org/ftp/python/3.11.4/python-3.11.4-amd64.exe +- make sure python is installed with the option "Add to "PATh"; +- python -m pip install --upgrade pip + +- pip install Pillow==11.0.0 +- pip install telebot +- pip install asyncio +- pip install aiohttp + +Setup Guide(Linux): +- sudo apt update +- sudo apt upgrade +- sudo apt install -y python3 +- sudo apt install -y python3-pip +- pip install Pillow==11.0.0 +- pip install telebot +- pip install asyncio +- pip install aiohttp + +- Make .env file with variables for: +- TELEGRAM_API_TOKEN diff --git a/checker/accounts/placeholder.txt b/checker/accounts/placeholder.txt new file mode 100644 index 0000000..e69de29 diff --git a/checker/badges/alpha1.png b/checker/badges/alpha1.png new file mode 100644 index 0000000..338eb82 Binary files /dev/null and b/checker/badges/alpha1.png differ diff --git a/checker/badges/alpha2.png b/checker/badges/alpha2.png new file mode 100644 index 0000000..1761426 Binary files /dev/null and b/checker/badges/alpha2.png differ diff --git a/checker/badges/alpha3.png b/checker/badges/alpha3.png new file mode 100644 index 0000000..1b37b8b Binary files /dev/null and b/checker/badges/alpha3.png differ diff --git a/checker/badges/epic.png b/checker/badges/epic.png new file mode 100644 index 0000000..93a5389 Binary files /dev/null and b/checker/badges/epic.png differ diff --git a/checker/badges/icon/alpha1.png b/checker/badges/icon/alpha1.png new file mode 100644 index 0000000..6f8c74d Binary files /dev/null and b/checker/badges/icon/alpha1.png differ diff --git a/checker/badges/icon/alpha2.png b/checker/badges/icon/alpha2.png new file mode 100644 index 0000000..9b938eb Binary files /dev/null and b/checker/badges/icon/alpha2.png differ diff --git a/checker/badges/icon/alpha3.png b/checker/badges/icon/alpha3.png new file mode 100644 index 0000000..ac273de Binary files /dev/null and b/checker/badges/icon/alpha3.png differ diff --git a/checker/badges/icon/epic.png b/checker/badges/icon/epic.png new file mode 100644 index 0000000..95342b0 Binary files /dev/null and b/checker/badges/icon/epic.png differ diff --git a/checker/commands.py b/checker/commands.py new file mode 100644 index 0000000..0a86cc3 --- /dev/null +++ b/checker/commands.py @@ -0,0 +1,2002 @@ +import os +from PIL import Image, ImageDraw, ImageFont, ImageOps +import json +import user +import colorsys +import logging +import math +import urllib.request +from datetime import datetime +from io import BytesIO +from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton +from utils import mask_email, mask_account_id, bool_to_emoji, country_to_flag +from user import RiftUser +from cosmetic import FortniteCosmetic +from epic_auth import EpicUser, EpicEndpoints, EpicGenerator, LockerData + +def escape_markdown(text): + """ + Escapes special characters for markdown formatting + @note: sometimes external connections shows error due to these, so we handle it that way + """ + escape_chars = ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'] + for char in escape_chars: + text = text.replace(char, f"\\{char}") + + return text + +class FortniteCache: + def __init__(self): + self.cache = {} + self.cache_dir = "cache" + if not os.path.exists(self.cache_dir): + os.makedirs(self.cache_dir) + + self.load_cache_from_directory() + + def load_cache_from_directory(self): + for filename in os.listdir(self.cache_dir): + if filename.endswith(".png"): + id = os.path.splitext(filename)[0] + file_path = os.path.join(self.cache_dir, filename) + try: + image = Image.open(file_path).convert('RGBA') + self.cache[id] = image + except Exception as e: + continue + + def get_cosmetic_icon_from_cache(self, url, id): + if not url: + print(f"Error: No URL provided for ID: {id}") + return None + + cache_path = os.path.join(self.cache_dir, f"{id}.png") + if id in self.cache: + return self.cache[id] + + if os.path.exists(cache_path): + # getting the icon from filesystem + try: + image = Image.open(cache_path).convert('RGBA') + self.cache[id] = image + return image + except Exception as e: + print(f"Error loading {cache_path}: {e}") + + try: + # downloading the icon from url + with urllib.request.urlopen(url) as response: + image_data = response.read() + image = Image.open(BytesIO(image_data)).convert('RGBA') + try: + image.save(cache_path) + except Exception as e: + print(f"Error saving {cache_path}: {e}") + + self.cache[id] = image + return image + except Exception as e: + print(f"Error downloading image from {url}: {e}") + return None + +# global members +fortnite_cache = FortniteCache() + +available_styles = [ + {"ID": 0, "name": "Rift", "image": "img/styles/rift.png"}, + {"ID": 1, "name": "Easy", "image": "img/styles/easy.png"}, + {"ID": 2, "name": "Raika", "image": "img/styles/raika.png"}, + {"ID": 3, "name": "kayy", "image": "img/styles/kayy.png"}, + {"ID": 4, "name": "Storm", "image": "img/styles/storm.png"} +] + +avaliable_badges = [ + {"name": "Alpha Tester 1", "data": "alpha_tester_1_badge", "data2": "alpha_tester_1_badge_active", "image": "badges/icon/alpha1.png"}, + {"name": "Alpha Tester 2", "data": "alpha_tester_2_badge", "data2": "alpha_tester_2_badge_active", "image": "badges/icon/alpha2.png"}, + {"name": "Alpha Tester 3", "data": "alpha_tester_3_badge", "data2": "alpha_tester_3_badge_active", "image": "badges/icon/alpha3.png"}, + {"name": "Epic Games", "data": "epic_badge", "data2": "epic_badge_active", "image": "badges/icon/epic.png"} +] + +locker_categories = ['AthenaCharacter', 'AthenaBackpack', 'AthenaPickaxe', 'AthenaDance', 'AthenaGlider', 'AthenaPopular', 'AthenaExclusive'] +# global members + + + +def draw_gradient_text(gradient_type, draw, position, text, font, fill=(255, 255, 255)): + """ + Draw text with a rainbow gradient at a given position. + + :param gradient_type: The gradient we use to render the text as. + :param draw: ImageDraw object to draw on. + :param position: Tuple (x, y) of the position where the text starts. + :param text: Text to draw. + :param font: Font object to use for the text. + :param fill: the color in RGB in base to draw + """ + + num_colors = len(text) + if gradient_type == 0: + # white text(no gradient) + gradient_colors = [(255, 255, 255)] * num_colors + + elif gradient_type == 1: + # rainbow gradient + gradient_colors = [ + tuple(int(c * 255) for c in colorsys.hsv_to_rgb(i / num_colors, 1, 1)) + for i in range(num_colors) + ] + + elif gradient_type == 2: + # golden gradient + gradient_colors = [ + tuple(int(c * 255) for c in colorsys.hsv_to_rgb(0.13, 0.5 + (i / num_colors) * 0.5, 0.8 + (i / num_colors) * 0.2)) + for i in range(num_colors) + ] + + elif gradient_type == 3: + # silver gradient + gradient_colors = [ + tuple(int(c * 255) for c in colorsys.hsv_to_rgb(0, 0 + (i / num_colors) * 0.2, 0.6 + (i / num_colors) * 0.4)) + for i in range(num_colors) + ] + + x, y = position + for i, char in enumerate(text): + color = gradient_colors[i] + char_width = font.getbbox(char)[2] + draw.text((x, y), char, font=font, fill=color) + x += char_width + + +def render_rift_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding = 30 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width) + image_height = int(thumbnail_height + 5 + thumbnail_width * num_rows + 180) + font_path = 'styles/rift/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (0, 0, 0)) + + # custom background + custom_background_path = f"users/backgrounds/{user_data['ID']}.png" + if os.path.isfile(custom_background_path): + custom_background = Image.open(custom_background_path).resize((image_width, image_height), Image.Resampling.BILINEAR) + image.paste(custom_background, (0, 0)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + # top + icon_logo = Image.open(f'cosmetic_icons/{header}.png') + icon_logo.thumbnail((thumbnail_width, thumbnail_height)) + image.paste(icon_logo, (5, 0), mask=icon_logo) + draw.text((thumbnail_width + 12, 14), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(0, 0, 0)) # shadow + draw.text((thumbnail_width + 12, 82), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((thumbnail_width + 8, 10), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(255, 255, 255)) + draw.text((thumbnail_width + 8, 78), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(200, 200, 200)) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/rift/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/rift/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 28), (0, 0, 0, 100)) + photo.paste(box, (0, new_img.size[1] - 28), mask=box) + + if header != "Exclusives" and cosmetic.cosmetic_id in popular_cosmetics: + star_image = Image.open('cosmetic_icons/WantedStar.png').resize((128, 128), Image.BILINEAR) + photo.paste(star_image, (0, 0), star_image.convert("RGBA")) + + x = thumbnail_width * current_column + y = thumbnail_width + thumbnail_height * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name.upper() + max_text_width = thumbnail_width - 10 + max_text_height = 20 + + # fixed font size + font_size = 16 + offset = 9 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset += 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - padding + offset)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%B %d, %Y') + + # custom logo + custom_logo_path = f"users/logos/{user_data['ID']}.png" + if os.path.isfile(custom_logo_path): + custom_logo = Image.open(custom_logo_path).resize((150, 150), Image.Resampling.BILINEAR) + image.paste(custom_logo, (10, image_height - 165), mask=custom_logo) + else: + # original logo if not found + logo = Image.open('img/logo.png').resize((150, 150), Image.Resampling.BILINEAR) + image.paste(logo, (10, image_height - 165), mask=logo) + + draw.text((174, image_height - 40 * 3 - 24), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 40 * 3 - 28), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + draw.text((174, image_height - 40 * 2 - 24), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw_gradient_text(user_data['gradient_type'], draw, (170, image_height - 40 * 2 - 28), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40)) + # badges + font_size = 40 + font = ImageFont.truetype(font_path, font_size) + username_width = font.getbbox(f"@{user_data['username']}")[2] + offset_badge = 170 + username_width + 8 + + if user_data['epic_badge_active'] == True and user_data['epic_badge'] == True: + # epic games badge(special people only) + alpha_badge = Image.open('badges/epic.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_3_badge_active'] == True and user_data['alpha_tester_3_badge'] == True: + # alpha tester 3 badge + alpha_badge = Image.open('badges/alpha3.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_2_badge_active'] == True and user_data['alpha_tester_2_badge'] == True: + # alpha tester 2 badge + alpha_badge = Image.open('badges/alpha2.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_1_badge_active'] == True and user_data['alpha_tester_1_badge'] == True: + # alpha tester 1 badge + alpha_badge = Image.open('badges/alpha1.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + draw.text((174, image_height - 61), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 65), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + image.save(nametosave) + +def render_easy_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding_height = 10 + padding_width = 50 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width + padding_width * 2) + image_height = int(padding_width + (padding_height + thumbnail_width) * num_rows + padding_width * 2) + font_path = 'styles/easy/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (58, 58, 58)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + # cosmetics count + cosmetics = '{} count: {}'.format(header, len(arr)) + max_text_width = image_width - 20 + max_text_height = 40 + min_font_size = 10 + + font_size = 40 + while True: + bbox = draw.textbbox((0, 0), cosmetics, font=font) + text_width = bbox[2] - bbox[0] + text_height = bbox[3] - bbox[1] + + if text_width > max_text_width or font_size > image_height - 2: + font_size -= 1 + if font_size < min_font_size: + font_size = min_font_size + break + font = ImageFont.truetype(font_path, font_size) + else: + break + + + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), cosmetics, font=font) + text_width = bbox[2] - bbox[0] + text_x = (image_width - text_width) // 2 + draw.text((text_x, 9), cosmetics, font=font, fill=(255, 255, 255)) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull_old.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/easy/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/easy/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 20), (0, 0, 0, 75)) + photo.paste(box, (0, new_img.size[1] - 40), mask=box) + + border = Image.open(f'styles/easy/border/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + photo.paste(border, mask=border) + + x = padding_width + thumbnail_width * current_column + y = padding_width + (thumbnail_height + padding_height) * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name + max_text_width = thumbnail_width - 10 + max_text_height = 20 + offset_y = 38 + font_size = 18 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset_y -= 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - offset_y)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%d/%m/%Y') + footer = 'Submitted by @{} on {}'.format(user_data['username'], current_date) + max_text_width = image_width - 20 + max_text_height = 40 + min_font_size = 15 + + font_size = 40 + while True: + bbox = draw.textbbox((0, 0), footer, font=font) + text_width = bbox[2] - bbox[0] + text_height = bbox[3] - bbox[1] + + if text_width > max_text_width or font_size > image_height - 2: + font_size -= 1 + if font_size < min_font_size: + font_size = min_font_size + break + + font = ImageFont.truetype(font_path, font_size) + else: + break + + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), footer, font=font) + text_width = bbox[2] - bbox[0] + text_x = (image_width - text_width) // 2 + text_y = image_height - font_size - 52 + draw.text((text_x, text_y), footer, font=font, fill=(255, 255, 255)) + + # bot advertisment + footer2 = 't.me/RiftCheckerBot' + max_text_width = image_width - 20 + max_text_height = 40 + min_font_size = 15 + + font_size = 40 + while True: + bbox = draw.textbbox((0, 0), footer2, font=font) + text_width = bbox[2] - bbox[0] + text_height = bbox[3] - bbox[1] + + if text_width > max_text_width or font_size > image_height - 2: + font_size -= 1 + if font_size < min_font_size: + font_size = min_font_size + break + + font = ImageFont.truetype(font_path, font_size) + else: + break + + + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), footer2, font=font) + text_width = bbox[2] - bbox[0] + text_x = (image_width - text_width) // 2 + text_y = image_height - font_size - 8 + draw.text((text_x, text_y), footer2, font=font, fill=(255, 255, 255)) + + image.save(nametosave) + +def render_raika_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding = 30 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width) + image_height = int(thumbnail_height + 5 + thumbnail_width * num_rows + 180) + font_path = 'styles/raika/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (0, 0, 0)) + + # custom background + custom_background_path = f"users/backgrounds/{user_data['ID']}.png" + if os.path.isfile(custom_background_path): + custom_background = Image.open(custom_background_path).resize((image_width, image_height), Image.Resampling.BILINEAR) + image.paste(custom_background, (0, 0)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + # top + icon_logo = Image.open(f'cosmetic_icons/{header}.png') + icon_logo.thumbnail((thumbnail_width, thumbnail_height)) + image.paste(icon_logo, (5, 0), mask=icon_logo) + draw.text((thumbnail_width + 12, 14), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(0, 0, 0)) # shadow + draw.text((thumbnail_width + 12, 82), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((thumbnail_width + 8, 10), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(255, 255, 255)) + draw.text((thumbnail_width + 8, 78), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(200, 200, 200)) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull_old.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/raika/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/raika/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 28), (0, 0, 0, 100)) + photo.paste(box, (0, new_img.size[1] - 28), mask=box) + + if header != "Exclusives" and cosmetic.cosmetic_id in popular_cosmetics: + star_image = Image.open('cosmetic_icons/WantedStar.png').resize((128, 128), Image.BILINEAR) + photo.paste(star_image, (0, 0), star_image.convert("RGBA")) + + x = thumbnail_width * current_column + y = thumbnail_width + thumbnail_height * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name.upper() + max_text_width = thumbnail_width - 10 + max_text_height = 20 + + # fixed font size + font_size = 16 + offset = 6 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset += 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - padding + offset)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%B %d, %Y') + + # custom logo + custom_logo_path = f"users/logos/{user_data['ID']}.png" + if os.path.isfile(custom_logo_path): + custom_logo = Image.open(custom_logo_path).resize((150, 150), Image.Resampling.BILINEAR) + image.paste(custom_logo, (10, image_height - 165), mask=custom_logo) + else: + # original logo if not found + logo = Image.open('img/logo.png').resize((150, 150), Image.Resampling.BILINEAR) + image.paste(logo, (10, image_height - 165), mask=logo) + + draw.text((174, image_height - 40 * 3 - 24), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 40 * 3 - 28), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + draw.text((174, image_height - 40 * 2 - 24), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw_gradient_text(user_data['gradient_type'], draw, (170, image_height - 40 * 2 - 28), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40)) + + # badges + font_size = 40 + font = ImageFont.truetype(font_path, font_size) + username_width = font.getbbox(f"@{user_data['username']}")[2] + offset_badge = 170 + username_width + 8 + + if user_data['epic_badge_active'] == True and user_data['epic_badge'] == True: + # epic games badge(special people only) + alpha_badge = Image.open('badges/epic.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_3_badge_active'] == True and user_data['alpha_tester_3_badge'] == True: + # alpha tester 3 badge + alpha_badge = Image.open('badges/alpha3.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_2_badge_active'] == True and user_data['alpha_tester_2_badge'] == True: + # alpha tester 2 badge + alpha_badge = Image.open('badges/alpha2.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_1_badge_active'] == True and user_data['alpha_tester_1_badge'] == True: + # alpha tester 1 badge + alpha_badge = Image.open('badges/alpha1.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + draw.text((174, image_height - 61), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 65), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + image.save(nametosave) + +def render_kayy_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding = 30 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width) + image_height = int(thumbnail_width * num_rows + 180) + font_path = 'styles/kayy/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (0, 0, 0)) + + # custom background + custom_background_path = f"users/backgrounds/{user_data['ID']}.png" + if os.path.isfile(custom_background_path): + custom_background = Image.open(custom_background_path).resize((image_width, image_height), Image.Resampling.BILINEAR) + image.paste(custom_background, (0, 0)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull_old.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/kayy/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/kayy/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 28), (0, 0, 0, 100)) + photo.paste(box, (0, new_img.size[1] - 28), mask=box) + + if header != "Exclusives" and cosmetic.cosmetic_id in popular_cosmetics: + star_image = Image.open('cosmetic_icons/WantedStar.png').resize((128, 128), Image.BILINEAR) + photo.paste(star_image, (0, 0), star_image.convert("RGBA")) + + x = thumbnail_width * current_column + y = thumbnail_height * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name.upper() + max_text_width = thumbnail_width - 10 + max_text_height = 20 + + # fixed font size + font_size = 16 + offset = 9 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset += 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - padding + offset)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%d/%m/%Y') + + # custom logo + custom_logo_path = f"users/logos/{user_data['ID']}.png" + if os.path.isfile(custom_logo_path): + custom_logo = Image.open(custom_logo_path).resize((150, 150), Image.Resampling.BILINEAR) + image.paste(custom_logo, (10, image_height - 165), mask=custom_logo) + else: + # original logo if not found + logo = Image.open('img/logo.png').resize((150, 150), Image.Resampling.BILINEAR) + image.paste(logo, (10, image_height - 165), mask=logo) + + draw.text((174, image_height - 40 * 3 - 24), 'Objects Total: {}'.format(len(arr)), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) # shadow + draw.text((170, image_height - 40 * 3 - 28), 'Objects Total: {}'.format(len(arr)), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + draw.text((174, image_height - 40 * 2 - 24), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) # shadow + draw_gradient_text(user_data['gradient_type'], draw, (170, image_height - 40 * 2 - 28), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40)) + + # badges + font_size = 40 + font = ImageFont.truetype(font_path, font_size) + username_width = font.getbbox(f"@{user_data['username']}")[2] + offset_badge = 170 + username_width + 8 + + if user_data['epic_badge_active'] == True and user_data['epic_badge'] == True: + # epic games badge(special people only) + alpha_badge = Image.open('badges/epic.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_3_badge_active'] == True and user_data['alpha_tester_3_badge'] == True: + # alpha tester 3 badge + alpha_badge = Image.open('badges/alpha3.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_2_badge_active'] == True and user_data['alpha_tester_2_badge'] == True: + # alpha tester 2 badge + alpha_badge = Image.open('badges/alpha2.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_1_badge_active'] == True and user_data['alpha_tester_1_badge'] == True: + # alpha tester 1 badge + alpha_badge = Image.open('badges/alpha1.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + draw.text((offset_badge + 10, image_height - 40 * 2 - 26), '| {}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((offset_badge + 8, image_height - 40 * 2 - 28), '| {}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + draw.text((174, image_height - 61), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 65), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + image.save(nametosave) + +def render_storm_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding = 30 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width) + image_height = int(thumbnail_width * num_rows + 180) + font_path = 'styles/storm/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (0, 0, 0)) + + # custom background + custom_background_path = f"users/backgrounds/{user_data['ID']}.png" + if os.path.isfile(custom_background_path): + custom_background = Image.open(custom_background_path).resize((image_width, image_height), Image.Resampling.BILINEAR) + image.paste(custom_background, (0, 0)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull_old.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/storm/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/storm/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 28), (0, 0, 0, 100)) + photo.paste(box, (0, new_img.size[1] - 28), mask=box) + + if header != "Exclusives" and cosmetic.cosmetic_id in popular_cosmetics: + star_image = Image.open('cosmetic_icons/WantedStar.png').resize((128, 128), Image.BILINEAR) + photo.paste(star_image, (0, 0), star_image.convert("RGBA")) + + x = thumbnail_width * current_column + y = thumbnail_height * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name.upper() + max_text_width = thumbnail_width - 10 + max_text_height = 20 + + # fixed font size + font_size = 16 + offset = 9 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset += 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - padding + offset)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%d %B %Y') + + # custom logo + custom_logo_path = f"users/logos/{user_data['ID']}.png" + if os.path.isfile(custom_logo_path): + custom_logo = Image.open(custom_logo_path).resize((150, 150), Image.Resampling.BILINEAR) + image.paste(custom_logo, (10, image_height - 165), mask=custom_logo) + else: + # original logo if not found + logo = Image.open('img/logo.png').resize((150, 150), Image.Resampling.BILINEAR) + image.paste(logo, (10, image_height - 165), mask=logo) + + draw.text((174, image_height - 40 * 3 - 24), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 40 * 3 - 28), '{}'.format(current_date), font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + draw.text((174, image_height - 40 * 2 - 24), 'Submitted by ', font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw_gradient_text(0, draw, (170, image_height - 40 * 2 - 28), 'Submitted by ', font=ImageFont.truetype(font_path, 40)) + + # badges + font_size = 40 + font = ImageFont.truetype(font_path, font_size) + submit_width = font.getbbox(f"Submitted by")[2] + offset_submit = 170 + submit_width + 8 + username_width = font.getbbox(f"Submitted by @{user_data['username']}")[2] + offset_badge = 170 + username_width + 8 + + if user_data['epic_badge_active'] == True and user_data['epic_badge'] == True: + # epic games badge(special people only) + alpha_badge = Image.open('badges/epic.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_3_badge_active'] == True and user_data['alpha_tester_3_badge'] == True: + # alpha tester 3 badge + alpha_badge = Image.open('badges/alpha3.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_2_badge_active'] == True and user_data['alpha_tester_2_badge'] == True: + # alpha tester 2 badge + alpha_badge = Image.open('badges/alpha2.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + if user_data['alpha_tester_1_badge_active'] == True and user_data['alpha_tester_1_badge'] == True: + # alpha tester 1 badge + alpha_badge = Image.open('badges/alpha1.png').resize((40, 40), Image.BILINEAR) + image.paste(alpha_badge, (offset_badge, image_height - 40 * 2 - 28), alpha_badge.convert("RGBA")) + offset_badge += 45 + + draw.text((offset_submit + 2, image_height - 40 * 2 - 26), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw_gradient_text(user_data['gradient_type'], draw, (offset_submit, image_height - 40 * 2 - 28), '@{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 40)) + draw.text((174, image_height - 61), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((170, image_height - 65), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 40), fill=(255, 255, 255)) + image.save(nametosave) + +def render_aqua_style(header:str, user_data: json, arr: list[str], nametosave:str) -> None: + # calculating cosmetics per row + cosmetic_per_row = 6 + total_cosmetics = len(arr) + num_rows = math.ceil(total_cosmetics / cosmetic_per_row) + if total_cosmetics > 30: + num_rows = int(math.sqrt(total_cosmetics)) + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + while cosmetic_per_row * num_rows < total_cosmetics: + num_rows += 1 + cosmetic_per_row = math.ceil(total_cosmetics / num_rows) + + # setup for our image, thumbnails + padding = 30 + padding_height = 2 + thumbnail_width = 128 + thumbnail_height = 128 + image_width = int(cosmetic_per_row * thumbnail_width) + image_height = int(thumbnail_height + 5 + (num_rows * (padding_height + thumbnail_height)) + 140) + font_path = 'styles/aqua/font.ttf' + font_size = 16 + font = ImageFont.truetype(font_path, font_size) + image = Image.new('RGB', (image_width, image_height), (0, 0, 0)) + + current_row = 0 + current_column = 0 + sortarray = ['mythic', 'legendary', 'dark', 'slurp', 'starwars', 'marvel', 'lava', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common'] + arr.sort(key=lambda x: sortarray.index(x.rarity_value)) + + # had some issues with exclusives rendering in wrong order, so i'm sorting them + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Error: 'exclusive.txt' or 'most_wanted.txt' not found.") + exclusive_cosmetics = [] + popular_cosmetics = [] + + mythic_items = [item for item in arr if item.rarity_value == 'mythic'] + other_items = [item for item in arr if item.rarity_value != 'mythic'] + mythic_items.sort( + key=lambda x: exclusive_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in exclusive_cosmetics else float('inf') + ) + + if header == "Popular": + other_items.sort( + key=lambda x: popular_cosmetics.index(x.cosmetic_id) + if x.cosmetic_id in popular_cosmetics else float('inf') + ) + + arr = mythic_items + other_items + draw = ImageDraw.Draw(image) + + # top + icon_logo = Image.open(f'cosmetic_icons/{header}.png').resize((128, 128), Image.Resampling.BILINEAR) + icon_logo.thumbnail((thumbnail_width, thumbnail_height)) + image.paste(icon_logo, (10, 5), mask=icon_logo) + draw.text((162, 30), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(0, 0, 0)) # shadow + draw.text((166, 87), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(0, 0, 0)) # shadow + draw.text((162, 26), '{}'.format(len(arr)), font=ImageFont.truetype(font_path, 70), fill=(255, 255, 255)) + draw.text((166, 83), '{}'.format(header), font=ImageFont.truetype(font_path, 40), fill=(167, 167, 167)) + + special_items = { + "CID_029_Athena_Commando_F_Halloween": "cache/pink_ghoul.png", + "CID_030_Athena_Commando_M_Halloween": "cache/purple_skull_old.png", + "CID_116_Athena_Commando_M_CarbideBlack": "cache/omega_max.png", + "CID_694_Athena_Commando_M_CatBurglar": "cache/gold_midas.png", + "CID_693_Athena_Commando_M_BuffCat": "cache/gold_cat.png", + "CID_691_Athena_Commando_F_TNTina": "cache/gold_tntina.png", + "CID_690_Athena_Commando_F_Photographer": "cache/gold_skye.png", + "CID_701_Athena_Commando_M_BananaAgent": "cache/gold_peely.png", + "CID_315_Athena_Commando_M_TeriyakiFish": "cache/worldcup_fish.png", + "CID_971_Athena_Commando_M_Jupiter_S0Z6M": "cache/black_masterchief.png", + "CID_028_Athena_Commando_F": "cache/og_rene.png", + "CID_017_Athena_Commando_M": "cache/og_aat.png" + } + + for cosmetic in arr: + special_icon = False + is_banner = cosmetic.is_banner + photo = None + if cosmetic.rarity_value.lower() == "mythic" and cosmetic.cosmetic_id in special_items: + special_icon = True + icon_path = special_items[cosmetic.cosmetic_id] + if os.path.exists(icon_path): + try: + photo = Image.open(icon_path) + except Exception as e: + special_icon = False + else: + special_icon = False + else: + photo = fortnite_cache.get_cosmetic_icon_from_cache(cosmetic.small_icon, cosmetic.cosmetic_id) + + if is_banner: + scaled_width = int(photo.width * 1.5) + scaled_height = int(photo.height * 1.5) + photo = photo.resize((scaled_width, scaled_height), Image.Resampling.LANCZOS) + x_offset = 32 + y_offset = 10 + + new_img = Image.open(f'styles/aqua/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA') + new_img.paste(photo, (x_offset, y_offset), mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + else: + new_img = Image.open(f'styles/aqua/rarity/{cosmetic.rarity_value.lower()}.png').convert('RGBA').resize(photo.size) + new_img.paste(photo, mask=photo) + photo = new_img + photo.thumbnail((thumbnail_width, thumbnail_height)) + + # black box for cosmetic name + box = Image.new('RGBA', (128, 27), (0, 0, 0, 100)) + photo.paste(box, (0, new_img.size[1] - 27), mask=box) + + if header != "Exclusives" and cosmetic.cosmetic_id in popular_cosmetics: + star_image = Image.open('cosmetic_icons/WantedStar.png').resize((128, 128), Image.BILINEAR) + photo.paste(star_image, (0, 0), star_image.convert("RGBA")) + + x = thumbnail_width * current_column + y = thumbnail_width + (thumbnail_height + padding_height) * current_row + image.paste(photo, (x, y)) + + name = cosmetic.name.upper() + max_text_width = thumbnail_width - 10 + max_text_height = 20 + + # fixed font size + font_size = 16 + offset = 6 + while True: + font = ImageFont.truetype(font_path, font_size) + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + name_height = bbox[3] - bbox[1] + + if name_width > max_text_width or name_height > max_text_height: + font_size -= 1 + offset += 0.5 + else: + break + + # cosmetic name + bbox = draw.textbbox((0, 0), name, font=font) + name_width = bbox[2] - bbox[0] + draw.text((x + (thumbnail_width - name_width) // 2, y + (thumbnail_height - padding + offset)), name, font=font, fill=(255, 255, 255)) + + # make the cosmetics show ordered in rows(cosmetic_per_row is hardcoded) + current_column += 1 + if current_column >= cosmetic_per_row: + current_row += 1 + current_column = 0 + + # footer + current_date = datetime.now().strftime('%d %B %Y') + + # custom logo + custom_logo_path = f"users/logos/{user_data['ID']}.png" + if os.path.isfile(custom_logo_path): + custom_logo = Image.open(custom_logo_path).resize((125, 125), Image.Resampling.BILINEAR) + image.paste(custom_logo, (25, image_height - 140), mask=custom_logo) + else: + # original logo if not found + logo = Image.open('img/logo.png').resize((125, 125), Image.Resampling.BILINEAR) + image.paste(logo, (25, image_height - 140), mask=logo) + + draw.text((179, image_height - 114), '{}'.format(current_date), font=ImageFont.truetype(font_path, 30), fill=(0, 0, 0)) # shadow + draw.text((175, image_height - 118), '{}'.format(current_date), font=ImageFont.truetype(font_path, 30), fill=(255, 255, 255)) + draw.text((179, image_height - 84), 'Submitted By: @{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 30), fill=(0, 0, 0)) # shadow + draw.text((175, image_height - 88), 'Submitted By: @{}'.format(user_data['username']), font=ImageFont.truetype(font_path, 30), fill=(255, 255, 255)) + draw.text((179, image_height - 31), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 20), fill=(0, 0, 0)) # shadow + draw.text((175, image_height - 55), "t.me/RiftCheckerBot", font=ImageFont.truetype(font_path, 20), fill=(255, 255, 255)) + image.save(nametosave) + + + +def command_start(bot, message): + if message.chat.type != "private": + return + + user = RiftUser(message.from_user.id, message.from_user.username) + user_data = user.register() + if not user_data: + bot.reply_to(message, "You have already used this command, you don't have to use it anymore!") + return + + bot.reply_to(message, f''' +What is Rift Checker Bot? +> Rift checker is provably safe open-sourced telegram fortnite skin checker bot, it visualises your locker into an image and sends it back to you, aswell it does display info about your account. + +Why should we use Rift and not other skincheckers? +> Unlike majority of skincheckers, we make NO profit from our service, the bot is entirely hosted by choice, as well unlike Raika we DO NOT store your account information anywhere, for security reasons all account credentials are private and inaccessible. + +How do i know you're not stealing our accounts? +> Rift checker is open-sourced bot, if you don't believe that it's safe, you could check the source code yourself to make sure that rift is completely safe! +> Rift Checker's Official Github Repository: https://github.com/Debugtopia/RiftCheckerBot +> Yes, you could use rift's source code to create your own bot aswell! just make to credit @xhexago for his work :) + +> Other open sourced projects by @xhexago: + - GrowBase(Growtopia Private Server - Game Server source code): https://github.com/Debugtopia/GrowBase + +Who are the developers of Rift Checker Bot? +> Rift is a single-handedly developed by @xhexago and nobody else. + +Commands: +/start - register to rift checker +/help - displays info about the bot, it's commands. +/login - skincheck your epic games fortnite account. +/style - choose your style based on your need, we support multiple skincheck styles. +/badges - toggle your achieved badges on your skincheck. +/stats - shows statistics of how many accounts have u checked with our bot or the badges you have enabled. +''') + + markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔗 Source Code", url="https://github.com/Debugtopia/RiftCheckerBot")], + [InlineKeyboardButton("🔗 Stock Channel", url="https://t.me/riftstock"), + InlineKeyboardButton("🔗 News Channel", url="https://t.me/RiftCheckerNews")] + ]) + + bot.send_message( + chat_id=message.chat.id, + text=( + "Welcome to Rift Checker Bot!\n" + "Developed by @xhexago\n" + "Interested in purchasing Fortnite accounts?\n" + "- @riftstock\n\n" + "Rift Checker Bot's News channel:\n" + "- @riftcheckernews" + ), + reply_markup=markup, + parse_mode="Markdown" + ) + +def command_help(bot, message): + bot.reply_to(message, f''' +What is Rift Checker Bot? +> Rift checker is provably safe open-sourced telegram fortnite skin checker bot, it visualises your locker into an image and sends it back to you, aswell it does display info about your account. + +Why should we use Rift and not other skincheckers? +> Unlike majority of skincheckers, we make NO profit from our service, the bot is entirely hosted by choice, as well unlike Raika we DO NOT store your account information anywhere, for security reasons all account credentials are private and inaccessible. + +How do i know you're not stealing our accounts? +> Rift checker is open-sourced bot, if you don't believe that it's safe, you could check the source code yourself to make sure that rift is completely safe! +> Rift Checker's Official Github Repository: https://github.com/Debugtopia/RiftCheckerBot +> Yes, you could use rift's source code to create your own bot aswell! just make to credit @xhexago for his work :) + +> Other open sourced projects by @xhexago: + - GrowBase(Growtopia Private Server - Game Server source code): https://github.com/Debugtopia/GrowBase + +Who are the developers of Rift Checker Bot? +> Rift is a single-handedly developed by @xhexago and nobody else. + +Commands: +/start - register to rift checker +/help - displays info about the bot, it's commands. +/login - skincheck your epic games fortnite account. +/style - choose your style based on your need, we support multiple skincheck styles. +/badges - toggle your achieved badges on your skincheck. +/stats - shows statistics of how many accounts have u checked with our bot or the badges you have enabled. +''') + + markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔗 Source Code", url="https://github.com/Debugtopia/RiftCheckerBot")], + [InlineKeyboardButton("🔗 Stock Channel", url="https://t.me/riftstock"), + InlineKeyboardButton("🔗 News Channel", url="https://t.me/RiftCheckerNews")] + ]) + + bot.send_message( + chat_id=message.chat.id, + text=( + "Welcome to Rift Checker Bot!\n" + "Developed by @xhexago\n" + "Interested in purchasing Fortnite accounts?\n" + "- @riftstock\n\n" + "Rift Checker Bot's News channel:\n" + "- @riftcheckernews" + ), + reply_markup=markup, + parse_mode="Markdown" + ) + +async def command_login(bot, message): + if message.chat.type != "private": + return + + user = RiftUser(message.from_user.id, message.from_user.username) + user_data = user.load_data() + if user_data == {}: + bot.reply_to(message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + msg = bot.reply_to(message, "⏳ Creating authorization login link...") + epic_generator = EpicGenerator() + await epic_generator.start() + device_data = await epic_generator.create_device_code() + epic_games_auth_link = f"https://www.epicgames.com/activate?userCode={device_data['user_code']}" + + # login link message(embed link button) + markup = InlineKeyboardMarkup() + button = InlineKeyboardButton("🔗 Login", url=epic_games_auth_link) + markup.add(button) + bot.edit_message_text( + chat_id=msg.chat.id, + message_id=msg.message_id, + text=f"Open [this link](<{epic_games_auth_link}>) to log in to your account.", + reply_markup=markup, + parse_mode="Markdown") + + epic_user = await epic_generator.wait_for_device_code_completion(bot, message, code=device_data['device_code']) + if not epic_user: + # something went wrong so we can't check the account + await epic_generator.kill() + return + + account_data = await epic_generator.get_account_metadata(epic_user) + + accountID = account_data.get('id', "INVALID_ACCOUNT_ID") + if (accountID == "INVALID_ACCOUNT_ID"): + bot.edit_message_text(chat_id=msg.chat.id, message_id=msg.message_id, text="Invalid account(banned or fortnite has not been launched).") + return + + bot.delete_message(msg.chat.id, msg.message_id) + msg = bot.send_message(message.chat.id, f'✅ Logged in account {account_data.get("displayName", "HIDDEN_ID_ACCOUNT")}') + + # account information + account_public_data = await epic_generator.get_public_account_info(epic_user) + bot.send_message(message.chat.id,f''' +━━━━━━━━━━━ +Account Information +━━━━━━━━━━━ +#️⃣ Account ID: {mask_account_id(accountID)} +📧 Email: {mask_email(account_data.get('email', ''))} +🧑‍🦱 Display Name: {account_data.get('displayName', 'DeletedUser')} +📛 Full Name: {account_data.get('name', '')} {account_data.get('lastName', '')} +🌐 Country: {account_data.get('country', 'US')} {country_to_flag(account_data.get('country', 'US'))} +🔐 Email Verified: {bool_to_emoji(account_data.get('emailVerified', False))} +🔒 Mandatory 2FA Security: {bool_to_emoji(account_data.get('tfaEnabled', False))} +''') + + # external connections + connected_accounts = 0 + connected_accounts_message = f""" +━━━━━━━━━━━ +Connected Account +━━━━━━━━━━━\n""" + + external_auths = account_public_data.get('externalAuths', []) + for auth in external_auths: + auth_type = auth.get('type', '?').lower() + display_name = auth.get('externalDisplayName', '?') + external_id = auth.get('externalAuthId', '?') + date_added = auth.get('dateAdded', '?') + if date_added != '?': + parsed_date = datetime.strptime(date_added, "%Y-%m-%dT%H:%M:%S.%fZ") + date_added = parsed_date.strftime("%d/%m/%Y") + + connected_accounts += 1 + connected_accounts_message += f""" +Connection Type: {escape_markdown(auth_type.upper())} +External Display Name: {escape_markdown(display_name)} +Date of Connection: {escape_markdown(date_added)} +""" + + if connected_accounts == 0: + connected_accounts_message += "No connected accounts." + + markup = InlineKeyboardMarkup() + button = InlineKeyboardButton("🔗 Remove Restrictions", url='https://www.epicgames.com/help/en/wizards/w4') + markup.add(button) + bot.send_message( + chat_id=msg.chat.id, + text=connected_accounts_message, + reply_markup=markup, + parse_mode="Markdown") + + # purchases infos + vbucks_categories = [ + "Currency:MtxPurchased", + "Currency:MtxEarned", + "Currency:MtxGiveaway", + "Currency:MtxPurchaseBonus" + ] + + total_vbucks = 0 + refunds_used = 0 + refund_credits = 0 + receipts = [] + vbucks_purchase_history = { + "1000": 0, + "2800": 0, + "5000": 0, + "7500": 0, + "13500": 0 + } + + gift_received = 0 + gift_sent = 0 + pending_gifts_amount = 0 + + common_profile_data = await epic_generator.get_common_profile(epic_user) + for item_id, item_data in common_profile_data.get("profileChanges", [{}])[0].get("profile", {}).get("items", {}).items(): + if item_data.get("templateId") in vbucks_categories: + # getting vbucks + total_vbucks += item_data.get("quantity", 0) + + for profileChange in common_profile_data.get("profileChanges", []): + attributes = profileChange["profile"]["stats"]["attributes"] + mtx_purchases = attributes.get("mtx_purchase_history", {}) + if mtx_purchases: + refunds_used = mtx_purchases.get("refundsUsed", 0) + refund_credits = mtx_purchases.get("refundCredits", 0) + + iap = attributes.get("in_app_purchases", {}) + if iap: + receipts = iap.get("receipts", []) + purchases = iap.get("fulfillmentCounts", {}) + if purchases: + # vbucks purchases packs amount + vbucks_purchase_history["1000"] = purchases.get("FN_1000_POINTS", 0) + vbucks_purchase_history["2800"] = purchases.get("FN_2800_POINTS", 0) + vbucks_purchase_history["5000"] = purchases.get("FN_5000_POINTS", 0) + vbucks_purchase_history["7500"] = purchases.get("FN_7500_POINTS", 0) + vbucks_purchase_history["13500"] = purchases.get("FN_13500_POINTS", 0) + + gift_history = attributes.get("gift_history", {}) + if gift_history: + # pending gifts count + gifts_pending = gift_history.get("gifts", []) + pending_gifts_amount = len(gifts_pending) + + # gifts sent & received count + gift_sent = gift_history.get("num_sent", 0) + gift_received = gift_history.get("num_received", 0) + + total_vbucks_bought = 1000 * vbucks_purchase_history["1000"] + 2800 * vbucks_purchase_history["2800"] + 5000 * vbucks_purchase_history["5000"] + 7500 * vbucks_purchase_history["7500"] + 13500 * vbucks_purchase_history["13500"] + bot.send_message(message.chat.id,f''' +━━━━━━━━━━━ +Purchases Information +━━━━━━━━━━━ +💰 VBucks: {total_vbucks} +🎟 Refunds Used: {refunds_used} +🎟 Refund Tickets: {refund_credits} + +━━━━━━━━━━━ +Vbucks Purchases +━━━━━━━━━━━ +#️⃣ Receipts: {len(receipts)} +💰 1000 Vbucks Packs: {vbucks_purchase_history["1000"]} +💰 2800 Vbucks Packs: {vbucks_purchase_history["2800"]} +💰 5000 Vbucks Packs: {vbucks_purchase_history["5000"]} +💰 7500 Vbucks Packs: {vbucks_purchase_history["7500"]} +💰 13500 Vbucks Packs: {vbucks_purchase_history["13500"]} + +💰 Total Vbucks Purchased: {total_vbucks_bought} + +━━━━━━━━━━━ +Gifts Information +━━━━━━━━━━━ +🎁 Pending Gifts: {pending_gifts_amount} +🎁 Gifts Sent: {gift_sent} +🎁 Gifts Received: {gift_received} +''') + + # season history + seasons_msg = await epic_generator.get_seasons_message(epic_user) + bot.send_message(message.chat.id, seasons_msg) + + # locker data + locker_data = await epic_generator.get_locker_data(epic_user) + + # activity info + bot.send_message(message.chat.id,f''' +━━━━━━━━━━━ +Activity Information +━━━━━━━━━━━ +👪 Parental Control: {bool_to_emoji(account_data.get('minorVerified', False))} +🕘 Last Match: {locker_data.last_match} +🤯 Headless: {bool_to_emoji(account_data.get("headless", False))} +✏️ Display Name Changes: {account_data.get("numberOfDisplayNameChanges", 0)} +✏️ Display Name Changeable: {bool_to_emoji(account_data.get("canUpdateDisplayName", False))} +#️⃣ Hashed email: {bool_to_emoji(account_data.get("hasHashedEmail", False))} +''') + + bot.send_message(message.chat.id,f''' +━━━━━━━━━━━ +Locker Information +━━━━━━━━━━━ +🧍‍♂️ Outfits: {len(locker_data.cosmetic_array.get('AthenaCharacter', []))} +🎒 Backpacks: {len(locker_data.cosmetic_array.get('AthenaBackpack', []))} +⛏️ Pickaxes: {len(locker_data.cosmetic_array.get('AthenaPickaxe', []))} +🕺 Emotes: {len(locker_data.cosmetic_array.get('AthenaDance', []))} +✈️ Gliders: {len(locker_data.cosmetic_array.get('AthenaGlider', []))} +⭐ Most Wanted Cosmetics: {len(locker_data.cosmetic_array.get('AthenaPopular', []))} +🌟 Exclusives: {len(locker_data.cosmetic_array.get('AthenaExclusive', []))} +''') + + homebase_data = await epic_generator.get_homebase_profile(epic_user) + stats = homebase_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}) + if stats: + stw_level = 1 + research_offence = 1 + research_fortitude = 1 + research_resistance = 1 + research_tech = 1 + collection_book_level = 1 + stw_claimed = False + legacy_research_points = 0 + matches_played = 0 + + stats = homebase_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}) + if stats: + stw_level = stats.get("level", 1) + research_offence = stats.get("research_levels", {}).get("offence", 1) + research_fortitude = stats.get("research_levels", {}).get("fortitude", 1) + research_resistance = stats.get("research_levels", {}).get("resistance", 1) + research_tech = stats.get("research_levels", {}).get("technology", 1) + collection_book_level = stats.get("collection_book", {}).get("maxBookXpLevelAchieved", 1) + stw_claimed = stats.get("mfa_reward_claimed", False) + legacy_research_points = stats.get("legacy_research_points_spent", 0) + matches_played = stats.get("matches_played", 0) + bot.send_message(message.chat.id,f''' +━━━━━━━━━━━ +Homebase Information +━━━━━━━━━━━ +#️⃣ Level: {stw_level} +🎒 Collection Book Level: {collection_book_level} +🎁 Claimed Rewards: {bool_to_emoji(stw_claimed)} + +Research: +⭐ Total spent points: {legacy_research_points} +⛏️ Offence: {research_offence} +⚔️ Fortitude: {research_fortitude} +🪖 Resistance: {research_resistance} +🔧 Tech: {research_tech} + +Activity: +🎟 Matches Played: {matches_played} +''') + + # saved data path + # note: it only saves the rendered images for locker, data that DOES NOT contain private or login information!!! + save_path = f"accounts/{accountID}" + if not os.path.exists(save_path): + os.mkdir(save_path) + + for category in locker_categories: + if category not in locker_data.cosmetic_array or len(locker_data.cosmetic_array[category]) < 1: + continue + + header = 'Outfits' + if category == 'AthenaBackpack': + header = 'Backblings' + elif category == 'AthenaPickaxe': + header = 'Pickaxes' + elif category == 'AthenaDance': + header = 'Emotes' + elif category == 'AthenaGlider': + header = 'Gliders' + elif category == 'AthenaExclusive': + header = 'Exclusives' + elif category == 'AthenaPopular': + header = 'Popular' + + if user_data['style'] == 0: # rift style + render_rift_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + elif user_data['style'] == 1: # easy style + render_easy_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + elif user_data['style'] == 2: # raika style + render_raika_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + elif user_data['style'] == 3: # kayy style + render_kayy_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + elif user_data['style'] == 4: # storm style + render_storm_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + elif user_data['style'] == 5: # aqua style + render_aqua_style(header, user_data, locker_data.cosmetic_array[category], f'{save_path}/{category}.png') + + with open(f'{save_path}/{category}.png', 'rb') as photo_file: + file_size = os.path.getsize(f'{save_path}/{category}.png') + if file_size > 10 * 1024 * 1024: # 10 MBs + print("File too large for photo, sending as a document.") + bot.send_document(msg.chat.id, photo_file) + else: + bot.send_photo(msg.chat.id, photo_file) + + skins = len(locker_data.cosmetic_array['AthenaCharacter']) + excl = locker_data.cosmetic_array['AthenaExclusive'] + cosmetic_list = '' + desc = '' + cosmetics_listed = 0 + for cosmetic in excl: + cosmetic_list += cosmetic.name + " + " + cosmetics_listed += 1 + + if cosmetics_listed >= 10: + break + + cosmetic_list = cosmetic_list.rstrip(" + ") + desc = f'{skins} + {cosmetic_list} + {total_vbucks}VB' + bot.send_message(message.chat.id,f'{desc}') + await epic_generator.kill() + + # button-embed message + markup = InlineKeyboardMarkup([ + [InlineKeyboardButton("🔗 Source Code", url="https://github.com/Debugtopia/RiftCheckerBot")], + [InlineKeyboardButton("🔗 Rift Stock", url="https://t.me/riftstock"), + InlineKeyboardButton("🔗 News Channel", url="https://t.me/RiftCheckerNews")] + ]) + + bot.send_message( + chat_id=message.chat.id, + text=( + "Thanks for using Rift Checker Bot!\n" + "Developed by @xhexago\n" + "Interested in purchasing Fortnite accounts?\n" + "- @riftstock\n\n" + "Rift Checker Bot's News channel:\n" + "- @riftcheckernews" + ), + reply_markup=markup, + parse_mode="Markdown" + ) + + +async def command_style(bot, message): + if message.chat.type != "private": + return + + user = RiftUser(message.from_user.id, message.from_user.username) + user_data = user.load_data() + if not user_data: + bot.reply_to(message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + current_style_index = user_data['style'] + send_style_message(bot, message.chat.id, current_style_index) + +async def command_badges(bot, message): + if message.chat.type != "private": + return + + user = RiftUser(message.from_user.id, message.from_user.username) + user_data = user.load_data() + if not user_data: + bot.reply_to(message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + badges_unlocked = 0 + for badge in avaliable_badges: + if user_data[badge['data']] == True: + badges_unlocked += 1 + + if badges_unlocked < 1: + msg = bot.reply_to(message, "You don't have any badges unlocked.") + return + + current_badge_index = 0 + send_badges_message(bot, message.chat.id, current_badge_index, user_data) + +async def command_stats(bot, message): + if message.chat.type != "private": + return + + user = RiftUser(message.from_user.id, message.from_user.username) + user_data = user.load_data() + if not user_data: + bot.reply_to(message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + style = 'rift' + if user_data['style'] == 0: + style = 'rift' + elif user_data['style'] == 1: + style = 'easy' + elif user_data['style'] == 2: + style = 'raika' + elif user_data['style'] == 3: + style = 'kayy' + elif user_data['style'] == 4: + style = 'storm' + elif user_data['style'] == 5: + style = 'aqua' + else: + style = 'unknown style' + + msg = bot.reply_to(message, f''' +Stats for user {message.from_user.username}(#{user_data['ID']}): +Checked accounts: {user_data['accounts_checked']} +Style: {style} + +Badges: +Alpha Tester 1 Badge: {bool_to_emoji(user_data['alpha_tester_1_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['alpha_tester_1_badge_active'])} +Alpha Tester 2 Badge: {bool_to_emoji(user_data['alpha_tester_2_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['alpha_tester_2_badge_active'])} +Alpha Tester 3 Badge: {bool_to_emoji(user_data['alpha_tester_3_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['alpha_tester_3_badge_active'])} +Epic Games Badge: {bool_to_emoji(user_data['epic_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['epic_badge_active'])} +100 Checks Badge: {bool_to_emoji(user_data['newbie_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['newbie_badge_active'])} +200 Checks Badge: {bool_to_emoji(user_data['advanced_badge'])} +> Badge Enabled: {bool_to_emoji(user_data['advanced_badge_active'])} +''') + +def send_style_message(bot, chat_id, style_index): + style = available_styles[style_index] + markup = InlineKeyboardMarkup() + + if style_index > 0: + markup.add(InlineKeyboardButton("◀️", callback_data=f"style_{style_index - 1}")) + if style_index < len(available_styles) - 1: + markup.add(InlineKeyboardButton("▶️", callback_data=f"style_{style_index + 1}")) + + markup.add(InlineKeyboardButton("✅ Select This Style", callback_data=f"select_{style_index}")) + with open(style['image'], 'rb') as img_file: + img = Image.open(style['image']).convert("RGBA") + bot.send_photo( + chat_id, + img, + caption=f"{style['name']}", + reply_markup=markup, + parse_mode="Markdown" + ) + +def send_badges_message(bot, chat_id, badge_index, user_data): + unlocked_badges = [ + (i, badge) + for i, badge in enumerate(avaliable_badges) + if user_data.get(badge['data'], False) + ] + + if not unlocked_badges: + bot.send_message(chat_id, "You don't have any badges unlocked.") + return + + badge_index = min(max(0, badge_index), len(unlocked_badges) - 1) + actual_index, badge = unlocked_badges[badge_index] + + badge_status = user_data.get(badge['data2'], False) + toggle_text = "✅ Enabled" if badge_status else "❌ Disabled" + + markup = InlineKeyboardMarkup() + if badge_index > 0: + markup.add(InlineKeyboardButton("◀️", callback_data=f"badge_{badge_index - 1}")) + if badge_index < len(unlocked_badges) - 1: + markup.add(InlineKeyboardButton("▶️", callback_data=f"badge_{badge_index + 1}")) + markup.add(InlineKeyboardButton(toggle_text, callback_data=f"toggle_{actual_index}")) + + try: + with open(badge['image'], 'rb') as img: + bot.send_photo( + chat_id, + img, + caption=f"{badge['name']}", + reply_markup=markup, + parse_mode="Markdown" + ) + except FileNotFoundError: + bot.send_message(chat_id, f"Image for badge {badge['name']} not found.") \ No newline at end of file diff --git a/checker/cosmetic.py b/checker/cosmetic.py new file mode 100644 index 0000000..b67aef5 --- /dev/null +++ b/checker/cosmetic.py @@ -0,0 +1,24 @@ +class FortniteCosmetic: + def __init__(self): + self.cosmetic_id = "" + self.name = "" + self.backend_value = "AthenaCharacter" + self.rarity_value = "common" + self.small_icon = "" + self.is_banner = False + self.unlocked_styles = {} + self.is_exclusive = False + self.is_popular = False + + def to_dict(self): + return { + "cosmetic_id": self.cosmetic_id, + "name": self.name, + "backend_value": self.backend_value, + "rarity_value": self.rarity_value, + "small_icon": self.small_icon, + "is_banner": self.is_banner, + "unlocked_styles": self.unlocked_styles, + "is_exclusive": self.is_exclusive, + "is_popular": self.is_popular, + } \ No newline at end of file diff --git a/checker/cosmetic_icons/Backblings.png b/checker/cosmetic_icons/Backblings.png new file mode 100644 index 0000000..cc15e1e Binary files /dev/null and b/checker/cosmetic_icons/Backblings.png differ diff --git a/checker/cosmetic_icons/Emotes.png b/checker/cosmetic_icons/Emotes.png new file mode 100644 index 0000000..678c8ef Binary files /dev/null and b/checker/cosmetic_icons/Emotes.png differ diff --git a/checker/cosmetic_icons/Exclusives.png b/checker/cosmetic_icons/Exclusives.png new file mode 100644 index 0000000..257f0e1 Binary files /dev/null and b/checker/cosmetic_icons/Exclusives.png differ diff --git a/checker/cosmetic_icons/Gliders.png b/checker/cosmetic_icons/Gliders.png new file mode 100644 index 0000000..c5e0489 Binary files /dev/null and b/checker/cosmetic_icons/Gliders.png differ diff --git a/checker/cosmetic_icons/Outfits.png b/checker/cosmetic_icons/Outfits.png new file mode 100644 index 0000000..df8cb13 Binary files /dev/null and b/checker/cosmetic_icons/Outfits.png differ diff --git a/checker/cosmetic_icons/Pickaxes.png b/checker/cosmetic_icons/Pickaxes.png new file mode 100644 index 0000000..3f19bf5 Binary files /dev/null and b/checker/cosmetic_icons/Pickaxes.png differ diff --git a/checker/cosmetic_icons/Popular.png b/checker/cosmetic_icons/Popular.png new file mode 100644 index 0000000..de98dca Binary files /dev/null and b/checker/cosmetic_icons/Popular.png differ diff --git a/checker/cosmetic_icons/WantedStar.png b/checker/cosmetic_icons/WantedStar.png new file mode 100644 index 0000000..11b61a3 Binary files /dev/null and b/checker/cosmetic_icons/WantedStar.png differ diff --git a/checker/cosmetic_icons/Wraps.png b/checker/cosmetic_icons/Wraps.png new file mode 100644 index 0000000..aafd414 Binary files /dev/null and b/checker/cosmetic_icons/Wraps.png differ diff --git a/checker/epic_auth.py b/checker/epic_auth.py new file mode 100644 index 0000000..a59fc7c --- /dev/null +++ b/checker/epic_auth.py @@ -0,0 +1,690 @@ +import aiohttp +import requests +import asyncio +import os +import platform +import json +import math +from typing import Optional +from datetime import datetime, timezone +from cosmetic import FortniteCosmetic +from utils import bool_to_emoji + +# these tokens are used to authorize in epic games's API and let us do the skincheck without getting errors +EPIC_API_SWITCH_TOKEN = "OThmN2U0MmMyZTNhNGY4NmE3NGViNDNmYmI0MWVkMzk6MGEyNDQ5YTItMDAxYS00NTFlLWFmZWMtM2U4MTI5MDFjNGQ3" +# keep in mind, sometimes epic games block the client ids, so then you have to generate new ios token for it to start working again +EPIC_API_IOS_CLIENT_TOKEN = "M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU=" + +class EpicEndpoints: + endpoint_oauth_token = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token" + endpoint_prod03_oauth_token = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token" + endpoint_redirect_url = "https://www.epicgames.com/id/login?redirectUrl=https%3A//www.epicgames.com/id/login%3FredirectUrl%3Dhttps%253A%252F%252Fwww.epicgames.com%252Fid%252Fapi%252Fredirect%253FclientId%253Dec684b8c687f479fadea3cb2ad83f5c6%2526responseType%253Dcode" + endpoint_oauth_exchange = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/exchange" + endpoint_device_auth = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/deviceAuthorization" + +# locker categories we render +locker_categories = ['AthenaCharacter', 'AthenaBackpack', 'AthenaPickaxe', 'AthenaDance', 'AthenaGlider', 'AthenaPopular', 'AthenaExclusive'] + +class EpicUser: + def __init__(self, data: dict = {}): + self.raw = data + + # api response for login link generation + self.access_token = data.get("access_token", "") + self.expires_in = data.get("expires_in", 0) + self.expires_at = data.get("expires_at", "") + self.token_type = data.get("token_type", "") + self.client_id = data.get("client_id", "") + self.internal_client = data.get("internal_client", False) + self.client_service = data.get("client_service", "") + self.product_id = data.get("product_id", "") + self.application_id = data.get("application_id", "") + + # api response for account metadata + self.refresh_token = data.get("refresh_token", "") + self.refresh_expires = data.get("refresh_expires", "") + self.refresh_expires_at = data.get("refresh_expires_at", "") + self.account_id = data.get("account_id", "") + self.display_name = data.get("displayName", "") + self.app = data.get("app", "") + self.in_app_id = data.get("in_app_id", "") + self.acr = data.get("acr", "") + self.auth_time = data.get("auth_time", "") + +class LockerData: + def __init__(self): + self.cosmetic_categories = {} + self.cosmetic_array = {} + self.unlocked_styles = {} + self.homebase_banners = {} + self.last_match = '' + + def to_dict(self): + return { + "cosmetic_categories": self.cosmetic_categories, + "cosmetic_array": self.cosmetic_array, + "unlocked_styles": self.unlocked_styles, + "homebase_banners": self.homebase_banners, + } + +def add_missing_array2(arr, arr2, category, idclean): + # i hate hardcoding stuff, so ill make helper funcs instead + if category not in arr: + arr[category] = [] + arr2[category] = [] + + arr[category].append(idclean) + +def add_missing_array(arr, arr2, category): + # i hate hardcoding stuff, so ill make helper funcs instead + if category not in arr: + arr[category] = [] + arr2[category] = [] + +async def get_cosmetic_data(cosmetic_lowercase_id): + try: + response = requests.get( + f'https://fortnite-api.com/v2/cosmetics/br/search/ids?language=en{cosmetic_lowercase_id}' + ) + + response.raise_for_status() + return response.json().get('data', []) + + except Exception as e: + print(f"Error getting cosmetic info for cosmetic with ID: {cosmetic_lowercase_id}\n> Exception: {e}") + return [] + +class EpicGenerator: + def __init__(self) -> None: + # init the generator + self.http: aiohttp.ClientSession + self.user_agent = f"DeviceAuthGenerator/{platform.system()}/{platform.version()}" + self.access_token = "" + + async def start(self) -> None: + self.http = aiohttp.ClientSession(headers={"User-Agent": self.user_agent}) + self.access_token = await self.get_access_token() + + async def kill(self) -> None: + await self.http.close() + + async def get_access_token(self) -> str: + # getting the access token from epic's api(REQUIRES usage of EPIC_API_SWITCH_TOKEN as Authorization in headers for it to work) + # if it's not getting any data, it means the EPIC_API_SWITCH_TOKEN is expired, you must find new one :D + async with self.http.request( + method="POST", + url=EpicEndpoints.endpoint_oauth_token, + headers={ + "Content-Type": "application/x-www-form-urlencoded", + "Authorization": f"basic {EPIC_API_SWITCH_TOKEN}" + }, + data={ "grant_type": "client_credentials" }, + ) as response: + data = await response.json() + return data["access_token"] + + async def create_device_code(self) -> tuple: + # devide code is used on the link the checker bot sends u "active?userCode=SOMETHING" something like this + # REQUIRES usage of self.access_token, which we got from get_access_token function, as Authorization in headers + # returns the device code, used in the link we generate for the user to login + async with self.http.request( + method="POST", + url=EpicEndpoints.endpoint_device_auth, + headers={ + "Authorization": f"bearer {self.access_token}", + "Content-Type": "application/x-www-form-urlencoded" + } + ) as response: + data = await response.json() + return data + + async def create_exchange_code(self, user: EpicUser) -> str: + # creates exchange code for the api requests & returns it + # REQUIRES usage of user.access_token, which we got from get_access_token function, as Authorization in headers + async with self.http.request( + method="GET", + url=EpicEndpoints.endpoint_oauth_exchange, + headers={"Authorization": f"bearer {user.access_token}"}, + ) as response: + data = await response.json() + return data["code"] + + async def wait_for_device_code_completion(self, bot, message, code: str) -> Optional[EpicUser]: + while True: + try: + async with self.http.request( + method="POST", + url=EpicEndpoints.endpoint_prod03_oauth_token, + headers={ + "Authorization": f"basic {EPIC_API_SWITCH_TOKEN}", + "Content-Type": "application/x-www-form-urlencoded", + }, + data={"grant_type": "device_code", "device_code": code}, + timeout=10 + ) as request: + token_data = await request.json() + + if request.status == 200 and "access_token" in token_data: + break + + # Handle specific API errors + error_code = token_data.get("errorCode") + if error_code == "errors.com.epicgames.account.oauth.authorization_pending": + pass + + elif error_code == "g": + pass + + elif error_code == "errors.com.epicgames.not_found": + bot.send_message(message.chat.id, f'❌ Login link expired, please use /login again.') + return None + else: + bot.send_message(message.chat.id, f'❌ Error occurred: {token_data.get("errorMessage", "Unknown error")}') + return None + + await asyncio.sleep(10) + except ValueError as ve: + print(f"Error with waiting for device code: {ve}") + bot.send_message(message.chat.id, f'❌ An unexpected error occurred, please try again later.') + return None + except Exception as e: + print(f"Unhandled exception: {e}") + bot.send_message(message.chat.id, f'❌ An error occurred, please contact support.') + return None + + try: + async with self.http.request( + method="GET", + url=EpicEndpoints.endpoint_oauth_exchange, + headers={"Authorization": f"bearer {token_data['access_token']}"}, + ) as request: + if request.status != 200: + bot.send_message(message.chat.id, f'❌ Failed to retrieve exchange code. Please try again.') + return None + + exchange_data = await request.json() + + async with self.http.request( + method="POST", + url=EpicEndpoints.endpoint_prod03_oauth_token, + headers={ + "Authorization": f"basic {EPIC_API_IOS_CLIENT_TOKEN}", + "Content-Type": "application/x-www-form-urlencoded" + }, + data={ + "grant_type": "exchange_code", + "exchange_code": exchange_data["code"] + }, + ) as request: + if request.status != 200: + bot.send_message(message.chat.id, f'❌ Failed to authenticate using exchange code. Please try again.') + return None + + auth_data = await request.json() + + return EpicUser(data=auth_data) + + except KeyError as ke: + bot.send_message(message.chat.id, f'❌ Unexpected response format from server.') + return None + except Exception as e: + print(f"Unhandled exception during token exchange: {e}") + bot.send_message(message.chat.id, f'❌ An error occurred while completing authentication.') + return None + + async def create_device_auths(self, user: EpicUser) -> dict: + # creates device auth + # REQUIRES usage of user.access_token as Authorization in headers + async with self.http.request( + method="POST", + url=f"https://account-public-service-prod.ol.epicgames.com/account/api/public/account/{user.account_id}/deviceAuth", + headers={ + "Authorization": f"bearer {user.access_token}", + "Content-Type": "application/json", + }, + ) as request: + data = await request.json() + + return { + "device_id": data["deviceId"], + "account_id": data["accountId"], + "secret": data["secret"], + "user_agent": data["userAgent"], + "created": { + "location": data["created"]["location"], + "ip_address": data["created"]["ipAddress"], + "datetime": data["created"]["dateTime"], + }, + } + + async def get_account_metadata(self, user: EpicUser) -> json: + # grabs account's metadata(basic information) from the api + # REQUIRES usage of user.access_token as Authorization in headers + + url = f'https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/displayName/{user.display_name}' + headers = { + "Authorization": f"bearer {user.access_token}", + "Content-Type": "application/json", + } + + async with self.http.get(url, headers=headers) as response: + metadata = await response.json() + + return metadata + + async def get_external_connections(self, user: EpicUser) -> dict: + # returns external connected accounts info + # REQUIRES usage of user.access_token as Authorization in headers + async with self.http.request( + method="GET", + url=f"https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/{user.account_id}/externalAuths", + headers={"Authorization": f"bearer {user.access_token}"} + ) as resp: + if resp.status != 200: + return [] + + external_auths = await resp.json() + + return external_auths + + async def get_public_account_info(self, user: EpicUser) -> dict: + # returns basic public info about the account + # REQUIRES usage of user.access_token as Authorization in headers + url = f'https://account-public-service-prod03.ol.epicgames.com/account/api/public/account/{user.account_id}' + headers = { + "Authorization": f"bearer {user.access_token}" + } + + async with self.http.get(url, headers=headers) as response: + account_data = await response.json() + + account_info = {} # creating json for only stuff we are interested into + creation_date = account_data.get("created", "?") + if creation_date != "?": + creation_date = datetime.strptime(creation_date, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%d/%m/%Y") + + account_info['creation_date'] = creation_date + account_info['externalAuths'] = await self.get_external_connections(user) + return account_info + + async def get_common_profile(self, user: EpicUser) -> json: + # gets the common profile, containing vbucks, receipts amount, vbucks purchases history, banners list + # REQUIRES usage of user.access_token as Authorization in headers + + url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=common_core&rvn=-1' + headers = { + "Authorization": f"bearer {user.access_token}", + "Content-Type": "application/json" + } + + profile_data = requests.post(url, headers=headers, json={}).json() + return profile_data + + async def get_friend_codes(self, user: EpicUser, platform: str) -> json: + # https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/v2/game/friendcodes// + # gets the save the world redeem codes based on the platform you've entered + # REQUIRES usage of user.access_token as Authorization in headers + # this always returns an error saying page isn't found, im not sure why. + url = f'https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/v2/game/friendcodes/{user.account_id}/{platform}' + headers = { + "Authorization": f"bearer {user.access_token}" + } + + async with self.http.get(url, headers=headers) as response: + codes_data = await response.json() + + return codes_data + + async def get_homebase_profile(self, user: EpicUser) -> json: + # gets the save the world profile data + # REQUIRES usage of user.access_token as Authorization in headers + + url = f'https://fngw-mcp-gc-livefn.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryPublicProfile' + querystring = { "profileId":"campaign", "rvn":"-1" } + payload = {} + headers = { + "Content-Type": "application/json", + "Authorization": f"bearer {user.access_token}" + } + + profile_data = requests.request("POST", url, json=payload, headers=headers, params=querystring).json() + + return profile_data + + async def set_affiliate(self, user: EpicUser, affiliate_name: str): + url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/SetAffiliateName?profileId=common_core' + payload = { "affiliateName": affiliate_name } + headers = { + "Content-Type": "application/json", + "Authorization": f"bearer {user.access_token}" + } + + affiliate_response = requests.request("POST", url, json=payload, headers=headers) + + if affiliate_response.status != 200: + print(f"Error setting affiliate name ({affiliate_response.status})") + + async def get_locker_data(self, user: EpicUser) -> LockerData: + # gets locker arrays + # locker_categories - the locker categories we render + url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=athena' + headers = { + "Authorization": f"bearer {user.access_token}", + "Content-Type": "application/json" + } + + athena_data = requests.post(url, headers=headers, json={}).json() + + locker_data = LockerData() + exclusive_cosmetics = [] + popular_cosmetics = [] + if "profileChanges" not in athena_data: + return LockerData() + + # activity + account_level = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("accountLevel", 1) + last_match_end = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("last_match_end_datetime", "") + if last_match_end: + last_match_end_date = datetime.fromisoformat(last_match_end.replace("Z", "+00:00")) + days_since_last_match = (datetime.now(timezone.utc) - last_match_end_date).days + last_match_date_str = last_match_end_date.strftime("%d.%m.%y") + locker_data.last_match = f"{last_match_date_str} ({days_since_last_match} days ago)" + else: + locker_data.last_match = "800+ days ago" + + # getting extra cosmetics + try: + with open('exclusive.txt', 'r', encoding='utf-8') as f: + exclusive_cosmetics = [i.strip() for i in f.readlines()] + + with open('most_wanted.txt', 'r', encoding='utf-8') as f: + popular_cosmetics = [i.strip() for i in f.readlines()] + except FileNotFoundError: + print("Warning: exclusive.txt or most_wanted.txt not found.") + + # getting owned items list + for i in athena_data['profileChanges'][0]['profile']['items']: + template_id = athena_data['profileChanges'][0]['profile']['items'][i]['templateId'] + if template_id.startswith('Athena'): + cosmetic_category = template_id.split(':')[0] + cosmetic_id = template_id.split(':')[1] + locker_data.unlocked_styles[cosmetic_id] = [] + + # adding missing categories to the arrays + if 'AthenaExclusive' not in locker_data.cosmetic_categories: + locker_data.cosmetic_categories['AthenaExclusive'] = [] + locker_data.cosmetic_array['AthenaExclusive'] = [] + locker_data.cosmetic_categories['AthenaExclusive'].append(cosmetic_id) + + if 'AthenaPopular' not in locker_data.cosmetic_categories: + locker_data.cosmetic_categories['AthenaPopular'] = [] + locker_data.cosmetic_array['AthenaPopular'] = [] + locker_data.cosmetic_categories['AthenaPopular'].append(cosmetic_id) + + if 'HomebaseBannerIcons' not in locker_data.cosmetic_categories: + locker_data.cosmetic_categories['HomebaseBannerIcons'] = [] + locker_data.cosmetic_array['HomebaseBannerIcons'] = [] + locker_data.cosmetic_categories['HomebaseBannerIcons'].append(cosmetic_id) + + if cosmetic_category not in locker_data.cosmetic_categories: + locker_data.cosmetic_categories[cosmetic_category] = [] + locker_data.cosmetic_array[cosmetic_category] = [] + locker_data.cosmetic_categories[cosmetic_category].append(cosmetic_id) + + # listing the owned unlocked styles for each cosmetic + for item_id, item_data in athena_data['profileChanges'][0]['profile']['items'].items(): + template_id = item_data.get('templateId', '') + + if template_id.startswith('Athena'): + lowercase_cosmetic_id = template_id.split(':')[1] + + # adding the cosmetic to the "unlocked styles" + if lowercase_cosmetic_id not in locker_data.unlocked_styles: + locker_data.unlocked_styles[lowercase_cosmetic_id] = [] + + attributes = item_data.get('attributes', {}) + variants = attributes.get('variants', []) + + for variant in variants: + # adding the cosmetic's owned styles + locker_data.unlocked_styles[lowercase_cosmetic_id].extend(variant.get('owned', [])) + + # getting banners + common_profile_data = await self.get_common_profile(user) + if common_profile_data: + # common profile found + for profileChange in common_profile_data["profileChanges"]: + profile_items = profileChange["profile"]["items"] + + # checking every item + for item_key, item_value in profile_items.items(): + cosmetic_template_id = item_value.get("templateId", "") + if cosmetic_template_id: + # the banner is found, so we adding it + lowercase_banner_id = cosmetic_template_id.split(':')[1] + if lowercase_banner_id not in locker_data.homebase_banners: + locker_data.homebase_banners[lowercase_banner_id] = [] + + + for category in locker_categories: + if category == "AthenaPopular" or category == 'AthenaExclusive': + continue + + try: + list_of_cosmetic_ids = [] + # splitting the category's cosmetic ids to sublists + for i in range(0, len(locker_data.cosmetic_categories[category]), 50): + sublist = locker_data.cosmetic_categories[category][i:i+50] + list_of_cosmetic_ids.append(sublist) + + for cosmetic_id in list_of_cosmetic_ids: + cosmetics_data = requests.get('https://fortnite-api.com/v2/cosmetics/br/search/ids?language=en&id={}'.format('&id='.join(cosmetic_id))) + c_data = cosmetics_data.json().get("data", []) + if not c_data: + # cosmetics data not found + continue + + for cosmetic in c_data: + if cosmetic['id'] == "CID_DefaultOutfit": + # skipping default skin + continue + + if category == 'AthenaDance' and cosmetic['type']['value'] != 'emote' and cosmetic['id'] not in exclusive_cosmetics: + # emote category, but isnt exclusive and isnt emote + continue + + make_mythic = False + if cosmetic['id'] in exclusive_cosmetics: + make_mythic = True + # Pink Ghoul Trooper + if cosmetic['id'].lower() == 'cid_029_athena_commando_f_halloween': + make_mythic = False + if 'Mat3' in locker_data.unlocked_styles.get('cid_029_athena_commando_f_halloween', []): + make_mythic = True + + # Purple Skull Trooper + if cosmetic['id'].lower() == 'cid_030_athena_commando_m_halloween': + make_mythic = False + if 'Mat1' in locker_data.unlocked_styles.get('cid_030_athena_commando_m_halloween', []): + make_mythic = True + + # Aerial Assault Trooper + if cosmetic['id'].lower() == 'cid_017_athena_commando_m': + make_mythic = False + if 'Stage2' in locker_data.unlocked_styles.get('cid_017_athena_commando_m', []): + make_mythic = True + + # Renegade Raider + if cosmetic['id'].lower() == 'cid_028_athena_commando_f': + make_mythic = False + if 'Mat3' in locker_data.unlocked_styles.get('cid_028_athena_commando_f', []): + make_mythic = True + + # Raider's Revenge + if cosmetic['id'].lower() == 'pickaxe_lockjaw': + make_mythic = False + if 'Stage2' in locker_data.unlocked_styles.get('pickaxe_lockjaw', []): + make_mythic = True + + # Aerial Assault One + if cosmetic['id'].lower() == 'glider_id_001': + make_mythic = False + if 'Stage2' in locker_data.unlocked_styles.get('glider_id_001', []): + make_mythic = True + + # Stage 5 Omega Lights + if cosmetic['id'].lower() == 'cid_116_athena_commando_m_carbideblack': + make_mythic = False + if 'Stage5' in locker_data.unlocked_styles.get('cid_116_athena_commando_m_carbideblack', []): + make_mythic = True + + # Gold Midas + if cosmetic['id'].lower() == 'cid_694_athena_commando_m_catburglar': + make_mythic = False + if 'Stage4' in locker_data.unlocked_styles.get('cid_694_athena_commando_m_catburglar', []): + make_mythic = True + + # Gold Meowscles + if cosmetic['id'].lower() == 'cid_693_athena_commando_m_buffcat': + make_mythic = False + if 'Stage4' in locker_data.unlocked_styles.get('cid_693_athena_commando_m_buffcat', []): + make_mythic = True + + # Gold TNtina + if cosmetic['id'].lower() == 'cid_691_athena_commando_f_tntina': + make_mythic = False + if 'Stage7' in locker_data.unlocked_styles.get('cid_691_athena_commando_f_tntina', []): + make_mythic = True + + # Gold Skye + if cosmetic['id'].lower() == 'cid_690_athena_commando_f_photographer': + make_mythic = False + if 'Stage4' in locker_data.unlocked_styles.get('cid_690_athena_commando_f_photographer', []): + make_mythic = True + + # Gold Agent Peely + if cosmetic['id'].lower() == 'cid_701_athena_commando_m_bananaagent': + make_mythic = False + if 'Stage4' in locker_data.unlocked_styles.get('cid_701_athena_commando_m_bananaagent', []): + make_mythic = True + + # World Cup Fishtick + if cosmetic['id'].lower() == 'cid_315_athena_commando_m_teriyakifish': + make_mythic = False + if 'Stage3' in locker_data.unlocked_styles.get('cid_315_athena_commando_m_teriyakifish', []): + make_mythic = True + + # Mate Black Masterchief + if cosmetic['id'].lower() == 'cid_971_athena_commando_m_jupiter_s0z6m': + make_mythic = False + if 'Mat2' in locker_data.unlocked_styles.get('cid_971_athena_commando_m_jupiter_s0z6m', []): + make_mythic = True + + if make_mythic == True: + cosmetic['rarity']['value'] = 'mythic' + + cosmetic_info = FortniteCosmetic() + cosmetic_info.cosmetic_id = cosmetic['id'] + cosmetic_info.name = cosmetic['name'] + cosmetic_info.small_icon = cosmetic['images']['smallIcon'] + cosmetic_info.backend_value = category + cosmetic_info.rarity_value = cosmetic['rarity']['value'] + cosmetic_info.is_banner = False + cosmetic_info.is_exclusive = make_mythic + cosmetic_info.is_popular = cosmetic['id'] in popular_cosmetics + cosmetic_info.unlocked_styles = locker_data.unlocked_styles[cosmetic['id'].lower()] + + locker_data.cosmetic_array[category].append(cosmetic_info) + + # now special ones + if cosmetic_info.is_popular: + locker_data.cosmetic_array['AthenaPopular'].append(cosmetic_info) + + if make_mythic: + locker_data.cosmetic_array['AthenaExclusive'].append(cosmetic_info) + + except Exception as e: + print(f'exception: {e}') + continue + + # handle banners + banners_data = requests.get('https://fortnite-api.com/v1/banners') + for fn_banner in banners_data.json()['data']: + banner_lower_id = fn_banner['id'].lower() + if banner_lower_id not in locker_data.homebase_banners: + # banner isn't owned + continue + + make_mythic = False + icon = fn_banner['images']['icon'] + rarity = 'uncommon' + if fn_banner['id'] in exclusive_cosmetics: + make_mythic = True + rarity = 'mythic' + + # for future + cosmetic_info = FortniteCosmetic() + cosmetic_info.cosmetic_id = fn_banner['id'] + cosmetic_info.name = fn_banner['devName'] + cosmetic_info.small_icon = fn_banner['images']['smallIcon'] + cosmetic_info.rarity_value = rarity + cosmetic_info.backend_value = 'HomebaseBannerIcons' + cosmetic_info.is_banner = True + cosmetic_info.is_exclusive = make_mythic + cosmetic_info.is_popular = fn_banner['id'] in popular_cosmetics + + locker_data.cosmetic_array['HomebaseBannerIcons'].append(cosmetic_info) + # now exclusive ones + if make_mythic: + locker_data.cosmetic_array['AthenaExclusive'].append(cosmetic_info) + + # sorting exclusives category + locker_data.cosmetic_array['AthenaExclusive'].sort( + key=lambda cosmetic: exclusive_cosmetics.index(cosmetic.cosmetic_id) + if cosmetic.cosmetic_id in exclusive_cosmetics + else float('inf') + ) + + # returning back the locker data + return locker_data + + async def get_seasons_message(self, user: EpicUser) -> str: + url = f'https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/{user.account_id}/client/QueryProfile?profileId=athena' + headers = { + "Authorization": f"bearer {user.access_token}", + "Content-Type": "application/json" + } + + athena_data = requests.post(url, headers=headers, json={}).json() + + past_seasons = {} + seasons_info = [] + + # seasons infos + past_seasons = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}).get("past_seasons", []) + total_wins = sum(season.get("numWins", 0) for season in past_seasons) + total_matches = sum( + season.get("numHighBracket", 0) + season.get("numLowBracket", 0) + + season.get("numHighBracket_LTM", 0) + season.get("numLowBracket_LTM", 0) + + season.get("numHighBracket_Ar", 0) + season.get("numLowBracket_Ar", 0) + for season in past_seasons + ) + + curses = athena_data.get("profileChanges", [{}])[0].get("profile", {}).get("stats", {}).get("attributes", {}) + cursesinfo = { + 'level': curses.get('level', 1), + 'book_level': curses.get('book_level', 1) + } + + for season in past_seasons: + seasons_info.append(f""" +#️⃣Season {season.get('seasonNumber', 1)} +› Level: {season.get('seasonLevel', '1')} +› Battle Pass: {bool_to_emoji(season.get('purchasedVIP', False))} +› Wins: {season.get('numWins', 0)} + """) + + seasons_info_embeds = seasons_info + seasons_info_message = "Previous Seasons History:\n" + "\n".join(seasons_info_embeds) + seasons_info_message += f"\nCurrent Season:\n› Level: {cursesinfo['level']}\n› Battle Pass Level: {cursesinfo['book_level']}" + return seasons_info_message \ No newline at end of file diff --git a/checker/exclusive.txt b/checker/exclusive.txt new file mode 100644 index 0000000..f620b43 --- /dev/null +++ b/checker/exclusive.txt @@ -0,0 +1,415 @@ +Pickaxe_Lockjaw +CID_028_Athena_Commando_F +CID_029_Athena_Commando_F_Halloween +CID_017_Athena_Commando_M +CID_030_Athena_Commando_M_Halloween +Glider_ID_001 +Pickaxe_ID_376_FNCS +Pickaxe_FNCS_S32 +CID_035_Athena_Commando_M_Medieval +CID_039_Athena_Commando_F_Disco + +CID_660_Athena_Commando_F_BandageNinjaBlue +CID_619_Athena_Commando_F_TechLlama +CID_434_Athena_Commando_F_StealthHonor +CID_757_Athena_Commando_F_WildCat +CID_175_Athena_Commando_M_Celestial +CID_342_Athena_Commando_M_StreetRacerMetallic +CID_313_Athena_Commando_M_KpopFashion +CID_386_Athena_Commando_M_StreetOpsStealth +CID_259_Athena_Commando_M_StreetOps +CID_174_Athena_Commando_F_CarbideWhite +Character_MasterKeyOrder +CID_371_Athena_Commando_M_SpeedyMidnight +CID_753_Athena_Commando_F_Hostile +CID_183_Athena_Commando_M_ModernMilitaryRed +CID_479_Athena_Commando_F_Davinci +CID_516_Athena_Commando_M_BlackWidowRogue +CID_441_Athena_Commando_F_CyberScavengerBlue +CID_783_Athena_Commando_M_AquaJacket +CID_850_Athena_Commando_F_SkullBriteCube +CID_113_Athena_Commando_M_BlueAce +CID_515_Athena_Commando_M_BarbequeLarry +CID_971_Athena_Commando_M_Jupiter_S0Z6M + + +CID_033_Athena_Commando_F_Medieval +CID_032_Athena_Commando_M_Medieval + + +CID_084_Athena_Commando_M_Assassin +CID_083_Athena_Commando_F_Tactical +CID_090_Athena_Commando_M_Tactical + +CID_116_Athena_Commando_M_CarbideBlack + + +CID_703_Athena_Commando_M_Cyclone +CID_761_Athena_Commando_M_CycloneSpace +CID_478_Athena_Commando_F_WorldCup +CID_964_Athena_Commando_M_Historian_869BC +CID_315_Athena_Commando_M_TeriyakiFish + +CID_085_Athena_Commando_M_Twitch +CID_089_Athena_Commando_M_RetroGrey +CID_114_Athena_Commando_F_TacticalWoodland + + +CID_096_Athena_Commando_F_Founder +CID_095_Athena_Commando_M_Founder + + +Character_SnowNinjaDark +CID_052_Athena_Commando_F_PSBlue +CID_138_Athena_Commando_M_PSBurnout +CID_296_Athena_Commando_M_Math +CID_360_Athena_Commando_M_TechOpsBlue +CID_A_101_Athena_Commando_M_TacticalWoodlandBlue +CID_A_421_Athena_Commando_F_BlizzardBomber +CID_657_Athena_Commando_F_TechOpsBlue +CID_711_Athena_Commando_M_LongShorts +Character_BlueJet +CID_926_Athena_Commando_F_StreetFashionDiamond +Character_RetroWheels + + +CID_701_Athena_Commando_M_BananaAgent +CID_690_Athena_Commando_F_Photographer +CID_691_Athena_Commando_F_TNTina +CID_693_Athena_Commando_M_BuffCat +CID_694_Athena_Commando_M_CatBurglar + + +Character_TubaGummi + + +BID_004_BlackKnight +BID_415_TechLlama +BID_138_Celestial +BID_521_WildCat +BID_249_StreetOpsStealth +BID_234_SpeedyMidnight +BID_604_SkullBritecube +BID_114_ModernMilitaryRed +BID_346_BlackWidowRogue +PetCarrier_013_BbqLarry + +BID_002_RoyaleKnight +BID_001_BlueSquire + + +Backpack_SnowNinjaDark +BID_A_019_BlizzardBomberFemale +BID_169_MathMale +BID_224_TechOpsBlue +Backpack_BlueJet +Backpack_SnowSoldierFashion + + +BID_027_Scavenger +BID_468_Cyclone +BID_520_CycloneUniverse + + +Backpack_FNCSShield_S32 + + +Pickaxe_ID_116_Celestial +Pickaxe_ID_398_WildCatFemale +Pickaxe_ID_077_CarbideWhite +Pickaxe_ID_099_ModernMilitaryRed +Pickaxe_ID_461_SkullBriteCube +Pickaxe_ID_189_StreetOpsStealth +Pickaxe_ID_178_SpeedyMidnight + + +Pickaxe_ID_294_CandyCane +Pickaxe_ID_508_HistorianMale_6BQSW + + +Pickaxe_ID_013_Teslacoil +Pickaxe_ID_011_Medieval +Pickaxe_ID_028_Space +Pickaxe_ID_092_Bling + + +Pickaxe_ID_039_TacticalBlack +Pickaxe_ID_044_TacticalUrbanHammer + + +Pickaxe_ID_265_BarbequeLarry1H + + +Pickaxe_ID_STW006_Tier_7 +Pickaxe_ID_153_RoseLeader + + +Pickaxe_SnowNinjaDark +BID_055_PSBurnout +Pickaxe_ID_088_PSBurnout +Pickaxe_ID_256_TechOpsBlue +Pickaxe_ID_464_LongShortsMale +Pickaxe_ID_717_NetworkFemale +Pickaxe_SnowSoldierFashion +Pickaxe_RetroWheels + + +Pickaxe_ID_STW005_Tier_6 +Pickaxe_ID_STW004_Tier_5 +Pickaxe_ID_STW003_Tier_4 +Pickaxe_ID_STW002_Tier_3 +Pickaxe_ID_STW007_Basic +Pickaxe_ID_STW001_Tier_1 + + +Pickaxe_SpookyNeonRed +Pickaxe_SpookyNeonBlue +Pickaxe_ID_359_CycloneMale + + +EID_KPopDance03 +EID_Davinci + + +EID_Fresh +EID_Floss +EID_Worm +EID_RideThePonyTwo +EID_TakeTheL +EID_HipHop01 +EID_GoodVibes +EID_IceKing +EID_RichFam +EID_PlayerEleven +EID_RigorMortis +EID_Gleam +EID_Downward_8GZUA +EID_CycloneHeadBang +EID_SandwichBop +EID_JulyBooks +EID_Laugh +EID_Textile_3O8QG +EID_Uproar_496SC +EID_Tidy +EID_Zippy + + +EID_Avian + + +Emoji_S22_Showdown_Mae +Emoji_S22_Showdown_Zet + + +Spray_Showdown_Mae +Spray_Showdown_Zet +Spray_Showdown_Pi +SPID_066_Llamalaxy +SPID_065_DiscoBaller +SPID_043_Flairspray +SPID_274_Alt_3 +SPID_022_SoloShowdown + + +Glider_Warthog +Glider_ID_003_District + +Glider_ID_211_WildCatBlue +Glider_ID_090_Celestial +Glider_ID_056_CarbideWhite +Glider_ID_075_ModernMilitaryRed +Glider_ID_137_StreetOpsStealth +Glider_ID_131_SpeedyMidnight + + +Glider_ID_002_Medieval +Glider_ID_015_Brite + + +Glider_ID_161_RoseLeader +FounderGlider +Glider_Military + + +Glider_ID_013_PSBlue +Glider_ID_067_PSBurnout +Glider_ID_150_TechOpsBlue +Glider_ID_309_TacticalWoodlandBlue +Glider_ID_389_BlizzardBomberFemale +Glider_SnowSoldierFashion + +Glider_ID_196_CycloneMale +Glider_ID_347_PeachMale + + +FounderUmbrella +Umbrella_Snowflake +Umbrella_PaperParasol +Umbrella_AssassinSuit +Umbrella_Lettuce +Umbrella_Vendetta + + +Wrap_SnowNinjaDark +Wrap_333_StealthWoodland +Wrap_UnknownNetwork +Wrap_DyedBurst +Wrap_210_Thermal +Wrap_303_GasCloud + + +Trails_ID_059_Sony2 +Trails_ID_123_TacticalWoodlandBlue +Trails_ID_150_Avalanche + + +OT11Banner +OT10Banner +OT9Banner +OT8Banner +OT7Banner +OT6Banner +OT5Banner +OT4Banner +OT3Banner +OT2Banner +OT1Banner +OtherBanner51 +BRSeason01 +NewsletterBanner +Winter2018Krampus +Winter2018BearTrapFoot +Winter2018Cooker +Winter2018SnowmanBuried +Winter2018CrownFlame +Winter2018IcicleCluster +Winter2018Tower +Winter2018Wave30Complete +Winter2018GingerbreadMan +StarlightBanner6 +StarlightBanner5 +StarlightBanner4 +StarlightBanner3 +StarlightBanner2 +StarlightBanner1 +EnduranceWave30Theater04 +EnduranceWave30Theater03 +EnduranceWave30Theater02 +EnduranceWave30Theater01 +WargamesTprifts +WargamesTiki +WargamesPods +SurvivalBannerStorm2018Med +HordeBanner2018TwinePeaks +SurvivalBannerStorm2018Stonewood +WargamesAnomaly +WargamesMeteor +WargamesTornado +AchievementUnspeakableHorrors +AchievementWorldExplorer +AchievementGuardianAngel +AchievementPlaysWellWithOthers +AchievementTalentedBuilder +AchievementGoGnome +AchievementLootLegend +SurvivalBannerPlankertonComplete +SurvivalBannerCannyValleyComplete +SurvivalBannerStonewoodComplete +InfluencerBanner1 +InfluencerBanner2 +InfluencerBanner3 +InfluencerBanner4 +InfluencerBanner5 +InfluencerBanner6 +InfluencerBanner7 +InfluencerBanner8 +InfluencerBanner9 +InfluencerBanner10 +InfluencerBanner11 +InfluencerBanner12 +InfluencerBanner13 +InfluencerBanner14 +InfluencerBanner15 +InfluencerBanner16 +InfluencerBanner17 +InfluencerBanner18 +InfluencerBanner19 +InfluencerBanner20 +InfluencerBanner21 +InfluencerBanner22 +InfluencerBanner23 +InfluencerBanner24 +InfluencerBanner25 +InfluencerBanner26 +InfluencerBanner27 +InfluencerBanner28 +InfluencerBanner29 +InfluencerBanner30 +InfluencerBanner31 +InfluencerBanner32 +InfluencerBanner33 +InfluencerBanner34 +InfluencerBanner35 +InfluencerBanner36 +InfluencerBanner37 +InfluencerBanner38 +InfluencerBanner39 +InfluencerBanner40 +InfluencerBanner41 +InfluencerBanner42 +InfluencerBanner43 +InfluencerBanner44 +InfluencerBanner45 +InfluencerBanner46 +InfluencerBanner47 +InfluencerBanner48 +InfluencerBanner49 +InfluencerBanner50 +InfluencerBanner51 +InfluencerBanner52 +InfluencerBanner53 +InfluencerBanner54 +InfluencerBanner55 +InfluencerBanner56 +InfluencerBanner57 +InfluencerBanner58 +BRS22_Showdown_Mae +FounderTier5Banner1 +FounderTier5Banner2 +FounderTier5Banner3 +FounderTier5Banner4 +FounderTier5Banner5 +FounderTier4Banner1 +FounderTier4Banner2 +FounderTier4Banner3 +FounderTier4Banner4 +FounderTier4Banner5 +FounderTier3Banner1 +FounderTier3Banner2 +FounderTier3Banner3 +FounderTier3Banner4 +FounderTier3Banner5 +FounderTier2Banner1 +FounderTier2Banner2 +FounderTier2Banner3 +FounderTier2Banner4 +FounderTier2Banner5 +FounderTier1Banner1 +FounderTier1Banner2 +FounderTier1Banner3 +FounderTier1Banner4 +FounderTier1Banner5 +SurvivalBannerHolidayHard +SurvivalBannerHolidayMed +SurvivalBannerHolidayEasy +SurvivalBannerStorm2018Hard +SurvivalBannerStorm2018Med +SurvivalBannerStorm2018Easy +BRS10Level100 +BRS9Lvl100 +BRS8Level100 +NewsletterBanne +BRWorldCup2019 +BRS23_FNCS_Drops +BRS9Doggus +BRS9Cattus \ No newline at end of file diff --git a/checker/homebase_data.txt b/checker/homebase_data.txt new file mode 100644 index 0000000..99b3ebd --- /dev/null +++ b/checker/homebase_data.txt @@ -0,0 +1,14823 @@ +{ + "profileRevision": 54464, + "profileId": "campaign", + "profileChangesBaseRevision": 54464, + "profileChanges": [ + { + "changeType": "fullProfileUpdate", + "profile": { + "created": "2018-05-05T02:23:12.149Z", + "updated": "2025-01-02T21:03:29.044Z", + "rvn": 54464, + "wipeNumber": 9, + "accountId": "4b47fd94adb640b8b08ca1e24a7ca584", + "profileId": "campaign", + "version": "season33_3300_PrimalFlamebowMakegood_Dec_2024", + "stats": { + "attributes": { + "node_costs": { + "homebase_node_default_page": { + "Token:homebasepoints": 137 + }, + "research_node_default_page": { + "Token:collectionresource_nodegatetoken01": 994200 + } + }, + "mission_alert_redemption_record": { + "claimData": [ + { + "missionAlertId": "a0f81b94-9990-485d-a805-0ae477239ce6", + "evictClaimDataAfterUtc": "2024-10-19T00:00:00.000Z", + "redemptionDateUtc": "2024-10-18T09:14:43.751Z" + }, + { + "missionAlertId": "dd579149-d5a3-4ba1-b922-8eb657d67f87", + "evictClaimDataAfterUtc": "2024-10-19T00:00:00.000Z", + "redemptionDateUtc": "2024-10-18T17:47:34.012Z" + }, + { + "missionAlertId": "8fad38dd-50fa-476c-9dfb-3ea9cc36666f", + "evictClaimDataAfterUtc": "2024-10-19T00:00:00.000Z", + "redemptionDateUtc": "2024-10-18T19:34:27.518Z" + } + ] + }, + "client_settings": { + "pinnedQuestInstances": [] + }, + "research_levels": { + "offense": 120, + "technology": 120, + "fortitude": 120, + "resistance": 91 + }, + "level": 253, + "selected_hero_loadout": "00216df5-eb1e-45be-9549-76674b95d047", + "collection_book": { + "maxBookXpLevelAchieved": 284 + }, + "latent_xp_marker": "7088495", + "mfa_reward_claimed": true, + "quest_manager": { + "dailyLoginInterval": "2025-01-02T20:30:31.529Z", + "dailyQuestRerolls": 1, + "questPoolStats": { + "dailyLoginInterval": "2025-01-02T20:30:31.529Z", + "poolLockouts": { + "poolLockouts": [ + { + "lockoutName": "EnduranceDaily" + }, + { + "lockoutName": "Weekly" + } + ] + }, + "poolStats": [ + { + "questHistory": [], + "rerollsRemaining": 0, + "nextRefresh": "2024-04-06T04:28:40.074Z", + "poolName": "endurancedailyquests_01" + }, + { + "questHistory": [ + "Quest:stw_stormkinghard_weekly_005", + "Quest:stw_stormkinghard_weekly_002" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-09T00:00:00.000Z", + "poolName": "weeklystormkinghardroll_01" + }, + { + "questHistory": [ + "Quest:s11_holdfastquest_d2_soldier", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_outlander", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_outlander", + "Quest:s11_holdfastquest_d2_ninja", + "Quest:s11_holdfastquest_d2_outlander" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.522Z", + "poolName": "holdfastdaily_part2_01" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-09T00:00:00.000Z", + "poolName": "weeklyelderquestroll_01" + }, + { + "questHistory": [ + "Quest:maydayquest_2019_daily_complete" + ], + "rerollsRemaining": 1, + "nextRefresh": "2024-08-18T03:56:51.412Z", + "poolName": "maydaydailyquest_01" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.524Z", + "poolName": "stormkingdailyquest_01" + }, + { + "questHistory": [ + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest", + "Quest:wargames_completedailyquest" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.508Z", + "poolName": "dailywargameschallenge_01" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t21" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-02T00:00:00.000Z", + "poolName": "weeklyquestroll_19" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t13" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-05-23T00:00:00.000Z", + "poolName": "weeklyquestroll_12" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t15", + "Quest:weeklyquest_tiered_completemissionalerts_t15" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-08-08T00:00:00.000Z", + "poolName": "weeklyquestroll_13" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t11" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-05-16T00:00:00.000Z", + "poolName": "weeklyquestroll_10" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t12" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-05-23T00:00:00.000Z", + "poolName": "weeklyquestroll_11" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t17", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18", + "Quest:weeklyquest_tiered_completemissionalerts_t18" + ], + "rerollsRemaining": 1, + "nextRefresh": "2024-04-18T00:00:00.000Z", + "poolName": "weeklyquestroll_16" + }, + { + "questHistory": [], + "rerollsRemaining": 0, + "nextRefresh": "2025-01-03T20:30:31.515Z", + "poolName": "endurancedailyquests_15" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t18" + ], + "rerollsRemaining": 1, + "nextRefresh": "2024-04-18T00:00:00.000Z", + "poolName": "weeklyquestroll_17" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.510Z", + "poolName": "dailywargamesplankerton_01" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t16" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-08-22T00:00:00.000Z", + "poolName": "weeklyquestroll_14" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.513Z", + "poolName": "dailywargamestwine_01" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.511Z", + "poolName": "dailywargamesstonewood_01" + }, + { + "questHistory": [ + "Quest:s11_holdfastquest_d1_ice", + "Quest:s11_holdfastquest_d1_construct", + "Quest:s11_holdfastquest_d1_burner", + "Quest:s11_holdfastquest_d1_ice", + "Quest:s11_holdfastquest_d1_ice", + "Quest:s11_holdfastquest_d1_burner", + "Quest:s11_holdfastquest_d1_construct", + "Quest:s11_holdfastquest_d1_ice", + "Quest:s11_holdfastquest_d1_construct", + "Quest:s11_holdfastquest_d1_burner", + "Quest:s11_holdfastquest_d1_cramp" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.521Z", + "poolName": "holdfastdaily_part1_01" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2024-11-11T14:18:38.799Z", + "poolName": "starlightdailyquest_01" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t11" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-05-16T00:00:00.000Z", + "poolName": "weeklyquestroll_09" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t09", + "Quest:weeklyquest_tiered_completemissionalerts_t10" + ], + "rerollsRemaining": 1, + "nextRefresh": "2019-05-16T00:00:00.000Z", + "poolName": "weeklyquestroll_08" + }, + { + "questHistory": [ + "Quest:weeklyquest_tiered_completemissionalerts_t25", + "Quest:weeklyquest_tiered_completemissionalerts_t25" + ], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-09T00:00:00.000Z", + "poolName": "weeklyquestroll_23" + }, + { + "questHistory": [], + "rerollsRemaining": 0, + "nextRefresh": "2024-06-12T06:32:03.259Z", + "poolName": "hordev3dailyquests_01" + }, + { + "questHistory": [], + "rerollsRemaining": 1, + "nextRefresh": "2025-01-03T20:30:31.506Z", + "poolName": "dailywargamescanny_01" + }, + { + "questHistory": [], + "rerollsRemaining": 0, + "nextRefresh": "2024-12-30T13:20:28.528Z", + "poolName": "endurancedailyquests_05" + } + ] + } + }, + "legacy_research_points_spent": 119940, + "gameplay_stats": [ + { + "statValue": 1014, + "statName": "zonescompleted" + }, + { + "statValue": 14, + "statName": "habaneroprogression" + }, + { + "statValue": 0, + "statName": "totalroyalroyales" + } + ], + "event_currency": { + "cf": 1.0, + "templateId": "AccountResource:eventcurrency_snowballs" + }, + "matches_played": 376, + "mode_loadouts": [], + "unslot_mtx_spend": 120, + "xp": 5879673, + "quest_completion_session_ids": { + "Quest:starlightquest_daily_complete_d5science": "7a2651d7c23041dfbdec607283f3189e", + "Quest:daily_huskextermination_ranged_shotgun": "7f742e83896143d58c29126a5998b736", + "Quest:s11_holdfastquest_d1_construct": "a12c1aaca9ef40f3b07d9cf256f4226d", + "Quest:daily_destroytransformers": "ffa71d585cc7438695114a280ab8754f", + "Quest:starlightquest_daily_complete_d2": "0dd342903187428bbb6322c1e06be245", + "Quest:hordev3_quest_daily_a01": "49eccdcf8b4e4c0a83caa5680e5268b9", + "Quest:hordev3_quest_daily_a02": "49eccdcf8b4e4c0a83caa5680e5268b9", + "Quest:endurancedaily_t01_w15": "1cea9bb1497c461ea03a7bbd6021ba54", + "Quest:hordev3_quest_daily_a03": "49eccdcf8b4e4c0a83caa5680e5268b9", + "Quest:s11_holdfastquest_deliver_30": "a12c1aaca9ef40f3b07d9cf256f4226d", + "Quest:s11_holdfastquest_d2_ninja": "19170ea713bf4c9487fbc2dc62bba4af", + "Quest:endurancedaily_t01_w20": "1cea9bb1497c461ea03a7bbd6021ba54", + "Quest:s11_holdfastquest_d1_burner": "19170ea713bf4c9487fbc2dc62bba4af" + }, + "packs_granted": 1680 + } + }, + "commandRevision": 40512, + "_id": "a4a01940bca545b1a04626a049c7f8ee", + "items": { + "a53e48b2-737b-4be7-96bc-f4d913f3efa2": { + "templateId": "HomebaseNode:questreward_newfollower5_slot", + "attributes": {}, + "quantity": 1 + }, + "c1f08a65-efde-4847-967e-6d86b67f331e": { + "templateId": "Quest:cannyvalleyquest_filler_3_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-01T05:18:27.456Z", + "level": -1, + "completion_kill_husk_smasher_3_diff5_v3": 30, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5c3fe9d2-9d3c-476a-adee-c0899024b088": { + "templateId": "Worker:managerexplorer_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsExplorer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Explorer-F01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "263c25e6-5c5d-4059-9ff4-773dadf6e201": { + "templateId": "TeamPerk:tpid_dimmak", + "attributes": {}, + "quantity": 1 + }, + "2da14cbd-f35b-41af-99af-00eef23b0f39": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "1", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 38, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "5616e80e-d566-44b9-8e50-2b7173a7c5fb": { + "templateId": "Quest:stonewoodquest_ability_hoverboard", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T02:16:31.452Z", + "completion_stonewoodquest_ability_hoverboard": 1, + "level": -1, + "item_seen": true, + "completion_complete_pve01_diff4": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b623bb02-87b1-41ca-a484-cf8005b241bd": { + "templateId": "Quest:stonewoodquest_tutorial_upgrade", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.865Z", + "completion_upgrades_highlight": 1, + "completion_upgrades_guard_command": 1, + "completion_upgrades_intro": 1, + "level": -1, + "completion_upgrades_guard_upgrades": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_upgrades_tabcallout": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "eec0905f-634a-435a-ba22-370430c8ad35": { + "templateId": "Quest:plankertonquest_filler_4_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-09T05:22:35.288Z", + "completion_complete_mimic_2_diff4": 1, + "level": -1, + "item_seen": true, + "completion_interact_treasurechest_pve02_diff4": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "023256f8-7e86-4c67-8902-72f3a57cfef3": { + "templateId": "Expedition:expedition_sea_supplyrun_short_t01", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.773Z", + "level": 1, + "expedition_max_target_power": 95, + "expedition_min_target_power": 4, + "expedition_slot_id": "expedition.generation.sea.t01_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.773Z" + }, + "quantity": 1 + }, + "f839bf8e-3e32-4bd0-851d-b9c92756ecee": { + "templateId": "Quest:stonewoodquest_reactive_fetch_hoverboard", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T01:36:43.255Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_stonewoodquest_reactive_fetch_hoverboard": 10 + }, + "quantity": 1 + }, + "06475d67-b4cc-4a44-bc1d-a5212f74b54d": { + "templateId": "Quest:heroquest_loadout_outlander_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T19:28:26.836Z", + "level": -1, + "item_seen": true, + "completion_complete_pve03_diff26_loadout_outlander": 300, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "632f5284-310b-4994-85a5-64c48a56d3f2": { + "templateId": "Quest:challenge_missionaccomplished_10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-17T22:37:12.974Z", + "level": -1, + "completion_complete_primary": 7, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "16eeb64f-5258-443a-baa3-5758ffed7dc6": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "c4d5a740-c02a-4f94-ba62-50b0084c0a7c": { + "templateId": "Quest:challenge_toxictreasures_8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-09T05:23:01.370Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "554b76e6-cafa-4420-a9b1-006f3047370f": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd1", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "778b9aef-5257-4bd8-b653-e6699939eab8": { + "templateId": "Schematic:sid_shotgun_hydraulic_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_ele_fire_t03", + "Alteration:aid_att_headshotdamage_t02", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "71a0258f-92c2-4d79-8c39-e369bd65a1b2": { + "templateId": "HomebaseNode:questreward_expedition_propplane3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "7407e83a-d99e-488c-bec6-1c1aadb62539": { + "templateId": "Worker:managersoldier_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsSoldier", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Marksman-M01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "60e61bba-341b-44de-afb4-75a23a9e88db": { + "templateId": "Quest:challenge_missionaccomplished_11", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T03:30:21.667Z", + "level": -1, + "completion_complete_primary": 8, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f083383e-c47e-4c46-bb90-5df2465ec370": { + "templateId": "HomebaseNode:questreward_teamperk_slot1", + "attributes": {}, + "quantity": 1 + }, + "9dc53339-35e7-4b60-8607-5dad1ef6b85c": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAnalytical", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "2281756d-e483-457d-b8d2-fcfbf9cb3ffe": { + "templateId": "TeamPerk:tpid_totallygnarly", + "attributes": {}, + "quantity": 1 + }, + "44c2213d-dc3b-478c-8624-59e4c0b5b741": { + "templateId": "Hero:hid_outlander_008_foundersf_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "1a31438c-cb62-492f-916b-ccb2f4bb7b28": { + "templateId": "Quest:endurancewave30theater02", + "attributes": { + "creation_time": "2024-04-05T22:27:42.608Z", + "quest_state": "Active", + "last_state_change_time": "2024-04-05T22:27:42.608Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4f5779b4-3f30-4221-be4a-3d13cafba851": { + "templateId": "Quest:teamperkquest_holidaycheer", + "attributes": { + "creation_time": "2024-12-28T20:27:31.839Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-28T20:27:40.314Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "41a83d5d-c47e-4514-bff9-22dad7bcc13e": { + "templateId": "HomebaseNode:questreward_feature_survivorlevelup", + "attributes": {}, + "quantity": 1 + }, + "9070fc4b-c016-40ef-8294-f4139e1da209": { + "templateId": "Quest:s11_holdfastquest_season_misty", + "attributes": { + "creation_time": "2024-12-16T20:05:04.715Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-27T16:51:14.534Z", + "completion_s11_holdfastquest_season_misty": 50, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "45435374-23b8-4f2d-a936-44a597b8ae97": { + "templateId": "Schematic:sid_edged_sword_pirate_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_movementspeed_t02", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_g_onmeleecrit_pistolheadshotdamage" + ] + }, + "quantity": 1 + }, + "8c7e54fe-6996-48fd-bcc6-784212251e37": { + "templateId": "Quest:challenge_toxictreasures_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-30T03:11:53.534Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 2, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "08ce7f52-c8df-4a02-90df-d1e90fbc16e1": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAnalytical", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "29d1e5a3-cbda-419a-9bda-2f30fddb22ef": { + "templateId": "Quest:outpostquest_t2_endless", + "attributes": { + "creation_time": "2024-04-05T22:27:42.608Z", + "quest_state": "Active", + "last_state_change_time": "2024-04-05T22:27:42.608Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4c129f2b-5a2d-41b5-88a0-2902b191f53c": { + "templateId": "Quest:cannyvalley_reactive_forts", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T01:21:58.753Z", + "level": -1, + "completion_cannyvalley_reactive_forts": 3, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "29fd89d8-d110-4015-bdd8-b22ab928e792": { + "templateId": "HomebaseNode:questreward_newfollower4_slot", + "attributes": {}, + "quantity": 1 + }, + "a51a0ca1-4c4d-4f65-903c-4181a67b5cd5": { + "templateId": "Quest:cannyvalleyquest_side_3_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-27T05:22:22.950Z", + "completion_complete_powerreactor_3_diff4": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d181fc1c-0096-4774-9488-fc8dd6a57b65": { + "templateId": "Schematic:sid_floor_hoverboard_speed_r_t01", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "07281563-5dd3-441e-9561-1714b2065655": { + "templateId": "Quest:plankertonquest_filler_4_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-23T01:16:08.346Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_buildradargrid_2": 1 + }, + "quantity": 1 + }, + "527cbd26-30d2-4aa0-bae7-8e61f5da1317": { + "templateId": "Worker:worker_halloween_smasher_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "2", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 20, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Smasher", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "8da32986-506e-4a5e-8fb8-e5a34842ccf6": { + "templateId": "HomebaseNode:questreward_homebase_defender2", + "attributes": {}, + "quantity": 1 + }, + "b2f8397c-5e9d-43cf-8870-f0434c201265": { + "templateId": "Quest:cannyvalleyquest_filler_5_d4", + "attributes": { + "completion_complete_destroyencamp_3_diff4": 3, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-05T15:59:18.200Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d33dc929-8d53-41c8-9803-579adc4597ee": { + "templateId": "Worker:workerbasic_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 20, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "8410e936-3d8a-4080-8bfe-6009df214c73": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: 32.10 Hunt the Monster Quests", + "conditions": { + "event": { + "instanceId": "6gvpoahgenlmcbgqtk4vkhb1lu[0]0", + "eventName": "CalendarEvent_STWHuntMonster_Quests", + "eventStart": "2024-10-02T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:huntmonster_quest_a01_interact", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:huntmonster_quest_a01_interact", + "quantity": 1 + }, + { + "templateId": "Quest:huntmonster_quest_a02_destroycrystal", + "quantity": 1 + }, + { + "templateId": "Quest:huntmonster_quest_a03_completehuntmission", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "bc948e87-c327-42e3-8499-44eff29b53ab": { + "templateId": "PersonalVehicle:vid_hoverboard", + "attributes": { + "level": 1 + }, + "quantity": 1 + }, + "140983b6-6c1c-4951-8211-e0d8558ea0bb": { + "templateId": "AccountResource:reagent_evolverarity_sr", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 540 + }, + "fa011790-3f0e-4688-a99c-41555987065c": { + "templateId": "Quest:foundersquest_chooseherobundle", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-26T07:00:47.077Z", + "selection": 1, + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ae56be9e-f8c5-435f-bf39-de33fc696de8": { + "templateId": "Quest:cannyvalley_hidden_end_watchvideo", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-09-25T23:13:23.772Z", + "completion_cannyvalley_hidden_end_watchvideo": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1edfd5ca-f4db-4b06-af74-94867a4ab241": { + "templateId": "Quest:cannyvalleyquest_filler_6_d4", + "attributes": { + "creation_time": "2024-04-05T15:59:18.200Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-07T01:36:34.583Z", + "completion_complete_pve03_diff3_v2": 2, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "completion_questcollect_survivoritemdata_v2": 10, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "75448ad1-6df8-461f-95d7-9daeebc23db0": { + "templateId": "Quest:outpostquest_t2_l10", + "attributes": { + "creation_time": "2024-04-05T17:52:58.782Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-05T22:27:42.604Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_2_10": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "63d5f8d6-681f-4d42-a834-59ee683b77c1": { + "templateId": "Quest:s11_holdfastquest_soup_elite", + "attributes": { + "creation_time": "2025-01-02T20:30:31.504Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.504Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d39b2158-db27-4aa6-9a15-e3378066d75f": { + "templateId": "Quest:s11_holdfastquest_d2_outlander", + "attributes": { + "creation_time": "2025-01-02T20:30:31.524Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.524Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "holdfastdaily_part2_01" + }, + "quantity": 1 + }, + "fe0f89e6-aa00-471a-bba6-c1a19604c73c": { + "templateId": "Quest:outpostquest_t4_l7", + "attributes": { + "creation_time": "2024-04-15T20:29:19.367Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T20:56:14.948Z", + "completion_complete_outpost_4_7": 1, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7cd0922a-5e17-47f8-89be-e6931bd82d62": { + "templateId": "Quest:s11_holdfastquest_season_furnacemaint", + "attributes": { + "creation_time": "2024-12-16T20:05:04.714Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-28T20:27:31.858Z", + "level": -1, + "item_seen": true, + "completion_s11_holdfastquest_season_furnacemaint": 10, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2eac392a-9102-413a-a49f-cfb29db421aa": { + "templateId": "Schematic:sid_sniper_steampunk_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_stability_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_weaponimpact_t03", + "Alteration:aid_att_damage_t03", + "Alteration:aid_g_shrapnel" + ] + }, + "quantity": 1 + }, + "cd7b74f1-f58f-432a-a5fd-cf32ff63342f": { + "templateId": "Quest:plankertonquest_filler_4_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-05T14:37:48.381Z", + "completion_complete_relaysurvivor_2_diff3": 6, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4723b492-180e-4d34-b3ad-48f6f1b2bfcc": { + "templateId": "Quest:weekly_elder_missionalerts_herosupercharge", + "attributes": { + "creation_time": "2025-01-02T20:30:31.526Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.526Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "weeklyelderquestroll_01" + }, + "quantity": 1 + }, + "8a79886b-f58a-4665-a692-6b1d42cda287": { + "templateId": "Quest:wargames_visibilityquest_wargame_tornado", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "606a5d33-ba7f-478f-918e-b281534998d3": { + "templateId": "TeamPerk:tpid_blastfromthepast", + "attributes": {}, + "quantity": 1 + }, + "ce4d3d1c-23d0-46ac-b05c-c13822af985f": { + "templateId": "CollectedResource:Token_collectionresource_nodegatetoken01", + "attributes": { + "last_updated": "2024-12-30T12:37:59.811Z", + "stored_value": 0.19680799999878218 + }, + "quantity": 1 + }, + "f7fd9073-7ad8-483c-966e-3061f08fbc69": { + "templateId": "Quest:cannyvalley_reactive_trainstations", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-22T15:53:23.037Z", + "level": -1, + "completion_cannyvalley_reactive_trainstations": 4, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "58479e69-b925-4fcb-85dc-3786c14a4a1d": { + "templateId": "Quest:outpostquest_t2_l5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T15:59:51.486Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_2_5": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0fd90691-f74b-4487-9fd0-d06d4ed6095d": { + "templateId": "Quest:stonewoodquest_reactive_joelkarolina_visitpubs", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T19:28:34.195Z", + "level": -1, + "item_seen": true, + "completion_stonewoodquest_reactive_joelkarolina_visitpubs": 2, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6b55ed47-a783-42dd-90b9-57c947956c3d": { + "templateId": "Quest:cannyvalley_reactive_rifts", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T01:41:59.297Z", + "completion_cannyvalley_reactive_rifts": 5, + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3f74c199-857f-4c0d-9546-2281f7b4c646": { + "templateId": "HomebaseNode:skilltree_banner", + "attributes": {}, + "quantity": 5 + }, + "1387ffb1-a36d-45fa-9f63-e63924fd1361": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd1", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "765f5868-e62f-4d63-9e1c-a24dd36e11b5": { + "templateId": "Quest:cannyvalley_reactive_telegraph", + "attributes": { + "completion_cannyvalley_reactive_telegraph": 15, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T19:06:26.153Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "636c64d8-7531-44f1-98af-87ec55eac4f1": { + "templateId": "Hero:hid_outlander_025_pirateoutlander_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "64e82332-8055-4efa-b7cd-97d7a5566005": { + "templateId": "Schematic:ammo_shells", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "9ef19461-a1e8-4cbc-84b9-c83976e2ccf2": { + "templateId": "Schematic:ingredient_duct_tape", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "725e09fb-8239-40d1-a7bc-e8b1b44093dd": { + "templateId": "Quest:daily_huskextermination_ranged_sniper", + "attributes": { + "creation_time": "2024-09-23T00:31:58.886Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T20:56:10.752Z", + "completion_kill_husk_sniper": 300, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d29bee46-ba12-4d2e-a217-a49f31dd6427": { + "templateId": "AccountResource:reagent_alteration_upgrade_uc", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 7916 + }, + "805a7edc-0280-488f-bfa1-2c7157e9bdcf": { + "templateId": "HomebaseNode:questreward_expedition_dirtbike2", + "attributes": {}, + "quantity": 1 + }, + "91f357e6-6528-43ad-9bf5-3ea3d4fa3f20": { + "templateId": "Hero:hid_constructor_024_pirateconstructor_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "ec1c771e-20ae-4895-9d35-54df604cb9c9": { + "templateId": "Quest:outpostquest_t3_l8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-29T23:38:23.975Z", + "completion_complete_outpost_3_8": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "64a7850f-1870-4aca-8674-d066f1bc0998": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd1", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "8c924112-5f57-4e9b-92c2-ca99613a0577": { + "templateId": "Expedition:expedition_air_supplyrun_long_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.756Z", + "expedition_criteria": [ + "RequiresLegendaryConstructor", + "RequiresEpicOutlander" + ], + "level": 1, + "expedition_max_target_power": 730, + "expedition_min_target_power": 36, + "expedition_slot_id": "expedition.generation.air.t04_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.756Z" + }, + "quantity": 1 + }, + "6881dd2a-1ca4-4771-a516-f1e47f01b9ce": { + "templateId": "Schematic:ammo_bulletsmedium", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "a64eb7c4-add0-4c00-a0a9-5d11bdb33d8f": { + "templateId": "Schematic:sid_edged_scythe_flintlock_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_movementspeed_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_heavyattackstaminacost_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "9adb120a-2b05-4091-8e22-ddccad877a10": { + "templateId": "Quest:stwstarterbundle18_01", + "attributes": { + "creation_time": "2024-03-26T20:57:48.414Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-27T16:55:05.912Z", + "level": -1, + "item_seen": true, + "quest_rarity": "legendary", + "xp_reward_scalar": 1, + "completion_stwstarterbundle18_01_obj0": 1 + }, + "quantity": 1 + }, + "53144670-9f21-4b83-9af0-698eb9b1f785": { + "templateId": "Schematic:sid_sniper_standard_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_maxdurability_t01", + "Alteration:aid_ele_fire_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "61d73ec8-ebb3-463c-8869-ae20c7ba0272": { + "templateId": "Quest:cannyvalleyquest_side_4_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-05T05:08:19.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_gate_3_diff4": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4ce6e4cd-b7c6-4cfa-b2c4-19b0b08a4271": { + "templateId": "HomebaseNode:questreward_expedition_propplane", + "attributes": {}, + "quantity": 1 + }, + "160161f8-6aba-4fac-a857-3a72cfa6f0d5": { + "templateId": "Quest:challenge_toxictreasures_12", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T22:49:07.338Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f40b809c-c4fe-4770-ad97-535f993059cf": { + "templateId": "Schematic:sid_shotgun_tactical_founders_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_g_weapon_onreload_damagestack" + ] + }, + "quantity": 1 + }, + "9b0c4fd4-dbb0-4ae8-a968-fbdc6525d1eb": { + "templateId": "Quest:cannyvalley_reactive_signalexplore", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-19T03:28:35.444Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_cannyvalley_reactive_signalexplore": 7 + }, + "quantity": 1 + }, + "b83444a3-58c1-4056-bdba-ba6856c5bab1": { + "templateId": "Quest:pickaxequest_stw006_tier_7", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-08-27T17:18:39.202Z", + "level": -1, + "item_seen": true, + "completion_pickaxequest_stw006_tier_7": 7, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "25b0d708-e733-4a5c-8211-801ff2f27cae": { + "templateId": "Worker:worker_halloween_lobber_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Lobber", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "cb39d447-7297-4f2b-99d1-c5cef7051e65": { + "templateId": "Quest:stonewoodquest_fetch_stormcalls", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.842Z", + "completion_stonewoodquest_fetch_stormcalls": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "dcfcee63-9d52-438f-8a0f-332117aa9301": { + "templateId": "AccountResource:reagent_evolverarity_vr", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 635 + }, + "8bca60b6-d8ec-4844-b34d-2c26cd3d609f": { + "templateId": "Expedition:expedition_sea_supplyrun_medium_t02", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.773Z", + "expedition_criteria": [ + "RequiresRareOutlander", + "RequiresCommando" + ], + "level": 1, + "expedition_max_target_power": 200, + "expedition_min_target_power": 10, + "expedition_slot_id": "expedition.generation.sea.t02_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.773Z" + }, + "quantity": 1 + }, + "0218d5a9-5c7a-43c5-ba67-06b7c65fd1ff": { + "templateId": "Quest:outpostquest_t1_l5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T17:24:24.536Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_1_5": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a6aece06-7ffc-4b4f-8832-116099325904": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "8fd82c63-2e6b-4f8b-9dd1-260bdc30cc07": { + "templateId": "AccountResource:reagent_alteration_upgrade_sr", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 35 + }, + "ddbe140f-e52e-43dd-a6e1-ca58c7277948": { + "templateId": "Worker:workerbasic_c_t01", + "attributes": { + "gender": "2", + "personality": "Homebase.Worker.Personality.IsAnalytical", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "abd361dc-c2de-4e51-a7cd-47c28a538dd1": { + "templateId": "Quest:plankertonquest_filler_2_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T22:52:26.960Z", + "level": -1, + "completion_complete_evacuateshelter_2_diff5": 2, + "item_seen": true, + "completion_questcollect_survivoritemdata": 15, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7ae52ee2-11bd-4450-9271-c81a6532865a": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "2", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "e1ef174e-a4f6-4863-80ca-2dab1372bb5a": { + "templateId": "Quest:daily_huskextermination_outlander", + "attributes": { + "creation_time": "2024-12-30T12:36:47.013Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-30T12:36:47.013Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "77698032-0070-468b-8119-232f908417ac": { + "templateId": "Quest:reactivequest_trollstash_r2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-17T23:42:14.764Z", + "completion_quest_reactive_trollstash": 1, + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "08f4f2b5-d072-4f9c-b352-c7412a3133ca": { + "templateId": "Worker:managerexplorer_sr_spacebound_t05", + "attributes": { + "squad_id": "squad_attribute_scavenging_scoutingparty", + "personality": "Homebase.Worker.Personality.IsDreamer", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsExplorer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Explorer-spacebound", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "bd989109-d8a6-4ec4-b4cb-87e2be76932e": { + "templateId": "Quest:outpostquest_t4_l1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-05T21:03:46.374Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_4_1": 1, + "completion_custom_twinedeployoutpost": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9926db59-b4f8-45c6-8743-df7f9e373924": { + "templateId": "PrerollData:preroll_basic", + "attributes": { + "fulfillmentId": "63BE689248CAF1251C84B4B3574F90EF", + "expended_streakbreakers": {}, + "level": 1, + "highest_rarity": 0, + "offerId": "B9B0CE758A5049F898773C1A47A69ED4", + "expiration": "2025-01-03T00:00:00.000Z", + "items": [ + { + "itemType": "AccountResource:personnelxp", + "attributes": {}, + "quantity": 800 + }, + { + "itemType": "Worker:managerexplorer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Explorer-M01" + }, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_pistol_auto_uc_ore_t01", + "attributes": { + "Alteration": { + "LootTierGroup": "AlterationTG.Ranged.UC", + "Tier": 0 + }, + "alterations": [ + "Alteration:aid_att_firerate_ranged_t01", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_ranged_headshotstreak_dmgbonus_v2" + ] + }, + "quantity": 1 + }, + { + "itemType": "Worker:managerexplorer_uc_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Explorer-M01" + }, + "quantity": 1 + }, + { + "itemType": "AccountResource:eventcurrency_snowballs", + "attributes": {}, + "quantity": 50 + } + ] + }, + "quantity": 1 + }, + "cfd02e76-21d3-4e52-8855-509560ccfcd3": { + "templateId": "Defender:did_defenderassault_basic_c_t00", + "attributes": { + "squad_id": "", + "level": 1, + "squad_slot_idx": 0, + "item_seen": true + }, + "quantity": 1 + }, + "6c623927-435e-4cae-b8c8-fa4e91dd12ea": { + "templateId": "HomebaseNode:questreward_newheroloadout4_dummy", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "76a82044-8598-4024-b9b3-3c3232abb1f6": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "team_perk": "606a5d33-ba7f-478f-918e-b281534998d3", + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "33db9e9f-efe4-463b-83f6-c9a84079d3b8" + }, + "loadout_index": 6 + }, + "quantity": 1 + }, + "9ee1ca44-569e-4859-9a8b-02db5ec55bc8": { + "templateId": "HomebaseNode:questreward_newfollower1_slot", + "attributes": {}, + "quantity": 1 + }, + "4fe42382-724d-47d6-a14c-0f06030d3ed9": { + "templateId": "AccountResource:reagent_alteration_generic", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 2991 + }, + "916f0b57-fb9e-4e4c-9b71-b665c78606a5": { + "templateId": "Quest:cannyvalley_landmark_mansion", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-26T21:07:28.723Z", + "completion_cannyvalley_landmark_mansion": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6e51625d-95e1-4351-b856-6739a9e0fe7d": { + "templateId": "HomebaseNode:questreward_buildingupgradelevel2", + "attributes": {}, + "quantity": 1 + }, + "67058590-2bcc-4341-831c-5ebc053761fa": { + "templateId": "HomebaseNode:questreward_mission_defender2", + "attributes": {}, + "quantity": 1 + }, + "f3e9c0b9-a4b2-42d8-98a0-f41b55b9bf2a": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "1d4ad99c-c7d1-4f25-a1d2-ff25dc3db5bf": { + "templateId": "BannerToken:bannertoken_stw005_starlight2", + "attributes": { + "level": 1, + "banner_id": "HomebaseBannerIcon:starlightbanner2" + }, + "quantity": 1 + }, + "e3c87d8c-22e9-4741-bff5-3956cc5aca48": { + "templateId": "Quest:wargames_visibilityquest_challenge_nobuild", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ba5120db-2f22-44f7-b650-38772f1442b0": { + "templateId": "Hero:hid_commando_008_foundersm_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "385a5023-a2f3-4e5b-a7ba-45dd6c135beb": { + "templateId": "Quest:achievement_buildstructures", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2018-08-09T22:33:07.412Z", + "completion_build_any_structure": 54980, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "86aff30c-4698-4d13-8a6d-e9582aade865": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAnalytical", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "9d642a4f-5595-47a8-9221-78fcb882c18a": { + "templateId": "HomebaseNode:startnode_commandcenter", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "8f12b443-4269-4087-a824-04ad600461e9": { + "templateId": "Quest:cannyvalleyquest_filler_4_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-05T00:37:03.268Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_whackatroll_3_diff4_v3": 1 + }, + "quantity": 1 + }, + "c812a049-5cab-46c1-9494-8d7efbbe4be0": { + "templateId": "Quest:outpostquest_t3_l9", + "attributes": { + "completion_complete_outpost_3_9": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-12-29T19:21:16.098Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3e4b764d-2516-4982-a516-a6566f913d39": { + "templateId": "Quest:challenge_eldritchabominations_18", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-23T16:54:14.401Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 90, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c731e33c-794c-473e-9d1f-8e11ada67a1f": { + "templateId": "Schematic:sid_edged_sword_neonglow_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_firerate_melee_t01", + "Alteration:aid_att_heavyattackstaminacost_t03", + "Alteration:aid_att_heavyattackstaminacost_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_onmeleehit_stackbuff_armor" + ] + }, + "quantity": 1 + }, + "61f9e2d7-e2d4-4842-af80-dfa2771d26c9": { + "templateId": "Quest:heroquest_outlanderleadership", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:36:30.981Z", + "level": -1, + "completion_unlock_skill_tree_outlander_leadership": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9bbd7cb1-1b6f-4577-80f9-4c247f503250": { + "templateId": "Quest:endurancewave30theater04", + "attributes": { + "creation_time": "2024-12-30T12:37:03.332Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-30T12:37:03.332Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "307b0a1a-c812-4646-8164-fb852e45a6a6": { + "templateId": "Token:xpboost", + "attributes": { + "level": 1 + }, + "quantity": 3726522 + }, + "0d474ac3-c070-414f-a7aa-712a91b8f12a": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "1915151a-0b62-4465-99b0-bad53320200a": { + "templateId": "Quest:phoenixquest_tutorial_theater", + "attributes": { + "creation_time": "min", + "completion_phoenixtheater_level_guardscreen": 1, + "level": -1, + "completion_phoenixtheater_level_highlight": 1, + "sent_new_notification": true, + "xp_reward_scalar": 1, + "completion_phoenixtheater_power_highlight": 1, + "quest_state": "Claimed", + "last_state_change_time": "2021-02-09T01:56:40.466Z", + "completion_phoenixtheater_inventory_guardscreen": 1, + "completion_phoenixtheater_intro_guardscreen": 1, + "completion_phoenixtheater_power_guardscreen": 1, + "quest_rarity": "uncommon" + }, + "quantity": 1 + }, + "e8f693ed-fe3d-4389-8203-0206849ad961": { + "templateId": "Quest:cannyvalley_reactive_coaches", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T16:00:06.381Z", + "completion_cannyvalley_reactive_coaches": 7, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "10def7ff-8ba0-4f9b-8355-fd46b8cae60b": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 20, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "706211f1-405f-415a-8ebb-e1c42b1d51e2": { + "templateId": "Quest:outpostquest_t3_l6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-03T20:57:33.996Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_outpost_3_6": 1 + }, + "quantity": 1 + }, + "b5d43f97-a3d8-4e9f-bb23-cc5b764e7e2c": { + "templateId": "Quest:stonewoodquest_retrievedata_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T20:49:40.715Z", + "level": -1, + "item_seen": true, + "completion_complete_retrievedata_1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4d43e7e2-0b46-4c61-b698-e51ad99493de": { + "templateId": "HomebaseNode:questreward_expedition_truck2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "073636b1-637e-4edf-8245-4a26fb577136": { + "templateId": "Quest:plankertonquest_mechanical_refuelintro", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.857Z", + "completion_plankertonquest_mechanical_refuelintro": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fb8c88e6-6550-440b-8521-293b041e04bf": { + "templateId": "Quest:stw_stormkinghard_weekly_002", + "attributes": { + "creation_time": "2025-01-02T20:30:31.529Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.529Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "weeklystormkinghardroll_01" + }, + "quantity": 1 + }, + "14f1d8e0-36cd-4f2f-9eab-698ff75d9359": { + "templateId": "Schematic:sid_piercing_spear_scavenger_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_att_lifeleech_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critchance_t03", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_onmeleehit_stackbuff_damage" + ] + }, + "quantity": 1 + }, + "923b794c-c676-45aa-8666-bc30dc2cdf24": { + "templateId": "Quest:challenge_missionaccomplished_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T07:19:47.166Z", + "level": -1, + "completion_complete_primary": 5, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1690fbfe-61ca-4d4b-be59-8c887a95f18d": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd6", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "54c63741-14ec-42db-912f-6fa58af7f9a8": { + "templateId": "Quest:wargame_quest_firstopen", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T19:48:29.601Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_wargame_firstopen": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0d557462-fad6-461f-995e-3d6e71fb169e": { + "templateId": "HomebaseNode:questreward_newfollower3_slot", + "attributes": {}, + "quantity": 1 + }, + "f95d166c-f5e8-4442-9002-9607ba0ec617": { + "templateId": "Quest:wargames_visibilityquest_challenge_surprise", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2ad382ef-47a2-4558-8dc5-e94026030dda": { + "templateId": "HomebaseNode:questreward_evolution2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "6139e9b0-33d0-4728-810c-cf44dc1772c6": { + "templateId": "Schematic:sid_assault_auto_halloween_sr_ore_t05", + "attributes": { + "level": 50, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_physical_t05", + "Alteration:aid_att_critdamage_t05", + "Alteration:aid_conditional_afflicted_dmgbonus_t05", + "Alteration:aid_att_critdamage_t05", + "Alteration:aid_att_damage_t05", + "Alteration:aid_g_affliction_v2" + ], + "alteration_base_rarities": [ + "uncommon", + "common", + "uncommon", + "uncommon", + "rare", + "common" + ], + "favorite": true + }, + "quantity": 1 + }, + "dfd2a5a9-44ed-4cd3-94ff-e80ffae05dc3": { + "templateId": "Quest:twinepeaksquest_filler_2_d1", + "attributes": { + "completion_complete_gate_4_diff1": 3, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-05T05:08:22.881Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cbd85b3e-a9fe-42a4-8ebc-887c9c42188f": { + "templateId": "HomebaseNode:skilltree_adrenalinerush", + "attributes": {}, + "quantity": 6 + }, + "d762160f-0adb-43fe-a393-0e0a419a3cfc": { + "templateId": "Quest:challenge_holdthedoor_16", + "attributes": { + "creation_time": "2024-03-29T05:40:33.653Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-31T21:36:54.190Z", + "completion_complete_outpost": 9, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7eba7bd5-f8b7-48f8-a990-1f8571c58dd5": { + "templateId": "Quest:plankertonquest_launchrocket_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T04:15:07.842Z", + "level": -1, + "sent_new_notification": true, + "completion_complete_launchrocket_2": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d81d17ff-857f-4ac1-9221-ef7e3622d5c0": { + "templateId": "Hero:hid_outlander_026_bunnyoutlander_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "9560f074-09e3-462d-a368-590245c7def1": { + "templateId": "Quest:stonewoodquest_reactive_joelkarolina_gatherportraits", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-30T01:47:00.421Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_stonewoodquest_reactive_joelkarolina_gatherportraits": 10, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "725aa069-d9f5-48ae-9e49-9fe7fbe71bc0": { + "templateId": "Quest:cannyvalley_reactive_bases", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T05:33:41.477Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_bases": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "27cf82de-a3d5-4759-a8ca-652b975e4858": { + "templateId": "Worker:workerbasic_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 20, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "35747289-83b3-40c2-8260-3656694eb650": { + "templateId": "Quest:challenge_eldritchabominations_20", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-07T15:35:17.242Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 100, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7b22adaf-1ffe-4e10-9718-84ef7e77fed2": { + "templateId": "Quest:stwstarterbundle18_getrewards", + "attributes": { + "creation_time": "2024-03-26T20:57:31.060Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-26T20:57:48.413Z", + "level": -1, + "completion_stwstarterbundle18_getrewards_obj0": 1, + "quest_rarity": "legendary", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "55265a0f-bed3-4947-915b-028c7749b269": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 30, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "96da96d9-b5c7-40f8-b01b-15970e8640ce": { + "templateId": "Quest:cannyvalley_reactive_junkfood", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-10T21:32:26.384Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_junkfood": 15, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9d62f2e6-5dfd-485c-a276-05eb6e227d8f": { + "templateId": "Quest:plankertonquest_filler_5_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T19:19:25.667Z", + "level": -1, + "item_seen": true, + "completion_complete_medbot_2_diff2": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a297ec2f-0c73-47b9-8480-1416e65551dc": { + "templateId": "Quest:cannyvalley_landmark_memorial", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T07:05:58.123Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_landmark_memorial": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5f537db3-892c-4615-a04e-61bd821dc833": { + "templateId": "Quest:reactivequest_gatherfood", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-08T19:52:04.236Z", + "completion_quest_reactive_gatherfood": 8, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f9b63aef-ae43-4377-9048-aac43187afb9": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "aeb89fd6-97c2-4475-84f7-0478c1f8892d": { + "templateId": "AccountResource:reagent_people", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 97254 + }, + "a4e9008b-1a42-4356-89bc-2cd0a3304c93": { + "templateId": "Quest:challenge_eldritchabominations_15", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-30T01:55:10.494Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 75, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "83cf5a12-997f-44f5-9187-213442870f2b": { + "templateId": "HomebaseNode:questreward_feature_defenderlevelup", + "attributes": {}, + "quantity": 1 + }, + "a0cef3ed-c72c-41a1-806c-a3663554b6a2": { + "templateId": "Schematic:sid_pistol_vacuumtube_auto_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_nature_intrin_t02", + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_slowed_dmgbonus_t03", + "Alteration:aid_g_ranged_headshot_explodeondeath_v2" + ] + }, + "quantity": 1 + }, + "3aa41f41-2195-42ce-8ac6-a33e2fd0a565": { + "templateId": "Token:worldinventorybonus", + "attributes": { + "level": 1 + }, + "quantity": 30 + }, + "099a815c-39c9-4a6d-821f-e9223894be6d": { + "templateId": "Quest:challenge_holdthedoor_11", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-04T23:47:24.632Z", + "completion_complete_outpost": 7, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a4d4c17c-912a-4bbb-830c-9f030605d279": { + "templateId": "Worker:worker_halloween_husky_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Husky", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "497d1967-b004-413a-ba35-017a3605c8e1": { + "templateId": "Worker:workerbasic_uc_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsDependable", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "d80533ee-3061-46a1-8420-6a1a316bcd76": { + "templateId": "Quest:outpostquest_t2_l1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T05:00:25.035Z", + "level": -1, + "item_seen": true, + "completion_custom_plankdeployoutpost": 1, + "completion_complete_outpost_2_1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b404e32b-d528-42d5-b3f9-f61ca391e9d6": { + "templateId": "Quest:stonewoodquest_fetch_triangulatingpop", + "attributes": { + "completion_stonewoodquest_fetch_triangulatingpop": 5, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.847Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5d60be01-3242-47b0-9fb9-a621e3af16de": { + "templateId": "Worker:workerbasic_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 10, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "2609df12-9b65-45b6-b394-3e66522bb6e3": { + "templateId": "Quest:stonewoodquest_gathercollect_armoryupgrade", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.846Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_stonewoodquest_gathercollect_armoryupgrade": 7, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0d8c339d-aacb-411d-af6b-0bb5a014bb3e": { + "templateId": "TeamPerk:tpid_blakebeardsstash", + "attributes": {}, + "quantity": 1 + }, + "155f8ff9-694c-4901-85c7-441e372e34d8": { + "templateId": "Quest:cannyvalleyquest_side_3_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-17T19:16:40.371Z", + "completion_complete_delivergoods_3_diff3": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "43daf40b-d235-4760-908e-adf40032729c": { + "templateId": "Quest:plankertonquest_filler_2_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-08T18:00:36.212Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_kill_husk_2_diff4_v2": 500, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "81e9bd35-24bf-4a99-947c-3a560836ce49": { + "templateId": "Quest:challenge_toxictreasures_14", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-28T17:49:36.379Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 8, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "36071087-17bb-46f0-b1db-118a0a8f6591": { + "templateId": "Quest:cannyvalleyquest_launchtherocket", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-05T00:37:08.229Z", + "selection": -1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_questcomplete_cannyvalleyquest_launchrocket_d5": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "adeb8169-0c3d-4820-80a7-4152df719826": { + "templateId": "Expedition:expedition_resourcerun_stone_medium", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.769Z", + "level": 1, + "expedition_max_target_power": 105, + "expedition_min_target_power": 5, + "expedition_slot_id": "expedition.generation.land.t01_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.769Z" + }, + "quantity": 1 + }, + "90aaeaa6-5013-4d6c-abf3-45f47a7fc755": { + "templateId": "TeamPerk:tpid_onetwopunch", + "attributes": {}, + "quantity": 1 + }, + "4dab08c3-dc14-43cc-965e-48af01ab0041": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "06e62186-1471-4968-a0f5-de789425227d": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "01bfaee2-3840-4523-8821-cdbdd160a523" + }, + "loadout_index": 0 + }, + "quantity": 1 + }, + "6575adfc-67fa-4489-bc64-58e3debd53b4": { + "templateId": "Quest:challenge_eldritchabominations_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T03:01:53.226Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4706989a-9e77-4624-9d19-4ae6a03adfed": { + "templateId": "Schematic:sid_edged_axe_light_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_firerate_melee_t03", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "52e35185-8179-4596-94bd-f1be24b85c8c": { + "templateId": "Quest:challenge_holdthedoor_7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T19:07:29.198Z", + "completion_complete_outpost": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0a3f43e5-c889-4583-8460-8be6c3c6f45f": { + "templateId": "Quest:plankertonquest_reactive_speakers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T16:35:06.541Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_plankertonquest_reactive_speakers": 7, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f0dac00e-8728-4e0c-abbe-eca343667938": { + "templateId": "Quest:outpostquest_t2_l7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-04T21:41:26.192Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_outpost_2_7": 1 + }, + "quantity": 1 + }, + "6f98b498-e0d4-4706-b92f-9875ce8c36a7": { + "templateId": "Quest:outpostquest_t3_l7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-29T19:58:26.884Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_3_7": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "07fe3732-0382-442e-9046-e86bc20136fd": { + "templateId": "Quest:plankertonquest_filler_6_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-01T04:59:00.919Z", + "completion_quick_complete_pve02": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "58b2fb9b-e280-4c87-be29-46269d6d218d": { + "templateId": "Worker:worker_halloween_lobber_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Lobber", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "70154143-755d-414d-a125-deb6c6603a94": { + "templateId": "HomebaseNode:questreward_expedition_speedboat4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "19eb7ab6-ddb1-40ca-a327-7431b3c35d89": { + "templateId": "Quest:s11_holdfastquest_seasonelite_group", + "attributes": { + "creation_time": "2024-12-16T20:05:04.718Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.718Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "83e5ff5c-4dc2-42c6-a491-cfdc9413d377": { + "templateId": "Quest:s11_holdfastquest_season_survive_15", + "attributes": { + "creation_time": "2024-12-16T20:05:04.716Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-27T16:51:14.496Z", + "completion_s11_holdfastquest_season_survive_15": 1, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "62b40a26-d9f0-4c96-a339-61d7c1c6c82d": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: 32.10 Beta Storm Mission Alert", + "conditions": { + "event": { + "instanceId": "77gbgiprdnq094hk9i5pkjn9p9[0]0", + "eventName": "CalendarEvent_BetaStorm_RepeatableQuest", + "eventStart": "2024-09-18T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:genericquest_completebetastorms_repeatable", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:genericquest_completebetastorms_repeatable", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "7c0fd20a-c1bd-4d43-a30d-216e193857d2": { + "templateId": "Quest:achievement_savesurvivors", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2018-08-09T22:33:07.412Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 1507, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "dadcd873-a0ae-470c-ad00-64192b1aa519": { + "templateId": "Quest:challenge_toxictreasures_10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T06:29:08.317Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 6, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "32735911-bdee-4b45-a5d8-c907a04da9eb": { + "templateId": "Quest:challenge_missionaccomplished_16", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-23T02:04:44.149Z", + "level": -1, + "completion_complete_primary": 10, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a3955dc1-8d69-45f1-a52d-74465dc5defd": { + "templateId": "Quest:cannyvalley_reactive_tinfoil", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-06T02:41:38.940Z", + "selection": 3, + "level": -1, + "completion_cannyvalley_reactive_tinfoil": 7, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "27a89c11-f851-438c-8217-eef9c2a2ecc2": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "437336f2-09df-4365-9681-683458041a9c": { + "templateId": "Quest:cannyvalleyquest_outpost_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T02:22:58.656Z", + "level": -1, + "item_seen": true, + "completion_questcomplete_outpostquest_t3_l2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6ba75fd9-f3ff-4a66-bafa-fe53238eb7cc": { + "templateId": "HomebaseNode:questreward_newheroloadout3_dummy", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "3afa9414-9035-40ad-9ab7-3e54a55ef520": { + "templateId": "Quest:stonewoodquest_side_1_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T03:01:45.547Z", + "completion_complete_whackatroll_1_diff3": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2e9dbc94-fee0-4dad-97f0-7cadfd4a272d": { + "templateId": "Schematic:sid_blunt_heavy_flintlock_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damageresistance_t01", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_onmeleehit_stackbuff_critrate" + ] + }, + "quantity": 1 + }, + "948bd2c2-575b-4007-a9c6-3064bc912331": { + "templateId": "AccountResource:reagent_traps", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 31011 + }, + "b8547b87-ec5e-4433-8985-1be667630339": { + "templateId": "Quest:cannyvalley_reactive_musichalls", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-20T05:19:01.566Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_musichalls": 5, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7ebe6ed0-673d-41cc-a686-6a3a30b281de": { + "templateId": "Expedition:expedition_traprun_air_medium_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.758Z", + "expedition_criteria": [ + "RequiresEpicNinja" + ], + "level": 1, + "expedition_max_target_power": 575, + "expedition_min_target_power": 28, + "expedition_slot_id": "expedition.generation.air.t04_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.758Z" + }, + "quantity": 1 + }, + "4bf8a292-95c8-46e4-b3a5-01fa9bfc525f": { + "templateId": "Quest:reactivequest_flingers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-31T04:00:50.157Z", + "completion_quest_reactive_flingers": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f921d1b4-158c-4a7a-a2ec-1b6bcb402332": { + "templateId": "Worker:managergadgeteer_sr_zapps_t05", + "attributes": { + "squad_id": "squad_attribute_scavenging_gadgeteers", + "personality": "Homebase.Worker.Personality.IsCurious", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsGadgeteer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Gadgeteer-zapps", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "d5c437b3-a328-4e4b-b843-0b86f0d79b24": { + "templateId": "Quest:achievement_destroygnomes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T20:47:09.390Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_destroy_gnome": 100, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6e97bd94-79b3-40de-ad86-65798a157fb8": { + "templateId": "Quest:outpostquest_t2_l6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T02:10:02.874Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_2_6": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5253e13b-d56f-46cc-9103-9a75fb2396b0": { + "templateId": "Schematic:ingredient_blastpowder", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "8e21f04d-babc-49e1-a847-2a1fc1521fc9": { + "templateId": "Quest:twinepeaksquest_filler_1_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-26T04:21:05.234Z", + "level": -1, + "item_seen": true, + "completion_complete_gate_double_4_diff1": 2, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "07b43bad-75be-441a-8753-c61e7004d6fd": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "4e099f6a-66bb-4741-8897-53e6b06a833c": { + "templateId": "Expedition:expedition_choppingwood_t00", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.763Z", + "level": 1, + "expedition_max_target_power": 15, + "expedition_min_target_power": 1, + "expedition_slot_id": "expedition.generation.miningore", + "expedition_expiration_start_time": "2025-01-02T20:30:29.763Z" + }, + "quantity": 1 + }, + "2617ca19-904d-4049-9528-f7b45af0d7c6": { + "templateId": "HomebaseNode:questreward_evolution3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "a32c1b83-a08e-423a-b90e-8ddfd722eff1": { + "templateId": "Quest:endurancewave30theater01", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-19T02:41:39.183Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7a6d7000-6003-4f1e-b606-c98821427ac6": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "07c30f8e-8c3d-42db-99f5-894a3eb7d9e4": { + "templateId": "Quest:cannyvalleyquest_filler_4_d3", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-16T21:00:10.089Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ddad77a7-bc4b-4b4a-a430-7118a7c5eb50": { + "templateId": "Schematic:sid_pistol_autoheavy_founders_r_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_firerate_ranged_t01", + "Alteration:aid_att_stability_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onreload_damagebuff" + ] + }, + "quantity": 1 + }, + "3c83ec1a-efaf-45f3-ad30-4898cda99d42": { + "templateId": "Quest:plankertonquest_filler_3_d4", + "attributes": { + "creation_time": "min", + "level": -1, + "item_seen": true, + "completion_custom_pylonused_stamina": 1, + "sent_new_notification": true, + "xp_reward_scalar": 1, + "quest_state": "Claimed", + "last_state_change_time": "2018-10-08T20:17:35.361Z", + "completion_custom_pylonused_health": 1, + "completion_custom_pylonused_shield": 1, + "completion_custom_pylonused_movement": 1, + "completion_custom_pylonused_build": 1, + "quest_rarity": "uncommon" + }, + "quantity": 1 + }, + "ee7228f7-8c6a-4a1e-a612-ecaef2948d9d": { + "templateId": "Quest:foundersquest_getrewards_3_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-26T06:58:15.501Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2e14503a-85ed-431e-886d-f3acfc0f4dbf": { + "templateId": "Quest:challenge_leavenoonebehind_13", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T22:24:06.770Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 85, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "282edd11-2635-4f9c-8f6e-28a87c227424": { + "templateId": "Quest:teamperkquest_roundtrip", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-06T17:30:13.086Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "df2fb610-0a01-4366-9592-d85f8a7d4e61": { + "templateId": "HomebaseNode:skilltree_buildinghealth", + "attributes": {}, + "quantity": 7 + }, + "1ca48ad5-d4bb-4153-b936-833e4c67fad2": { + "templateId": "Quest:plankertonquest_filler_5_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T19:48:17.668Z", + "completion_complete_launchballoon_2_diff5": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b10cb1b0-baf4-4bc8-904e-8715766afd96": { + "templateId": "Quest:wargames_visibilityquest_wargame_saucer", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-06T16:10:23.219Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "004c73ee-8fc7-434a-863a-fe0df643656c": { + "templateId": "Quest:cannyvalley_reactive_servers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T19:59:45.243Z", + "selection": 0, + "completion_cannyvalley_reactive_servers": 6, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "26805779-1098-4e37-8320-bf5009335e30": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "c8d1a220-c1a0-4d4d-a22a-167ea1a9dcba": { + "templateId": "Quest:tutorial_loadout_gadgets", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:27:49.933Z", + "completion_heroloadout_gadgets_guardscreen1": 1, + "level": -1, + "completion_heroloadout_gadgets_intro": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "702d4eac-8d22-44e9-ace2-cc754a6fd2db": { + "templateId": "Token:quests_stwstarterbundle18", + "attributes": { + "level": 1 + }, + "quantity": 1 + }, + "9797e777-253f-4d4f-b402-3f44b219f859": { + "templateId": "Schematic:sid_edged_sword_medium_laser_founders_r_ore_t01", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t02", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_maxdurability_t01", + "Alteration:aid_g_weapon_onhit_energynova" + ] + }, + "quantity": 1 + }, + "c1afe675-b3cb-444c-a50e-bc2900881ab8": { + "templateId": "Quest:cannyvalley_reactive_periscopes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T04:09:13.138Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_periscopes": 10, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3ece183f-885e-44db-949c-fb4cddfcb979": { + "templateId": "Quest:stonewoodquest_tutorial_expeditions", + "attributes": { + "completion_expeditions_tabcallout": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.868Z", + "completion_expeditions_guard_heroes": 1, + "level": -1, + "completion_expeditions_intro": 1, + "completion_expeditions_guard_command": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_expeditions_highlight_command": 1 + }, + "quantity": 1 + }, + "626e8016-d2d7-4613-8ccf-8d346c613b3c": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "b2537c78-dd6d-472b-9eb8-b006158ea338": { + "templateId": "Quest:cannyvalleyquest_filler_1_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-05T05:43:23.719Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_delivergoods_3_diff5": 2 + }, + "quantity": 1 + }, + "efa8149e-9b18-4aa4-8c14-49bb27c40c25": { + "templateId": "Quest:plankertonquest_autumnfoothills_locate", + "attributes": { + "creation_time": "2024-04-05T05:08:16.313Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-10T03:58:42.325Z", + "level": -1, + "completion_plankertonquest_autumnfoothills_locate": 9, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4d03c423-db33-40b9-8523-ac8ed0090b88": { + "templateId": "Quest:s11_holdfastquest_season_survive_30", + "attributes": { + "creation_time": "2024-12-16T20:05:04.716Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-27T16:51:14.537Z", + "level": -1, + "item_seen": true, + "completion_s11_holdfastquest_season_survive_30": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e31c10a9-49c9-47f3-aeaf-47e27fac3138": { + "templateId": "Hero:hid_ninja_021_sr_t03", + "attributes": { + "outfitvariants": [], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 30, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "76bf92dc-c223-4746-b1de-5ec9d17e0809": { + "templateId": "AccountResource:reagent_evolverarity_r", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 615 + }, + "fc254670-86b2-4eac-82d0-7669cf65e928": { + "templateId": "Quest:wargames_visibilityquest_wargame_tiki", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-22T14:38:10.647Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "eda81f6c-c6ec-40f4-9fb7-3acff34319df": { + "templateId": "Quest:outpostquest_t2_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T16:40:21.410Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_2_2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d9f31e70-ed3a-491a-8b37-def0c7d953cc": { + "templateId": "Schematic:sid_blunt_scavenger_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_damageresistance_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "edf69573-f27d-4fed-a423-e09668805c7d": { + "templateId": "Quest:wargames_visibilityquest_wargame_pods", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f48f1f2c-010b-4335-91cb-6b6a4840bf35": { + "templateId": "Quest:challenge_leavenoonebehind_11", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T17:27:10.697Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 75, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c7ab9992-95e8-4384-bea2-50725cd44e5e": { + "templateId": "Quest:cannyvalley_reactive_cannons", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-19T04:46:56.168Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_cannons": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "74121b43-be50-4a2e-a918-55c2d8cc4fc1": { + "templateId": "Stat:offense_team", + "attributes": { + "level": 1 + }, + "quantity": 224 + }, + "8648402f-4b01-4937-8f4c-973d88f00b70": { + "templateId": "Quota:restxp", + "attributes": { + "max_quota": 4320956, + "level": 1, + "units_per_minute_recharge": 3601, + "recharge_delay_minutes": 360, + "last_mod_time": "2024-12-29T23:03:37.839Z", + "current_value": 0.0 + }, + "quantity": 1 + }, + "d256fc5b-c644-4b78-815b-ba6aaec24b11": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "1", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "83020b22-970d-4519-a474-29f992fbeb95": { + "templateId": "Quest:challenge_missionaccomplished_7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T07:26:21.799Z", + "level": -1, + "completion_complete_primary": 6, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e2da84ab-2526-4389-9120-a87b5150fb72": { + "templateId": "Quest:outpostquest_t3_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T17:35:53.544Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_3_3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "12537b3e-1ad7-4c8a-8c8e-dc30389cc99c": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "ee0bfe74-1360-4e70-ab48-c9532105b9cf": { + "templateId": "Quest:challenge_upgradealteration", + "attributes": { + "completion_alteration_upgrade": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T17:00:49.426Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2bd40328-7c52-40c5-860a-fe520e9808c6": { + "templateId": "Quest:cannyvalley_reactive_tubs", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-18T17:07:50.765Z", + "completion_cannyvalley_reactive_tubs": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "844363c8-5706-4d7e-866f-a844f3c15dca": { + "templateId": "Schematic:sid_assault_dragon_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t01", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_stability_t02", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_ranged_headshot_explodeondeath_v2" + ] + }, + "quantity": 1 + }, + "3c5616d5-3dc9-4e9b-a567-9d3fa1053509": { + "templateId": "AccountResource:schematicxp", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 3983649 + }, + "c2556b71-f450-4091-ab0e-cb6e98bf0c38": { + "templateId": "Quest:heroquest_loadout_constructor_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T19:28:07.736Z", + "level": -1, + "item_seen": true, + "completion_complete_pve01_diff24_loadout_constructor": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b2b64e81-7da8-4c73-ba6c-58549022407b": { + "templateId": "TeamPerk:tpid_longarmofthelaw", + "attributes": {}, + "quantity": 1 + }, + "a2180e61-dab7-4783-9a25-8ae228452f04": { + "templateId": "HomebaseNode:questreward_pickaxe", + "attributes": {}, + "quantity": 1 + }, + "a77d6664-f10c-48cd-a751-eb49d9c8bb90": { + "templateId": "Schematic:ammo_explosive", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "70c04b8d-567e-4cb6-8463-b645d77e5b5c": { + "templateId": "Quest:wargames_visibilityquest_challenge_headgames", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "95478aaa-36df-458d-bb59-8012601b32a3": { + "templateId": "HomebaseNode:skilltree_pickaxe", + "attributes": {}, + "quantity": 7 + }, + "0318f9b4-f784-449c-98e3-74d675b0c36a": { + "templateId": "Quest:winter_seasonal_destroy_01", + "attributes": { + "creation_time": "2024-12-16T20:05:04.723Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.723Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "910f8fa6-d4f2-4916-a661-b83811e067b4": { + "templateId": "Quest:plankertonquest_filler_1_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-21T15:56:10.328Z", + "completion_complete_gate_double_2": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "284cfed5-4759-401b-a762-c2207a74dd0f": { + "templateId": "Quest:challenge_missionaccomplished_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T20:32:36.790Z", + "level": -1, + "completion_complete_primary": 4, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bc5a2525-0e0c-445d-bce3-99bf5e342975": { + "templateId": "HomebaseNode:skilltree_buildandrepairspeed", + "attributes": {}, + "quantity": 7 + }, + "b4030a41-ecfc-4d64-b91b-b3c3703af68a": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "036e4d7c-3a61-4d8d-95e1-042da1a354f8": { + "templateId": "Quest:plankertonquest_outpost_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.861Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t2_l4": 1 + }, + "quantity": 1 + }, + "1108983c-7222-48bd-b88b-9e8acb81179b": { + "templateId": "Quest:cannyvalleyquest_side_1_d5", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-08-05T00:37:13.682Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ae157a7f-0019-4701-bee7-9c0836251d5e": { + "templateId": "Quest:stonewoodquest_joelkarolina_killmistmonsters", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T05:33:46.599Z", + "completion_stonewoodquest_joelkarolina_killmistmonsters": 100, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8d042133-7c8d-4087-a326-fea56ae71203": { + "templateId": "Quest:heroquest_ninja_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T03:53:08.187Z", + "completion_unlock_skill_tree_ninja_leadership": 1, + "level": -1, + "item_seen": true, + "completion_kill_husk_melee": 20, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2e3c3f5d-1b99-4936-8dbc-48ff079efd75": { + "templateId": "Hero:hid_ninja_016_f_v1_sr_t03", + "attributes": { + "outfitvariants": [], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 30, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "8c425dc7-459f-44b7-ac76-31171a5c7b36": { + "templateId": "Quest:challenge_leavenoonebehind_20", + "attributes": { + "creation_time": "2024-05-11T02:10:41.112Z", + "quest_state": "Active", + "last_state_change_time": "2024-05-11T02:10:41.112Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 117, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5702170e-17c9-473d-9eac-9ace0e21f5ca": { + "templateId": "Quest:challenge_eldritchabominations_13", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T16:28:26.544Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 65, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cb48bff7-66d6-4f7b-9dc1-12fc8b0d1e7f": { + "templateId": "Quest:winter_seasonal_mission_01", + "attributes": { + "creation_time": "2024-12-16T20:05:04.724Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.724Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6ab7212f-e8f3-4bf2-a34c-437a326e8802": { + "templateId": "Quest:cannyvalleyquest_outpost_l5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-22T21:47:41.681Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcomplete_outpostquest_t3_l5": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "674656b3-57ef-48b6-9bfc-6b4c33698f06": { + "templateId": "Quest:cannyvalley_reactive_mandelaeffect", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T00:01:33.989Z", + "completion_cannyvalley_reactive_mandelaeffect": 9, + "selection": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "09987e00-2500-45ec-b8bc-da26b00a61a0": { + "templateId": "Defender:did_defenderpistol_basic_f_sr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_critchance_ranged", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_firerate", + "Alteration:aid_att_def_maxhealth" + ] + }, + "quantity": 1 + }, + "9ecf989f-1346-498d-998b-2efac5cf66b7": { + "templateId": "Schematic:sid_assault_neonglow_lmg_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t02", + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_att_stability_t02", + "Alteration:aid_att_firerate_ranged_t03", + "Alteration:aid_g_weapon_hitstreak_aoe_dmg_v2" + ] + }, + "quantity": 1 + }, + "a49fc41e-fb29-4a18-b5d6-7a3f08f4dda1": { + "templateId": "Quest:heroquest_outlander_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T01:00:57.737Z", + "level": -1, + "item_seen": true, + "completion_complete_exploration_1_diff2": 1, + "completion_unlock_skill_tree_outlander_leadership": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "59df3c50-0bc7-461e-8261-be9221425ea9": { + "templateId": "HomebaseNode:questreward_evolution4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "ff769d4d-f572-49f5-a817-24404aeed79f": { + "templateId": "Quest:wargames_visibilityquest_challenge_explode", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d7b0347f-c5d1-4bb4-9c35-4ef0acf42508": { + "templateId": "Quest:endurancedaily_t02_w30", + "attributes": { + "creation_time": "2024-12-29T13:20:28.534Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.534Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "fb761e21-8658-47d2-b50c-95835c543ee1": { + "templateId": "Quest:outpostquest_t1_l1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:48:29.660Z", + "level": -1, + "completion_custom_supplydropreceived": 1, + "completion_complete_outpost_1_1": 1, + "item_seen": true, + "sent_new_notification": true, + "completion_custom_deployoutpost": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8edacd65-277c-4340-ba9e-091d8c96befd": { + "templateId": "Stat:fortitude", + "attributes": { + "level": 1 + }, + "quantity": 504 + }, + "791b6b55-9a0c-4a82-8cdc-a32005748460": { + "templateId": "Quest:stonewoodquest_tutorial_research", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.865Z", + "level": -1, + "sent_new_notification": true, + "completion_research_highlight": 1, + "quest_rarity": "uncommon", + "completion_research_tabcallout": 1, + "completion_research_guard_command": 1, + "completion_research_intro": 1, + "xp_reward_scalar": 1, + "completion_research_guard_research": 1 + }, + "quantity": 1 + }, + "2283fadb-2309-4b83-b713-5564bb89ba27": { + "templateId": "Quest:plankertonquest_filler_5_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-23T01:44:59.040Z", + "completion_complete_exploration_2": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f9b12e2a-023d-4b90-8f4b-d11d2f01f484": { + "templateId": "HomebaseNode:questreward_expedition_dirtbike3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "2ecc3466-1b5a-47e7-85a2-18e9322e91df": { + "templateId": "Quest:outpostquest_t1_l8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-21T05:37:09.818Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_outpost_1_8": 1 + }, + "quantity": 1 + }, + "2a0b1a80-ccdd-4b8c-9343-cc498a7b101a": { + "templateId": "Quest:challenge_leavenoonebehind_16", + "attributes": { + "creation_time": "2024-03-25T16:51:26.813Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-29T05:24:54.717Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 100, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "742b6c8b-ac94-479f-afa1-5432ef0a54a6": { + "templateId": "Quest:challenge_eldritchabominations_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T02:16:12.855Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 15, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6f73f149-9d76-4fe8-a3a6-cea7fc3c3f5f": { + "templateId": "AccountResource:reagent_alteration_ele_nature", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 13000 + }, + "26f75fd9-2069-424e-97c5-6a851db54eeb": { + "templateId": "Quest:plankertonquest_autumnfoothills_eliminate", + "attributes": { + "creation_time": "2024-03-25T18:08:05.729Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-05T05:08:16.313Z", + "completion_plankertonquest_autumnfoothills_eliminate": 10, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e5215b8c-d1bd-4e68-b71f-778f4de9f4aa": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "ef2d064a-4dd9-4015-b812-1548dde58723": { + "templateId": "Schematic:sid_shotgun_tactical_founders_r_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_g_weapon_onreload_damagestack" + ] + }, + "quantity": 1 + }, + "4279bdd5-35a7-4e5c-a18c-4e23fec56c11": { + "templateId": "TeamPerk:tpid_holidaycheer", + "attributes": {}, + "quantity": 1 + }, + "c286773c-5612-4162-bb90-c0d474b6a4f3": { + "templateId": "Quest:challenge_missionaccomplished_18", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-26T18:16:12.419Z", + "level": -1, + "completion_complete_primary": 11, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6cdc2e58-10f2-462f-9cd8-d309a0c7ac72": { + "templateId": "Quest:plankertonquest_landmark_plankharbor", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T16:50:41.368Z", + "level": -1, + "item_seen": true, + "completion_plankertonquest_landmark_plankharbor": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3778292f-d1da-48da-ae1d-0c2967ce0a76": { + "templateId": "Quest:challenge_leavenoonebehind_15", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-03-25T16:51:26.808Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 95, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "851b968c-0cb2-4ed0-9ad1-3c348a9aae46": { + "templateId": "HomebaseNode:questreward_newfollower2_slot", + "attributes": {}, + "quantity": 1 + }, + "2cdd2c5d-3f5a-402a-8cbb-e74c522b1fda": { + "templateId": "Quest:cannyvalleyquest_outpost_l6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-03T20:57:38.923Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcomplete_outpostquest_t3_l6": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5c71e0f0-ec39-4d44-9494-742a8aba7b81": { + "templateId": "Quest:s11_holdfastquest_soup_30", + "attributes": { + "creation_time": "2025-01-02T20:30:31.504Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.504Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "030d2565-2bde-489d-bd1b-3807eff715d6": { + "templateId": "Quest:plankertonquest_filler_4_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-28T04:46:00.602Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_destroyencamp_2_diff2": 2, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cdb99dd9-fcbb-4e25-84fa-c77c90942c0c": { + "templateId": "HomebaseNode:questreward_mission_defender3", + "attributes": {}, + "quantity": 1 + }, + "ecdb7b8b-173e-4498-83a2-6b4c628d5917": { + "templateId": "Quest:stonewoodquest_side_1_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T02:36:40.375Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_quick_complete_pve01": 2, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "90f4c1e8-39dd-4bf6-bf22-b6bd348ae8a3": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 50, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "ee6dc231-e0f1-4260-9cb9-e6378f993f8d": { + "templateId": "Quest:challenge_weaponupgrade_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T09:08:10.585Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_upgrade_any_weapon": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bf1bea88-0e74-45a0-8660-c82879aabf7b": { + "templateId": "Quest:heroquest_blakebeard_blakebeardsstash", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T03:27:43.945Z", + "completion_heroquest_blakebeard_blakebeardsstash": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b0eb98db-044c-4b51-b54d-5817c1f8c3d1": { + "templateId": "Quest:cannyvalleyquest_filler_1_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-19T04:30:50.130Z", + "completion_complete_mimic_3_diff4": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0fa41ebd-d876-4316-a5ae-0a55d727ad2c": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Mission Alerts", + "conditions": { + "event": { + "instanceId": "rig5qb36g0vmrqh5u73285ifvm[0]1", + "eventName": "CalendarEvent_Persistent_EventMissionAlerts", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "67bdb30f-6f86-4627-a80a-a6979cea770a": { + "templateId": "Quest:challenge_eldritchabominations_17", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-07T15:53:40.322Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 85, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "35e1a79e-cf40-4e6b-bbb8-c87057aee43b": { + "templateId": "Worker:managerinventor_c_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsDependable", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsInventor", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Inventor-M01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "16f6cda0-bb07-4137-b3e3-37f705bc935f": { + "templateId": "Quest:cannyvalley_reactive_dinobones", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T19:25:32.241Z", + "completion_cannyvalley_reactive_dinobones": 7, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "51da1928-20dd-442e-9c09-d5a1b8f7ba5a": { + "templateId": "HomebaseNode:questreward_expedition_speedboat3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "de4dbec5-0737-406d-9c4d-2da1c328807e": { + "templateId": "Schematic:ammo_energycell", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "8d844f5d-fe6c-4bb2-a8fe-b85426b1e54b": { + "templateId": "Quest:challenge_toxictreasures_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T22:38:32.155Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 2, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e5955b79-eca6-4de6-9b0d-77b74b5fe525": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Frostnite Weekly Challenge 6", + "conditions": { + "event": { + "instanceId": "tj4n9158flfv1d09arkc56i791[0]1", + "eventName": "CalendarEvent_Holdfast_Week6", + "eventStart": "2025-01-02T00:00:00.000Z", + "eventEnd": "2025-01-09T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:s11_holdfastquest_soup_30", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_soup_elite", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_soup_deposit", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:s11_holdfastquest_soup_30", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_soup_elite", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_soup_deposit", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_soup_45", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "3193e0df-4666-47a3-884e-b9191f0ef8ea": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "10fd7c7c-66fa-4b73-a402-084e1ee47fe8": { + "templateId": "Schematic:sid_edged_sword_medium_vt_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_heavyattackstaminacost_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "7c970eed-2875-4149-9030-18cd8247f2ac": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "efcbb2fb-ad08-4bfd-a8c6-3d28c397681a": { + "templateId": "Quest:plankertonquest_fetch_searchingforlab", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.849Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_plankertonquest_fetch_searchingforlab": 7 + }, + "quantity": 1 + }, + "c5bc4590-e222-4ee7-b7cb-4f6993c3c438": { + "templateId": "Schematic:sid_edged_scythe_neonglow_vr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_conditional_slowed_dmgbonus_t03", + "Alteration:aid_g_onmeleehit_stackbuff_damage" + ] + }, + "quantity": 1 + }, + "c9bbdaa0-8413-4a4c-848e-1349d73b8c04": { + "templateId": "Quest:plankertonquest_filler_1_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T03:00:30.615Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_powerreactor_2_diff2_v2": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a87fd622-bd7c-468a-885f-7ab0ec72f018": { + "templateId": "Quest:weeklyquest_tiered_completemissionalerts_t25", + "attributes": { + "creation_time": "2025-01-02T20:30:31.528Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.528Z", + "selection": -1, + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "weeklyquestroll_23" + }, + "quantity": 1 + }, + "ef8beeb5-aff3-4437-9fe9-445b92394419": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "fc305981-a3e2-41f1-a567-ca4b62c80260": { + "templateId": "Quest:daily_mission_specialist_soldier", + "attributes": { + "creation_time": "2024-05-27T04:32:11.756Z", + "quest_state": "Active", + "last_state_change_time": "2024-05-27T04:32:11.756Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f9ba6644-543d-43e5-b7dd-7a821c5fe947": { + "templateId": "Hero:hid_commando_008_foundersf_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "0fa7704f-eb9d-4a37-a84b-be91ab4210da": { + "templateId": "Quest:plankertonquest_filler_3_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-30T02:30:44.143Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_anomaly_2_diff3_v2": 3 + }, + "quantity": 1 + }, + "1bf94ad2-00a1-412a-b53c-8a30e3c47687": { + "templateId": "Quest:teamperkquest_dangerdanger", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-01T06:10:43.306Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "99edfd11-7e85-4b31-935a-8622a8a83f22": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "bd011d5f-4537-4d5b-a302-af0af40c5f6a": { + "templateId": "Quest:challenge_herotraining_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-01T05:07:53.446Z", + "level": -1, + "item_seen": true, + "completion_upgraderarity_hero": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e6ba8951-35d1-458a-94b1-830a468ce087": { + "templateId": "HomebaseNode:questreward_feature_reperk", + "attributes": {}, + "quantity": 1 + }, + "d9e6012d-a150-4cef-9b7b-e5e2f0041edd": { + "templateId": "Quest:challenge_leavenoonebehind_18", + "attributes": { + "creation_time": "2024-04-07T01:36:38.226Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-14T01:15:16.317Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 110, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0673b85b-0aad-4482-af94-e34588ed9d47": { + "templateId": "Quest:cannyvalley_reactive_dinosaurs", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-26T16:24:18.662Z", + "level": -1, + "completion_cannyvalley_reactive_dinosaurs": 5, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "999f82e6-e638-4768-ae3d-5dee216a7fed": { + "templateId": "Quest:outpostquest_t1_endless", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-19T02:41:39.183Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d479ba4c-0ee4-4ff7-91dc-392af2c0e805": { + "templateId": "Quest:challenge_missionaccomplished_19", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T18:45:51.808Z", + "level": -1, + "completion_complete_primary": 12, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a924fd8c-057a-4b9e-9eb0-16815f462781": { + "templateId": "Quest:cannyvalley_landmark_highnoon", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:37:28.141Z", + "level": -1, + "completion_cannyvalley_landmark_highnoon": 1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4b800616-165c-4554-8138-566ef1885cf0": { + "templateId": "Worker:workerbasic_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 13, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "caf243ab-e418-40d6-aaf6-447b471f82a0": { + "templateId": "HomebaseNode:questreward_newheroloadout5_dummy", + "attributes": {}, + "quantity": 1 + }, + "128df2b1-0ecf-4196-bc9d-9c4278e1c445": { + "templateId": "Quest:challenge_replacealteration", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T16:59:35.698Z", + "level": -1, + "item_seen": true, + "completion_alteration_respec": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "300a321d-702d-4096-bb91-37ceb57a76f5": { + "templateId": "Quest:wargames_visibilityquest_challenge_notraps", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2a963e32-4560-4d75-a613-3bd5df5570dd": { + "templateId": "Schematic:sid_blunt_light_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_heavyattackstaminacost_t02", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_heavyattackstaminacost_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "222ba5d8-c29b-4ac1-8b3a-5b8c0409cd7e": { + "templateId": "Schematic:sid_pistol_pirate_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_headshotdamage_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_g_ranged_headshot_buffswordcritrating" + ] + }, + "quantity": 1 + }, + "9c4c09df-7910-43ad-b275-252db52ef54c": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: 33.10 Storm King's Domain", + "conditions": { + "event": { + "instanceId": "6g35aukg2s1q2epl9npdmusviu[0]0", + "eventName": "CalendarEvent_StormKing_Domain_Quests", + "eventStart": "2024-12-10T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:stormking_daily_landmark_bossfight", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "54f6620c-b4fa-40fd-9881-7307956cc247": { + "templateId": "Hero:hid_constructor_basehyper_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "041d13bb-bda8-4ca4-aa61-a5f339723dfd": { + "templateId": "Quest:stonewoodquest_tutorial_survivorslotting", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.868Z", + "completion_survivorslotting_tabcallout": 1, + "level": -1, + "completion_survivorslotting_highlight_command": 1, + "sent_new_notification": true, + "completion_survivorslotting_guard_survivors": 1, + "quest_rarity": "uncommon", + "completion_survivorslotting_guard_command": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6eba6c88-b740-4cb8-8d42-f1cc9a60cdf0": { + "templateId": "Worker:managergadgeteer_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsGadgeteer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Gadgeteer-M01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "8b46fff4-3d38-44d4-8b63-96ca461bddd0": { + "templateId": "Quest:cannyvalleyquest_filler_7_d4", + "attributes": { + "creation_time": "2024-04-07T01:36:34.584Z", + "quest_state": "Active", + "last_state_change_time": "2024-04-07T01:36:34.584Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9c1fa3ed-60fc-4eb8-b255-38bd6a626af0": { + "templateId": "Worker:managersoldier_sr_ramsie_t05", + "attributes": { + "squad_id": "squad_attribute_arms_fireteamalpha", + "personality": "Homebase.Worker.Personality.IsAdventurous", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsSoldier", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Soldier-ramsie", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "0103a382-884b-4ab7-893c-3a78e725e62f": { + "templateId": "Quest:challenge_eldritchabominations_14", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-28T04:06:20.486Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 70, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "944bd08e-e0a8-42ce-9557-9dbfe027dbcc": { + "templateId": "Quest:pickaxequest_stw001_tier_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:14.490Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6626561a-81d8-4975-91a3-537ad126bdc1": { + "templateId": "Quest:pickaxequest_stw007_basic", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:20.146Z", + "level": -1, + "completion_questcomplete_stonewoodquest_closegate_d1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "453d1917-c6fb-4aca-b89a-e14fedf821d4": { + "templateId": "Quest:wargames_visibilityquest_challenge_fog", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "52c396fc-1231-465a-b0cb-00991c37a16f": { + "templateId": "Schematic:sid_piercing_spear_dragon_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t01", + "Alteration:aid_att_firerate_melee_t01", + "Alteration:aid_att_heavyattackstaminacost_t03", + "Alteration:aid_att_firerate_melee_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_meleedmgvslightning" + ] + }, + "quantity": 1 + }, + "f29680e6-14b6-49dd-81b8-2116b1972cf7": { + "templateId": "Schematic:sid_blunt_hammer_heavy_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_att_lifeleech_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "8a177918-c42e-4f81-8561-d0cc34d1837f": { + "templateId": "HomebaseNode:questreward_homebase_defender5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "b4c86522-2ba9-41ca-9f12-5ce8929b93ee": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "0a3c859c-dd97-4722-99cb-36dc31c1ab86": { + "templateId": "Quest:challenge_eldritchabominations_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T05:45:41.262Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 30, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e007f5df-05c8-4af5-b581-83fa1ef1c1c9": { + "templateId": "HomebaseNode:questreward_feature_researchsystem", + "attributes": {}, + "quantity": 1 + }, + "81412f73-5281-4caa-bb98-dca76dfe8806": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Lobby", + "conditions": { + "event": { + "instanceId": "ql7erq29n8fu66il13nm30tqpn[0]1", + "eventName": "CalendarEvent_Persistent_LobbyStW_Winterfest", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "b87476a8-4c05-40c6-908a-e6e41bbe299e": { + "templateId": "Worker:workerbasic_r_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsAnalytical", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "bd34c31f-6bfc-49db-8436-f230f321177d": { + "templateId": "Schematic:sid_pistol_handcannon_semi_vt_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "a046355e-2050-4e09-b9f3-3caec93f2e1a": { + "templateId": "Expedition:expedition_air_supplyrun_medium_t02", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.762Z", + "expedition_criteria": [ + "RequiresRareCommando" + ], + "level": 1, + "expedition_max_target_power": 215, + "expedition_min_target_power": 10, + "expedition_slot_id": "expedition.generation.air.t02_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.762Z" + }, + "quantity": 1 + }, + "40bece7d-c045-44b0-b35d-33e3007b0839": { + "templateId": "Quest:reactivequest_shielders", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T06:00:31.611Z", + "level": -1, + "item_seen": true, + "completion_quest_reactive_shielders": 20, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d788badb-c40c-44ad-8720-699f2d43043f": { + "templateId": "Quest:foundersquest_outlander_weaponupgrade_vr", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-08T17:17:34.168Z", + "level": -1, + "completion_craft_founders_pistol_r": 1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "epic", + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t1_l3": 1 + }, + "quantity": 1 + }, + "3f2e13b3-e702-44b1-a386-4c6c511a09b2": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "1", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 50, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "b29e3a1b-8c07-4459-9fc7-3eaf842b3495": { + "templateId": "Token:accountinventorybonus", + "attributes": { + "level": 1 + }, + "quantity": 535 + }, + "bc602e6f-e19e-4193-8172-0d4f58593abc": { + "templateId": "TeamPerk:tpid_trickandtreat", + "attributes": {}, + "quantity": 1 + }, + "c11804c5-6f1e-4b5b-ba0b-c671ce7d008b": { + "templateId": "Quest:endurancedaily_t02_w05", + "attributes": { + "creation_time": "2024-12-29T13:20:28.532Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.532Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "9cf10993-fb15-43cc-8834-3500ba522472": { + "templateId": "Quest:tutorial_loadout_preset1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:27:54.115Z", + "completion_heroloadout_preset_highlight": 1, + "level": -1, + "completion_heroloadout_preset_guardscreen1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "81fcac3d-70c5-4342-9380-e3febae7bdb6": { + "templateId": "TeamPerk:tpid_keepout", + "attributes": {}, + "quantity": 1 + }, + "1a1bfe11-0e68-4580-90c6-8479c536fd6a": { + "templateId": "Schematic:sid_pistol_flintlock_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_ranged_headshotstreak_dmgbonus_v2" + ] + }, + "quantity": 1 + }, + "2ce1a2c7-89c0-474d-9105-fc1d7a944ae1": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "2", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "ee88ab33-dec7-4ccd-81b2-6fde20861c0e": { + "templateId": "Quest:homebasequest_slotoutpostdefender", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T20:52:03.118Z", + "completion_assign_defender": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0e073b69-7cf7-4039-adb6-2a75b598b13a": { + "templateId": "Quest:cannyvalley_reactive_demotape", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-09-25T23:13:19.073Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_demotape": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b07ba0df-3d8c-4d9d-8100-17ba30daee7c": { + "templateId": "Schematic:sid_pistol_stormking_sr_ore_t05", + "attributes": { + "level": 50, + "item_seen": true, + "alterations": [ + "Alteration:aid_g_stormkingpistolhomingprojectiles", + "Alteration:aid_att_critdamage_t04", + "Alteration:aid_att_headshotdamage_t04", + "Alteration:aid_att_damage_physical_t05", + "Alteration:aid_att_damage_t04", + "Alteration:aid_att_weaponimpact_t04" + ], + "alteration_base_rarities": [ + "common", + "common", + "uncommon", + "rare", + "uncommon", + "rare" + ], + "favorite": true + }, + "quantity": 1 + }, + "fb942960-1e1a-4f3e-a0bb-a6601a81ea58": { + "templateId": "Quest:achievement_killmistmonsters", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2018-08-09T22:33:07.412Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 9090, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e0d244d4-6351-4a0b-a063-cda0ed189784": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "1855234a-b724-4a13-9895-391c009ad068" + }, + "loadout_index": 3 + }, + "quantity": 1 + }, + "b004fdd9-025e-4ef5-b994-6addc7c58473": { + "templateId": "Schematic:sid_edged_sword_heavy_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_maxdurability_t01", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "5c6650da-5e1b-44eb-a5a2-cee5151f031d": { + "templateId": "Quest:challenge_leavenoonebehind_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-15T22:15:02.937Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 30, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1f40bff2-0a85-475a-8022-5b0249324b51": { + "templateId": "Stat:resistance", + "attributes": { + "level": 1 + }, + "quantity": 354 + }, + "78fa81a3-8d00-4037-9f7b-8a79a0868ec4": { + "templateId": "Quest:outpostquest_t3_l1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T19:07:38.761Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_3_1": 1, + "completion_custom_cannydeployoutpost": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5173e2cc-b5e3-499a-abd2-6dea7980d2d8": { + "templateId": "Quest:stonewoodquest_tutorial_levelup_weapon", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.864Z", + "level": -1, + "completion_schematicupgrade_armoryguard": 1, + "completion_schematicupgrade_tabcallout": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3fd7d93c-cb39-4b06-8865-fec481786efd": { + "templateId": "Expedition:expedition_sea_supplyrun_long_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.750Z", + "expedition_criteria": [ + "RequiresEpicCommando" + ], + "level": 1, + "expedition_max_target_power": 485, + "expedition_min_target_power": 24, + "expedition_slot_id": "expedition.generation.sea.t03_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.750Z" + }, + "quantity": 1 + }, + "e0ee949a-eaa7-4a96-9092-ea57ecb114e9": { + "templateId": "Schematic:sid_assault_lmg_drum_founders_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_stability_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_ele_water_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onfire_damagestack" + ] + }, + "quantity": 1 + }, + "2090c41c-fa13-441a-bbb1-97e837d5540e": { + "templateId": "Quest:outpostquest_t4_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-20T05:45:27.571Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_4_2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9e3d5a3f-0c81-41a0-ab89-ad09931f056a": { + "templateId": "Hero:hid_commando_021_sr_t03", + "attributes": { + "outfitvariants": [], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 30, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "6833991b-0187-4acb-969c-25302382700b": { + "templateId": "HomebaseNode:skilltree_hoverturret", + "attributes": {}, + "quantity": 5 + }, + "7cfa7ae3-4a62-4bdf-8aa0-f643770c84cc": { + "templateId": "Quest:stonewoodquest_closegate_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T00:07:57.544Z", + "level": -1, + "item_seen": true, + "completion_complete_gate_1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cfae5ec3-8c12-4c16-a6ad-47a632b64a00": { + "templateId": "Stat:fortitude_team", + "attributes": { + "level": 1 + }, + "quantity": 224 + }, + "1a79f739-b1e4-40bc-9bce-de35f0f4a9c4": { + "templateId": "Expedition:expedition_supplyrun_short_t01", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.766Z", + "expedition_criteria": [ + "RequiresConstructor" + ], + "level": 1, + "expedition_max_target_power": 80, + "expedition_min_target_power": 4, + "expedition_slot_id": "expedition.generation.land.t01_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.766Z" + }, + "quantity": 1 + }, + "d2c84468-4c52-4ebf-b2ae-22932f4d6931": { + "templateId": "Quest:stormking_daily_landmark_bossfight", + "attributes": { + "creation_time": "2025-01-02T20:30:31.525Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.525Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "stormkingdailyquest_01" + }, + "quantity": 1 + }, + "af7c674c-8279-4aea-88d4-156dec8dd10b": { + "templateId": "Quest:stonewoodquest_fetch_directorstuff", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.848Z", + "level": -1, + "sent_new_notification": true, + "completion_stonewoodquest_fetch_directorstuff": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "89b4cdf4-f124-49ea-8260-bf563d4af3e9": { + "templateId": "Quest:cannyvalley_landmark_bossfight", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-02T01:28:20.341Z", + "selection": 3, + "level": -1, + "item_seen": true, + "completion_cannyvalley_landmark_bossfight": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b4d9f1e6-551a-4053-839a-6663e917cb84": { + "templateId": "Quest:challenge_holdthedoor_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T03:38:08.394Z", + "completion_complete_outpost": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3315733b-fdcb-416f-bdab-dc1fb9738190": { + "templateId": "Quest:challenge_leavenoonebehind_19", + "attributes": { + "creation_time": "2024-04-14T01:15:16.323Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-05-11T02:10:41.105Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 115, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0e845f5d-c06c-434c-997d-b35a2dd82d30": { + "templateId": "Quest:cannyvalley_reactive_vacuum", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-27T05:30:05.408Z", + "completion_cannyvalley_reactive_vacuum": 30, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "400263e0-89b6-4abc-8802-4961419272a8": { + "templateId": "Quest:heroquest_loadout_soldier_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T20:47:14.067Z", + "level": -1, + "item_seen": true, + "completion_complete_pve03_diff24_loadout_soldier": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3fc09e97-ee04-4a1b-8c75-bf42cae0da65": { + "templateId": "Quest:challenge_herotraining_1", + "attributes": { + "completion_upgrade_any_hero": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T09:07:09.120Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "416375de-3207-4f60-b805-9f6f56f9f498": { + "templateId": "Quest:stonewoodquest_side_1_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-16T19:42:21.846Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 15, + "sent_new_notification": true, + "completion_complete_pve01_diff5_v2": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "028ec0de-5e52-44cb-b905-ed313b96a1bf": { + "templateId": "Hero:hid_ninja_010_f_vr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "95541465-3645-48c4-baca-31bb874e22e7": { + "templateId": "Quest:challenge_holdthedoor_8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T18:14:03.634Z", + "completion_complete_outpost": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b1bddef4-d313-4147-9424-a0a23b992a8b": { + "templateId": "Quest:challenge_holdthedoor_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-20T00:00:11.331Z", + "completion_complete_outpost": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3b2aa5d9-0c4d-4204-93ea-fbe268403527": { + "templateId": "Quest:endurancedaily_t02_w20", + "attributes": { + "creation_time": "2024-12-29T13:20:28.533Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.533Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "67cdfe26-8498-4aef-8838-1e314eb58b4b": { + "templateId": "Quest:cannyvalleyquest_filler_1_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T18:39:20.273Z", + "level": -1, + "completion_complete_evacuate_3_diff3": 2, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a78b5f49-8baa-48e7-99ce-29381170844d": { + "templateId": "HomebaseNode:questreward_homebase_defender4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "2352c5bb-c6d7-46af-bfba-33273d45934c": { + "templateId": "HomebaseNode:questreward_newheroloadout8_dummy", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "61e2ef20-fd06-43be-aa53-7bad3d41b84f": { + "templateId": "Quest:cannyvalley_reactive_oilsamples", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T07:18:56.426Z", + "completion_cannyvalley_reactive_oilsamples": 5, + "selection": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fb676339-b97c-4661-afe7-af56aea16867": { + "templateId": "HomebaseNode:questreward_recyclecollection", + "attributes": {}, + "quantity": 1 + }, + "e6285a04-15fe-4279-8cdd-ad72e6c7eb52": { + "templateId": "Expedition:expedition_air_survivorscouting_medium_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.760Z", + "level": 1, + "expedition_max_target_power": 375, + "expedition_min_target_power": 18, + "expedition_slot_id": "expedition.generation.air.t03_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.760Z" + }, + "quantity": 1 + }, + "39580467-7b62-45f0-8dd3-88589e871264": { + "templateId": "Quest:challenge_leavenoonebehind_7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T23:40:04.283Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 50, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "abc6b8e1-1a8b-4e09-af44-ba0443f1d20b": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "870dd4a3-1fc8-40e5-a8f4-5cf7e0197d65": { + "templateId": "Quest:cannyvalley_reactive_route99", + "attributes": { + "completion_cannyvalley_reactive_route99_gasstation": 1, + "completion_cannyvalley_reactive_route99_motel": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T06:47:51.105Z", + "completion_cannyvalley_reactive_route99_truckstop": 1, + "completion_cannyvalley_reactive_route99_diner": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "09974b22-af34-46ed-876b-fd4c321342ad": { + "templateId": "Quest:challenge_leavenoonebehind_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-20T18:22:00.131Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 40, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5afe893b-68f2-44cd-b53b-ba507fa47220": { + "templateId": "Quest:cannyvalleyquest_filler_1_d1", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-10T19:07:38.765Z", + "completion_quick_complete_pve03": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e23564a1-3e0e-4a41-b7a4-ce262db4caff": { + "templateId": "Quest:challenge_missionaccomplished_12", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-19T03:52:34.738Z", + "level": -1, + "completion_complete_primary": 8, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0c9e1a5e-b06a-4548-9733-f29019b98725": { + "templateId": "Quest:tutorial_loadout_commander", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:27:57.270Z", + "level": -1, + "completion_heroloadout_commander_guardscreen1": 1, + "completion_heroloadout_commander_highlight": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4057c2e9-1f78-46f0-b548-3f9f6bf60389": { + "templateId": "Schematic:sid_assault_raygun_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_magazinesize_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "c2bd14ee-8305-407f-8247-b19242970e86": { + "templateId": "Hero:hid_commando_011_m_easter_sr_t03", + "attributes": { + "outfitvariants": [], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 30, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "e7259f05-f629-40ce-b98d-a7073442067d": { + "templateId": "Quest:heroquest_loadout_soldier_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T20:29:35.079Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_pve03_diff26_loadout_soldier": 300, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4b89bdcd-b5c4-452e-8c91-e45a1ed3f293": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "8b439962-0cfd-4595-86fa-183927b24259": { + "templateId": "Quest:reactivequest_copperore", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T00:07:31.334Z", + "completion_quest_reactive_copperore": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "36778938-bdd9-4d6d-a6cb-782954f33dfa": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "1", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "6310e3ad-1b15-4be4-ba54-fd3b69f779dc": { + "templateId": "Quest:challenge_toxictreasures_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-01T20:12:30.651Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1379e2a8-7531-42b6-ace9-89daff74302b": { + "templateId": "Quest:endurancedaily_t02_w15", + "attributes": { + "creation_time": "2024-12-29T13:20:28.533Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.533Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "a59f8a92-a549-47bd-8847-e9ba04bb1dac": { + "templateId": "Quest:pickaxequest_stw003_tier_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:29.442Z", + "level": -1, + "completion_pickaxequest_stw003_tier_4": 2, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b916b90d-235b-46cf-b05d-4a2682e57153": { + "templateId": "Quest:plankertonquest_filler_7_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-07T16:33:11.514Z", + "level": -1, + "item_seen": true, + "completion_kill_husk_smasher_2_diff4_v2": 20, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5e5e2f74-16b9-4247-8b0d-5fdf3ce48928": { + "templateId": "Quest:foundersquest_getrewards_2_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-26T06:57:45.597Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "05f75614-9e7e-4822-b649-6c8ac1e98da7": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "dde7b069-cee4-4fb2-b44e-9917afadcd5f": { + "templateId": "Schematic:sid_pistol_scavenger_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_att_stability_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_ranged_headshot_explodeondeath_v2" + ] + }, + "quantity": 1 + }, + "2e5575f3-653e-4a22-8e60-abcffcafae7b": { + "templateId": "Quest:challenge_missionaccomplished_8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T21:58:12.138Z", + "level": -1, + "completion_complete_primary": 6, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c3802076-c84e-42cd-a0d3-a1a19d9801a6": { + "templateId": "Quest:outpostquest_t1_l10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T18:22:20.981Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_1_10": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6dd2d9b7-308e-4c65-a749-e442918257a9": { + "templateId": "Quest:challenge_toxictreasures_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-28T16:28:15.889Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 4, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cc10c7af-efea-4061-b01d-87a552722a94": { + "templateId": "HomebaseNode:questreward_expedition_rowboat3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "88f7c9b3-60fa-4b75-b988-f081a4a1e13b": { + "templateId": "Worker:worker_karolina_ur_t05", + "attributes": { + "squad_id": "squad_attribute_arms_fireteamalpha", + "personality": "Homebase.Worker.Personality.IsAdventurous", + "level": 50, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "86d9ff23-f08e-4b5b-8cbc-7a920354e03e": { + "templateId": "Quest:outpostquest_t1_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T21:16:38.785Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_1_3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_custom_defendersupplyreceived": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "261b0400-e45d-4bc6-a359-2c13376b645f": { + "templateId": "Schematic:sid_assault_lmg_drum_founders_vr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_stability_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_ele_water_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onfire_damagestack" + ] + }, + "quantity": 1 + }, + "118f8695-9973-4288-a24d-8feafa3d6344": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 30, + "squad_slot_idx": 7, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "a6e10a98-7042-4bf3-b7cd-4293cfaf4fc8": { + "templateId": "Quest:plankertonquest_outpost_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.859Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcomplete_outpostquest_t2_l3": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "86e94960-073d-4479-b16b-74164ab35aff": { + "templateId": "Quest:outpostquest_t3_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T21:00:00.114Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_3_4": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f5224e5e-b23d-4d2a-8d9e-26eb26f9ebf9": { + "templateId": "Quest:plankertonquest_reactive_records", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T05:29:30.884Z", + "level": -1, + "completion_plankertonquest_reactive_records": 5, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f5f4f164-8f7d-4fb9-868a-bbba9ad6c9ea": { + "templateId": "HomebaseNode:skilltree_airstrike", + "attributes": {}, + "quantity": 6 + }, + "56dfb353-87ac-4f15-b0b5-f0f2b25ec415": { + "templateId": "Schematic:sid_edged_sword_medium_c_ore_t00", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "a8edabbc-f5a5-4253-94c2-6dbc8ac7e2dc": { + "templateId": "Quest:plankertonquest_filler_3_d5", + "attributes": { + "completion_complete_retrievedata_2_diff5": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T23:25:24.479Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8131da1b-a3e5-4dbc-883c-a0d6dc2a774f": { + "templateId": "AccountResource:reagent_alteration_ele_water", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 10050 + }, + "6b476b58-4bee-4cdb-bb23-49ec90ab98a6": { + "templateId": "Quest:reactivequest_roadhome", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-07T18:24:27.729Z", + "completion_quest_reactive_roadhome": 4, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ba169bbc-1fc6-4984-aa10-34b31f9e1a01": { + "templateId": "HomebaseNode:skilltree_backpacksize", + "attributes": {}, + "quantity": 7 + }, + "92e88261-a7c3-4662-af25-adeea7fdf1b1": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "ad47c747-d8d6-4019-a152-9bd93cf11822": { + "templateId": "Quest:cannyvalleyquest_filler_2_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-21T17:13:38.971Z", + "selection": 0, + "level": -1, + "item_seen": true, + "completion_complete_gate_triple_3_diff4": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2d26125d-30a1-4b1e-895b-33f7b7fce216": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "33db9e9f-efe4-463b-83f6-c9a84079d3b8" + }, + "loadout_index": 7 + }, + "quantity": 1 + }, + "b623364d-617d-4a0a-bdf1-538a2fbb2b44": { + "templateId": "Quest:outpostquest_firstopen_endless", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-23T16:43:02.333Z", + "level": -1, + "sent_new_notification": true, + "completion_complete_endless_firstopen": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1ca93d1d-7b32-49e9-b51c-d9584c29a490": { + "templateId": "Worker:managerengineer_sr_countess_t05", + "attributes": { + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "personality": "Homebase.Worker.Personality.IsPragmatic", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsEngineer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Engineer-countess", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "b9a24899-320b-4d6f-b96b-7e3a87a94a88": { + "templateId": "Quest:stonewoodquest_fetch_trashcans", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.840Z", + "level": -1, + "completion_stonewoodquest_fetch_trashcans": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6c411875-cf54-4487-a39c-a825263ed14c": { + "templateId": "HomebaseNode:questreward_homebase_defender", + "attributes": {}, + "quantity": 1 + }, + "b27f2f7e-cec9-4334-b59a-ef51a3709459": { + "templateId": "Quest:challenge_toxictreasures_17", + "attributes": { + "creation_time": "2024-04-13T06:21:23.484Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-05-26T00:15:53.523Z", + "level": -1, + "item_seen": true, + "completion_complete_mimic": 10, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c48d2b55-a7f4-4bb0-bf87-984fd63bfcad": { + "templateId": "Quest:cannyvalley_reactive_canoes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-01T03:36:26.208Z", + "completion_cannyvalley_reactive_canoes": 7, + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "61485532-24d5-4963-b6ff-11362bddc9ff": { + "templateId": "AccountResource:personnelxp", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 580288 + }, + "26903b49-99f3-4dec-ac96-aaa77928cbe3": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 50, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "12692f58-5990-4d10-8ee7-8db92bc96efa": { + "templateId": "AccountResource:reagent_c_t04", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 98 + }, + "7ea81def-3b6f-46d6-a29b-5ea845e37d80": { + "templateId": "Quest:challenge_toxictreasures_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-04T02:55:52.291Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 4, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "af4f6993-bade-46bf-9230-d6904b5d013e": { + "templateId": "Hero:hid_constructor_023_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "e11d6fc5-bc9a-44a1-89bb-44c2dd1c3922": { + "templateId": "Quest:teamperkquest_kineticoverdrive", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T14:17:51.080Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "47e2d2da-ea9c-415a-9510-c8cec8a4f3d6": { + "templateId": "AccountResource:reagent_alteration_upgrade_r", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 17984 + }, + "97417fd7-b2bf-4855-bbe5-254a3e822b05": { + "templateId": "Quest:cannyvalley_reactive_stores", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-17T19:16:57.057Z", + "completion_cannyvalley_reactive_stores": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "00323b27-6476-4617-b77f-0d6e2a999e23": { + "templateId": "Quest:challenge_missionaccomplished_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T03:49:48.150Z", + "level": -1, + "completion_complete_primary": 4, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "946eb1cf-0478-46d4-8b82-1d17dfe418bc": { + "templateId": "HomebaseNode:questreward_newheroloadout6_dummy", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "e61f9547-80f1-4f8d-a83a-385dc4a97742": { + "templateId": "Schematic:sid_pistol_autoheavy_founders_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_firerate_ranged_t01", + "Alteration:aid_att_stability_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onreload_damagebuff" + ] + }, + "quantity": 1 + }, + "486fca8e-8476-4541-86ff-cee909520b8e": { + "templateId": "Quest:challenge_eldritchabominations_16", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-03T19:04:18.207Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 80, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fbfeb105-d4ff-48f5-a06f-b4d1b0ba8336": { + "templateId": "HomebaseNode:questreward_feature_herolevelup", + "attributes": {}, + "quantity": 1 + }, + "3e3f50fc-9173-4552-a6c9-f5c0de673401": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Repeatable Quests", + "conditions": { + "event": { + "instanceId": "tfik3horo1eunkmkfn6cj8bnst[0]1", + "eventName": "CalendarEvent_Persistent_EventRepeatables", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:genericquest_completestormzones_repeatable", + "quantity": 1 + }, + { + "templateId": "Quest:genericquest_killmistmonsters_repeatable", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:genericquest_completestormzones_repeatable", + "quantity": 1 + }, + { + "templateId": "Quest:genericquest_killmistmonsters_repeatable", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "193a0d3c-a930-451c-994b-45bc29caec31": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "1", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 50, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "5e5f73aa-2499-43ec-84fa-a96dc2283d55": { + "templateId": "Quest:cannyvalley_reactive_clocks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-23T20:09:41.987Z", + "level": -1, + "completion_cannyvalley_reactive_clocks": 50, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "42c85026-69e8-4121-9906-7470ed56b022": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "0ff9d80e-611f-41e9-8c2c-78acda4f8c70" + }, + "loadout_index": 1 + }, + "quantity": 1 + }, + "bad8b5ca-34de-4f62-a05b-56ec412107da": { + "templateId": "Quest:foundersquest_getrewards_0_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:49:02.404Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3b47e2c2-64d4-4090-8d2f-2883660760ce": { + "templateId": "Quest:stonewoodquest_filler_1_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T19:14:21.820Z", + "level": -1, + "item_seen": true, + "completion_complete_evacuate_1_diff3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "19e61a53-baab-4520-9172-426d19e9e714": { + "templateId": "Schematic:sid_edged_sword_medium_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t02", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "6e0958d4-1edd-4846-8f63-9d8964b2b56c": { + "templateId": "Quest:stonewoodquest_joelkarolina_savesurvivors", + "attributes": { + "completion_stonewoodquest_joelkarolina_savesurvivors": 100, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T18:48:35.735Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "997f10fd-2ef0-4366-9894-25894a1d4399": { + "templateId": "Worker:worker_halloween_husky_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Husky", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "31143afc-38c2-44e6-a588-e2a54de0c26a": { + "templateId": "Quest:stonewoodquest_joelkarolina_killhusks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T17:27:16.585Z", + "completion_stonewoodquest_joelkarolina_killhusks": 1000, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6155b7da-4004-400a-8a0f-83ab4771c24e": { + "templateId": "Quest:winter_seasonal_monster_01", + "attributes": { + "creation_time": "2024-12-16T20:05:04.725Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.725Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2d9dc03c-0fec-4f40-bba9-ca5b1bcad52a": { + "templateId": "CardPack:cardpack_jackpot_collectionbook", + "attributes": { + "level": 1672, + "pack_source": "CollectionBook" + }, + "quantity": 1 + }, + "4f5c2a7d-3e27-449f-88b6-9dc577c7c1ca": { + "templateId": "HomebaseNode:questreward_buildingresourcecap2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "7b1830a2-f47f-46f1-a3df-37bf88bc6c08": { + "templateId": "Schematic:sid_blunt_club_light_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_att_damageresistance_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "a95df666-e3b3-4d9c-bf59-7466333f3390": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "07133c5f-99c2-4221-b7ce-3bdbb5b70a99": { + "templateId": "Quest:heroquest_constructor_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T04:16:10.313Z", + "completion_upgrade_constructor": 1, + "completion_complete_pve01_diff2_constructor": 1, + "level": -1, + "item_seen": true, + "completion_assign_hero_constructor": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bf419855-9e9e-4b4d-aa0e-b348326841b2": { + "templateId": "HomebaseNode:questreward_buildingresourcecap", + "attributes": {}, + "quantity": 1 + }, + "06bf5bc2-71ef-4b30-8047-af32dfad9006": { + "templateId": "Worker:workerbasic_uc_t01", + "attributes": { + "gender": "2", + "personality": "Homebase.Worker.Personality.IsDreamer", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "1d05194f-403e-4dc3-840c-90a9a37235f0": { + "templateId": "Quest:outpostquest_t2_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-04T02:20:21.648Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_2_4": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e55a6132-1d1f-4cd5-ad5b-5dd06f46c903": { + "templateId": "Quest:challenge_holdthedoor_18", + "attributes": { + "creation_time": "2024-04-05T17:52:54.477Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-09T16:49:07.066Z", + "completion_complete_outpost": 10, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "40862ba2-ab8b-462e-8177-48ffd4e736f5": { + "templateId": "Quest:s11_holdfastquest_soup_deposit", + "attributes": { + "creation_time": "2025-01-02T20:30:31.505Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.505Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4acc53ad-f019-4a86-8be9-90437face50d": { + "templateId": "Quest:plankertonquest_filler_7_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-31T05:00:59.488Z", + "completion_complete_launchballoon_2_diff3": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "06e7e7e8-a25f-40b5-96ab-12366774913b": { + "templateId": "HomebaseNode:questreward_mission_defender", + "attributes": {}, + "quantity": 1 + }, + "361a13b4-8771-4d5b-95dd-0a3900476008": { + "templateId": "Defender:did_defenderpistol_founders_vr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_critchance_ranged", + "Alteration:aid_att_def_critdamage_ranged", + "Alteration:aid_att_def_weapondamage_pistol", + "Alteration:aid_att_def_maxhealth" + ] + }, + "quantity": 1 + }, + "885a69fb-debc-4ae5-9a40-628d5a5fa98c": { + "templateId": "Quest:homebasequest_completeexpedition", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T18:39:19.851Z", + "completion_collectexpedition": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "456ba955-fa85-4f1c-9840-3db1a2ad5f88": { + "templateId": "Quest:stonewoodquest_launchrocket_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T04:18:35.131Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_launchrocket_1": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c26d43ae-a1ca-4298-a999-d7e0e7ac32bf": { + "templateId": "Quest:stonewoodquest_launchballoon_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T07:23:30.388Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_launchweatherballoon_1": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "852c8074-9759-40ec-a606-5170737a4cc3": { + "templateId": "Quest:wargames_dailyquest_tiki_with_notraps_stonewood", + "attributes": { + "creation_time": "2025-01-02T20:30:31.513Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.513Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "dailywargamesstonewood_01" + }, + "quantity": 1 + }, + "43dd2c87-a937-487a-b504-591e8f95bc8c": { + "templateId": "Schematic:sid_sniper_neonglow_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t02", + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_headshotdamage_t03", + "Alteration:aid_g_ranged_headshotstreak_dmgbonus_v2" + ] + }, + "quantity": 1 + }, + "e8fdaf72-91ce-42c2-a7dd-4c08a1ab99f3": { + "templateId": "AccountResource:reagent_c_t02", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 191 + }, + "17402c57-b70f-4e95-936a-66c3674562b0": { + "templateId": "Quest:achievement_explorezones", + "attributes": { + "completion_complete_exploration_1": 178, + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2018-08-09T22:33:07.412Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5ee16679-9682-418d-9a44-736fb60fd952": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "54aaef2f-66bb-47e2-a682-9357bd378d2a": { + "templateId": "Schematic:sid_sniper_crossbow_military_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_ele_water_t03", + "Alteration:aid_att_magazinesize_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_standstill_stackbuff_damage" + ] + }, + "quantity": 1 + }, + "87a2c32a-6003-4f12-bd77-f38b964bbe4e": { + "templateId": "CardPack:cardpack_jackpot_collectionbook", + "attributes": { + "level": 1675, + "pack_source": "CollectionBook" + }, + "quantity": 1 + }, + "9342dd14-57d3-41cf-8c53-c4ee4273058f": { + "templateId": "ConsumableAccountItem:smallxpboost_gift", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 343 + }, + "3705533f-6318-45a7-880c-5ba0bfe14639": { + "templateId": "Schematic:sid_assault_auto_c_ore_t00", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "a959c8a7-957a-48c9-8cf3-5d812ed491fb": { + "templateId": "HomebaseNode:questreward_newheroloadout7_dummy", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "88b3f5a1-cf11-414c-850d-2d3dd1e8e4a0": { + "templateId": "Token:receivemtxcurrency", + "attributes": { + "level": 1 + }, + "quantity": 1 + }, + "68a5ca5f-d0ec-467c-bbcd-d742aa1a1a05": { + "templateId": "Worker:worker_halloween_smasher_sr_t02", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 11, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Smasher", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "a1767bbc-b274-4bbb-890e-82f7d8074c96": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "2", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "7535c2e3-e5be-4d8f-a001-b6b0435aff5e": { + "templateId": "Quest:outpostquest_t1_l6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T03:37:48.639Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_1_6": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3e24b305-6828-4e55-8807-eba1f0a0487c": { + "templateId": "Quest:challenge_holdthedoor_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-02T17:12:52.670Z", + "completion_complete_outpost": 4, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a10b44d8-a002-4308-a475-f694e4918cbe": { + "templateId": "Worker:workerbasic_uc_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "47fcc105-ffa6-42d4-8afb-2de481e730ed": { + "templateId": "HomebaseNode:skilltree_proximitymine", + "attributes": {}, + "quantity": 1 + }, + "c2e1d0a6-45ad-4f13-90e1-afeaafe611db": { + "templateId": "Defender:did_defenderassault_basic_m_r_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_weapondamage_assault", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_critchance_ranged" + ] + }, + "quantity": 1 + }, + "a007b157-26c6-4089-a32b-ae71ecce13f9": { + "templateId": "Hero:hid_commando_027_piratesoldier_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "39d22064-3ecf-494b-8aed-2c7a78485dc4": { + "templateId": "Quest:outpostquest_t1_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T02:04:03.050Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_1_4": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bba4ccdf-1635-4ddf-9cae-d36dfc8d356e": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 40, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "f7e4f7c5-9c8f-4b8f-a877-e099c327c929": { + "templateId": "Quest:s11_holdfastquest_d1_cramp", + "attributes": { + "creation_time": "2025-01-02T20:30:31.522Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.522Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "holdfastdaily_part1_01" + }, + "quantity": 1 + }, + "745dbaf5-73c4-4af8-8bfb-fcaaa5b2d9f1": { + "templateId": "Quest:stonewoodquest_fetch_researchcrates", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.830Z", + "level": -1, + "completion_stonewoodquest_fetch_researchcrates": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4a2fb74d-fdb9-48a4-9398-599b06a021c3": { + "templateId": "Defender:did_defenderassault_founders_vr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_ammosave", + "Alteration:aid_att_def_firerate", + "Alteration:aid_att_def_weapondamage_assault", + "Alteration:aid_att_def_maxhealth" + ] + }, + "quantity": 1 + }, + "d5d13927-3f99-4c5d-92d6-489a60eda9f3": { + "templateId": "Schematic:sid_edged_scythe_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_firerate_melee_t01", + "Alteration:aid_att_movementspeed_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_critchance_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "f3549d78-1429-4a63-9076-eabcaed3e53f": { + "templateId": "Quest:tutorial_loadout_support2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:28:05.393Z", + "level": -1, + "sent_new_notification": true, + "completion_heroloadout_support2_intro": 1, + "completion_heroloadout_support2_guardscreen1": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d1145782-79a2-4e43-9ac7-2596dd9afbc5": { + "templateId": "Quest:challenge_holdthedoor_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T02:03:41.504Z", + "completion_complete_outpost": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9afaa7b9-2671-4311-8bef-3cbce7872ae0": { + "templateId": "TeamPerk:tpid_recycling", + "attributes": {}, + "quantity": 1 + }, + "820eaf64-c8e5-4b12-b6e2-1db0be231d96": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Phoenix", + "conditions": { + "event": { + "instanceId": "ai3r5g3drgrf3g0cnbannp1ber[0]1", + "eventName": "CalendarEvent_Persistent_Phoenix_Winterfest", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Weapon:wid_edged_axe_light_c_ore_t01", + "quantity": 1 + }, + { + "templateId": "Weapon:wid_shotgun_standard_c_ore_t01", + "quantity": 1 + }, + { + "templateId": "Ammo:ammodatashells", + "quantity": 12 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "AccountResource:phoenixxp", + "quantity": 2147483647 + }, + { + "templateId": "Stat:technology_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:resistance_team_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:fortitude_team_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:offense_team_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:technology_team_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:fortitude_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:offense_phoenix", + "quantity": 2147483647 + }, + { + "templateId": "Stat:resistance_phoenix", + "quantity": 2147483647 + } + ], + "questsToPause": [] + }, + "metaData": { + "grantTo": "theater2", + "phoenixEventType": "EventFlag.Phoenix.Winterfest", + "endAction": "{\"actionClassName\":\"com.epicgames.fortnite.core.game.managers.calendareventactions.ResetSeasonalTheaterCalendarEventAction\",\"profile\":\"campaign\"}" + } + } + } + }, + "quantity": 1 + }, + "5be3497e-ef4d-4865-aad4-12b09f224bdf": { + "templateId": "Defender:did_defenderassault_basic_sr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_critdamage_ranged", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_maxhealth", + "Alteration:aid_att_def_weapondamage_assault", + "Alteration:aid_att_def_maxhealth" + ] + }, + "quantity": 1 + }, + "73e0caa5-47a8-4d65-b93f-82e701afe328": { + "templateId": "HomebaseNode:questreward_herotactical_slot", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "65209200-eb60-4253-b063-33eb57edcb62": { + "templateId": "ConsumableAccountItem:smallxpboost", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 74 + }, + "1667429a-451e-49fb-bbf8-d071c9fd0849": { + "templateId": "Quest:plankertonquest_filler_6_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-10T23:21:22.923Z", + "completion_complete_gate_2_diff4": 1, + "completion_complete_gate_double_2_diff4": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3abbb25d-9246-4f1d-be09-64024d12583e": { + "templateId": "Quest:s11_holdfastquest_season_burner", + "attributes": { + "creation_time": "2024-12-16T20:05:04.714Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.714Z", + "level": -1, + "completion_s11_holdfastquest_season_burner": 158, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2cca0859-eba4-46ed-9d29-8048c7dc8aa3": { + "templateId": "Quest:cannyvalleyquest_filler_3_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-27T04:56:39.945Z", + "level": -1, + "completion_kill_husk_taker_3_diff4_v3": 25, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9161d75a-ec36-4978-bc7d-f214069aa665": { + "templateId": "Quest:challenge_toxictreasures_15", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-01T15:38:38.210Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 9, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7b8bdcce-5974-4fd0-a18a-556baf8840e0": { + "templateId": "Quest:cannyvalley_mechanical_killriotshields", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-26T18:24:09.845Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_mechanical_killriotshields": 15, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "911e71ee-9a07-4162-a286-bfb3a9d060ba": { + "templateId": "Quest:cannyvalley_reactive_bikes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-27T03:58:40.143Z", + "selection": 1, + "completion_cannyvalley_reactive_bikes": 7, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "05f61f1c-2f36-4840-96ea-e86c31f09c6b": { + "templateId": "Schematic:sid_shotgun_neonglow_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t02", + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_onrangedfire_stackbuff_shield" + ] + }, + "quantity": 1 + }, + "eeaf2fac-f394-4b09-858f-2553ae386df6": { + "templateId": "Quest:challenge_weaponupgrade_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-16T04:39:06.536Z", + "level": -1, + "item_seen": true, + "completion_convert_any_weapon": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e3441a34-1ec1-40da-9559-d42b29697961": { + "templateId": "Quest:challenge_toxictreasures_7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-08T17:26:53.657Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ed58b3e8-701e-48b2-a3e2-a8ede84ee5e7": { + "templateId": "Schematic:sid_shotgun_break_flintlock_sr_ore_t01", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_reloadspeed_ranged_t03", + "Alteration:aid_conditional_slowed_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "5948f43f-8bdf-4106-a7f3-606c039f562a": { + "templateId": "HomebaseNode:questreward_evolution", + "attributes": {}, + "quantity": 1 + }, + "7e47066f-3f8e-48ac-9cea-6565360873e7": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Phoenix - Quests", + "conditions": { + "event": { + "instanceId": "vd042nrof4i0er3oiaj5h82l7b[0]1", + "eventName": "CalendarEvent_Persistent_Phoenix_Winterfest_Quests", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:winter_seasonal_destroy_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_01", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:winter_seasonal_destroy_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_02", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_03", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_04", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_05", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_06", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_07", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_08", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_09", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_10", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_11", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_destroy_12", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_02", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_03", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_04", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_05", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_06", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_07", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_08", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_09", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_10", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_11", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_locating_12", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_02", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_03", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_04", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_05", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_06", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_07", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_08", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_09", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_10", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_11", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_mission_12", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_02", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_03", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_04", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_05", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_06", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_07", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_08", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_09", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_10", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_11", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_monster_12", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_01", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_02", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_03", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_04", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_05", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_06", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_07", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_08", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_09", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_10", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_11", + "quantity": 1 + }, + { + "templateId": "Quest:winter_seasonal_weapon_12", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "fd22bda6-f0ff-4872-89d8-116e67fca47e": { + "templateId": "Quest:achievement_craftfirstweapon", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:31:12.497Z", + "completion_custom_craftfirstweapon": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7424a19b-5b86-4d2c-912a-33c0f8500d6c": { + "templateId": "Schematic:sid_shotgun_tactical_founders_vr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_g_weapon_onreload_damagestack" + ] + }, + "quantity": 1 + }, + "58cc84fc-9cbf-4efd-bb35-05253ba58714": { + "templateId": "Quest:cannyvalley_hidden_enablegunslinger", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:37:04.267Z", + "completion_questcomplete_cannyvalley_landmark_highnoon": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5e5a23e5-a01a-47c0-a007-d568264b884e": { + "templateId": "HomebaseNode:skilltree_supplydrop", + "attributes": {}, + "quantity": 5 + }, + "2bf6b989-7f40-4f7a-8a2b-c8baedaaa3c6": { + "templateId": "Schematic:sid_blunt_light_rocketbat_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_heavyattackstaminacost_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "04d49cb8-4e93-47a5-b7cb-ab2b679b0fee": { + "templateId": "Quest:outpostquest_t4_l9", + "attributes": { + "creation_time": "2024-12-29T21:42:49.982Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T22:20:10.386Z", + "completion_complete_outpost_4_9": 1, + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "992b2dc6-04c6-4564-8e88-d9def4c8421c": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "STORE: Holiday - Event - Campaign Currency", + "conditions": { + "event": { + "instanceId": "re339po36gf3s9srl7enklv2kl[0]1", + "eventName": "CalendarEvent_Persistent_Holiday_EventCurrency", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [], + "questsToUnpause": [], + "eventCurrencyToSet": { + "templateId": "AccountResource:eventcurrency_snowballs", + "cf": 1.0 + } + }, + "endActions": { + "hasRun": false, + "conversions": [ + { + "recipe": { + "static_results": [ + { + "templateId": "CardPack:cardpack_event_persistent_holiday", + "quantity": 1 + } + ], + "static_costs": [ + { + "templateId": "AccountResource:eventcurrency_snowballs", + "quantity": 500 + } + ], + "static_catalysts": [] + }, + "quantity": -1, + "convert_remainder_up": true + } + ], + "itemsToRemove": [], + "questsToPause": [], + "eventCurrencyToUnset": "AccountResource:eventcurrency_snowballs" + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "3850f15a-3158-448e-a3d5-799ac53ee2c8": { + "templateId": "Schematic:sid_pistol_firecracker_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "f656c027-7cd6-4397-923c-5b9441b628ec": { + "templateId": "Quest:reactivequest_seebot", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T05:06:40.968Z", + "level": -1, + "item_seen": true, + "completion_quest_reactive_seebotv2": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "828c225e-bcdb-4736-b3a6-5bf6e3b88870": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Frostnite", + "conditions": { + "event": { + "instanceId": "brf6isvthqmekujd40mbh2oiq2[0]1", + "eventName": "CalendarEvent_Season11FrostniteEvent", + "eventStart": "2024-11-21T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:s11_holdfastquest_repeat_ice", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_repeat_taste", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_burner", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_furnacemaint", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_loot", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_misty", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_15", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_30", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_45", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_trapcraft", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_cramps", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_group", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_knight", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:s11_holdfastquest_repeat_ice", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_repeat_taste", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_burner", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_furnacemaint", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_loot", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_misty", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_15", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_30", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_survive_45", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_season_trapcraft", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_cramps", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_group", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_seasonelite_knight", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d1_burner", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d1_construct", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d1_cramp", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d1_ice", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d2_constructor", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d2_ninja", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d2_outlander", + "quantity": 1 + }, + { + "templateId": "Quest:s11_holdfastquest_d2_soldier", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "e2f96e76-fad2-4f15-a9d9-4355712d3965": { + "templateId": "Expedition:expedition_traprun_long_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.775Z", + "expedition_criteria": [ + "RequiresEpicConstructor", + "RequiresRareConstructor" + ], + "level": 1, + "expedition_max_target_power": 480, + "expedition_min_target_power": 24, + "expedition_slot_id": "expedition.generation.land.t03_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.775Z" + }, + "quantity": 1 + }, + "0317b6b8-667a-4ed6-b7f7-87325574988d": { + "templateId": "HomebaseNode:questreward_homebase_defender3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "9dd3c196-be02-46b1-9c5c-85e047403093": { + "templateId": "Quest:plankertonquest_landmark_lars", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T17:15:18.072Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_plankertonquest_landmark_lars": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "894cbee5-9485-40db-b327-04d319c67e39": { + "templateId": "Quest:cannyvalley_reactive_dredgers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-18T20:45:52.229Z", + "selection": 0, + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_dredgers": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "53a569f3-b083-4d22-9a80-853e5e874c07": { + "templateId": "Quest:challenge_workertraining_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T06:59:45.900Z", + "level": -1, + "sent_new_notification": true, + "completion_convert_any_worker": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "48987567-6ac8-483e-b0cd-ea9c57865ce5": { + "templateId": "Quest:genericquest_completestormzones_repeatable", + "attributes": { + "creation_time": "2024-12-16T20:05:04.726Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.726Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d6e19a49-c8c3-4eff-b589-30b2ec8ea577": { + "templateId": "Quest:winter_seasonal_locating_01", + "attributes": { + "creation_time": "2024-12-16T20:05:04.724Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.724Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "714fd6bb-57db-4c17-83f8-6d7c19189435": { + "templateId": "Quest:cannyvalley_reactive_tabs", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T21:02:45.821Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_tabs": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7258bb87-a9d4-439d-b2e1-406aa42f523a": { + "templateId": "Quest:wargames_dailyquest_overload_with_dangerclose_plankerton", + "attributes": { + "creation_time": "2025-01-02T20:30:31.511Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.511Z", + "selection": -1, + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "dailywargamesplankerton_01" + }, + "quantity": 1 + }, + "3041564b-f857-47a2-b448-bc8bbd1e8b52": { + "templateId": "Expedition:expedition_traprun_sea_medium_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.753Z", + "expedition_criteria": [ + "RequiresEpicCommando" + ], + "level": 1, + "expedition_max_target_power": 575, + "expedition_min_target_power": 28, + "expedition_slot_id": "expedition.generation.sea.t04_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.753Z" + }, + "quantity": 1 + }, + "ed7cc2e7-4207-4c1e-a894-0b758ed4d66a": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "gender": "2", + "personality": "Homebase.Worker.Personality.IsDependable", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "0051b4c4-fe71-4789-b2c6-1b453c841da2": { + "templateId": "Quest:challenge_toxictreasures_18", + "attributes": { + "creation_time": "2024-05-26T00:15:53.528Z", + "quest_state": "Active", + "last_state_change_time": "2024-05-26T00:15:53.528Z", + "level": -1, + "item_seen": true, + "completion_complete_mimic": 4, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "815b1084-ce96-4de6-9751-a536865f32d2": { + "templateId": "Hero:hid_constructor_008_foundersf_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "63027556-d87e-4366-b200-aab5f0fed266": { + "templateId": "Quest:foundersquest_soldier_weaponupgrade_sr", + "attributes": { + "creation_time": "2024-03-31T18:38:32.022Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-31T18:39:58.290Z", + "level": -1, + "item_seen": true, + "completion_craft_founders_assault_vr": 1, + "quest_rarity": "legendary", + "completion_questcomplete_stonewoodquest_launchrocket_d5": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cb869d7c-2347-485f-80a0-fa1dcdaec055": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 30, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "66a6bde2-6631-4f06-aeb1-43d9f366646b": { + "templateId": "Quest:reactivequest_trollstash_r1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-17T20:27:25.793Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_quest_reactive_trollstashinit": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "08a4cb1a-9e65-4eae-9096-aa0e4603b57f": { + "templateId": "Worker:managertrainer_sr_raider_t05", + "attributes": { + "squad_id": "squad_attribute_medicine_trainingteam", + "personality": "Homebase.Worker.Personality.IsCurious", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsTrainer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-PersonalTrainer-raider", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "cbfb893c-274b-4b75-8198-ac686310c8f0": { + "templateId": "Worker:managermartialartist_sr_dragon_t05", + "attributes": { + "squad_id": "squad_attribute_arms_closeassaultsquad", + "personality": "Homebase.Worker.Personality.IsAdventurous", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsMartialArtist", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-MartialArtist-dragon", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "0146e17d-8784-4fa8-af0f-ce98bf0d666e": { + "templateId": "Quest:challenge_eldritchabominations_11", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T05:21:32.126Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 55, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a8f68e59-b17d-4f0b-bcef-75e611d8390f": { + "templateId": "TeamPerk:tpid_superchargedtraps", + "attributes": {}, + "quantity": 1 + }, + "e36442f6-50ff-4ad0-aa8c-fa60d6861dcd": { + "templateId": "Quest:plankertonquest_filler_3_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T02:36:47.435Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_launchballoon_2": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8746ab43-a25c-4d98-848e-b3e97c26d35a": { + "templateId": "Quest:heroquest_ninja_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-20T18:57:12.102Z", + "completion_ability_throwingstars": 3, + "completion_ability_mantisleap": 3, + "level": -1, + "completion_upgrade_ninja_lvl_3": 1, + "completion_complete_pve01_diff3_ninja": 3, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5995f9c5-cf1d-48bb-90ca-601f1a8a5e59": { + "templateId": "Quest:tutorial_loadout_support1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:27:48.062Z", + "completion_heroloadout_support1_intro": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_heroloadout_support1_guardscreen1": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "14afc37b-c617-4b63-983e-039ea6cacbd6": { + "templateId": "Quest:cannyvalley_reactive_outhouses", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T22:49:25.016Z", + "level": -1, + "completion_cannyvalley_reactive_outhouses": 5, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "516bbada-58e7-47b7-ad04-b80d8dfcc273": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsDreamer", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "92ab8cd1-aea6-4624-8592-65fedc12fb53": { + "templateId": "Quest:wargames_dailyquest_riotcity_with_fog_canny", + "attributes": { + "creation_time": "2025-01-02T20:30:31.507Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.507Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "dailywargamescanny_01" + }, + "quantity": 1 + }, + "faa7983e-facc-4a01-a40e-5e00666c705c": { + "templateId": "Quest:reactivequest_blasters", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T21:34:37.315Z", + "completion_quest_reactive_blasters": 10, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c8d2901f-7187-4857-8b4c-6ed02c2b4671": { + "templateId": "BannerToken:bannertoken_stw007_starlightscience", + "attributes": { + "level": 1, + "banner_id": "HomebaseBannerIcon:brs18_sciencedungeonstw" + }, + "quantity": 1 + }, + "863c51a9-c750-49bc-8fa8-612bdb9bec44": { + "templateId": "Quest:endurancedaily_t02_w25", + "attributes": { + "creation_time": "2024-12-29T13:20:28.533Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.533Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "b8476082-95ab-4fbf-9a1f-2960acc74880": { + "templateId": "Quest:challenge_eldritchabominations_9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T00:01:47.079Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 45, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "00216df5-eb1e-45be-9549-76674b95d047": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "team_perk": "1394b714-31d9-42b4-923a-3484129b9dd4", + "level": 1, + "crew_members": { + "followerslot5": "9e3d5a3f-0c81-41a0-ab89-ad09931f056a", + "followerslot4": "c2bd14ee-8305-407f-8247-b19242970e86", + "followerslot3": "2e3c3f5d-1b99-4936-8dbc-48ff079efd75", + "followerslot2": "a886cd80-5fbc-4540-bed6-28e36ddb3de3", + "followerslot1": "e31c10a9-49c9-47f3-aeaf-47e27fac3138", + "commanderslot": "33db9e9f-efe4-463b-83f6-c9a84079d3b8" + }, + "loadout_index": 2, + "gadgets": [ + { + "gadget": "Gadget:g_airstrike", + "slot_index": 0 + }, + { + "gadget": "Gadget:g_generic_botturret", + "slot_index": 1 + } + ] + }, + "quantity": 1 + }, + "4e4c3b0c-579a-4247-89ae-dd9bb09ea9ec": { + "templateId": "Quest:s11_holdfastquest_repeat_taste", + "attributes": { + "creation_time": "2024-12-28T20:27:31.862Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-28T20:27:31.862Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "completion_s11_holdfastquest_repeat_taste": 5, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ceeb5b44-2f08-4258-bba5-72a0cb2633fd": { + "templateId": "Schematic:sid_pistol_rapid_founders_vr_ore_t02", + "attributes": { + "level": 20, + "refund_legacy_item": true, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_headshotdamage_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_g_ranged_chainbullet" + ] + }, + "quantity": 1 + }, + "e01281fe-1356-4675-a4db-d46458b7c703": { + "templateId": "Quest:outpostquest_t4_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-20T18:53:00.877Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_4_3": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a9083fc9-7dbf-4e10-abd6-6904ca2227d9": { + "templateId": "PrerollData:preroll_basic", + "attributes": { + "fulfillmentId": "6D7B61F6CAC14875B6B7113D69ADBB42", + "expended_streakbreakers": {}, + "level": 1, + "highest_rarity": 2, + "offerId": "6D7B61F6CAC14875B6B7113D69ADBB42", + "expiration": "2025-01-03T00:00:00.000Z", + "items": [ + { + "itemType": "Hero:hid_ninja_007_uc_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Hero:hid_ninja_015_f_v1_uc_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Hero:hid_ninja_009_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Hero:hid_outlander_zoneharvest_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "CardPack:cardpack_choice_hero_sr", + "attributes": { + "pack_source": "", + "options": [ + { + "itemType": "Hero:hid_constructor_007_sr_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Hero:hid_ninja_starsrain_sr_t01", + "attributes": {}, + "quantity": 1 + } + ] + }, + "quantity": 1 + }, + { + "itemType": "AccountResource:eventcurrency_snowballs", + "attributes": {}, + "quantity": 1000 + }, + { + "itemType": "Hero:hid_outlander_009_vr_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Hero:hid_ninja_starsrain_vr_t01", + "attributes": {}, + "quantity": 1 + } + ] + }, + "quantity": 1 + }, + "6f256e32-688f-40cc-a56e-a6d1b6da8385": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd6", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "ef77e1a3-ea46-4e22-9e70-979d155e52d3": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "2998fdd4-9dc7-4802-9867-a46283faa6dd": { + "templateId": "Schematic:sid_assault_auto_sr_ore_t05", + "attributes": { + "level": 50, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t04", + "Alteration:aid_att_maxdurability_t04", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ], + "alteration_base_rarities": [ + "common", + "common", + "uncommon", + "uncommon", + "rare", + "common" + ] + }, + "quantity": 1 + }, + "62d79722-826f-4d96-aa14-3e07b22368f2": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "fe0ff886-e96c-4352-bd0f-a982d043b106": { + "templateId": "Quest:cannyvalley_reactive_oillamps", + "attributes": { + "completion_cannyvalley_reactive_oillamps": 7, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T20:56:29.667Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0f47b6a1-50e3-4d2a-8fb3-67226995f59d": { + "templateId": "Expedition:expedition_miningore_t00", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.765Z", + "level": 1, + "expedition_max_target_power": 20, + "expedition_min_target_power": 1, + "expedition_slot_id": "expedition.generation.choppingwood", + "expedition_expiration_start_time": "2025-01-02T20:30:29.765Z" + }, + "quantity": 1 + }, + "b43f11a6-f42a-4de1-aa51-6c74926951bf": { + "templateId": "Hero:hid_commando_shockdamage_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "01d800b0-a6c9-4dc5-b8a8-b1290325dc38": { + "templateId": "Hero:hid_ninja_015_f_v1_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "42d3b857-8430-48d9-8f71-621ea67eaaae": { + "templateId": "Schematic:sid_assault_semiauto_c_ore_t00", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "178f7fb5-fc95-4504-bd16-76e95bcca498": { + "templateId": "Quest:plankertonquest_filler_2_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T03:29:41.332Z", + "selection": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_destroyencamp_2_diff2": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7fd5894b-0962-4169-a91b-f57357383237": { + "templateId": "Schematic:sid_shotgun_longarm_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_headshotdamage_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_ranged_headshotstreak_dmgbonus_v2" + ] + }, + "quantity": 1 + }, + "1a6cc556-9920-43d9-92ed-4049973d6f63": { + "templateId": "Quest:cannyvalleyquest_filler_2_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T00:29:49.943Z", + "completion_complete_delivergoods_3_diff3": 1, + "completion_complete_refuel_3_diff3": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cb61e11e-df7f-4814-86d8-8b0cf6f9a137": { + "templateId": "Quest:outpostquest_t1_l9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T23:13:11.773Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_1_9": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c51f30de-342b-4b80-9701-34b7031203e3": { + "templateId": "Quest:challenge_toxictreasures_9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-10T23:50:31.828Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 6, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "80ce8095-30f1-45ff-8a08-c0ed4c4e3f0b": { + "templateId": "Quest:plankertonquest_filler_7_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T04:27:40.961Z", + "level": -1, + "item_seen": true, + "completion_complete_exploration_2_diff5": 2, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "37bc70ff-e07f-4fd6-a848-944569d2e1ae": { + "templateId": "Quest:challenge_holdthedoor_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T03:30:15.117Z", + "completion_complete_outpost": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "33db9e9f-efe4-463b-83f6-c9a84079d3b8": { + "templateId": "Hero:hid_ninja_029_dinoninja_sr_t05", + "attributes": { + "outfitvariants": [ + { + "channel": "Parts", + "active": "CampaignHero.Tier1.Legendary" + } + ], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 50, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "7dcf2e54-5724-4486-b359-687bbe9b2e73": { + "templateId": "PrerollData:preroll_basic", + "attributes": { + "linked_offer": "OfferId:4D64CBE3618D41FBB5CAD0E472F4610A", + "fulfillmentId": "OfferId:D2E08EFA731D437B85B7340EB51A5E1D", + "level": 1, + "highest_rarity": 2, + "offerId": "D2E08EFA731D437B85B7340EB51A5E1D", + "expiration": "2025-01-03T00:00:00.000Z", + "items": [ + { + "itemType": "Worker:managertrainer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-PersonalTrainer-M01" + }, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_edged_sword_heavy_c_ore_t01", + "attributes": { + "Alteration": { + "LootTierGroup": "AlterationTG.Melee.C", + "Tier": 0 + }, + "alterations": [ + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_att_movementspeed_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + { + "itemType": "Worker:managertrainer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-PersonalTrainer-M01" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F02", + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + { + "itemType": "ConsumableAccountItem:smallxpboost_gift", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "AccountResource:eventcurrency_snowballs", + "attributes": {}, + "quantity": 50 + }, + { + "itemType": "Hero:hid_ninja_015_f_v1_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_shotgun_tactical_r_ore_t01", + "attributes": { + "Alteration": { + "LootTierGroup": "AlterationTG.Ranged.R", + "Tier": 0 + }, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAnalytical", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-M01", + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + { + "itemType": "Hero:hid_outlander_008_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-M01", + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F03", + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-F02", + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_ceiling_electric_single_vr_t01", + "attributes": { + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_buildingheal_t03" + ] + }, + "quantity": 1 + } + ] + }, + "quantity": 1 + }, + "a3e8133d-6906-4fdd-82fc-b290dea884e5": { + "templateId": "Quest:teamperkquest_slowyourroll", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-01T03:20:18.571Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "609de7d6-0e17-41d1-83b5-024c3889fd3e": { + "templateId": "Quest:cannyvalley_reactive_cards", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-19T05:09:34.592Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_cards": 15, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "05f00be1-6167-449d-9b92-3a54e27304d3": { + "templateId": "Quest:foundersquest_constructor_weaponupgrade_sr", + "attributes": { + "creation_time": "2024-03-31T18:28:52.872Z", + "completion_craft_founders_shotgun_vr": 1, + "quest_state": "Claimed", + "last_state_change_time": "2024-03-31T18:30:13.149Z", + "level": -1, + "item_seen": true, + "quest_rarity": "legendary", + "completion_questcomplete_stonewoodquest_launchrocket_d5": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6b042bc2-d533-46a8-b27c-90293ce48e43": { + "templateId": "HomebaseNode:questreward_buildingupgradelevel", + "attributes": {}, + "quantity": 1 + }, + "081e74ca-51ed-4bc2-b921-34caeabe77cf": { + "templateId": "Quest:reactivequest_taker", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T00:44:31.012Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_quest_reactive_taker": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8498f4e6-fcb4-40da-9f9e-6854063f1ec5": { + "templateId": "Schematic:sid_assault_boombox_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_ele_fire_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_dancing_dmgbonus_t03", + "Alteration:aid_g_onrangedhitstreak_dance" + ] + }, + "quantity": 1 + }, + "3a666a25-d73d-4bab-b396-fafa146f36bd": { + "templateId": "Expedition:expedition_traprun_short_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.754Z", + "expedition_criteria": [ + "RequiresEpicOutlander" + ], + "level": 1, + "expedition_max_target_power": 510, + "expedition_min_target_power": 25, + "expedition_slot_id": "expedition.generation.land.t04_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.754Z" + }, + "quantity": 1 + }, + "3af99e2b-ed57-4e0a-ab49-37ecd24c345c": { + "templateId": "Quest:challenge_missionaccomplished_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T05:53:19.588Z", + "level": -1, + "completion_complete_primary": 3, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fd6b33c9-60d4-4588-83ce-7f3d9a6f98ee": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd6", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "7f46fdaf-8c58-4992-bfd5-9e086669bf67": { + "templateId": "Quest:tutorial_loadout_teamperkandsupport3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:28:03.349Z", + "completion_heroloadout_teamperk_intro": 1, + "completion_heroloadout_support3_guardscreen1": 1, + "level": -1, + "sent_new_notification": true, + "completion_heroloadout_support3_intro": 1, + "completion_heroloadout_teamperk_guardscreen1": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f8611b71-f132-4b04-9ec6-7d31fdaedc8c": { + "templateId": "Quest:s11_holdfastquest_season_loot", + "attributes": { + "creation_time": "2024-12-16T20:05:04.715Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.715Z", + "level": -1, + "item_seen": true, + "completion_s11_holdfastquest_season_loot": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1eb9e6e6-bfc6-4568-8d91-f302e2c91c33": { + "templateId": "HomebaseNode:questreward_herosupport_slot", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "b70e3cce-5d45-4c9b-b0f9-fdd4152b5a40": { + "templateId": "Quest:challenge_holdthedoor_19", + "attributes": { + "creation_time": "2024-04-09T16:49:07.070Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-14T00:15:01.138Z", + "completion_complete_outpost": 11, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "00ed89c1-55c6-4744-b6a6-2d383de20ff3": { + "templateId": "Quest:cannyvalley_reactive_rockformations", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T23:24:45.167Z", + "completion_cannyvalley_reactive_rockformations": 17, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "71892ead-dcb6-4f3b-afa0-68d29896f13b": { + "templateId": "Quest:cannyvalley_mechanical_constructor", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T16:53:36.214Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_cannyvalley_mechanical_constructor": 100 + }, + "quantity": 1 + }, + "879485f6-249d-44a0-a6d9-f8cd851b8f88": { + "templateId": "Quest:wargames_visibilityquest_challenge_dangerclose", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.662Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f9925d49-f7c2-48db-a6e7-1a2fdeffd9eb": { + "templateId": "Quest:heroquest_loadout_ninja_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:24:36.657Z", + "completion_complete_pve03_diff3_loadout_ninja": 300, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3c36e677-49b3-4bf8-8b23-b8bdb5d8311b": { + "templateId": "Quest:wargames_completedailyquest", + "attributes": { + "creation_time": "2025-01-02T20:30:31.509Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.509Z", + "level": -1, + "quest_rarity": "legendary", + "xp_reward_scalar": 1, + "quest_pool": "dailywargameschallenge_01" + }, + "quantity": 1 + }, + "eed7e9c1-439e-4d68-811e-810858254385": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 50, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "31f3e369-edc4-45e9-a3ff-8ac5570ae5af": { + "templateId": "Quest:challenge_holdthedoor_10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-27T17:41:35.874Z", + "completion_complete_outpost": 6, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d5f02a72-f9d2-4fdb-a8e9-652bb5339997": { + "templateId": "Worker:managermartialartist_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsMartialArtist", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-MartialArtist-M01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "51536ead-1117-48da-85e8-ec5a40025a9a": { + "templateId": "Quest:heroquest_ninjaleadership", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:36:30.980Z", + "completion_unlock_skill_tree_ninja_leadership": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "61b4b6b6-2b75-4cc3-a5ea-e77bffad1cda": { + "templateId": "Quest:cannyvalley_mechanical_exploration", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T20:30:12.863Z", + "completion_cannyvalley_mechanical_exploration": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ba72318f-e69f-47d9-b45f-ae27ece2e461": { + "templateId": "HomebaseNode:questreward_expedition_helicopter", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "0ff9d80e-611f-41e9-8c2c-78acda4f8c70": { + "templateId": "Hero:hid_ninja_smokedimmak_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "8b3be619-504d-45fe-aba9-e708b97979e0": { + "templateId": "Schematic:sid_pistol_autoheavy_founders_vr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_firerate_ranged_t01", + "Alteration:aid_att_stability_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onreload_damagebuff" + ] + }, + "quantity": 1 + }, + "1f533b95-aeb9-4b63-92b7-43b3d6ca39e1": { + "templateId": "HomebaseNode:questreward_expedition_dirtbike", + "attributes": {}, + "quantity": 1 + }, + "39592c76-008b-4704-ab09-e72cde545385": { + "templateId": "HomebaseNode:questreward_newheroloadout2_dummy", + "attributes": {}, + "quantity": 1 + }, + "5a7e0ae6-cb15-43a4-84d0-63c658cc5775": { + "templateId": "HomebaseNode:questreward_plankerton_squad_ssd5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "4e0dd929-8be7-4707-a650-353d32aba2a3": { + "templateId": "Quest:huntmonster_quest_a01_interact", + "attributes": { + "creation_time": "2024-12-16T20:05:04.711Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.711Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "82c821d7-32dc-4c09-a4e2-2f122f73b58d": { + "templateId": "AccountResource:reagent_weapons", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 86873 + }, + "abb8aaef-dc9a-47ef-8827-a75cb491bd67": { + "templateId": "Quest:cannyvalley_landmark_rift", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-18T20:58:28.346Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_landmark_rift": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9d253571-a0ec-4689-a927-201be6ec1d03": { + "templateId": "Quest:outpostquest_t3_endless", + "attributes": { + "creation_time": "2024-12-29T19:51:36.476Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T19:51:36.476Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3dcbad32-a71b-4c1a-947f-8e803c8ec6f4": { + "templateId": "Quest:s11_holdfastquest_repeat_ice", + "attributes": { + "creation_time": "2024-12-28T22:47:59.472Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-28T22:47:59.472Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "74a1f0a0-2447-41ec-bf55-552c8a3b7fc6": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "8ccd462f-181c-4c40-ba98-aaac4103f267": { + "templateId": "Quest:teamperkquest_endlessshadow", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-01T03:20:18.571Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "afb6f2f2-ea80-49c1-b3b3-30b13052759d": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "2e09c41d-8397-4d05-b5b8-4a05ef63bf46": { + "templateId": "Quest:s11_rescuehero_quest_h1", + "attributes": { + "creation_time": "2024-12-16T20:05:04.728Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.728Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6e3ba055-1f6e-4f05-a663-d04a365ba2dd": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd6", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "e48dca4b-789a-4d2c-8faa-fba4b9ad9f23": { + "templateId": "Quest:cannyvalley_reactive_trail", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T07:13:46.730Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_trail": 7, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "aaaabd1e-b72c-49d0-978c-4441ff1c7ac0": { + "templateId": "AccountResource:reagent_alteration_ele_fire", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 18290 + }, + "11d6571f-bca6-4ae8-8564-3fe76e026f93": { + "templateId": "Quest:challenge_holdthedoor_20", + "attributes": { + "creation_time": "2024-04-14T00:15:01.142Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-17T18:02:37.338Z", + "completion_complete_outpost": 11, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f436f696-a643-4a1e-ad1a-0c759d2b7beb": { + "templateId": "HomebaseNode:questreward_expedition_truck5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "8cfd3d9a-14b9-4dc8-ab16-f65791fd6511": { + "templateId": "Quest:cannyvalley_mechanical_shelterrescue", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-20T05:59:55.209Z", + "selection": 0, + "completion_cannyvalley_mechanical_shelterrescue": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "471a8ccc-1c05-4943-bd9d-cba0f9d78be4": { + "templateId": "Quest:s11_holdfastquest_seasonelite_knight", + "attributes": { + "creation_time": "2024-12-16T20:05:04.718Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.718Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fa41d74f-0321-49f2-8a85-57a02a4cdfd1": { + "templateId": "Quest:cannyvalley_reactive_oldbooks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-24T16:56:23.253Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_oldbooks": 7, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "411fd1e2-48ca-49ff-a855-666d0dd1219f": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd1", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "9e29f536-4d15-49b9-b38e-e1b45adec403": { + "templateId": "Schematic:sid_pistol_handcannon_semi_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_headshotdamage_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_onimpactbreak_dealdamage" + ] + }, + "quantity": 1 + }, + "804c265c-0e12-4801-ac40-e4204749c469": { + "templateId": "Quest:stonewoodquest_tutorial_levelup_defender", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.866Z", + "completion_defenderupgrade_guard_heroes": 1, + "completion_defenderupgrade_tabcallout": 1, + "level": -1, + "completion_defenderupgrade_intro_defenders": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_defenderupgrade_guard_command": 1, + "completion_defenderupgrade_highlight_command": 1 + }, + "quantity": 1 + }, + "89f2fc1c-1034-4757-9285-0be3124dd4bd": { + "templateId": "Quest:cannyvalley_reactive_pianos", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-21T04:28:20.479Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_pianos": 5, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f9eb69d2-7268-401c-b390-6f633ec2a22f": { + "templateId": "Quest:challenge_defendertraining_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T02:53:34.395Z", + "level": -1, + "item_seen": true, + "completion_convert_any_defender": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8734e92d-5f1d-42ce-bbab-26f509da9df1": { + "templateId": "Quest:challenge_leavenoonebehind_17", + "attributes": { + "creation_time": "2024-03-29T05:24:54.722Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-07T01:36:38.221Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 105, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "42439ee7-93a0-4c69-9c42-4f83351f507e": { + "templateId": "Quest:challenge_eldritchabominations_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-14T03:38:16.030Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 20, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "befe398c-70d3-4a68-9286-c71950e97563": { + "templateId": "Quest:cannyvalley_reactive_trees", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-21T17:13:50.935Z", + "completion_cannyvalley_reactive_trees": 20, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "833dbd5e-0b7f-4647-8072-16db8cc4f4c4": { + "templateId": "Quest:foundersquest_getrewards_microsoft", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:48:44.588Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "dc9130c1-9d81-47af-88e0-eec6c9c76e9d": { + "templateId": "Quest:foundersquest_soldier_weaponupgrade_vr", + "attributes": { + "completion_craft_founders_assault_r": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-03-31T18:38:32.021Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "epic", + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t1_l3": 1 + }, + "quantity": 1 + }, + "b6bbe7e3-3a7d-4b44-b09e-86d028694690": { + "templateId": "Quest:cannyvalley_reactive_oldmaps", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-24T19:07:41.654Z", + "selection": 0, + "level": -1, + "completion_cannyvalley_reactive_oldmaps": 50, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e5d43f0a-61f9-4d12-9e87-7477b533a022": { + "templateId": "Token:homebasepoints", + "attributes": { + "level": 1 + }, + "quantity": 2 + }, + "40332eca-0197-4e58-ad9c-841c32f6263e": { + "templateId": "HomebaseNode:questreward_expedition_rowboat", + "attributes": {}, + "quantity": 1 + }, + "c2938631-148d-41ac-aed1-04d2a9540152": { + "templateId": "Schematic:sid_blunt_hammer_hydraulic_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damage_t01", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_weapon_stun_v2" + ] + }, + "quantity": 1 + }, + "11bf9e5b-0cfa-481a-be29-b8f26f712b9c": { + "templateId": "Quest:challenge_leavenoonebehind_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T01:44:52.467Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 35, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "566ca907-b800-42c7-b014-66b2c5312c86": { + "templateId": "Quest:challenge_eldritchabominations_8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-21T21:18:43.892Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 40, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6dab1f67-bfa4-4c21-a951-a51ce12c1687": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "1", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "77e74bfc-bbdc-4658-8725-63d88dc5de62": { + "templateId": "Quest:outpostquest_t2_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T03:46:36.521Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_2_3": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "409cf81d-f06e-4daf-a3e3-99bdef15da7c": { + "templateId": "Quest:wargames_visibilityquest_challenge_swarm", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "74f2433c-4e4b-466a-887d-ec8471eb7ea9": { + "templateId": "Quest:heroquest_outlander_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T04:24:51.184Z", + "level": -1, + "item_seen": true, + "completion_complete_pve01_diff3_outlander": 3, + "sent_new_notification": true, + "completion_ability_outlander_fragment": 1, + "quest_rarity": "uncommon", + "completion_upgrade_outlander_lvl_3": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f2a3bbe8-ab6d-4665-931b-128a7470149b": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "1855234a-b724-4a13-9895-391c009ad068" + }, + "loadout_index": 5 + }, + "quantity": 1 + }, + "09246477-a6e1-4c17-bb56-592638e6f011": { + "templateId": "Quest:heroquest_loadout_ninja_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T04:09:17.917Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_pve03_diff24_loadout_ninja": 3 + }, + "quantity": 1 + }, + "a04705c2-e659-4721-b80b-251cb4c0b97b": { + "templateId": "Quest:plankertonquest_tutorial_perk", + "attributes": { + "completion_plankertonquest_tutorial_perk_obj_guardscreen01": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.869Z", + "level": -1, + "completion_plankertonquest_tutorial_perk_obj_tabcallout": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ac8bf1ad-a903-40df-81fd-d7de195f2640": { + "templateId": "Quest:stwstarterbundle18_02", + "attributes": { + "creation_time": "2024-03-26T20:57:48.414Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-27T17:25:05.328Z", + "level": -1, + "item_seen": true, + "completion_stwstarterbundle18_02_obj0": 3, + "quest_rarity": "legendary", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "343d8f22-f9d3-4d31-b1d1-8fb3d144cb78": { + "templateId": "Quest:plankertonquest_filler_1_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T16:44:36.651Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcomplete_plankertonquest_landmark_plankharbor": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "288f006e-2d15-4e85-8f27-9b3d89dfda91": { + "templateId": "Hero:hid_commando_xbox_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "squad_id": "", + "level": 1, + "item_seen": true, + "squad_slot_idx": 0, + "refundable": false, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "c62ec01f-7de8-4df6-a2e3-bae60e6525e2": { + "templateId": "Quest:outpostquest_t4_l10", + "attributes": { + "creation_time": "2024-12-29T22:20:10.393Z", + "completion_complete_outpost_4_10": 1, + "quest_state": "Claimed", + "last_state_change_time": "2024-12-30T12:37:03.323Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "75f18fb8-ed27-4842-9f04-5a904215bc16": { + "templateId": "Worker:managerexplorer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsExplorer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Explorer-F01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "ff8fc92e-b85c-4588-83ed-f9b3f87e3202": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 40, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "0e453e28-a204-4268-a525-77a0b3d04f9d": { + "templateId": "Quest:foundersquest_ninja_weaponupgrade_sr", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-26T07:26:43.545Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_craft_founders_sword_vr": 1, + "quest_rarity": "legendary", + "completion_questcomplete_stonewoodquest_launchrocket_d5": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "08603cb0-1127-49e1-aa10-3273a047c00f": { + "templateId": "HomebaseNode:commanderlevel_rpcollection", + "attributes": {}, + "quantity": 8 + }, + "c42c70d0-3f58-4385-bc55-c2e683914212": { + "templateId": "Quest:cannyvalleyquest_side_3_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-18T19:52:35.049Z", + "completion_complete_powerreactor_3_diff1": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "dd43b41e-716e-4f68-8a7b-e7c7b1e11e1d": { + "templateId": "Quest:challenge_toxictreasures_16", + "attributes": { + "creation_time": "2024-04-01T15:38:38.215Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-13T06:21:23.479Z", + "level": -1, + "item_seen": true, + "completion_complete_mimic": 9, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a12677cb-59c3-49e5-86fc-717fd4c736e5": { + "templateId": "Schematic:sid_floor_defender", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "1d930308-b517-4fbe-9fd5-0146b99e3074": { + "templateId": "Quest:stonewoodquest_killcollect_mistmonsters", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.845Z", + "level": -1, + "completion_stonewoodquest_killcollect_mistmonsters": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3c65db11-9c82-485f-86a1-02c7066cf6fa": { + "templateId": "Quest:heroquest_loadout_outlander_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T05:33:56.438Z", + "level": -1, + "item_seen": true, + "completion_complete_pve03_diff24_loadout_outlander": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "601e707d-76c9-4439-9ecf-5915636abb20": { + "templateId": "Quest:cannyvalley_reactive_rustedcars", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T17:44:29.725Z", + "completion_cannyvalley_reactive_rustedcars": 9, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0fdd7864-0704-411c-8986-1999b8323440": { + "templateId": "AccountResource:reagent_alteration_upgrade_vr", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 26 + }, + "043b2066-0f17-427e-8063-ec8f1316dc98": { + "templateId": "Quest:cannyvalley_landmark_welcome", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T05:46:44.668Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_landmark_welcome": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8fdeaf28-f87e-4f6a-b0c1-c0aceb87b408": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "97604433-4834-454a-b9f7-fdfd4f2bc64e": { + "templateId": "Quest:challenge_missionaccomplished_9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-16T19:42:16.436Z", + "level": -1, + "completion_complete_primary": 7, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fa805ec0-b258-4d1a-a2e9-02ea0a74db50": { + "templateId": "Quest:cannyvalley_reactive_tumbleweed", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:25:08.715Z", + "selection": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_tumbleweed": 10, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5dfdcf51-15f6-4015-a7f0-f938e383f939": { + "templateId": "Quest:challenge_holdthedoor_9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-06T16:39:48.886Z", + "completion_complete_outpost": 6, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "421cd35a-c16a-4a49-bca2-39a47f9576d6": { + "templateId": "Hero:hid_outlander_xbox_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "squad_id": "", + "level": 1, + "item_seen": true, + "squad_slot_idx": 0, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "1cd1b87c-8c2d-45f4-bc70-68564c0185db": { + "templateId": "Quest:genericquest_killmistmonsters_repeatable", + "attributes": { + "creation_time": "2024-12-30T12:37:00.720Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-30T12:37:00.720Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6b241489-8d22-476d-bf25-b029313e1c5a": { + "templateId": "Quest:cannyvalleyquest_filler_3_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T21:00:10.088Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_kill_husk_flinger_3_diff3_v3": 20, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ce26a282-5614-4bed-b475-0a4085f8ae1c": { + "templateId": "Quest:achievement_playwithothers", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2018-08-09T22:33:07.412Z", + "level": -1, + "completion_quick_complete": 11, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c1b7738d-fb09-4e71-adb4-11b5a73f2158": { + "templateId": "Quest:reactivequest_waterhusks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T16:35:17.256Z", + "completion_quest_reactive_waterhusks": 10, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ab4fca2a-1ed6-482a-a561-a2f1a9df2086": { + "templateId": "AccountResource:currency_xrayllama", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 895 + }, + "44767dfd-5de4-48e4-afc9-0f25212b22a4": { + "templateId": "Quest:stonewoodquest_landmark_buildoff", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.838Z", + "level": -1, + "sent_new_notification": true, + "completion_stonewoodquest_landmark_buildoff": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "07e61435-c3c0-47b8-a7f0-4a2e7f8b2b28": { + "templateId": "Quest:teamperkquest_nevertellmetheodds", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-29T00:13:45.987Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2423899b-5cfc-4c1e-a53e-49ca3f8812f4": { + "templateId": "Quest:wargames_visibilityquest_wargame_generators", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2c3281d3-3c84-405e-b169-9d1f886652a2": { + "templateId": "Quest:plankertonquest_autumnfoothills_destroy", + "attributes": { + "creation_time": "2023-01-18T17:44:58.505Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-25T18:08:05.728Z", + "completion_plankertonquest_autumnfoothills_destroy": 26, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "77488aac-76a8-46c3-abc8-ffcf6ffa1ba0": { + "templateId": "Worker:managerdoctor_sr_kingsly_t05", + "attributes": { + "squad_id": "squad_attribute_medicine_emtsquad", + "personality": "Homebase.Worker.Personality.IsCompetitive", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsDoctor", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Doctor-kingsly", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "44633448-2f40-4877-8dfa-8bf207bfdde0": { + "templateId": "Quest:cannyvalley_reactive_watertowers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T08:04:01.668Z", + "completion_cannyvalley_reactive_watertowers": 7, + "selection": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "58171c79-5632-4733-9ea5-7fe9539f3e69": { + "templateId": "Quest:stonewoodquest_mechanical_killhusks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.844Z", + "completion_stonewoodquest_mechanical_killhusks_melee": 20, + "level": -1, + "completion_stonewoodquest_mechanical_killhusks_ranged": 20, + "completion_stonewoodquest_mechanical_killhusks_trap": 20, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a3da60be-51c4-48ad-9db2-a6df4fbafeb8": { + "templateId": "Quest:plankertonquest_outpost_l5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T16:00:04.282Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_questcomplete_outpostquest_t2_l5": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e81dfc2d-abef-4285-909b-97f6731bfee1": { + "templateId": "Quest:plankertonquest_autumnfoothills_explore", + "attributes": { + "creation_time": "2024-04-10T03:58:42.326Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-10T04:34:41.269Z", + "level": -1, + "item_seen": true, + "completion_plankertonquest_autumnfoothills_explore": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "80dd395c-f910-45a6-81fe-127d1b72a6aa": { + "templateId": "Quest:cannyvalleyquest_side_4_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-23T20:09:46.937Z", + "completion_complete_evacuateshelter_3_diff3": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4a4d6424-4553-4892-b5a0-f3ad1067dd94": { + "templateId": "Quest:stw_stormkinghard_kingme", + "attributes": { + "creation_time": "2024-04-15T02:50:59.388Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T17:01:28.645Z", + "completion_stw_stormkinghard_kingme": 2, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ceb568cf-b965-40b4-b9a7-972dce695256": { + "templateId": "Worker:managerengineer_uc_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsEngineer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-Engineer-M01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "7ca4274c-4c56-4fef-a4a7-75946211d212": { + "templateId": "Quest:reactivequest_radiostation", + "attributes": { + "completion_quest_reactive_radiostation": 5, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-28T20:27:48.023Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1df107ec-6f07-42a6-ad7c-2b5391470d7b": { + "templateId": "HomebaseNode:questreward_feature_weaponlevelup", + "attributes": {}, + "quantity": 1 + }, + "1855234a-b724-4a13-9895-391c009ad068": { + "templateId": "Hero:hid_ninja_011_vr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "d760c4fa-f476-4416-b77d-06982c036873": { + "templateId": "Quest:reactivequest_finddj", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T04:35:52.973Z", + "level": -1, + "item_seen": true, + "completion_quest_reactive_finddj": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "48949d29-9840-4580-a4e4-80abfa896c73": { + "templateId": "Hero:hid_outlander_008_foundersm_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "5556f3dc-19a4-4919-8747-fa00a55a25a7": { + "templateId": "Expedition:expedition_craftingrun_short_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.771Z", + "level": 1, + "expedition_max_target_power": 210, + "expedition_min_target_power": 10, + "expedition_slot_id": "expedition.generation.land.t03_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.771Z" + }, + "quantity": 1 + }, + "cb709760-f70a-41bf-8a91-d29b7c95dc59": { + "templateId": "Quest:wargames_visibilityquest_wargame_anomaly", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3b2eca56-0409-4a62-84b9-77a05cbb8c9c": { + "templateId": "HomebaseNode:questreward_buildingresourcecap3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "1394b714-31d9-42b4-923a-3484129b9dd4": { + "templateId": "TeamPerk:tpid_soaringmantis", + "attributes": {}, + "quantity": 1 + }, + "482d47a4-04c4-4203-9946-cad9611ff1e6": { + "templateId": "Quest:plankertonquest_filler_2_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T22:38:36.200Z", + "completion_complete_delivergoods_2_diff3_v2": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "48feebbf-05bf-4cb6-b5bc-cd078cc414fd": { + "templateId": "Quest:outpostquest_t4_endless", + "attributes": { + "creation_time": "2024-12-30T12:37:03.331Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-30T12:37:03.331Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f4803dd7-2c96-419a-8ee5-69994726c975": { + "templateId": "Quest:challenge_missionaccomplished_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T01:37:06.413Z", + "level": -1, + "completion_complete_primary": 5, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3ef251f4-de74-4199-ba0b-0fe571687b2d": { + "templateId": "Quest:cannyvalleyquest_filler_4_d5", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-08-01T05:18:27.457Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4587f01c-d875-4ae8-a627-876a557856db": { + "templateId": "Quest:outpostquest_t4_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-11T17:47:32.171Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_4_4": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6fae7ff7-dac4-4dd3-9220-9bf091954d2a": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsAdventurous", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 10, + "item_seen": true, + "squad_slot_idx": 7, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "d443fca7-67a9-46eb-8fd2-96ca66f7fd8a": { + "templateId": "Worker:managermartialartist_c_t01", + "attributes": { + "gender": "2", + "personality": "Homebase.Worker.Personality.IsCompetitive", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsMartialArtist", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-MartialArtist-F01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "4c2d3934-80be-4993-ae16-28522b209c05": { + "templateId": "Quest:challenge_eldritchabominations_12", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T23:13:22.776Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 60, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9362492e-f9ac-48e1-bbde-a7c33ee9c9a3": { + "templateId": "Quest:heroquest_constructor_2", + "attributes": { + "completion_build_any_floor_constructor": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T04:44:49.627Z", + "completion_complete_pve01_diff2_constructor": 1, + "completion_ability_bullrush": 1, + "level": -1, + "completion_ability_base": 1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "dc582a5e-9988-4297-9279-94cbd6606af4": { + "templateId": "HomebaseNode:questreward_expedition_truck3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "bb9b7a6d-bf34-4457-8351-082851b8eac5": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "cd977003-ff88-4cab-a214-ea9a189bffff": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "9678b8a1-5704-4796-afd7-10b4318c184f": { + "templateId": "HomebaseNode:questreward_feature_traplevelup", + "attributes": {}, + "quantity": 1 + }, + "faabf7f3-e9c3-48f2-8a93-8f060cdca0c5": { + "templateId": "Quest:cannyvalley_reactive_powertransformers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-26T20:08:30.765Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_powertransformers": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7bb4e490-ab4e-4a2d-8af0-04e11651f8b7": { + "templateId": "CardPack:cardpack_weapons_collectionbook", + "attributes": { + "level": 1673, + "pack_source": "CollectionBook" + }, + "quantity": 1 + }, + "2e49ad93-2493-412c-9e56-c08bc4c54926": { + "templateId": "AccountResource:voucher_cardpack_bronze", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 4 + }, + "6c416f49-b408-4754-9905-c52e788d8433": { + "templateId": "AccountResource:eventcurrency_snowballs", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 3908 + }, + "912e6ee1-d469-48cb-bf09-22ca69944bbf": { + "templateId": "Quest:outpostquest_t3_l10", + "attributes": { + "creation_time": "2024-12-29T19:21:16.104Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T19:51:36.468Z", + "completion_complete_outpost_3_10": 1, + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "474405d3-aa1f-4bdf-b986-c2de255f794d": { + "templateId": "Schematic:sid_edged_axe_medium_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t02", + "Alteration:aid_att_maxdurability_t02", + "Alteration:aid_ele_nature_t02", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "aa8e1886-28ec-4890-ad17-33bc67f88586": { + "templateId": "HomebaseNode:questreward_expedition_truck", + "attributes": {}, + "quantity": 1 + }, + "f22111ca-c695-4bfa-adbc-240c43c06fd8": { + "templateId": "Quest:weeklyquest_tiered_completemissionalerts_t21", + "attributes": { + "creation_time": "2024-04-16T00:02:13.770Z", + "quest_state": "Active", + "last_state_change_time": "2024-04-16T00:02:13.770Z", + "selection": -1, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "weeklyquestroll_19", + "completion_weeklyquest_tiered_completemissionalerts_t21": 4 + }, + "quantity": 1 + }, + "a0096952-9002-48c8-9aa9-043deb8a2e67": { + "templateId": "Quest:pickaxequest_stw002_tier_3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:24.788Z", + "level": -1, + "completion_pickaxequest_stw002_tier_3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2f0a8d3f-a744-42f4-a5ee-014d4efc058f": { + "templateId": "Quest:stonewoodquest_filler_1_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T09:50:36.066Z", + "completion_complete_pve01_diff2": 1, + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 3, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "878865ce-6bcb-4d92-896b-fc467e82bee8": { + "templateId": "Quest:plankertonquest_launchtherocket", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T17:15:49.424Z", + "completion_questcomplete_plankertonquest_launchrocket_d5": 1, + "selection": -1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "50e31c5b-5e0e-41ac-b4dd-3661eed3baaf": { + "templateId": "Quest:wargames_visibilityquest_wargame_overload", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-19T02:41:39.183Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "46b83266-f257-45c2-b525-6d3ff0066a61": { + "templateId": "Quest:outpostquest_t4_l8", + "attributes": { + "creation_time": "2024-12-29T20:56:14.954Z", + "completion_complete_outpost_4_8": 1, + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T21:42:49.976Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3d11f2cb-e4a4-40fc-b326-36a1e6651ae7": { + "templateId": "Schematic:sid_shotgun_break_ou_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_stability_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "39a5e7a1-5602-49b1-adf1-4779a89b42de": { + "templateId": "HomebaseNode:questreward_expedition_helicopter3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "89d799d1-7edb-418b-a0af-8ae7bf308bd7": { + "templateId": "Schematic:sid_edged_sword_medium_laser_founders_sr_ore_t05", + "attributes": { + "level": 50, + "refund_legacy_item": true, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t04", + "Alteration:aid_att_critchance_t04", + "Alteration:aid_att_critdamage_t04", + "Alteration:aid_att_damage_t04", + "Alteration:aid_att_maxdurability_t04", + "Alteration:aid_g_weapon_onhit_energynova" + ], + "favorite": true + }, + "quantity": 1 + }, + "ae51858f-18b3-43c0-9101-8720e6ff7617": { + "templateId": "Quest:challenge_holdthedoor_14", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-12-04T19:10:59.896Z", + "completion_complete_outpost": 8, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "beacce3b-a81d-410f-a542-8bb633960aa3": { + "templateId": "Quest:teamperkquest_onetwopunch", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-21T17:22:12.819Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "73a5908e-99a9-48ce-bc92-9c1c1b9240eb": { + "templateId": "TeamPerk:tpid_shiftinggears", + "attributes": {}, + "quantity": 1 + }, + "7fa34486-20fb-49f3-ad63-7da7a9472d72": { + "templateId": "Schematic:sid_piercing_spear_laser_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_critchance_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "5ca44f22-bb36-41fa-bd22-fc467657496e": { + "templateId": "TeamPerk:tpid_boombase", + "attributes": {}, + "quantity": 1 + }, + "2479238f-3567-4530-86fb-2286339c7b29": { + "templateId": "Quest:achievement_protectthesurvivors", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:31:12.496Z", + "level": -1, + "completion_custom_protectthesurvivors": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cf122df4-bf83-4151-a2b0-d26f31e84ccd": { + "templateId": "Quest:challenge_toxictreasures_13", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-25T00:29:37.060Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 8, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7933addb-d741-4dd6-8105-706430ed2367": { + "templateId": "PrerollData:preroll_basic", + "attributes": { + "fulfillmentId": "OfferId:4D64CBE3618D41FBB5CAD0E472F4610A", + "expended_streakbreakers": { + "Currency:SB_Silver": 100, + "Currency:SB_Bronze": 100 + }, + "level": 1, + "highest_rarity": 2, + "offerId": "4D64CBE3618D41FBB5CAD0E472F4610A", + "expiration": "2025-01-03T00:00:00.000Z", + "items": [ + { + "itemType": "Worker:managertrainer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-PersonalTrainer-M01" + }, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_edged_sword_heavy_c_ore_t01", + "attributes": { + "Alteration": { + "LootTierGroup": "AlterationTG.Melee.C", + "Tier": 0 + }, + "alterations": [ + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_att_movementspeed_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + { + "itemType": "Worker:managertrainer_c_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-PersonalTrainer-M01" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F02", + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + { + "itemType": "ConsumableAccountItem:smallxpboost_gift", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "AccountResource:eventcurrency_snowballs", + "attributes": {}, + "quantity": 50 + }, + { + "itemType": "Hero:hid_ninja_015_f_v1_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_shotgun_tactical_r_ore_t01", + "attributes": { + "Alteration": { + "LootTierGroup": "AlterationTG.Ranged.R", + "Tier": 0 + }, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAnalytical", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Analytical-M01", + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + { + "itemType": "Hero:hid_outlander_008_r_t01", + "attributes": {}, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "1", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-M01", + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F03", + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + { + "itemType": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "2", + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-F02", + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + { + "itemType": "Schematic:sid_ceiling_electric_single_vr_t01", + "attributes": { + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_buildingheal_t03" + ] + }, + "quantity": 1 + } + ] + }, + "quantity": 1 + }, + "9b124d00-406d-4a49-b28c-c0d8394f9ab5": { + "templateId": "Quest:reactivequest_smasher", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T02:16:06.222Z", + "completion_quest_reactive_smasher": 5, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "44f85d13-029b-42d0-8abc-9bf578e200d1": { + "templateId": "AccountResource:reagent_c_t01", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 1895 + }, + "472e90dd-2651-4376-b225-ad3719f5b35d": { + "templateId": "Expedition:expedition_sea_survivorscouting_medium_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.752Z", + "expedition_criteria": [ + "RequiresEpicOutlander", + "RequiresEpicOutlander" + ], + "level": 1, + "expedition_max_target_power": 355, + "expedition_min_target_power": 17, + "expedition_slot_id": "expedition.generation.sea.t03_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.752Z" + }, + "quantity": 1 + }, + "0f37ce6a-119b-4825-a582-71a2b2c6570f": { + "templateId": "Quest:challenge_missionaccomplished_14", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-21T05:37:04.797Z", + "level": -1, + "completion_complete_primary": 9, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2aea7fde-9c0b-4429-b928-3dda4f0f35e7": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "e972f5c2-8e47-4901-9416-19831f0c58ea": { + "templateId": "Quest:foundersquest_outlander_weaponupgrade_sr", + "attributes": { + "creation_time": "2024-04-08T17:17:34.168Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-13T15:16:43.869Z", + "level": -1, + "item_seen": true, + "quest_rarity": "legendary", + "completion_questcomplete_stonewoodquest_launchrocket_d5": 1, + "completion_craft_founders_pistol_vr": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d80fe249-4062-46e3-8cd5-9737c5c6716a": { + "templateId": "HomebaseNode:questreward_expedition_speedboat", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "238335ca-07d6-495e-8cde-5b8da709c9f9": { + "templateId": "AccountResource:heroxp", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 11003824 + }, + "01bfaee2-3840-4523-8821-cdbdd160a523": { + "templateId": "Hero:hid_ninja_smokedimmak_vr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "6bd2ec91-ede6-4f52-bcb1-6aaa08347870": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_closeassaultsquad", + "level": 40, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "ea1df154-76aa-43c6-9332-c5b05ebeaa4f": { + "templateId": "Quest:outpostquest_t3_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T23:49:45.071Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_3_2": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ec3be0ba-19a0-4019-905c-c5582f7dc6e7": { + "templateId": "Schematic:sid_edged_scythe_neonglow_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_energy_intrin_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_firerate_melee_t03", + "Alteration:aid_conditional_afflicted_dmgbonus_t03", + "Alteration:aid_g_onmeleekill_regenshields" + ] + }, + "quantity": 1 + }, + "962da2ef-ba52-4259-958e-3e8fb779c20e": { + "templateId": "Quest:outpostquest_t4_l6", + "attributes": { + "creation_time": "2024-04-15T02:50:59.388Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-15T20:29:19.361Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_4_6": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e244efc8-142e-4b58-9727-fb2e5d783473": { + "templateId": "Quest:cannyvalleyquest_outpost_l4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-16T21:00:17.782Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t3_l4": 1 + }, + "quantity": 1 + }, + "f8d7eaad-d933-4b8d-8bf7-985cdd510571": { + "templateId": "Quest:challenge_holdthedoor_15", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-03-29T05:40:33.650Z", + "completion_complete_outpost": 9, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cbd8dc43-3af6-48e9-8495-3d52f0335f55": { + "templateId": "Quest:outpostquest_t3_l5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-22T21:48:59.748Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_3_5": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3f167808-0eb6-4571-8006-1c3bc150b614": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "2", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "fc88b709-97e6-455a-9619-637ced19c9cd": { + "templateId": "Worker:workerbasic_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 50, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "282db0d2-6957-4396-bbda-a55200a64228": { + "templateId": "Quest:cannyvalleyquest_filler_2_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-30T05:21:29.462Z", + "completion_complete_pve03_diff5_v2": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcollect_survivoritemdata_v2": 15, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "7c549b74-4835-40b0-8f50-094d7f6bb826": { + "templateId": "Expedition:expedition_air_supplyrun_long_t03", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.757Z", + "expedition_criteria": [ + "RequiresEpicConstructor" + ], + "level": 1, + "expedition_max_target_power": 505, + "expedition_min_target_power": 25, + "expedition_slot_id": "expedition.generation.air.t03_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.757Z" + }, + "quantity": 1 + }, + "6bf74234-63d7-48cd-be16-63004992fcec": { + "templateId": "Quest:challenge_toxictreasures_11", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T18:04:41.123Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "752ce1f0-eec3-4360-a34e-fac90434c3f4": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "4522d996-4192-40a9-a6d6-c7dbd333be40": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "ea2999d3-28d3-4a71-9393-f8eba3c0874e": { + "templateId": "Schematic:sid_floor_player_jump_pad_free_direction", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "e8353f3d-fd9b-4c6e-a7a7-0abd8867c8dc": { + "templateId": "TeamPerk:tpid_phaseblaster", + "attributes": {}, + "quantity": 1 + }, + "222d1edb-11e6-40a7-aa77-d593a7958627": { + "templateId": "HomebaseNode:questreward_expedition_helicopter4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "f28498d0-8121-47b0-9a55-87f3df145e3a": { + "templateId": "Quest:wargames_visibilityquest_challenge_fulltime", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "36d11704-7eb6-4883-8be9-3fcf38b33137": { + "templateId": "AccountResource:reagent_c_t03", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 119 + }, + "0ebb8e6a-3f5f-4211-a970-0d9b69581522": { + "templateId": "Expedition:expedition_resourcerun_woodstone_medium", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.767Z", + "level": 1, + "expedition_max_target_power": 115, + "expedition_min_target_power": 5, + "expedition_slot_id": "expedition.generation.land.t02_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.767Z" + }, + "quantity": 1 + }, + "0d245f75-5752-4c8d-b8b2-e1fc45c43a8b": { + "templateId": "Quest:challenge_eldritchabominations_19", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-08T18:00:46.804Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 95, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2c1f8130-b99e-4f84-a22d-ddba6c1fa3bf": { + "templateId": "Stat:offense", + "attributes": { + "level": 1 + }, + "quantity": 504 + }, + "f0de0b7c-9be8-460a-98ed-56f196ff946f": { + "templateId": "Quest:outpostquest_t2_l9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-04-05T17:52:58.778Z", + "completion_complete_outpost_2_9": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "937b831f-2254-486e-a062-96703e5753e9": { + "templateId": "Quest:twinepeaksquest_filler_3_d1", + "attributes": { + "creation_time": "2024-04-05T05:08:22.881Z", + "quest_state": "Active", + "last_state_change_time": "2024-04-05T05:08:22.881Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9958db7c-b20c-4153-b9f2-94d3b67d1f3b": { + "templateId": "Worker:managerinventor_sr_rad_t05", + "attributes": { + "squad_id": "squad_attribute_synthesis_thethinktank", + "personality": "Homebase.Worker.Personality.IsCooperative", + "level": 50, + "squad_slot_idx": 0, + "item_seen": true, + "managerSynergy": "Homebase.Manager.IsInventor", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-SR-Inventor-rad", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "22ea8848-a2d6-467b-8e00-46d42de90ded": { + "templateId": "Quest:challenge_holdthedoor_12", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-18T17:59:10.758Z", + "completion_complete_outpost": 7, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e5599cd8-c286-4fc1-b5bc-68e8f0da1523": { + "templateId": "Quest:heroquest_constructorleadership", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:58:33.340Z", + "completion_unlock_skill_tree_constructor_leadership": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d0e7f1f9-25fe-42c1-899d-3595f846dbe6": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "33db9e9f-efe4-463b-83f6-c9a84079d3b8" + }, + "loadout_index": 8 + }, + "quantity": 1 + }, + "07696694-7240-4018-a099-65f1f31e1526": { + "templateId": "Stat:technology", + "attributes": { + "level": 1 + }, + "quantity": 504 + }, + "68966139-135c-42c5-897e-ba706641f055": { + "templateId": "Quest:foundersquest_ninja_weaponupgrade_vr", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-26T07:26:05.634Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "epic", + "completion_craft_founders_sword_r": 1, + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t1_l3": 1 + }, + "quantity": 1 + }, + "e46068c5-fd87-4014-9882-e687fc136bbc": { + "templateId": "Quest:plankertonquest_filler_9_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-08T15:35:49.597Z", + "level": -1, + "item_seen": true, + "completion_complete_powerreactor_2_diff4": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6729f9a4-ecd7-41f4-a183-489837f5e396": { + "templateId": "Quest:bbpromoquest_2019_reactive_jesscabinet", + "attributes": { + "completion_bbpromoquest_2019_reactive_jesscabinet_obj0": 5, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-03-26T19:28:40.668Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_bbpromoquest_2019_reactive_jesscabinet": 4, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5ac3d501-343b-4c8c-b06f-f800cafe2a21": { + "templateId": "Quest:challenge_leavenoonebehind_8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-05T14:38:03.327Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 55, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "32e9c15e-0655-4679-b3cd-fe5f9c1b8f42": { + "templateId": "Schematic:sid_edged_sword_dragon_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_att_damageresistance_t02", + "Alteration:aid_att_firerate_melee_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "d41bb14c-64b4-41a5-8f28-e1f4ad2ed2e4": { + "templateId": "Quest:cannyvalley_reactive_telescopes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-21T05:05:37.629Z", + "completion_cannyvalley_reactive_telescopes": 7, + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5623ae48-a36c-4cbc-a8e0-d034945bc79a": { + "templateId": "Quest:plankertonquest_filler_1_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-29T21:43:04.456Z", + "level": -1, + "item_seen": true, + "completion_complete_stormchest_2_diff3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "78cbaec5-6cdc-48a7-a2b5-dc346a0cc2a7": { + "templateId": "Defender:did_defendershotgun_basic_f_sr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_clipsize", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_critchance_ranged", + "Alteration:aid_att_def_clipsize", + "Alteration:aid_att_def_shieldregen" + ] + }, + "quantity": 1 + }, + "fd1532b6-4eda-4c7d-a060-24009830cbd4": { + "templateId": "Quest:challenge_leavenoonebehind_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T05:50:16.264Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 25, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "36942725-74a5-47b4-aa1c-447652aed2c1": { + "templateId": "Quest:teamperkquest_trickandtreat", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-12-16T14:55:35.878Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cbc2adec-8cc4-4d92-b9ca-e974a6e8f3aa": { + "templateId": "HomebaseNode:questreward_expedition_rowboat2", + "attributes": {}, + "quantity": 1 + }, + "ce3320fb-819e-45b5-8574-25fc5295d39e": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "b389fa66-408b-41db-8cb8-a2d706a7cd26": { + "templateId": "Defender:did_defendersniper_basic_sr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_durability", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_clipsize", + "Alteration:aid_att_def_weapondamage_sniper", + "Alteration:aid_att_def_maxshield" + ] + }, + "quantity": 1 + }, + "f9cdef18-bbd0-4abd-a229-225a6bb87eb3": { + "templateId": "Quest:stwstarterbundle18_05", + "attributes": { + "creation_time": "2024-03-26T20:57:48.414Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-02T01:06:42.673Z", + "level": -1, + "item_seen": true, + "completion_stwstarterbundle18_05_obj0": 9, + "quest_rarity": "legendary", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "1463e855-6256-46fa-b73a-e8a24cd831f1": { + "templateId": "Schematic:sid_pistol_semiauto_c_ore_t00", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "dfc4a57a-2cee-4985-91b7-177218f8d802": { + "templateId": "HomebaseNode:skilltree_stormshieldstorage", + "attributes": {}, + "quantity": 5 + }, + "87d799ca-0f09-4fd2-adbc-a36f12b39ef3": { + "templateId": "Hero:hid_constructor_xbox_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "squad_id": "", + "level": 1, + "item_seen": true, + "squad_slot_idx": 0, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "33608329-433c-4ea3-a9b4-71562c54e56c": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M02", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "00f1afaa-9e25-4066-9e51-72e594c4a882": { + "templateId": "Quest:genericquest_completebetastorms_repeatable", + "attributes": { + "creation_time": "2024-12-16T20:05:04.711Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.711Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d0504e0d-60ad-4493-8e30-b9b34b611f9b": { + "templateId": "Quest:challenge_holdthedoor_17", + "attributes": { + "creation_time": "2024-03-31T21:36:54.193Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-05T17:52:54.473Z", + "completion_complete_outpost": 10, + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ac6777f3-23dd-4e25-b3a9-da51bdd5c38b": { + "templateId": "HomebaseNode:questreward_expedition_helicopter2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "16273cb5-a9a6-4800-bdd8-93e6ee2a9b0a": { + "templateId": "Quest:pickaxequest_stw004_tier_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:34.297Z", + "completion_pickaxequest_stw004_tier_5": 4, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "30d5e5c9-b107-476a-abda-822827ae879f": { + "templateId": "Quest:reactivequest_supplyrun", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T01:37:01.199Z", + "completion_complete_pve01_diff5": 2, + "level": -1, + "item_seen": true, + "completion_quest_reactive_larssupplies": 4, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f3771be9-54d5-41bf-8adb-100c36786049": { + "templateId": "Quest:cannyvalley_reactive_survey", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-12T04:32:26.705Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_cannyvalley_reactive_survey": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0b58d5a5-c891-45ef-af94-b8f62e78ff57": { + "templateId": "Quest:challenge_collectionbook_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T09:52:38.391Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_collectionbook_levelup": 2 + }, + "quantity": 1 + }, + "b87e297d-5a61-452e-9803-8fde6e8df3df": { + "templateId": "Quest:cannyvalley_reactive_truther", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T19:29:33.655Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_cannyvalley_reactive_truther": 5 + }, + "quantity": 1 + }, + "d956a286-f163-4157-a004-f94b11f72c70": { + "templateId": "Quest:challenge_leavenoonebehind_12", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T18:39:34.563Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 80, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "02e6e1b9-2b9d-4bf2-8149-c2332f0dab5f": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Quests - Misfit Toys", + "conditions": { + "event": { + "instanceId": "41852m4bc5c9a4rbr15gitl8sq[0]1", + "eventName": "CalendarEvent_Persistent_Holiday_MisfitToys_Quests", + "eventStart": "2024-12-12T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:s11_rescuehero_quest_h1", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:s11_rescuehero_quest_h1", + "quantity": 1 + }, + { + "templateId": "Quest:s11_destroy_quest_h2", + "quantity": 1 + }, + { + "templateId": "Quest:s11_fetch_quest_h3", + "quantity": 1 + }, + { + "templateId": "Quest:s11_landmark_quest_h4", + "quantity": 1 + }, + { + "templateId": "Quest:s11_killcollect_quest_h5", + "quantity": 1 + }, + { + "templateId": "Quest:s11_fetch_quest_h6", + "quantity": 1 + }, + { + "templateId": "Quest:s11_reactivefetch_quest_h7", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "ec6b69c8-7404-45d6-b264-e2f7d4d925d1": { + "templateId": "TeamPerk:tpid_slowyourroll", + "attributes": {}, + "quantity": 1 + }, + "0be6448d-41d2-4ad0-914a-2bda2173bb01": { + "templateId": "Quest:teamperkquest_boombase", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:37:42.061Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5e25cc3a-8250-4811-9f3f-d7e8b6ae24b3": { + "templateId": "Quest:teamperkquest_shiftinggears", + "attributes": { + "creation_time": "2024-04-16T00:10:04.320Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-16T00:11:09.658Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "039d3b93-1e21-4df5-a934-c6ca3a5fcc0c": { + "templateId": "Quest:teamperkquest_blastfromthepast", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T03:47:34.804Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "954d1590-a4dd-4514-a619-c5d42a20a9ea": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "5207cc22-317a-41b1-89c0-60eac9e63488": { + "templateId": "Quest:homebaseonboardinggrantschematics", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:48:01.341Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "247b169e-de8e-4f14-a31a-8f2610fe8def": { + "templateId": "Expedition:expedition_sea_survivorscouting_medium_t02", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.749Z", + "expedition_criteria": [ + "RequiresOutlander", + "RequiresCommando" + ], + "level": 1, + "expedition_max_target_power": 255, + "expedition_min_target_power": 12, + "expedition_slot_id": "expedition.generation.sea.t02_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.749Z" + }, + "quantity": 1 + }, + "b53f8d2c-42d6-4d09-81bd-faa6d5d3c170": { + "templateId": "Quest:cannyvalley_reactive_pamphlets", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T21:59:16.409Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_pamphlets": 7, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a32bf2aa-91cd-4543-9a8a-453fbd77b999": { + "templateId": "Quest:wargames_visibilityquest_wargame_telebomb", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-06T16:10:23.220Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "24b87317-7495-4415-8456-c953143d21c2": { + "templateId": "Quest:outpostquest_t1_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T08:49:31.743Z", + "level": -1, + "item_seen": true, + "completion_complete_outpost_1_2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f44d6da4-a3a7-4bbe-8943-4339cf76816f": { + "templateId": "Quest:plankertonquest_filler_6_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T03:28:03.547Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_relaysurvivor_2_diff5": 2, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a7836567-55a5-4ef2-b644-28f73add3d71": { + "templateId": "Hero:hid_commando_027_piratesoldier_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "38bd01af-e67e-4e24-b69f-315408d3cf16": { + "templateId": "HomebaseNode:questreward_expedition_rowboat4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "cdd29f44-3a06-47ec-b71c-c50ecc373557": { + "templateId": "Quest:heroquest_soldier_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-23T03:19:54.927Z", + "level": -1, + "item_seen": true, + "completion_kill_husk_commando_fraggrenade": 10, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2a3618ac-3e2e-4943-8827-0f16795e2d7e": { + "templateId": "Schematic:ammo_bulletsheavy", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "7fba9904-1b51-45b2-8f27-6c66ca5070a8": { + "templateId": "Quest:cannyvalley_reactive_pueblos", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T05:27:21.053Z", + "completion_cannyvalley_reactive_pueblos": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "abda8498-8d2e-4ccb-87cb-f85fe1833fad": { + "templateId": "Quest:challenge_leavenoonebehind_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T19:14:05.421Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 20, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "393a30f9-4b1c-4e5d-adcf-fdea7c7ae352": { + "templateId": "Expedition:expedition_sea_supplyrun_short_t01", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.770Z", + "expedition_criteria": [ + "RequiresCommando", + "RequiresCommando" + ], + "level": 1, + "expedition_max_target_power": 95, + "expedition_min_target_power": 4, + "expedition_slot_id": "expedition.generation.sea.t01_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.770Z" + }, + "quantity": 1 + }, + "cd6dd9c7-6f98-4c35-b5aa-42b8af81f0d7": { + "templateId": "Expedition:expedition_air_supplyrun_medium_t02", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.759Z", + "expedition_criteria": [ + "RequiresCommando", + "RequiresRareCommando" + ], + "level": 1, + "expedition_max_target_power": 215, + "expedition_min_target_power": 10, + "expedition_slot_id": "expedition.generation.air.t02_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.759Z" + }, + "quantity": 1 + }, + "d6c7ff4a-ac1d-4748-967a-0a78f9c8b9e1": { + "templateId": "Schematic:sid_edged_scythe_laser_sr_ore_t01", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_lifeleech_t01", + "Alteration:aid_att_movementspeed_t02", + "Alteration:aid_ele_energy_t02", + "Alteration:aid_att_critchance_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "44aae291-27b2-440b-ba4e-c0fced2550f3": { + "templateId": "Quest:teamperkquest_phaseblaster", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-01T03:20:18.571Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6dfb7959-086b-42f8-b8b3-f54f2c9eebb0": { + "templateId": "ConditionalAction:generic_instance", + "attributes": { + "alt_profile_types": [ + "athena" + ], + "_private": true, + "devName": "MAJOR: Holiday - Quests - Ghost of Christmas", + "conditions": { + "event": { + "instanceId": "mi11nt3e3ej0qidplr80v8ak7v[0]1", + "eventName": "CalendarEvent_Persistent_Holiday_GhostOfChristmas_Quests", + "eventStart": "2025-01-02T00:00:00.000Z", + "eventEnd": "2025-01-23T00:00:00.000Z", + "startActions": { + "hasRun": true, + "conversions": [], + "itemsToGrant": [ + { + "templateId": "Quest:phoenix_fetch_quest_c1", + "quantity": 1 + } + ], + "questsToUnpause": [] + }, + "endActions": { + "hasRun": false, + "conversions": [], + "itemsToRemove": [ + { + "templateId": "Quest:phoenix_fetch_quest_c1", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_destroy_quest_c2", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_survivor_quest_c3", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_reactivekill_quest_c4", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_fetch_quest_c5", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_rescuehero_quest_c6", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_reactivefetch_quest_c7", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_gathercollect_quest_c8", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_fetch_quest_c9", + "quantity": 1 + }, + { + "templateId": "Quest:phoenix_fetch_quest_c10", + "quantity": 1 + } + ], + "questsToPause": [] + }, + "metaData": {} + } + } + }, + "quantity": 1 + }, + "9d29ac53-db9f-4b8a-abae-aaaeac0bd98a": { + "templateId": "Hero:hid_ninja_starsassassin_foundersm_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 10, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "af7185c5-4d9b-4065-9a47-d3455b38340e": { + "templateId": "Quest:cannyvalleyquest_side_3_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T16:00:51.238Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_gate_triple_3_diff2": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d55f9ed8-b58c-4a98-b5c1-a42070b67bd3": { + "templateId": "Quest:heroquest_constructor_3", + "attributes": { + "quest_state": "Claimed", + "completion_complete_buildradar_1_diff2_con": 1, + "creation_time": "min", + "last_state_change_time": "2018-08-11T05:28:43.808Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "95e94b85-4a45-4712-8a65-67daa8492585": { + "templateId": "HomebaseNode:questreward_cannyvalley_squad_ssd3", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "9207ebae-b773-4123-8913-aa8ceae2ebcc": { + "templateId": "Quest:challenge_eldritchabominations_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-17T23:11:17.914Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 25, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "eaf3fccf-7a0d-4fc2-8c81-6ed24855d952": { + "templateId": "Worker:worker_joel_ur_t05", + "attributes": { + "squad_id": "squad_attribute_scavenging_scoutingparty", + "personality": "Homebase.Worker.Personality.IsDreamer", + "level": 50, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "83c4438c-a07d-431a-b22e-8ed0492b0237": { + "templateId": "Quest:homebaseonboarding", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:33:07.407Z", + "completion_hbonboarding_namehomebase": 1, + "level": -1, + "completion_hbonboarding_completezone": 1, + "completion_hbonboarding_watchsatellitecine": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "72ab8e2e-9d26-44fa-b7ba-00ebca099ea5": { + "templateId": "Quest:challenge_leavenoonebehind_10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T19:03:13.372Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 70, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "330de4bc-ab40-48b6-8eb5-67e27da0c22d": { + "templateId": "Quest:cannyvalley_reactive_trophies", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-07-30T05:21:51.109Z", + "completion_cannyvalley_reactive_trophies": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fc1b198f-0bb3-4c2f-8bfd-45f253e07bc5": { + "templateId": "Quest:stwstarterbundle18_03", + "attributes": { + "creation_time": "2024-03-26T20:57:48.414Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-30T07:17:57.710Z", + "level": -1, + "item_seen": true, + "completion_stwstarterbundle18_03_obj0": 5, + "quest_rarity": "legendary", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f6e1fbf8-4932-44df-aa01-c1f965cb9416": { + "templateId": "Hero:hid_ninja_smokedimmak_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "dfd8ac69-f587-4c8e-8390-a133b06db0a1": { + "templateId": "TeamPerk:tpid_nevertellmetheodds", + "attributes": {}, + "quantity": 1 + }, + "78df6489-347c-492c-8627-ff045fa1f4af": { + "templateId": "Quest:phoenix_fetch_quest_c1", + "attributes": { + "creation_time": "2025-01-02T20:30:31.503Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.503Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "adc09c54-f39c-4768-be67-fe3937b94046": { + "templateId": "Token:collectionresource_nodegatetoken01", + "attributes": { + "level": 1 + }, + "quantity": 3101 + }, + "8a2cd0a8-9c00-499b-9d70-efb6b73a7aaf": { + "templateId": "Quest:foundersquest_constructor_weaponupgrade_vr", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2024-03-31T18:28:52.872Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_craft_founders_shotgun_r": 1, + "quest_rarity": "epic", + "xp_reward_scalar": 1, + "completion_questcomplete_outpostquest_t1_l3": 1 + }, + "quantity": 1 + }, + "ffa7db35-4660-4266-b302-8ae313174b01": { + "templateId": "Quest:outpostquest_t2_l8", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-18T18:35:17.696Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_outpost_2_8": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4f2437d9-4159-4823-94c1-729bfce0515a": { + "templateId": "Quest:homebasequest_slotmissiondefender", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-10T21:21:52.096Z", + "completion_assign_defender_to_adventure_squadone": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "72682699-3376-4865-97a4-74f90ade9757": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dreamer-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsShieldRegenLow" + }, + "quantity": 1 + }, + "94ce084d-a84d-49c0-b779-75003cfdee8d": { + "templateId": "HomebaseNode:questreward_expedition_speedboat5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "f186cf98-5d15-4902-b847-07660eb5d340": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsAdventurous", + "gender": "1", + "squad_id": "squad_attribute_arms_fireteamalpha", + "level": 30, + "squad_slot_idx": 4, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Adventurous-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "07301730-ea86-49e3-b0e5-c38702643a71": { + "templateId": "Quest:challenge_eldritchabominations_7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-19T17:54:19.532Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 35, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "61838a8b-2f32-45bf-a9fa-34a71b052b40": { + "templateId": "Expedition:expedition_supplyrun_long_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.772Z", + "expedition_criteria": [ + "RequiresEpicCommando" + ], + "level": 1, + "expedition_max_target_power": 680, + "expedition_min_target_power": 34, + "expedition_slot_id": "expedition.generation.land.t04_0", + "expedition_expiration_start_time": "2025-01-02T20:30:29.772Z" + }, + "quantity": 1 + }, + "75911429-d32c-4819-a9a1-a9f47692c56b": { + "templateId": "Quest:outpostquest_t1_l7", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-18T23:34:10.201Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_outpost_1_7": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e8640a37-58a7-41b5-a973-98e498cdf63a": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCooperative", + "gender": "2", + "squad_id": "squad_attribute_synthesis_thethinktank", + "level": 30, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Cooperative-F01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "3d8b7f32-c21f-4717-a17b-3fb9dfe30674": { + "templateId": "HomebaseNode:questreward_expedition_speedboat2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "da5f4f76-d2c4-48f0-a3e0-c858cad90f89": { + "templateId": "Quest:teamperkquest_totallygnarly", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-30T00:35:34.721Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "277df41a-45be-442e-81a9-32bd7fa8656f": { + "templateId": "HomebaseNode:questreward_expedition_propplane2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "bb00222d-9808-4cff-98a1-a9b28207fb6e": { + "templateId": "HomebaseNode:questreward_feature_skillsystem", + "attributes": {}, + "quantity": 1 + }, + "d17f8be3-86c7-49c9-9d21-dfbf2db260a5": { + "templateId": "HomebaseNode:questreward_twinepeaks_squad_ssd2", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "c4ce1f18-be55-4fdb-a5a2-7b2f449cad65": { + "templateId": "Quest:tutorial_loadout_support4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:28:07.916Z", + "completion_heroloadout_support4_intro": 1, + "level": -1, + "completion_heroloadout_support4_guardscreen1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "432abac9-0e9c-4ce1-b370-169dfec5e915": { + "templateId": "Quest:cannyvalley_reactive_seebot", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-11T17:27:57.667Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_seebot": 5, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9110203e-3c42-4e29-a8c1-3e8580781c66": { + "templateId": "Quest:reactivequest_masterservers", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T20:52:32.661Z", + "completion_complete_protecttheservers_2": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "f4eefa2e-d8bb-4f94-8689-a29f2da6353c": { + "templateId": "Quest:endurancewave30theater03", + "attributes": { + "creation_time": "2024-12-29T19:51:36.476Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T19:51:36.476Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "90e2c3dd-3e88-4f90-bfd6-6200d0c7dd46": { + "templateId": "Expedition:expedition_traprun_sea_medium_t04", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.755Z", + "level": 1, + "expedition_max_target_power": 575, + "expedition_min_target_power": 28, + "expedition_slot_id": "expedition.generation.sea.t04_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.755Z" + }, + "quantity": 1 + }, + "2aff3491-277f-45a6-82fc-019f149c2a08": { + "templateId": "Quest:cannyvalley_reactive_mainframes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-06-05T03:20:39.464Z", + "selection": 0, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cannyvalley_reactive_mainframes": 30, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cbb6fffa-afde-4d35-b377-5515032a3a5a": { + "templateId": "Quest:pickaxequest_stw005_tier_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T17:18:39.199Z", + "completion_pickaxequest_stw005_tier_6": 6, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "098e6e00-ed9f-42db-816a-ea519c6d4992": { + "templateId": "Schematic:ammo_bulletslight", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "8604c29e-c753-4ef4-a33d-629df9b65ef2": { + "templateId": "CampaignHeroLoadout:defaultloadout", + "attributes": { + "team_perk": "2281756d-e483-457d-b8d2-fcfbf9cb3ffe", + "level": 1, + "crew_members": { + "followerslot5": "", + "followerslot4": "", + "followerslot3": "", + "followerslot2": "", + "followerslot1": "", + "commanderslot": "028ec0de-5e52-44cb-b905-ed313b96a1bf" + }, + "loadout_index": 4 + }, + "quantity": 1 + }, + "14fc47bf-9b5d-428f-a5be-667726bd999b": { + "templateId": "Quest:cannyvalleyquest_filler_1_d2", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-12T23:49:45.075Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9674c982-983e-4b82-a6c6-9c47384d1617": { + "templateId": "Hero:hid_ninja_starsassassin_foundersf_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "c2336d2b-a651-430b-a674-d934bec18e9b": { + "templateId": "Hero:hid_constructor_008_foundersm_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "f4f05204-97f3-4031-a903-a353a894ee7e": { + "templateId": "Quest:cannyvalley_landmark_deploytheprobe", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-22T22:34:04.713Z", + "completion_cannyvalley_landmark_deploytheprobe": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "2b87bdf0-3c2d-4ffa-b58d-5a94f3b27ab5": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsPragmatic", + "gender": "1", + "squad_id": "squad_attribute_synthesis_corpsofengineering", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Pragmatic-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsFortitudeLow" + }, + "quantity": 1 + }, + "ffde4b46-a604-4443-9d1a-951a7fbbab3c": { + "templateId": "Worker:worker_halloween_smasher_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_scavenging_gadgeteers", + "level": 50, + "squad_slot_idx": 1, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Smasher", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDurabilityHigh" + }, + "quantity": 1 + }, + "3eaf1e77-831a-40bd-ac44-52f4198f0dfc": { + "templateId": "Quest:reactivequest_lightninghusks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-08T18:40:48.449Z", + "level": -1, + "completion_quest_reactive_lightninghusks": 10, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "768e77d0-7040-45f3-bea7-9f39b8faa9b3": { + "templateId": "Quest:cannyvalley_reactive_glyphs", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-13T02:22:47.027Z", + "selection": 1, + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_glyphs": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "57a41b2d-96a0-41bc-9afe-f36113a9f8be": { + "templateId": "Quest:heroquest_soldier_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T19:14:12.863Z", + "level": -1, + "item_seen": true, + "completion_kill_husk_commando_assault": 100, + "completion_upgrade_soldier": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0f9de45a-5cef-49b9-9366-49d0d2af9392": { + "templateId": "HomebaseNode:questreward_stonewood_squad_ssd5", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "0000d9b2-1956-4a1f-aed2-c09ce5de0fdd": { + "templateId": "Quest:bbpromoquest_2019_reactive_kylecabinet", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-12-04T20:25:26.026Z", + "level": -1, + "item_seen": true, + "completion_bbpromoquest_2019_reactive_kylecabinet": 5, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0bb58587-b7e1-40b4-b5e3-aec738bd3c2d": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Dependable-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "109cdcfb-0a2d-491c-8524-09a00a2d9de1": { + "templateId": "Expedition:expedition_supplyrun_short_t02", + "attributes": { + "expedition_expiration_end_time": "2025-01-02T22:00:29.775Z", + "expedition_criteria": [ + "RequiresCommando", + "RequiresRareNinja" + ], + "level": 1, + "expedition_max_target_power": 140, + "expedition_min_target_power": 7, + "expedition_slot_id": "expedition.generation.land.t02_1", + "expedition_expiration_start_time": "2025-01-02T20:30:29.775Z" + }, + "quantity": 1 + }, + "5c1d8b6a-7349-4620-944a-c607fe45b9d2": { + "templateId": "Quest:outpostquest_firstopen_ssd", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T18:21:51.108Z", + "completion_complete_ssd_firstopen": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0c044f4d-244b-4efd-8275-1c2ce9c5c4c1": { + "templateId": "Quest:s11_holdfastquest_seasonelite_cramps", + "attributes": { + "creation_time": "2024-12-16T20:05:04.718Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.718Z", + "level": -1, + "item_seen": true, + "completion_s11_holdfastquest_seasonelite_cramps1": 13, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "c58050fe-4cc6-446a-80e0-ad9f82699bc4": { + "templateId": "Stat:technology_team", + "attributes": { + "level": 1 + }, + "quantity": 224 + }, + "e65d8dbd-f3d0-4830-9b51-98241ff0212b": { + "templateId": "Quest:foundersquest_getrewards_4_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2020-10-06T02:46:12.610Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d8aad1a7-cc65-4b13-a93b-47ccbd659709": { + "templateId": "Token:stw_accolade_tracker", + "attributes": { + "last_reset": "2024-12-27T16:51:14.478Z", + "match_accolades": [ + { + "totalMissionXPEarnedInMatch": 109812, + "totalQuestXPEarnedInMatch": 0, + "accoladesToGrant": [ + { + "realXPGranted": 3250, + "numToGrant": 1, + "rawXPGranted": 3250, + "templateToGrant": "Accolades:accoladeid_stw_badge_building_platinum" + }, + { + "realXPGranted": 3250, + "numToGrant": 1, + "rawXPGranted": 3250, + "templateToGrant": "Accolades:accoladeid_stw_badge_combat_platinum" + }, + { + "realXPGranted": 687, + "numToGrant": 1, + "rawXPGranted": 687, + "templateToGrant": "Accolades:accoladeid_stw_badge_utility_bronze" + }, + { + "realXPGranted": 87500, + "numToGrant": 1, + "rawXPGranted": 87500, + "templateToGrant": "Accolades:accoladeid_stw_ssd_t04_l10" + }, + { + "realXPGranted": 15125, + "numToGrant": 1, + "rawXPGranted": 15125, + "templateToGrant": "Accolades:accoladeid_stw_ssd_t04_bonus" + } + ], + "totalSecondsInMatch": 2308, + "matchmakingSessionId": "639651ebf0de49a3935870352b215485", + "partyEligibility": "User", + "totalRestSpentInMatch": 0, + "primaryMissionName": "MissionInfo_Outpost_PvE_04" + } + ], + "level": 1, + "last_update": "2024-12-30T12:36:55.041Z", + "weekly_xp": 1458249 + }, + "quantity": 1 + }, + "4cb01f5d-c6a3-4603-89bb-796f20170efa": { + "templateId": "Quest:stonewoodquest_tutorial_survivorsquads", + "attributes": { + "completion_survivorsquads_changeherointro": 1, + "creation_time": "min", + "completion_survivorsquads_levelintro": 1, + "level": -1, + "completion_survivorsquads_squadsguard": 1, + "completion_survivorsquads_squadsintro": 1, + "completion_survivorsquads_squadtilesguard": 1, + "sent_new_notification": true, + "completion_survivorsquads_commandguardaccount": 1, + "xp_reward_scalar": 1, + "quest_state": "Claimed", + "last_state_change_time": "2018-11-14T22:00:53.863Z", + "completion_survivorsquads_changeheroguard": 1, + "completion_survivorsquads_powerintro": 1, + "completion_survivorsquads_squadshighlight": 1, + "completion_survivorsquads_tabcallout": 1, + "completion_survivorsquads_commandguardsquad": 1, + "completion_survivorsquads_survivorshighlight": 1, + "quest_rarity": "uncommon", + "completion_survivorsquads_commandguardintro": 1 + }, + "quantity": 1 + }, + "097f1a49-32c5-4425-9179-033311adbf8c": { + "templateId": "Quest:stwstarterbundle18_04", + "attributes": { + "creation_time": "2024-03-26T20:57:48.414Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-31T01:52:05.904Z", + "level": -1, + "item_seen": true, + "completion_stwstarterbundle18_04_obj0": 7, + "quest_rarity": "legendary", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "79bcd4b3-4a39-4f70-a3fb-d84c4c3d8a18": { + "templateId": "Quest:teamperkquest_soaringmantis", + "attributes": { + "creation_time": "2024-03-30T16:06:51.893Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-03-30T16:52:26.529Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "435dcff5-bf42-4304-b23f-76d0c1cb698f": { + "templateId": "Quest:plankertonquest_filler_5_d3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-25T05:18:31.104Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 15, + "completion_complete_powerreactor_2_diff3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e58deb70-f45c-4654-bd62-ff0a0f896e09": { + "templateId": "TeamPerk:tpid_roundtrip", + "attributes": {}, + "quantity": 1 + }, + "a5ce1c0b-2521-42b7-956a-3f405d0308d2": { + "templateId": "Worker:worker_halloween_smasher_sr_t05", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "2", + "squad_id": "squad_attribute_scavenging_scoutingparty", + "level": 50, + "squad_slot_idx": 2, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Smasher", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "81cc6ce0-ea99-476b-b4d3-4ed48c092208": { + "templateId": "Quest:stw_stormkinghard_firsttakedown", + "attributes": { + "creation_time": "2024-12-29T17:01:28.646Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-12-29T17:29:47.588Z", + "level": -1, + "completion_stw_stormkinghard_firsttakedown": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "5599576e-f676-4934-84d9-1dd2bb1d8248": { + "templateId": "Quest:reactivequest_riftdata", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T16:28:31.137Z", + "completion_quest_reactive_riftdata": 3, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "3e829030-6bb3-4c1c-bfd9-7995ef1331c9": { + "templateId": "Hero:hid_ninja_xbox_r_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "squad_id": "", + "mode_loadouts": [], + "level": 1, + "squad_slot_idx": 0, + "item_seen": true, + "refundable": false, + "favorite": false, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "5ddacbb9-3cfb-41cc-9813-a80ea33f3f76": { + "templateId": "Schematic:sid_assault_auto_founders_sr_ore_t05", + "attributes": { + "level": 50, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_reloadspeed_ranged_t05", + "Alteration:aid_att_damage_t05", + "Alteration:aid_ele_energy_t05", + "Alteration:aid_att_damage_t05", + "Alteration:aid_att_critdamage_t05", + "Alteration:aid_g_weapon_onreload_explode" + ], + "alteration_base_rarities": [ + "common", + "uncommon", + "common", + "rare", + "common", + "common" + ], + "favorite": true + }, + "quantity": 1 + }, + "41a2c130-51a5-4c54-8ef6-3ee722b1f943": { + "templateId": "Stat:resistance_team", + "attributes": { + "level": 1 + }, + "quantity": 150 + }, + "612d2cc0-7cec-4207-8552-2c38a03f4e08": { + "templateId": "Quest:plankertonquest_outpost_l6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-10T17:15:28.733Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_questcomplete_outpostquest_t2_l6": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a76f3c2b-2dde-4a23-9ccb-f138aaa089d4": { + "templateId": "Defender:did_defendersniper_basic_vr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_firerate", + "Alteration:aid_att_def_maxhealth", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_critdamage_ranged" + ] + }, + "quantity": 1 + }, + "55520c23-2543-48fe-a691-53572e5a0b29": { + "templateId": "Schematic:sid_floor_health_c_t00", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "5acf3cd5-73a2-4c56-bd91-4d2a36e62be9": { + "templateId": "Quest:challenge_leavenoonebehind_14", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-11-21T23:50:39.624Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 90, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a95c7f04-0f00-4b31-8b50-d5edcf19af88": { + "templateId": "AccountResource:eventcurrency_scaling", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 187 + }, + "bd037c30-7a49-4c69-9cc7-16b676565373": { + "templateId": "Quest:challenge_eldritchabominations_10", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T04:06:18.109Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 50, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a9b66b58-be90-4da9-bf0b-1475aaa1a9f3": { + "templateId": "CardPack:cardpack_choice_manager_vr", + "attributes": { + "level": 1674, + "pack_source": "CollectionBook", + "options": [ + { + "itemType": "CardPack:cardpack_manager_doctor_vr", + "quantity": 1 + }, + { + "itemType": "CardPack:cardpack_manager_explorer_vr", + "quantity": 1 + } + ] + }, + "quantity": 1 + }, + "80ac1aef-7f3e-4716-b4fd-39a8f68b86bb": { + "templateId": "Quest:stonewoodquest_tutorial_levelup_hero", + "attributes": { + "completion_heroupgrade_tabcallout": 1, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.863Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_heroupgrade_guard_command": 1, + "completion_heroupgrade_guard_heroes": 1, + "xp_reward_scalar": 1, + "completion_heroupgrade_highlight_heroes_button": 1 + }, + "quantity": 1 + }, + "575ca090-cee7-46af-bdcf-c1645b1a5973": { + "templateId": "HomebaseNode:questreward_expedition_truck4", + "attributes": { + "item_seen": true + }, + "quantity": 1 + }, + "cd88ebdf-e5b2-4d1e-9b7e-ed5f48fcfb98": { + "templateId": "Schematic:sid_shotgun_break_scavenger_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critdamage_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_critchance_t03", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_shrapnel" + ] + }, + "quantity": 1 + }, + "f028a570-2c69-4eb9-a25c-52363ce190d7": { + "templateId": "Quest:winter_seasonal_weapon_01", + "attributes": { + "creation_time": "2024-12-16T20:05:04.725Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.725Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "355ecd25-3599-417c-a67e-48ba82172e63": { + "templateId": "Quest:reactivequest_firehusks", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-30T15:32:31.687Z", + "completion_quest_reactive_firehusks": 10, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "71dbabe0-fdcc-43dc-86c2-d30f83903d4d": { + "templateId": "Quest:plankertonquest_filler_5_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-09T20:03:30.057Z", + "completion_complete_retrievedata_2_diff4": 2, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fdd7f03f-0477-4e0e-a049-79f9a84b0af5": { + "templateId": "Quest:wargames_visibilityquest_wargame_lava", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-09T14:15:52.663Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "42cbca4b-8b6e-428a-995b-1cd29daf17c1": { + "templateId": "Defender:did_defenderpistol_basic_uc_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_weapondamage_pistol", + "Alteration:aid_att_def_maxhealth" + ] + }, + "quantity": 1 + }, + "57b9586e-5945-4efc-b47f-4fa5d13b491c": { + "templateId": "Quest:challenge_leavenoonebehind_9", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-04T03:13:00.904Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 60, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9db536df-c699-4736-952b-580ac6e7c300": { + "templateId": "Quest:reactivequest_elemhusky", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T19:33:45.943Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_quest_reactive_elemhusky": 10, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "9df8ae78-54d2-4f11-9544-2401f00bbc2f": { + "templateId": "Quest:challenge_herotraining_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-13T01:37:23.669Z", + "completion_convert_any_hero": 1, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "ed3d41a8-4632-4b57-9912-4e07d2797a1b": { + "templateId": "Quest:plankertonquest_filler_8_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-07T19:01:50.163Z", + "level": -1, + "item_seen": true, + "completion_complete_delivergoods_2_diff4": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "835fe850-42ca-4f4d-88d4-33e357506a0b": { + "templateId": "Quest:stonewoodquest_tutorial_collectionbook", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.867Z", + "completion_cb_tabcallout": 1, + "level": -1, + "completion_cb_guard_armory": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_cb_intro": 1, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "42c16dab-d17d-45c1-ac57-39fbde5b0274": { + "templateId": "Quest:challenge_holdthedoor_13", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-27T07:01:56.805Z", + "completion_complete_outpost": 8, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d39a8496-32c8-4ef9-8f4e-ba5b1e0f2768": { + "templateId": "Quest:cannyvalleyquest_outpost_l3", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T18:37:39.787Z", + "level": -1, + "completion_questcomplete_outpostquest_t3_l3": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4b5e7821-a9fc-4574-808a-2be67c2c7e5b": { + "templateId": "Quest:challenge_missionaccomplished_17", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T04:19:13.702Z", + "level": -1, + "completion_complete_primary": 11, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "8cc14b60-8ed5-4f5f-acf7-ae78f2696740": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 30, + "squad_slot_idx": 3, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "eb3c1a8e-82d0-423d-a86e-11a76b3059cf": { + "templateId": "Quest:plankertonquest_filler_1_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-10-04T03:13:10.832Z", + "level": -1, + "item_seen": true, + "completion_complete_evacuateshelter_2_diff4_v2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e79fc053-ba43-49cc-ac40-36dcab64a42c": { + "templateId": "Quest:wargames_visibilityquest_wargame_meteor", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-05-22T14:38:10.647Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bd7bdc5f-fd1b-4a9c-b856-88335c263ca2": { + "templateId": "Worker:worker_halloween_husky_vr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Husky", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsAbilityDamageLow" + }, + "quantity": 1 + }, + "2ca32d8f-91a5-4c91-94aa-abff120cb6bc": { + "templateId": "Quest:challenge_defendertraining_1", + "attributes": { + "quest_state": "Claimed", + "completion_upgrade_any_defender": 1, + "creation_time": "min", + "last_state_change_time": "2018-08-11T19:17:42.270Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "16d87c23-8c21-498d-a950-7c52e20d642b": { + "templateId": "Quest:cannyvalleyquest_side_4_d2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-15T19:06:28.686Z", + "level": -1, + "completion_complete_buildradargrid_3_diff2": 3, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "85d3dffc-855e-4ffb-8e27-75038eea6178": { + "templateId": "Quest:challenge_workertraining_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T05:53:40.076Z", + "completion_upgrade_any_worker": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b62f74d4-8317-4c82-99ae-70b023a4dada": { + "templateId": "Schematic:sid_sniper_flintlock_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_reloadspeed_ranged_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_conditional_boss_dmgbonus_t03", + "Alteration:aid_att_stability_t03", + "Alteration:aid_g_shrapnel" + ] + }, + "quantity": 1 + }, + "80c5e396-d8b0-4d96-9b8b-de5547eba821": { + "templateId": "Hero:hid_constructor_024_pirateconstructor_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "8b78c471-8bf5-46fc-80c5-8e694c63b1f6": { + "templateId": "Worker:workerbasic_vr_t01", + "attributes": { + "gender": "1", + "personality": "Homebase.Worker.Personality.IsCurious", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M01", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsMeleeDamageLow" + }, + "quantity": 1 + }, + "3ab8520b-8a27-4fd2-a8da-33018e9173a6": { + "templateId": "Quest:teamperkquest_superchargedtraps", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-09-05T00:46:15.044Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "149c1a78-cc19-419d-a642-cea1a473026a": { + "templateId": "Worker:workerbasic_sr_t04", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCompetitive", + "gender": "2", + "squad_id": "squad_attribute_medicine_emtsquad", + "level": 30, + "squad_slot_idx": 6, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Competitive-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsResistanceLow" + }, + "quantity": 1 + }, + "ed39b206-569b-419b-b620-682b117ac4a3": { + "templateId": "Buff:partyxpbuff", + "attributes": { + "level": 1 + }, + "quantity": 1 + }, + "ac486a52-cf85-45a3-85df-a68c0526eb5e": { + "templateId": "Quest:outpostquest_t4_l5", + "attributes": { + "creation_time": "2024-04-11T17:47:32.179Z", + "quest_state": "Claimed", + "last_state_change_time": "2024-04-15T02:50:59.383Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_outpost_4_5": 1 + }, + "quantity": 1 + }, + "95740e02-cd16-4d8d-9652-08782b8032dd": { + "templateId": "Quest:challenge_eldritchabominations_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T17:24:31.971Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_kill_husk_smasher": 10, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d2c1eeef-0c2f-41c0-b12f-b0fb0969d27d": { + "templateId": "Schematic:sid_sniper_boombox_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_weaponimpact_t01", + "Alteration:aid_att_damage_t02", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_stability_t02", + "Alteration:aid_att_critdamage_t03", + "Alteration:aid_g_onimpactbreak_dance" + ] + }, + "quantity": 1 + }, + "d2bff1cb-5172-4af8-86ad-d74e18c6dac2": { + "templateId": "Quest:reactivequest_poisonlobbers", + "attributes": { + "completion_quest_reactive_poisonlobbers": 10, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T18:03:59.034Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a7d3c773-94fd-4df0-9149-91e940cbf830": { + "templateId": "CardPack:cardpack_jackpot_collectionbook", + "attributes": { + "level": 1671, + "pack_source": "CollectionBook" + }, + "quantity": 1 + }, + "43d46402-532a-433d-bbf3-f067761acd3b": { + "templateId": "Quest:foundersquest_herobundle_noninja", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2020-10-06T02:46:52.163Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "59704ca5-97cf-4d68-93fa-a6841ba79183": { + "templateId": "Quest:challenge_holdthedoor_5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-24T23:13:27.033Z", + "completion_complete_outpost": 4, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d17e3b7c-d738-44fa-9c74-592d39a32b4b": { + "templateId": "Quest:plankertonquest_outpost_l2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.851Z", + "level": -1, + "completion_questcomplete_outpostquest_t2_l2": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "d593584a-9ab5-4354-8732-2aacca0b663d": { + "templateId": "Schematic:sid_sniper_standard_scope_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_damage_t01", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_conditional_stunned_dmgbonus_t03", + "Alteration:aid_g_standstill_stackbuff_damagevsmist" + ] + }, + "quantity": 1 + }, + "08117794-3fb5-46c6-98dd-1d00f1cc15b6": { + "templateId": "Hero:hid_constructor_024_pirateconstructor_sr_t01", + "attributes": { + "hero_name": "DefaultHeroName", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "84b73c21-eb1a-4921-96f7-a443d4eb60b0": { + "templateId": "Quest:challenge_missionaccomplished_20", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-31T19:04:29.960Z", + "level": -1, + "completion_complete_primary": 12, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "84292de2-ceba-4020-a2ef-caebac673974": { + "templateId": "Quest:daily_safes", + "attributes": { + "creation_time": "2024-08-15T18:18:31.755Z", + "quest_state": "Active", + "last_state_change_time": "2024-08-15T18:18:31.755Z", + "level": -1, + "item_seen": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "b4b98969-cbb6-4618-bac3-f4cbe9f31c97": { + "templateId": "TeamPerk:tpid_dangerdanger", + "attributes": {}, + "quantity": 1 + }, + "43d78c9d-e3ce-48da-aa3d-4d6735623639": { + "templateId": "Quest:plankertonquest_filler_4_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-09T17:31:11.139Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_buildradar_2_diff5": 3 + }, + "quantity": 1 + }, + "4a261175-994f-461c-aa80-ef62acdca479": { + "templateId": "Quest:challenge_leavenoonebehind_6", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-25T18:04:04.080Z", + "level": -1, + "item_seen": true, + "completion_questcollect_survivoritemdata": 45, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "0e9fa6c9-aac4-4a24-9e10-7f35e14809fa": { + "templateId": "Worker:worker_halloween_husky_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDreamer", + "gender": "1", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Husky", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsRangedDamageLow" + }, + "quantity": 1 + }, + "25e4aeb1-46d5-4ca0-9192-6d49060adc65": { + "templateId": "Quest:tutorial_loadout_support5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-02T18:28:06.716Z", + "level": -1, + "sent_new_notification": true, + "completion_heroloadout_support5_guardscreen1": 1, + "completion_heroloadout_support5_intro": 1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a886cd80-5fbc-4540-bed6-28e36ddb3de3": { + "templateId": "Hero:hid_ninja_swordmaster_sr_t03", + "attributes": { + "outfitvariants": [], + "backblingvariants": [], + "hero_name": "DefaultHeroName", + "level": 30, + "item_seen": true, + "squad_slot_idx": -1, + "building_slot_used": -1 + }, + "quantity": 1 + }, + "b6a65ac7-5411-431c-ab4d-26fc06fc5b1d": { + "templateId": "TeamPerk:tpid_kineticoverdrive", + "attributes": {}, + "quantity": 1 + }, + "a91ca19e-47c8-4c1e-b05e-f6f9f5bea8ac": { + "templateId": "Quest:endurancedaily_t02_w10", + "attributes": { + "creation_time": "2024-12-29T13:20:28.532Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-29T13:20:28.532Z", + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "endurancedailyquests_15" + }, + "quantity": 1 + }, + "2ff87c5c-2c32-4fe3-b4e9-0bf9b8688881": { + "templateId": "Quest:stonewoodquest_hidden_hasitems", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:01:00.128Z", + "completion_stonewoodquest_hidden_hasitems": 50, + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e4f60bfb-fe36-431b-9bc6-50ff1f7ba2ee": { + "templateId": "Quest:s11_holdfastquest_season_trapcraft", + "attributes": { + "creation_time": "2024-12-16T20:05:04.717Z", + "quest_state": "Active", + "last_state_change_time": "2024-12-16T20:05:04.717Z", + "level": -1, + "item_seen": true, + "completion_s11_holdfastquest_season_trapcraft": 7, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "66ca6064-98f2-48c0-8c91-ce969bb8075b": { + "templateId": "Quest:cannyvalleyquest_launchrocket_d5", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-05T00:37:13.681Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "completion_complete_launchrocket_3": 1 + }, + "quantity": 1 + }, + "866e1d21-6077-4dc9-a6a0-79d472f3cba3": { + "templateId": "Worker:workerbasic_sr_t03", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "1", + "squad_id": "squad_attribute_medicine_trainingteam", + "level": 30, + "squad_slot_idx": 5, + "item_seen": true, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-M03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "9ab52a97-2418-4dbb-aa01-c40ea7b993ee": { + "templateId": "Quest:challenge_missionaccomplished_13", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-19T22:13:09.972Z", + "level": -1, + "completion_complete_primary": 9, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "fadcb3a4-66fe-4c52-9786-386464a9ee83": { + "templateId": "Quest:challenge_toxictreasures_4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-09-13T14:52:05.168Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_complete_mimic": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "251d18e4-eb96-4b0b-9d97-785cd81068ac": { + "templateId": "Quest:wargames_visibilityquest_wargame_riotcity", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-19T02:41:39.183Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "e1591227-876c-41bf-a3cb-7989da45fd5f": { + "templateId": "Quest:cannyvalley_reactive_aftercredits", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-08-02T01:52:37.979Z", + "completion_cannyvalley_reactive_aftercredits": 6, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4aec57a6-9057-4dec-9303-b10be59ec4a9": { + "templateId": "Quest:stonewoodquest_mechanical_buildlev2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-11-14T22:00:53.841Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_stonewoodquest_mechanical_buildlev2": 50, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "a7b436ea-1763-4fab-b80f-3ba1653dfa24": { + "templateId": "Schematic:sid_assault_hydraulic_drum_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_magazinesize_t02", + "Alteration:aid_att_damage_physical_t02", + "Alteration:aid_att_headshotdamage_t02", + "Alteration:aid_conditional_slowed_dmgbonus_t03", + "Alteration:aid_g_weapon_ondmg_applysnare_v2" + ] + }, + "quantity": 1 + }, + "e84b1d07-5a4f-4faf-b29d-01678f409515": { + "templateId": "Quest:plankertonquest_filler_2_d1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-21T22:17:25.725Z", + "completion_complete_evacuate_2": 1, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "4a0a458b-3d29-492c-92ef-02d8d5ec4cef": { + "templateId": "Quest:wargames_dailyquest_riotcity_with_headgames_twine", + "attributes": { + "creation_time": "2025-01-02T20:30:31.514Z", + "quest_state": "Active", + "last_state_change_time": "2025-01-02T20:30:31.514Z", + "selection": -1, + "level": -1, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1, + "quest_pool": "dailywargamestwine_01" + }, + "quantity": 1 + }, + "a33ed58d-83b6-4c38-88f3-d99d50c59350": { + "templateId": "Schematic:sid_floor_player_jump_pad", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true + }, + "quantity": 1 + }, + "2c3dc001-6e8f-4f7a-80a0-331cfb31818f": { + "templateId": "Defender:did_defendersniper_basic_sr_t01", + "attributes": { + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "alterations": [ + "Alteration:aid_att_def_reload", + "Alteration:aid_att_def_maxshield", + "Alteration:aid_att_def_shieldregen", + "Alteration:aid_att_def_critchance_ranged", + "Alteration:aid_att_def_shieldregen" + ] + }, + "quantity": 1 + }, + "8c3ff18f-345a-4d43-9d0f-ca5390f2073a": { + "templateId": "Quest:reactivequest_findpop", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-23T00:43:05.353Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "completion_quest_reactive_findpop": 3, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "95cdd8dc-0802-4478-9c93-87a1e4084a3f": { + "templateId": "Quest:challenge_missionaccomplished_15", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-22T02:36:41.982Z", + "level": -1, + "completion_complete_primary": 10, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "43fc8f7c-536e-486b-a433-216abbb60f26": { + "templateId": "TeamPerk:tpid_endlessshadow", + "attributes": {}, + "quantity": 1 + }, + "8e1df41c-6927-4cf4-81d8-9c0a0640cea3": { + "templateId": "Quest:challenge_missionaccomplished_1", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-11T04:16:16.634Z", + "level": -1, + "completion_complete_primary": 3, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "6b5bc6ce-6c49-442a-a4e3-f89be3aaada0": { + "templateId": "Quest:stonewoodquest_filler_1_d4", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-12T05:50:21.464Z", + "level": -1, + "item_seen": true, + "completion_complete_pve01_diff4": 2, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "completion_complete_encampment_1_diff4": 4, + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "eeffeeb9-b784-4598-b7c3-af9f9b596a89": { + "templateId": "Quest:wargames_visibilityquest_wargame_tprifts", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-06-19T02:41:39.183Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "01d4f9ed-e608-42d7-8266-94591e408a80": { + "templateId": "Schematic:sid_edged_sword_medium_laser_founders_vr_ore_t01", + "attributes": { + "refund_legacy_item": true, + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_ele_fire_intrin_t02", + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_critdamage_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_maxdurability_t01", + "Alteration:aid_g_weapon_onhit_energynova" + ] + }, + "quantity": 1 + }, + "68a84f8b-b525-4950-97c8-11ce744ad630": { + "templateId": "Worker:managertrainer_r_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsDependable", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "managerSynergy": "Homebase.Manager.IsTrainer", + "portrait": "WorkerPortrait:IconDef-ManagerPortrait-PersonalTrainer-F01", + "building_slot_used": -1 + }, + "quantity": 1 + }, + "6ad4e96d-e1ee-4a7d-8165-530df25ff2b9": { + "templateId": "Schematic:sid_blunt_medium_sr_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_critchance_t01", + "Alteration:aid_att_heavyattackstaminacost_t01", + "Alteration:aid_att_damage_physical_t03", + "Alteration:aid_att_heavyattackstaminacost_t02", + "Alteration:aid_conditional_slowed_dmgbonus_t03", + "Alteration:aid_g_affliction_v2" + ] + }, + "quantity": 1 + }, + "45ff9c96-6416-48b5-b82d-3f43c1b644f4": { + "templateId": "Schematic:sid_assault_surgical_drum_founders_r_ore_t01", + "attributes": { + "level": 1, + "item_seen": true, + "alterations": [ + "Alteration:aid_att_stability_t01", + "Alteration:aid_att_reloadspeed_ranged_t02", + "Alteration:aid_ele_water_t02", + "Alteration:aid_att_damage_t03", + "Alteration:aid_att_magazinesize_t01", + "Alteration:aid_g_weapon_onfire_damagestack" + ] + }, + "quantity": 1 + }, + "bd85bbbe-dc1a-4634-a765-73f280ca4834": { + "templateId": "Worker:workerbasic_sr_t01", + "attributes": { + "personality": "Homebase.Worker.Personality.IsCurious", + "gender": "2", + "level": 1, + "item_seen": true, + "squad_slot_idx": -1, + "portrait": "WorkerPortrait:IconDef-WorkerPortrait-Curious-F03", + "building_slot_used": -1, + "set_bonus": "Homebase.Worker.SetBonus.IsTrapDamageLow" + }, + "quantity": 1 + }, + "77050265-f9f9-4819-ad4a-3f30a98e5c51": { + "templateId": "AccountResource:voucher_basicpack", + "attributes": { + "level": 1, + "item_seen": true + }, + "quantity": 41 + }, + "d6da6e6a-f77a-4c1d-b8f1-d7a820dd5f4d": { + "templateId": "Quest:cannyvalley_hidden_watchvideo", + "attributes": { + "creation_time": "min", + "quest_state": "Active", + "last_state_change_time": "2019-08-02T01:28:20.342Z", + "level": -1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "bee22ed4-12a8-45f8-ab2f-38ff81b36476": { + "templateId": "Quest:achievement_loottreasurechests", + "attributes": { + "completion_interact_treasurechest": 300, + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T21:26:30.786Z", + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "cd61753c-76d7-4497-b41a-6271c46a28cb": { + "templateId": "Quest:foundersquest_getrewards_1_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2018-08-09T22:49:32.889Z", + "level": -1, + "completion_questcomplete_outpostquest_t1_l1": 1, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "433d57e3-d5bb-4c94-8f3e-9ede9a938b8d": { + "templateId": "Quest:heroquest_loadout_constructor_2", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T21:26:45.494Z", + "completion_complete_pve03_diff26_loadout_constructor": 300, + "level": -1, + "item_seen": true, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + }, + "52683082-e070-4763-b390-1239a429228d": { + "templateId": "Quest:cannyvalley_reactive_jukeboxes", + "attributes": { + "quest_state": "Claimed", + "creation_time": "min", + "last_state_change_time": "2019-05-14T05:52:27.056Z", + "level": -1, + "item_seen": true, + "completion_cannyvalley_reactive_jukeboxes": 10, + "sent_new_notification": true, + "quest_rarity": "uncommon", + "xp_reward_scalar": 1 + }, + "quantity": 1 + } + } + } + } + ], + "profileCommandRevision": 40512, + "serverTime": "2025-01-04T23:20:14.600Z", + "responseVersion": 1 +} \ No newline at end of file diff --git a/checker/img/logo.png b/checker/img/logo.png new file mode 100644 index 0000000..b5b26e4 Binary files /dev/null and b/checker/img/logo.png differ diff --git a/checker/img/styles/legacy.png b/checker/img/styles/legacy.png new file mode 100644 index 0000000..fdddcd7 Binary files /dev/null and b/checker/img/styles/legacy.png differ diff --git a/checker/img/styles/modern.png b/checker/img/styles/modern.png new file mode 100644 index 0000000..6bd6d3a Binary files /dev/null and b/checker/img/styles/modern.png differ diff --git a/checker/img/styles/origin.png b/checker/img/styles/origin.png new file mode 100644 index 0000000..a1552a5 Binary files /dev/null and b/checker/img/styles/origin.png differ diff --git a/checker/img/styles/rift.png b/checker/img/styles/rift.png new file mode 100644 index 0000000..448b6de Binary files /dev/null and b/checker/img/styles/rift.png differ diff --git a/checker/img/styles/storm.png b/checker/img/styles/storm.png new file mode 100644 index 0000000..37dd0e1 Binary files /dev/null and b/checker/img/styles/storm.png differ diff --git a/checker/most_wanted.txt b/checker/most_wanted.txt new file mode 100644 index 0000000..926c417 --- /dev/null +++ b/checker/most_wanted.txt @@ -0,0 +1,148 @@ +Pickaxe_ID_376_FNCS +Pickaxe_FNCS_S32 +CID_017_Athena_Commando_M +CID_028_Athena_Commando_F +Pickaxe_Lockjaw +Glider_ID_001 + + +CID_619_Athena_Commando_F_TechLlama +CID_035_Athena_Commando_M_Medieval +CID_039_Athena_Commando_F_Disco +CID_434_Athena_Commando_F_StealthHonor +CID_757_Athena_Commando_F_WildCat +CID_175_Athena_Commando_M_Celestial +CID_703_Athena_Commando_M_Cyclone +CID_761_Athena_Commando_M_CycloneSpace +CID_515_Athena_Commando_M_BarbequeLarry +CID_259_Athena_Commando_M_StreetOps + + +CID_A_215_Athena_Commando_F_SunriseCastle_48TIZ +CID_A_381_Athena_Commando_F_CactusRocker_3HTBV +Character_TigerRootFame +Character_Hitman_Dark +Character_VoltaicHuntress +Character_FallValleyBlink +Character_FallValleyCharge +Character_UpbeatIguana_D +Character_UpbeatIguana +CID_993_Athena_Commando_M_TyphoonRobot_2YRGV +Character_StallionAviator +CID_530_Athena_Commando_F_BlackMonday_1BV6J +CID_A_138_Athena_Commando_F_Foray_YQPB0 +CID_A_205_Athena_Commando_F_TextileRam_GMRJ0 +CID_A_206_Athena_Commando_F_TextileSparkle_V8YSA +CID_A_207_Athena_Commando_M_TextileKnight_9TE8L +CID_A_208_Athena_Commando_M_TextilePup_C85OD +CID_424_Athena_Commando_M_Vigilante +CID_423_Athena_Commando_F_Painter +CID_A_266_Athena_Commando_F_Grandeur_9CO1M +CID_A_265_Athena_Commando_M_Grandeur_TBC0O +Character_Hitman_Dark +Character_BlueMystery_Dark +Character_PinkTrooperDark +Character_DarkVogue +CID_A_256_Athena_Commando_F_UproarBraids_8IOZW +CID_A_329_Athena_Commando_F_Uproar_I5N5Z +CID_A_385_Athena_Commando_F_Rumble +CID_A_162_Athena_Commando_F_Quarrel_E5D63 +CID_A_161_Athena_Commando_M_Quarrel_SLXQG +CID_A_384_Athena_Commando_M_Rumble +CID_A_024_Athena_Commando_F_Skirmish_QW2BQ +CID_A_023_Athena_Commando_M_Skirmish_W1N7H +CID_478_Athena_Commando_F_WorldCup +Character_SpeedDialBattle +CID_704_Athena_Commando_F_LollipopTrickster +CID_715_Athena_Commando_F_TwinDark +CID_A_047_Athena_Commando_F_Windwalker +CID_805_Athena_Commando_F_PunkDevilSummer +CID_801_Athena_Commando_F_GolfSummer +CID_650_Athena_Commando_F_HolidayPJ_B +Character_FauxVenom +CID_365_Athena_Commando_M_LuckyRider +CID_512_Athena_Commando_F_CubePaintRedKnight +CID_653_Athena_Commando_F_UglySweaterFrozen +Character_BrightIon +CID_216_Athena_Commando_F_Medic +CID_A_338_Athena_Commando_F_Galactic_HN9D +Character_RedOasisPomegranate +Character_RedOasisApricot +CID_819_Athena_Commando_F_NeonTightSuit_B +Character_SuperNovaTaro +CID_A_096_Athena_Commando_F_TaxiUpgradedMulticolor +CID_A_388_Athena_Commando_F_Lyrical +CID_A_387_Athena_Commando_M_Lyrical +CID_861_Athena_Commando_F_Elastic_B +CID_A_250_Athena_Commando_F_ZombieElastic_B +CID_A_443_Athena_Commando_F_PennantSeasOne_C +CID_A_444_Athena_Commando_F_PennantSeasOne_D +CID_A_441_Athena_Commando_F_PennantSeasOne + + +CID_065_Athena_Commando_F_SkiGirl_FRA +CID_062_Athena_Commando_F_SkiGirl_USA +CID_066_Athena_Commando_F_SkiGirl_GER +CID_064_Athena_Commando_F_SkiGirl_GBR +CID_063_Athena_Commando_F_SkiGirl_CAN +CID_068_Athena_Commando_F_SkiGirl_KOR + + +Character_ReconExpert_FNCS +Character_GarbageFNCS +Character_TreasureHunterFashionsFNCS +Character_LeatherKey +CID_888_Athena_Commando_F_ChOneBanshee +CID_889_Athena_Commando_F_ChOneWildcat +CID_884_Athena_Commando_F_ChOneRamirez +CID_885_Athena_Commando_M_ChOneHawk + + +BID_138_Celestial +BID_004_BlackKnight +BID_229_LuckyRiderMale +BID_468_Cyclone +BID_273_AssassinSuitCoin + + +Pickaxe_ID_294_CandyCane +Pickaxe_ID_508_HistorianMale_6BQSW +Pickaxe_ID_363_LollipopTricksterFemale +HalloweenScythe +Pickaxe_ID_015_HolidayCandyCane +Pickaxe_ID_599_CavernFemale +Pickaxe_ID_804_FNCSS20Male +Pickaxe_ID_138_Gnome +Pickaxe_SlowBurn +Pickaxe_IronBlaze +Pickaxe_ID_074_SharpDresser +Pickaxe_ID_014_WinterCamo +Pickaxe_ID_359_CycloneMale +Pickaxe_ID_475_ChOnePickaxe + + +EID_Fresh +EID_Floss +EID_TakeTheL +EID_CycloneHeadBang +EID_SpeedDial +EID_JanuaryBop +EID_Devotion +EID_Laugh +EID_Griddles +EID_Coping +EID_Cyclone +EID_JanuaryBop +EID_Punctual +EID_Breakdance2 +EID_Jaywalking +EID_PlayerEleven +EID_HipHop01 +EID_GoodVibes +EID_SandwichBop +EID_LetsPlay + + +Glider_ID_314_SpaceChimpMale +Glider_Warthog +Glider_ID_244_ChOneGlider \ No newline at end of file diff --git a/checker/renderer.py b/checker/renderer.py new file mode 100644 index 0000000..21b405d --- /dev/null +++ b/checker/renderer.py @@ -0,0 +1 @@ +import os diff --git a/checker/styles/kayy/font.ttf b/checker/styles/kayy/font.ttf new file mode 100644 index 0000000..05b0255 Binary files /dev/null and b/checker/styles/kayy/font.ttf differ diff --git a/checker/styles/kayy/rarity/common.png b/checker/styles/kayy/rarity/common.png new file mode 100644 index 0000000..dfc1fc3 Binary files /dev/null and b/checker/styles/kayy/rarity/common.png differ diff --git a/checker/styles/kayy/rarity/dark.png b/checker/styles/kayy/rarity/dark.png new file mode 100644 index 0000000..1156740 Binary files /dev/null and b/checker/styles/kayy/rarity/dark.png differ diff --git a/checker/styles/kayy/rarity/dc.png b/checker/styles/kayy/rarity/dc.png new file mode 100644 index 0000000..2af2abc Binary files /dev/null and b/checker/styles/kayy/rarity/dc.png differ diff --git a/checker/styles/kayy/rarity/epic.png b/checker/styles/kayy/rarity/epic.png new file mode 100644 index 0000000..19a5f5a Binary files /dev/null and b/checker/styles/kayy/rarity/epic.png differ diff --git a/checker/styles/kayy/rarity/frozen.png b/checker/styles/kayy/rarity/frozen.png new file mode 100644 index 0000000..804e278 Binary files /dev/null and b/checker/styles/kayy/rarity/frozen.png differ diff --git a/checker/styles/kayy/rarity/gaminglegends.png b/checker/styles/kayy/rarity/gaminglegends.png new file mode 100644 index 0000000..3c61a77 Binary files /dev/null and b/checker/styles/kayy/rarity/gaminglegends.png differ diff --git a/checker/styles/kayy/rarity/icon.png b/checker/styles/kayy/rarity/icon.png new file mode 100644 index 0000000..cccc7f4 Binary files /dev/null and b/checker/styles/kayy/rarity/icon.png differ diff --git a/checker/styles/kayy/rarity/lava.png b/checker/styles/kayy/rarity/lava.png new file mode 100644 index 0000000..29bc62e Binary files /dev/null and b/checker/styles/kayy/rarity/lava.png differ diff --git a/checker/styles/kayy/rarity/legendary.png b/checker/styles/kayy/rarity/legendary.png new file mode 100644 index 0000000..a91fcf3 Binary files /dev/null and b/checker/styles/kayy/rarity/legendary.png differ diff --git a/checker/styles/kayy/rarity/marvel.png b/checker/styles/kayy/rarity/marvel.png new file mode 100644 index 0000000..cef7b3f Binary files /dev/null and b/checker/styles/kayy/rarity/marvel.png differ diff --git a/checker/styles/kayy/rarity/mythic.png b/checker/styles/kayy/rarity/mythic.png new file mode 100644 index 0000000..aa52f93 Binary files /dev/null and b/checker/styles/kayy/rarity/mythic.png differ diff --git a/checker/styles/kayy/rarity/rare.png b/checker/styles/kayy/rarity/rare.png new file mode 100644 index 0000000..23d211d Binary files /dev/null and b/checker/styles/kayy/rarity/rare.png differ diff --git a/checker/styles/kayy/rarity/shadow.png b/checker/styles/kayy/rarity/shadow.png new file mode 100644 index 0000000..e34bd18 Binary files /dev/null and b/checker/styles/kayy/rarity/shadow.png differ diff --git a/checker/styles/kayy/rarity/slurp.png b/checker/styles/kayy/rarity/slurp.png new file mode 100644 index 0000000..794b25c Binary files /dev/null and b/checker/styles/kayy/rarity/slurp.png differ diff --git a/checker/styles/kayy/rarity/starwars.png b/checker/styles/kayy/rarity/starwars.png new file mode 100644 index 0000000..e9759a4 Binary files /dev/null and b/checker/styles/kayy/rarity/starwars.png differ diff --git a/checker/styles/kayy/rarity/uncommon.png b/checker/styles/kayy/rarity/uncommon.png new file mode 100644 index 0000000..ebb68f4 Binary files /dev/null and b/checker/styles/kayy/rarity/uncommon.png differ diff --git a/checker/styles/legacy/font.ttf b/checker/styles/legacy/font.ttf new file mode 100644 index 0000000..3222b81 Binary files /dev/null and b/checker/styles/legacy/font.ttf differ diff --git a/checker/styles/legacy/rarity/common.png b/checker/styles/legacy/rarity/common.png new file mode 100644 index 0000000..9538ac0 Binary files /dev/null and b/checker/styles/legacy/rarity/common.png differ diff --git a/checker/styles/legacy/rarity/dark.png b/checker/styles/legacy/rarity/dark.png new file mode 100644 index 0000000..3e57fec Binary files /dev/null and b/checker/styles/legacy/rarity/dark.png differ diff --git a/checker/styles/legacy/rarity/dc.png b/checker/styles/legacy/rarity/dc.png new file mode 100644 index 0000000..abd32cb Binary files /dev/null and b/checker/styles/legacy/rarity/dc.png differ diff --git a/checker/styles/legacy/rarity/epic.png b/checker/styles/legacy/rarity/epic.png new file mode 100644 index 0000000..af71cc5 Binary files /dev/null and b/checker/styles/legacy/rarity/epic.png differ diff --git a/checker/styles/legacy/rarity/frozen.png b/checker/styles/legacy/rarity/frozen.png new file mode 100644 index 0000000..d3cbe18 Binary files /dev/null and b/checker/styles/legacy/rarity/frozen.png differ diff --git a/checker/styles/legacy/rarity/gaminglegends.png b/checker/styles/legacy/rarity/gaminglegends.png new file mode 100644 index 0000000..648b46a Binary files /dev/null and b/checker/styles/legacy/rarity/gaminglegends.png differ diff --git a/checker/styles/legacy/rarity/icon.png b/checker/styles/legacy/rarity/icon.png new file mode 100644 index 0000000..0c869a5 Binary files /dev/null and b/checker/styles/legacy/rarity/icon.png differ diff --git a/checker/styles/legacy/rarity/lava.png b/checker/styles/legacy/rarity/lava.png new file mode 100644 index 0000000..e309f92 Binary files /dev/null and b/checker/styles/legacy/rarity/lava.png differ diff --git a/checker/styles/legacy/rarity/legendary.png b/checker/styles/legacy/rarity/legendary.png new file mode 100644 index 0000000..0d037ff Binary files /dev/null and b/checker/styles/legacy/rarity/legendary.png differ diff --git a/checker/styles/legacy/rarity/marvel.png b/checker/styles/legacy/rarity/marvel.png new file mode 100644 index 0000000..9cac091 Binary files /dev/null and b/checker/styles/legacy/rarity/marvel.png differ diff --git a/checker/styles/legacy/rarity/mythic.png b/checker/styles/legacy/rarity/mythic.png new file mode 100644 index 0000000..1827a84 Binary files /dev/null and b/checker/styles/legacy/rarity/mythic.png differ diff --git a/checker/styles/legacy/rarity/rare.png b/checker/styles/legacy/rarity/rare.png new file mode 100644 index 0000000..96b2019 Binary files /dev/null and b/checker/styles/legacy/rarity/rare.png differ diff --git a/checker/styles/legacy/rarity/shadow.png b/checker/styles/legacy/rarity/shadow.png new file mode 100644 index 0000000..eae65e0 Binary files /dev/null and b/checker/styles/legacy/rarity/shadow.png differ diff --git a/checker/styles/legacy/rarity/slurp.png b/checker/styles/legacy/rarity/slurp.png new file mode 100644 index 0000000..ee63cb1 Binary files /dev/null and b/checker/styles/legacy/rarity/slurp.png differ diff --git a/checker/styles/legacy/rarity/starwars.png b/checker/styles/legacy/rarity/starwars.png new file mode 100644 index 0000000..ea34062 Binary files /dev/null and b/checker/styles/legacy/rarity/starwars.png differ diff --git a/checker/styles/legacy/rarity/uncommon.png b/checker/styles/legacy/rarity/uncommon.png new file mode 100644 index 0000000..f07f2a3 Binary files /dev/null and b/checker/styles/legacy/rarity/uncommon.png differ diff --git a/checker/styles/raika/font.ttf b/checker/styles/raika/font.ttf new file mode 100644 index 0000000..77d7ce0 Binary files /dev/null and b/checker/styles/raika/font.ttf differ diff --git a/checker/styles/raika/rarity/common.png b/checker/styles/raika/rarity/common.png new file mode 100644 index 0000000..ec65cdd Binary files /dev/null and b/checker/styles/raika/rarity/common.png differ diff --git a/checker/styles/raika/rarity/dark.png b/checker/styles/raika/rarity/dark.png new file mode 100644 index 0000000..3e57fec Binary files /dev/null and b/checker/styles/raika/rarity/dark.png differ diff --git a/checker/styles/raika/rarity/dc.png b/checker/styles/raika/rarity/dc.png new file mode 100644 index 0000000..abd32cb Binary files /dev/null and b/checker/styles/raika/rarity/dc.png differ diff --git a/checker/styles/raika/rarity/epic.png b/checker/styles/raika/rarity/epic.png new file mode 100644 index 0000000..05061a5 Binary files /dev/null and b/checker/styles/raika/rarity/epic.png differ diff --git a/checker/styles/raika/rarity/frozen.png b/checker/styles/raika/rarity/frozen.png new file mode 100644 index 0000000..d3cbe18 Binary files /dev/null and b/checker/styles/raika/rarity/frozen.png differ diff --git a/checker/styles/raika/rarity/gaminglegends.png b/checker/styles/raika/rarity/gaminglegends.png new file mode 100644 index 0000000..648b46a Binary files /dev/null and b/checker/styles/raika/rarity/gaminglegends.png differ diff --git a/checker/styles/raika/rarity/icon.png b/checker/styles/raika/rarity/icon.png new file mode 100644 index 0000000..0c869a5 Binary files /dev/null and b/checker/styles/raika/rarity/icon.png differ diff --git a/checker/styles/raika/rarity/lava.png b/checker/styles/raika/rarity/lava.png new file mode 100644 index 0000000..e309f92 Binary files /dev/null and b/checker/styles/raika/rarity/lava.png differ diff --git a/checker/styles/raika/rarity/legendary.png b/checker/styles/raika/rarity/legendary.png new file mode 100644 index 0000000..2f4d2a3 Binary files /dev/null and b/checker/styles/raika/rarity/legendary.png differ diff --git a/checker/styles/raika/rarity/marvel.png b/checker/styles/raika/rarity/marvel.png new file mode 100644 index 0000000..9cac091 Binary files /dev/null and b/checker/styles/raika/rarity/marvel.png differ diff --git a/checker/styles/raika/rarity/mythic.png b/checker/styles/raika/rarity/mythic.png new file mode 100644 index 0000000..0a13d05 Binary files /dev/null and b/checker/styles/raika/rarity/mythic.png differ diff --git a/checker/styles/raika/rarity/rare.png b/checker/styles/raika/rarity/rare.png new file mode 100644 index 0000000..0b1a3fd Binary files /dev/null and b/checker/styles/raika/rarity/rare.png differ diff --git a/checker/styles/raika/rarity/shadow.png b/checker/styles/raika/rarity/shadow.png new file mode 100644 index 0000000..eae65e0 Binary files /dev/null and b/checker/styles/raika/rarity/shadow.png differ diff --git a/checker/styles/raika/rarity/slurp.png b/checker/styles/raika/rarity/slurp.png new file mode 100644 index 0000000..ee63cb1 Binary files /dev/null and b/checker/styles/raika/rarity/slurp.png differ diff --git a/checker/styles/raika/rarity/starwars.png b/checker/styles/raika/rarity/starwars.png new file mode 100644 index 0000000..ea34062 Binary files /dev/null and b/checker/styles/raika/rarity/starwars.png differ diff --git a/checker/styles/raika/rarity/uncommon.png b/checker/styles/raika/rarity/uncommon.png new file mode 100644 index 0000000..70ab3f6 Binary files /dev/null and b/checker/styles/raika/rarity/uncommon.png differ diff --git a/checker/styles/rift/font.ttf b/checker/styles/rift/font.ttf new file mode 100644 index 0000000..05b0255 Binary files /dev/null and b/checker/styles/rift/font.ttf differ diff --git a/checker/styles/rift/rarity/common.png b/checker/styles/rift/rarity/common.png new file mode 100644 index 0000000..595e3d1 Binary files /dev/null and b/checker/styles/rift/rarity/common.png differ diff --git a/checker/styles/rift/rarity/dark.png b/checker/styles/rift/rarity/dark.png new file mode 100644 index 0000000..3e57fec Binary files /dev/null and b/checker/styles/rift/rarity/dark.png differ diff --git a/checker/styles/rift/rarity/dc.png b/checker/styles/rift/rarity/dc.png new file mode 100644 index 0000000..b4fc847 Binary files /dev/null and b/checker/styles/rift/rarity/dc.png differ diff --git a/checker/styles/rift/rarity/epic.png b/checker/styles/rift/rarity/epic.png new file mode 100644 index 0000000..272d016 Binary files /dev/null and b/checker/styles/rift/rarity/epic.png differ diff --git a/checker/styles/rift/rarity/frozen.png b/checker/styles/rift/rarity/frozen.png new file mode 100644 index 0000000..d3cbe18 Binary files /dev/null and b/checker/styles/rift/rarity/frozen.png differ diff --git a/checker/styles/rift/rarity/gaminglegends.png b/checker/styles/rift/rarity/gaminglegends.png new file mode 100644 index 0000000..648b46a Binary files /dev/null and b/checker/styles/rift/rarity/gaminglegends.png differ diff --git a/checker/styles/rift/rarity/icon.png b/checker/styles/rift/rarity/icon.png new file mode 100644 index 0000000..8da0020 Binary files /dev/null and b/checker/styles/rift/rarity/icon.png differ diff --git a/checker/styles/rift/rarity/lava.png b/checker/styles/rift/rarity/lava.png new file mode 100644 index 0000000..e309f92 Binary files /dev/null and b/checker/styles/rift/rarity/lava.png differ diff --git a/checker/styles/rift/rarity/legendary.png b/checker/styles/rift/rarity/legendary.png new file mode 100644 index 0000000..090caaf Binary files /dev/null and b/checker/styles/rift/rarity/legendary.png differ diff --git a/checker/styles/rift/rarity/marvel.png b/checker/styles/rift/rarity/marvel.png new file mode 100644 index 0000000..05a21e8 Binary files /dev/null and b/checker/styles/rift/rarity/marvel.png differ diff --git a/checker/styles/rift/rarity/mythic.png b/checker/styles/rift/rarity/mythic.png new file mode 100644 index 0000000..6437465 Binary files /dev/null and b/checker/styles/rift/rarity/mythic.png differ diff --git a/checker/styles/rift/rarity/rare.png b/checker/styles/rift/rarity/rare.png new file mode 100644 index 0000000..683513d Binary files /dev/null and b/checker/styles/rift/rarity/rare.png differ diff --git a/checker/styles/rift/rarity/shadow.png b/checker/styles/rift/rarity/shadow.png new file mode 100644 index 0000000..eae65e0 Binary files /dev/null and b/checker/styles/rift/rarity/shadow.png differ diff --git a/checker/styles/rift/rarity/slurp.png b/checker/styles/rift/rarity/slurp.png new file mode 100644 index 0000000..ee63cb1 Binary files /dev/null and b/checker/styles/rift/rarity/slurp.png differ diff --git a/checker/styles/rift/rarity/starwars.png b/checker/styles/rift/rarity/starwars.png new file mode 100644 index 0000000..dc4f6eb Binary files /dev/null and b/checker/styles/rift/rarity/starwars.png differ diff --git a/checker/styles/rift/rarity/uncommon.png b/checker/styles/rift/rarity/uncommon.png new file mode 100644 index 0000000..4085ec1 Binary files /dev/null and b/checker/styles/rift/rarity/uncommon.png differ diff --git a/checker/styles/storm/font.ttf b/checker/styles/storm/font.ttf new file mode 100644 index 0000000..05b0255 Binary files /dev/null and b/checker/styles/storm/font.ttf differ diff --git a/checker/styles/storm/rarity/common.png b/checker/styles/storm/rarity/common.png new file mode 100644 index 0000000..b1b4e49 Binary files /dev/null and b/checker/styles/storm/rarity/common.png differ diff --git a/checker/styles/storm/rarity/dark.png b/checker/styles/storm/rarity/dark.png new file mode 100644 index 0000000..c078ab5 Binary files /dev/null and b/checker/styles/storm/rarity/dark.png differ diff --git a/checker/styles/storm/rarity/dc.png b/checker/styles/storm/rarity/dc.png new file mode 100644 index 0000000..2af2abc Binary files /dev/null and b/checker/styles/storm/rarity/dc.png differ diff --git a/checker/styles/storm/rarity/epic.png b/checker/styles/storm/rarity/epic.png new file mode 100644 index 0000000..45a6b09 Binary files /dev/null and b/checker/styles/storm/rarity/epic.png differ diff --git a/checker/styles/storm/rarity/frozen.png b/checker/styles/storm/rarity/frozen.png new file mode 100644 index 0000000..804e278 Binary files /dev/null and b/checker/styles/storm/rarity/frozen.png differ diff --git a/checker/styles/storm/rarity/gaminglegends.png b/checker/styles/storm/rarity/gaminglegends.png new file mode 100644 index 0000000..3c61a77 Binary files /dev/null and b/checker/styles/storm/rarity/gaminglegends.png differ diff --git a/checker/styles/storm/rarity/icon.png b/checker/styles/storm/rarity/icon.png new file mode 100644 index 0000000..cccc7f4 Binary files /dev/null and b/checker/styles/storm/rarity/icon.png differ diff --git a/checker/styles/storm/rarity/lava.png b/checker/styles/storm/rarity/lava.png new file mode 100644 index 0000000..29bc62e Binary files /dev/null and b/checker/styles/storm/rarity/lava.png differ diff --git a/checker/styles/storm/rarity/legendary.png b/checker/styles/storm/rarity/legendary.png new file mode 100644 index 0000000..426ebfe Binary files /dev/null and b/checker/styles/storm/rarity/legendary.png differ diff --git a/checker/styles/storm/rarity/marvel.png b/checker/styles/storm/rarity/marvel.png new file mode 100644 index 0000000..a9a0031 Binary files /dev/null and b/checker/styles/storm/rarity/marvel.png differ diff --git a/checker/styles/storm/rarity/mythic.png b/checker/styles/storm/rarity/mythic.png new file mode 100644 index 0000000..ca424a2 Binary files /dev/null and b/checker/styles/storm/rarity/mythic.png differ diff --git a/checker/styles/storm/rarity/rare.png b/checker/styles/storm/rarity/rare.png new file mode 100644 index 0000000..8b5d21b Binary files /dev/null and b/checker/styles/storm/rarity/rare.png differ diff --git a/checker/styles/storm/rarity/shadow.png b/checker/styles/storm/rarity/shadow.png new file mode 100644 index 0000000..e34bd18 Binary files /dev/null and b/checker/styles/storm/rarity/shadow.png differ diff --git a/checker/styles/storm/rarity/slurp.png b/checker/styles/storm/rarity/slurp.png new file mode 100644 index 0000000..794b25c Binary files /dev/null and b/checker/styles/storm/rarity/slurp.png differ diff --git a/checker/styles/storm/rarity/starwars.png b/checker/styles/storm/rarity/starwars.png new file mode 100644 index 0000000..e9759a4 Binary files /dev/null and b/checker/styles/storm/rarity/starwars.png differ diff --git a/checker/styles/storm/rarity/uncommon.png b/checker/styles/storm/rarity/uncommon.png new file mode 100644 index 0000000..d8a0d5a Binary files /dev/null and b/checker/styles/storm/rarity/uncommon.png differ diff --git a/checker/telegram_bot.py b/checker/telegram_bot.py new file mode 100644 index 0000000..466b64f --- /dev/null +++ b/checker/telegram_bot.py @@ -0,0 +1,112 @@ +import os +import json +import aiohttp +import asyncio +import random +import threading +import telebot +from io import BytesIO +from telebot import types +from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton, InputMediaPhoto +from PIL import Image, ImageDraw, ImageFont +from epic_auth import EpicUser, EpicGenerator, EpicEndpoints +from user import RiftUser +from cosmetic import FortniteCosmetic +from commands import command_start, command_help, command_login, command_style, command_badges, command_stats, send_style_message, send_badges_message, available_styles, avaliable_badges + +import epic_auth +import cosmetic +import commands +import utils + +# your telegram bot's api token +TELEGRAM_API_TOKEN = "" + +# locker categories we render in the checker +telegram_bot = telebot.TeleBot(TELEGRAM_API_TOKEN) + +telegram_bot.set_my_commands([ + telebot.types.BotCommand("/start", "Setup your user to start skinchecking."), + telebot.types.BotCommand("/help", "Display Basic Info and the commands."), + telebot.types.BotCommand("/login", "Skincheck your Epic Games account."), + telebot.types.BotCommand("/style", "Customize your checker's style."), + telebot.types.BotCommand("/badges", "Toggle your owned badges."), + telebot.types.BotCommand("/stats", "View your stats.") +]) + +auth_code = None +@telegram_bot.message_handler(commands=['start']) +def handle_start(message): + command_start(telegram_bot, message) + +@telegram_bot.message_handler(commands=['help']) +def handle_help(message): + command_help(telegram_bot, message) + +@telegram_bot.message_handler(commands=['login']) +def handle_login(message): + asyncio.run(command_login(telegram_bot, message)) + +@telegram_bot.message_handler(commands=['style']) +def handle_style(message): + asyncio.run(command_style(telegram_bot, message)) + +@telegram_bot.message_handler(commands=['badges']) +def handle_badges(message): + asyncio.run(command_badges(telegram_bot, message)) + +@telegram_bot.message_handler(commands=['stats']) +def handle_stats(message): + asyncio.run(command_stats(telegram_bot, message)) + +@telegram_bot.callback_query_handler(func=lambda call: call.data.startswith("style_") or call.data.startswith("select_")) +def handle_style_navigation(call): + data = call.data + user = RiftUser(call.from_user.id, call.from_user.username) + user_data = user.load_data() + + if not user_data: + telegram_bot.reply_to(call.message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + if data.startswith("style_"): + new_index = int(data.split("_")[1]) + telegram_bot.delete_message(call.message.chat.id, call.message.message_id) + send_style_message(telegram_bot, call.message.chat.id, new_index) + + elif data.startswith("select_"): + selected_index = int(data.split("_")[1]) + selected_style = available_styles[selected_index] + user_data['style'] = selected_style['ID'] + user.update_data() + telegram_bot.send_message(call.message.chat.id, f"✅ Style {selected_style['name']} selected.") + +@telegram_bot.callback_query_handler(func=lambda call: call.data.startswith("badge_") or call.data.startswith("toggle_")) +def handle_badge_navigation(call): + data = call.data + user = RiftUser(call.from_user.id, call.from_user.username) + user_data = user.load_data() + + if not user_data: + telegram_bot.reply_to(call.message, "You haven't setup your user yet, please use /start before skinchecking!") + return + + if data.startswith("badge_"): + new_index = int(data.split("_")[1]) + telegram_bot.delete_message(call.message.chat.id, call.message.message_id) + send_badges_message(telegram_bot, call.message.chat.id, new_index, user_data) + + elif data.startswith("toggle_"): + badge_index = int(data.split("_")[1]) + badge = avaliable_badges[badge_index] + current_status = user_data.get(badge['data2'], False) + user_data[badge['data2']] = not current_status + + user.update_data() + telegram_bot.answer_callback_query(call.id, f"{badge['name']} is now {'Enabled' if not current_status else 'Disabled'}!") + telegram_bot.delete_message(call.message.chat.id, call.message.message_id) + send_badges_message(telegram_bot, call.message.chat.id, badge_index, user_data) + +print("starting rift checker...") +if __name__ == '__main__': + telegram_bot.infinity_polling() \ No newline at end of file diff --git a/checker/user.py b/checker/user.py new file mode 100644 index 0000000..0d62843 --- /dev/null +++ b/checker/user.py @@ -0,0 +1,75 @@ +import json +import os +import telebot +from telebot import types + +# the version of the json data we save to our telegram users's stats +# when something new gets added, we increase the version by 1 +TELEGRAM_USER_DATA_VERSION = 0 + +class RiftUser: + def __init__(self, userID: int, username: str): + self.userID: int = userID + self.username: str = username + self.user_data: json = {} + + def register(self) -> dict: + user_path = f"users/{self.userID}.json" + if os.path.exists(user_path): + # user is already registered + return {} + + os.makedirs(os.path.dirname(user_path), exist_ok=True) + self.user_data = { + 'ID': self.userID, + 'username': self.username, + 'version': TELEGRAM_USER_DATA_VERSION, + 'accounts_checked': 0, + 'style': 0, + 'gradient_type': 0, + 'alpha_tester_1_badge': False, + 'alpha_tester_2_badge': False, + 'alpha_tester_3_badge': False, + 'newbie_badge': False, + 'advanced_badge': False, + 'epic_badge': False, + 'alpha_tester_1_badge_active': False, + 'alpha_tester_2_badge_active': False, + 'alpha_tester_3_badge_active': False, + 'newbie_badge_active': False, + 'advanced_badge_active': False, + 'epic_badge_active': False + } + + with open(user_path, 'w') as user_data_file: + json.dump(self.user_data, user_data_file, indent=4) + + return self.user_data + + def load_data(self) -> dict: + # loading the telegram user profile's stats + user_path = f"users/{self.userID}.json" + if not os.path.exists(user_path): + # profile not found + return {} + + if os.path.getsize(user_path) > 0: + # loading the user profile's stats + with open(user_path, 'r') as user_data_file: + self.user_data = json.load(user_data_file) + + # versioning, making sure there is no missing info to not mess the user data + + # returning the user data + self.user_data['version'] = TELEGRAM_USER_DATA_VERSION + return self.user_data + + def update_data(self): + # updating the telegram user profile's stats + user_path = f"users/{self.userID}.json" + if not os.path.exists(user_path): + # user path doesn't exists, so we cannot update it + return + + with open(user_path, 'w') as user_data_file: + json.dump(self.user_data, user_data_file, indent=4) \ No newline at end of file diff --git a/checker/users/placeholder.txt b/checker/users/placeholder.txt new file mode 100644 index 0000000..e69de29 diff --git a/checker/utils.py b/checker/utils.py new file mode 100644 index 0000000..df4491b --- /dev/null +++ b/checker/utils.py @@ -0,0 +1,35 @@ +def bool_to_emoji(value: bool): + if value == True: + return '✅'; + + return '❌'; + +def country_to_flag(country_code): + # thanks to Kayy + if len(country_code) != 2: + return country_code + + return chr(ord(country_code[0]) + 127397) + chr(ord(country_code[1]) + 127397) + +def mask_email(email): + # thanks to Kayy + if "@" in email: + local_part, domain = email.split("@") + if len(local_part) > 2: + masked_local_part = local_part[0] + "*" * (len(local_part) - 2) + local_part[-1] + + elif len(local_part) == 2: + masked_local_part = local_part[0] + "*" + + else: + masked_local_part = local_part + + return f"{masked_local_part}@{domain}" + return email + +def mask_account_id(account_id): + # thanks to Kayy + if len(account_id) > 4: + return account_id[:2] + "*" * (len(account_id) - 4) + account_id[-2:] + + return account_id \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e1efc68 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1470 @@ +{ + "name": "discord-bot", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "discord-bot", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@napi-rs/canvas": "^1.0.0", + "discord.js": "^14.26.4", + "dotenv": "^17.4.2", + "form-data": "^4.0.6", + "sharp": "^0.35.2" + } + }, + "node_modules/@discordjs/builders": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.14.1.tgz", + "integrity": "sha512-gSKkhXLqs96TCzk66VZuHHl8z2bQMJFGwrXC0f33ngK+FLNau4hU1PYny3DNJfNdSH+gVMzE85/d5FQ2BpcNwQ==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/formatters": "^0.6.2", + "@discordjs/util": "^1.2.0", + "@sapphire/shapeshift": "^4.0.0", + "discord-api-types": "^0.38.40", + "fast-deep-equal": "^3.1.3", + "ts-mixer": "^6.0.4", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=16.11.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/collection": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.11.0" + } + }, + "node_modules/@discordjs/formatters": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.6.2.tgz", + "integrity": "sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ==", + "license": "Apache-2.0", + "dependencies": { + "discord-api-types": "^0.38.33" + }, + "engines": { + "node": ">=16.11.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.6.1.tgz", + "integrity": "sha512-wwQdgjeaoYFiaG+atbqx6aJDpqW7JHAo0HrQkBTbYzM3/PJ3GweQIpgElNcGZ26DCUOXMyawYd0YF7vtr+fZXg==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/collection": "^2.1.1", + "@discordjs/util": "^1.2.0", + "@sapphire/async-queue": "^1.5.3", + "@sapphire/snowflake": "^3.5.5", + "@vladfrangu/async_event_emitter": "^2.4.6", + "discord-api-types": "^0.38.40", + "magic-bytes.js": "^1.13.0", + "tslib": "^2.6.3", + "undici": "6.24.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/rest/node_modules/@sapphire/snowflake": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.5.tgz", + "integrity": "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@discordjs/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.2.0.tgz", + "integrity": "sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==", + "license": "Apache-2.0", + "dependencies": { + "discord-api-types": "^0.38.33" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.3.tgz", + "integrity": "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/collection": "^2.1.0", + "@discordjs/rest": "^2.5.1", + "@discordjs/util": "^1.1.0", + "@sapphire/async-queue": "^1.5.2", + "@types/ws": "^8.5.10", + "@vladfrangu/async_event_emitter": "^2.2.4", + "discord-api-types": "^0.38.1", + "tslib": "^2.6.2", + "ws": "^8.17.0" + }, + "engines": { + "node": ">=16.11.0" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@discordjs/ws/node_modules/@discordjs/collection": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz", + "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz", + "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz", + "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz", + "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz", + "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz", + "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz", + "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz", + "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz", + "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz", + "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz", + "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz", + "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz", + "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz", + "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz", + "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz", + "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz", + "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz", + "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz", + "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz", + "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz", + "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz", + "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz", + "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz", + "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz", + "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz", + "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@napi-rs/canvas": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-1.0.0.tgz", + "integrity": "sha512-Jqxcy1XOIqj+lH9sl1GT+il6GR3uQv13vI2mrwubP3uT8Olak2ClDrK2RnxlQKjwv8BRr4b3ug0YR7c6hBX8wg==", + "license": "MIT", + "workspaces": [ + "e2e/*" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "1.0.0", + "@napi-rs/canvas-darwin-arm64": "1.0.0", + "@napi-rs/canvas-darwin-x64": "1.0.0", + "@napi-rs/canvas-linux-arm-gnueabihf": "1.0.0", + "@napi-rs/canvas-linux-arm64-gnu": "1.0.0", + "@napi-rs/canvas-linux-arm64-musl": "1.0.0", + "@napi-rs/canvas-linux-riscv64-gnu": "1.0.0", + "@napi-rs/canvas-linux-x64-gnu": "1.0.0", + "@napi-rs/canvas-linux-x64-musl": "1.0.0", + "@napi-rs/canvas-win32-arm64-msvc": "1.0.0", + "@napi-rs/canvas-win32-x64-msvc": "1.0.0" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-1.0.0.tgz", + "integrity": "sha512-3hNKJObUK7JsCF9aJlVCs1J0/KE/gGfZNeK8MO1ge6bB3aicr5walGme9t9No1f/oyk9GgvdAT/rjSdsx3gbIw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-ZIja19/BiGz2puhki+WUYSRriwFeFJ8Mi9eK3hZdSS85w4Y60cuEAJVhMCfKwswQkKkUtrnzdKMBuO7TupvexA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-1.0.0.tgz", + "integrity": "sha512-hImggWc82jqZVpEsFR9S7PE9OQYjq/H/D7vwCGB6X1jRH+UVBP1+1niJTPBOat1B154T6GKK7/kcFtoWgjgFzQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-hlJRy6d+kWLKVOG/+1rEvNQVURZ0DxxRPJsLmEWwhwiXZUJc0BF5o9esALHSEP4CoJK4wChRtj3hnyBgVx2oWA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-5Hru4T3RXkosRQafcjelv7AUzw9mXqmGYsxnzeDDOWveFCJyEPMSJltvGCM+jfH98seOCbfwm9KyFg6Jm5FhAA==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-LTUl9jS8WsLSUGaxQZKQkxfluOJRpgvBuxxdM4pYcjib+di8AU4OzQc6+L6SzGMLcKc9H0RAjojRatBhTMqYdg==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-1.0.0.tgz", + "integrity": "sha512-Iz931SAZf+WVDzpjk52Q3ffW3zw0YflFwEZMgs036Wfu1kX/LrwT9wGjsuSqyduqefUkl91/vTdAjn8hQu5ezA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-pFEQ5eFK4JusgN1K6KkO9DKP/Hi1WMJOkF8Ch03/khTc4bFbCKkCCsJG4YcOMOW9bI4XbT2/eMAWxhO0xaWgPA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-jnvr8NrLHiZ3NCiOKWqDbkI4Ah+QDrqtZ+sddPZBltEb1mQ2coSvCSJYfict+oAwcm0c970oTmVySpjKP/lnaA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-y2j9/Gfd5joqiqxdP/L1smqjQ+uAx3C4N0EC7bDHrnZEEH8ToM/OC5p3uHvtj4Lq591aHj+ArL01UDLNwT5HgQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-qwdhh9N6Gge/hC4pL9S1tQp0iKwhSl/dYjg7+RGp9k26iRGRi5MqqUyKGOXIWli0zOcuy5Y2wIH/jk2ry6i/jA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", + "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz", + "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v16" + } + }, + "node_modules/@sapphire/snowflake": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz", + "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@types/node": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.0.tgz", + "integrity": "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==", + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.7.tgz", + "integrity": "sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/discord-api-types": { + "version": "0.38.49", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.49.tgz", + "integrity": "sha512-XnqcWmnFZFAE8ZM8SHAw9DIV8D3Or00rMQ8iQLotrEA2PmXhl+ykaf6L6q4l474hrSUH1JaYcv+iOMRWp2p6Tg==", + "license": "MIT", + "workspaces": [ + "scripts/actions/documentation" + ] + }, + "node_modules/discord.js": { + "version": "14.26.4", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.26.4.tgz", + "integrity": "sha512-4oBp8tc6Kf8IDBwAHhbsMaAqx1b5fob9SNasZT7V6yyyUydoO5i5fGuX7TmvRtR+q/WgKRnRViRoAWnG7fNyvA==", + "license": "Apache-2.0", + "dependencies": { + "@discordjs/builders": "^1.14.1", + "@discordjs/collection": "1.5.3", + "@discordjs/formatters": "^0.6.2", + "@discordjs/rest": "^2.6.1", + "@discordjs/util": "^1.2.0", + "@discordjs/ws": "^1.2.3", + "@sapphire/snowflake": "3.5.3", + "discord-api-types": "^0.38.40", + "fast-deep-equal": "3.1.3", + "lodash.snakecase": "4.1.1", + "magic-bytes.js": "^1.13.0", + "tslib": "^2.6.3", + "undici": "6.24.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/discordjs/discord.js?sponsor" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/form-data": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "license": "MIT" + }, + "node_modules/magic-bytes.js": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.13.0.tgz", + "integrity": "sha512-afO2mnxW7GDTXMm5/AoN1WuOcdoKhtgXjIvHmobqTD1grNplhGdv3PFOyjCVmrnOZBIT/gD/koDKpYG+0mvHcg==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz", + "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==", + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.2", + "@img/sharp-darwin-x64": "0.35.2", + "@img/sharp-freebsd-wasm32": "0.35.2", + "@img/sharp-libvips-darwin-arm64": "1.3.1", + "@img/sharp-libvips-darwin-x64": "1.3.1", + "@img/sharp-libvips-linux-arm": "1.3.1", + "@img/sharp-libvips-linux-arm64": "1.3.1", + "@img/sharp-libvips-linux-ppc64": "1.3.1", + "@img/sharp-libvips-linux-riscv64": "1.3.1", + "@img/sharp-libvips-linux-s390x": "1.3.1", + "@img/sharp-libvips-linux-x64": "1.3.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", + "@img/sharp-libvips-linuxmusl-x64": "1.3.1", + "@img/sharp-linux-arm": "0.35.2", + "@img/sharp-linux-arm64": "0.35.2", + "@img/sharp-linux-ppc64": "0.35.2", + "@img/sharp-linux-riscv64": "0.35.2", + "@img/sharp-linux-s390x": "0.35.2", + "@img/sharp-linux-x64": "0.35.2", + "@img/sharp-linuxmusl-arm64": "0.35.2", + "@img/sharp-linuxmusl-x64": "0.35.2", + "@img/sharp-webcontainers-wasm32": "0.35.2", + "@img/sharp-win32-arm64": "0.35.2", + "@img/sharp-win32-ia32": "0.35.2", + "@img/sharp-win32-x64": "0.35.2" + } + }, + "node_modules/ts-mixer": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/undici": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz", + "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..fafeb1d --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "discord-bot", + "version": "1.0.0", + "description": "", + "main": "discord bot.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "@napi-rs/canvas": "^1.0.0", + "discord.js": "^14.26.4", + "dotenv": "^17.4.2", + "form-data": "^4.0.6", + "sharp": "^0.35.2" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..3b78d1e --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,849 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@napi-rs/canvas': + specifier: ^1.0.0 + version: 1.0.1 + discord.js: + specifier: ^14.26.4 + version: 14.26.4 + dotenv: + specifier: ^17.4.2 + version: 17.4.2 + form-data: + specifier: ^4.0.6 + version: 4.0.6 + sharp: + specifier: ^0.35.2 + version: 0.35.2 + +packages: + + '@discordjs/builders@1.14.1': + resolution: {integrity: sha512-gSKkhXLqs96TCzk66VZuHHl8z2bQMJFGwrXC0f33ngK+FLNau4hU1PYny3DNJfNdSH+gVMzE85/d5FQ2BpcNwQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.1': + resolution: {integrity: sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.6.2': + resolution: {integrity: sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/rest@2.6.1': + resolution: {integrity: sha512-wwQdgjeaoYFiaG+atbqx6aJDpqW7JHAo0HrQkBTbYzM3/PJ3GweQIpgElNcGZ26DCUOXMyawYd0YF7vtr+fZXg==} + engines: {node: '>=18'} + + '@discordjs/util@1.2.0': + resolution: {integrity: sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==} + engines: {node: '>=18'} + + '@discordjs/ws@1.2.3': + resolution: {integrity: sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==} + engines: {node: '>=16.11.0'} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.2': + resolution: {integrity: sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.2': + resolution: {integrity: sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.2': + resolution: {integrity: sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.1': + resolution: {integrity: sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.1': + resolution: {integrity: sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.1': + resolution: {integrity: sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.1': + resolution: {integrity: sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.1': + resolution: {integrity: sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.1': + resolution: {integrity: sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.1': + resolution: {integrity: sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.1': + resolution: {integrity: sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.1': + resolution: {integrity: sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.1': + resolution: {integrity: sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.2': + resolution: {integrity: sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.2': + resolution: {integrity: sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.2': + resolution: {integrity: sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.2': + resolution: {integrity: sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.2': + resolution: {integrity: sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.2': + resolution: {integrity: sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.2': + resolution: {integrity: sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.2': + resolution: {integrity: sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.2': + resolution: {integrity: sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.2': + resolution: {integrity: sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.2': + resolution: {integrity: sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.2': + resolution: {integrity: sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.2': + resolution: {integrity: sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@napi-rs/canvas-android-arm64@1.0.1': + resolution: {integrity: sha512-d7ZCwJsgH4QNG50C7HQeVRsRG1gRDa1UeDUb1jEcqgLuiEJp6GVbGiZkFXPlmt0dEs2QHRQCPJoOv+bOkSQR/w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/canvas-darwin-arm64@1.0.1': + resolution: {integrity: sha512-ppyVSzIHsVldc3B++mdh03ed0Q0hoVR2QDG9O/wEUR0PurJKwDEEYV87uBQDpbSumJBfLEINDndsOPzQj71qEQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/canvas-darwin-x64@1.0.1': + resolution: {integrity: sha512-/BlXif9VOzf/WP32g9zxl612dO0KLvwqplBFqfRcyr3PyR5fhPrilTuJxSBq3zkwCKGKy82JsoPd2JeQI/HBlA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/canvas-linux-arm-gnueabihf@1.0.1': + resolution: {integrity: sha512-JTGq93/Pje+iSNVjL+ggB0+pqEfu7nXvQGrHTvugz+Lp08wCDa5rjov4JeEljGDk16/inVBU9sp4N9f0/+o+9A==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/canvas-linux-arm64-gnu@1.0.1': + resolution: {integrity: sha512-i74zqEh5yFmYwHkszFo+4EH4l5ATD4bSlJG21iW2j5kpqiN2b0WN9SG/xdq2O60MjZK0ZLSu3a/Z3aQAsmDQ5A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@napi-rs/canvas-linux-arm64-musl@1.0.1': + resolution: {integrity: sha512-COqBxybXcKb6gNgEhjh04rPHrpsJB+n/5+p4ySPgQWl0i+xVNYHn4rvzCtUBIFqOgY6HEJ9UaP6c4W9EMwzfpQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@napi-rs/canvas-linux-riscv64-gnu@1.0.1': + resolution: {integrity: sha512-1vdAZGpD85lMUo7K3qtEdoIWeMc0xcpUD5PagK3fVcMSdf8dkSL5bg/KE4Rwv5NF+PYx4plrgfn0KRMOqdKtwA==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@napi-rs/canvas-linux-x64-gnu@1.0.1': + resolution: {integrity: sha512-W/iC2qJZGqKKQJ0JrNo3QkhoAy/PvzlmdYLW8Yz5/L6XgT5d7t26dnqgP2rCbL58P3CbPw7ES0Rz8OG0gn7JeQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@napi-rs/canvas-linux-x64-musl@1.0.1': + resolution: {integrity: sha512-a5mmIVwxF92UGUe+1c7Ap32ZRnApbRMnQC/KgYyFB0AXZShBCHVGaURq+BDkiV7jvHhVwvvAP0Q/3aWNhqgVZg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@napi-rs/canvas-win32-arm64-msvc@1.0.1': + resolution: {integrity: sha512-rVnDhVvcXlqcHMsgnxxhZgdRkRIqVBlx+FJwSAHi4VbWWwsowvV5ldFEecEHD2+Ac/IL3fNWF/LB5CZTghNwRA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/canvas-win32-x64-msvc@1.0.1': + resolution: {integrity: sha512-UMstkP/nZHbithgdSJv1EvYVrYhdao5B5N3szMVU2i5/b6ijMcVPXOEyrk0QXl0iPjv8Hkoow+Tap+MiOxppOQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/canvas@1.0.1': + resolution: {integrity: sha512-mPD43G7pXbQhIGa7z4IpT/vXm1jbF8cBM1oY5UqjL8LSaTCNGhNi2Lidc/0+LwKbNiqbv/Tq0JlBRwKu+LW3iw==} + engines: {node: '>= 10'} + + '@sapphire/async-queue@1.5.5': + resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@4.0.0': + resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.3': + resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/snowflake@3.5.5': + resolution: {integrity: sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@types/node@26.0.1': + resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@vladfrangu/async_event_emitter@2.4.7': + resolution: {integrity: sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + discord-api-types@0.38.49: + resolution: {integrity: sha512-XnqcWmnFZFAE8ZM8SHAw9DIV8D3Or00rMQ8iQLotrEA2PmXhl+ykaf6L6q4l474hrSUH1JaYcv+iOMRWp2p6Tg==} + + discord.js@14.26.4: + resolution: {integrity: sha512-4oBp8tc6Kf8IDBwAHhbsMaAqx1b5fob9SNasZT7V6yyyUydoO5i5fGuX7TmvRtR+q/WgKRnRViRoAWnG7fNyvA==} + engines: {node: '>=18'} + + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + magic-bytes.js@1.13.0: + resolution: {integrity: sha512-afO2mnxW7GDTXMm5/AoN1WuOcdoKhtgXjIvHmobqTD1grNplhGdv3PFOyjCVmrnOZBIT/gD/koDKpYG+0mvHcg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.35.2: + resolution: {integrity: sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==} + engines: {node: '>=20.9.0'} + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + + undici@6.24.1: + resolution: {integrity: sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==} + engines: {node: '>=18.17'} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@discordjs/builders@1.14.1': + dependencies: + '@discordjs/formatters': 0.6.2 + '@discordjs/util': 1.2.0 + '@sapphire/shapeshift': 4.0.0 + discord-api-types: 0.38.49 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.8.1 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.1': {} + + '@discordjs/formatters@0.6.2': + dependencies: + discord-api-types: 0.38.49 + + '@discordjs/rest@2.6.1': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@sapphire/snowflake': 3.5.5 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.49 + magic-bytes.js: 1.13.0 + tslib: 2.8.1 + undici: 6.24.1 + + '@discordjs/util@1.2.0': + dependencies: + discord-api-types: 0.38.49 + + '@discordjs/ws@1.2.3': + dependencies: + '@discordjs/collection': 2.1.1 + '@discordjs/rest': 2.6.1 + '@discordjs/util': 1.2.0 + '@sapphire/async-queue': 1.5.5 + '@types/ws': 8.18.1 + '@vladfrangu/async_event_emitter': 2.4.7 + discord-api-types: 0.38.49 + tslib: 2.8.1 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.1 + optional: true + + '@img/sharp-darwin-x64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.1 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.2': + dependencies: + '@img/sharp-wasm32': 0.35.2 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.1': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.1': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.1': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.1': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.1': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.1': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.1': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.1': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.1': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.1': + optional: true + + '@img/sharp-linux-arm64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.1 + optional: true + + '@img/sharp-linux-arm@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.1 + optional: true + + '@img/sharp-linux-ppc64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.1 + optional: true + + '@img/sharp-linux-riscv64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.1 + optional: true + + '@img/sharp-linux-s390x@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.1 + optional: true + + '@img/sharp-linux-x64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.1 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.1 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.1 + optional: true + + '@img/sharp-wasm32@0.35.2': + dependencies: + '@emnapi/runtime': 1.11.1 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.2': + dependencies: + '@img/sharp-wasm32': 0.35.2 + optional: true + + '@img/sharp-win32-arm64@0.35.2': + optional: true + + '@img/sharp-win32-ia32@0.35.2': + optional: true + + '@img/sharp-win32-x64@0.35.2': + optional: true + + '@napi-rs/canvas-android-arm64@1.0.1': + optional: true + + '@napi-rs/canvas-darwin-arm64@1.0.1': + optional: true + + '@napi-rs/canvas-darwin-x64@1.0.1': + optional: true + + '@napi-rs/canvas-linux-arm-gnueabihf@1.0.1': + optional: true + + '@napi-rs/canvas-linux-arm64-gnu@1.0.1': + optional: true + + '@napi-rs/canvas-linux-arm64-musl@1.0.1': + optional: true + + '@napi-rs/canvas-linux-riscv64-gnu@1.0.1': + optional: true + + '@napi-rs/canvas-linux-x64-gnu@1.0.1': + optional: true + + '@napi-rs/canvas-linux-x64-musl@1.0.1': + optional: true + + '@napi-rs/canvas-win32-arm64-msvc@1.0.1': + optional: true + + '@napi-rs/canvas-win32-x64-msvc@1.0.1': + optional: true + + '@napi-rs/canvas@1.0.1': + optionalDependencies: + '@napi-rs/canvas-android-arm64': 1.0.1 + '@napi-rs/canvas-darwin-arm64': 1.0.1 + '@napi-rs/canvas-darwin-x64': 1.0.1 + '@napi-rs/canvas-linux-arm-gnueabihf': 1.0.1 + '@napi-rs/canvas-linux-arm64-gnu': 1.0.1 + '@napi-rs/canvas-linux-arm64-musl': 1.0.1 + '@napi-rs/canvas-linux-riscv64-gnu': 1.0.1 + '@napi-rs/canvas-linux-x64-gnu': 1.0.1 + '@napi-rs/canvas-linux-x64-musl': 1.0.1 + '@napi-rs/canvas-win32-arm64-msvc': 1.0.1 + '@napi-rs/canvas-win32-x64-msvc': 1.0.1 + + '@sapphire/async-queue@1.5.5': {} + + '@sapphire/shapeshift@4.0.0': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.18.1 + + '@sapphire/snowflake@3.5.3': {} + + '@sapphire/snowflake@3.5.5': {} + + '@types/node@26.0.1': + dependencies: + undici-types: 8.3.0 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 26.0.1 + + '@vladfrangu/async_event_emitter@2.4.7': {} + + asynckit@0.4.0: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + delayed-stream@1.0.0: {} + + detect-libc@2.1.2: {} + + discord-api-types@0.38.49: {} + + discord.js@14.26.4: + dependencies: + '@discordjs/builders': 1.14.1 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.6.2 + '@discordjs/rest': 2.6.1 + '@discordjs/util': 1.2.0 + '@discordjs/ws': 1.2.3 + '@sapphire/snowflake': 3.5.3 + discord-api-types: 0.38.49 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + magic-bytes.js: 1.13.0 + tslib: 2.8.1 + undici: 6.24.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + dotenv@17.4.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + fast-deep-equal@3.1.3: {} + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + lodash.snakecase@4.1.1: {} + + lodash@4.18.1: {} + + magic-bytes.js@1.13.0: {} + + math-intrinsics@1.1.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + semver@7.8.5: {} + + sharp@0.35.2: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.2 + '@img/sharp-darwin-x64': 0.35.2 + '@img/sharp-freebsd-wasm32': 0.35.2 + '@img/sharp-libvips-darwin-arm64': 1.3.1 + '@img/sharp-libvips-darwin-x64': 1.3.1 + '@img/sharp-libvips-linux-arm': 1.3.1 + '@img/sharp-libvips-linux-arm64': 1.3.1 + '@img/sharp-libvips-linux-ppc64': 1.3.1 + '@img/sharp-libvips-linux-riscv64': 1.3.1 + '@img/sharp-libvips-linux-s390x': 1.3.1 + '@img/sharp-libvips-linux-x64': 1.3.1 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.1 + '@img/sharp-libvips-linuxmusl-x64': 1.3.1 + '@img/sharp-linux-arm': 0.35.2 + '@img/sharp-linux-arm64': 0.35.2 + '@img/sharp-linux-ppc64': 0.35.2 + '@img/sharp-linux-riscv64': 0.35.2 + '@img/sharp-linux-s390x': 0.35.2 + '@img/sharp-linux-x64': 0.35.2 + '@img/sharp-linuxmusl-arm64': 0.35.2 + '@img/sharp-linuxmusl-x64': 0.35.2 + '@img/sharp-webcontainers-wasm32': 0.35.2 + '@img/sharp-win32-arm64': 0.35.2 + '@img/sharp-win32-ia32': 0.35.2 + '@img/sharp-win32-x64': 0.35.2 + + ts-mixer@6.0.4: {} + + tslib@2.8.1: {} + + undici-types@8.3.0: {} + + undici@6.24.1: {} + + ws@8.21.0: {} diff --git a/src/add-icons.js b/src/add-icons.js new file mode 100644 index 0000000..6a4ef60 --- /dev/null +++ b/src/add-icons.js @@ -0,0 +1,249 @@ +// ============================================= +// DISCORD ROLE EMOJI ADDER + ROLE ICON SETTER +// ============================================= +// !addicons — fetches skin icons and uploads as server emojis +// !setroleicons — applies uploaded emojis as role icons +// !removeoldemojis — removes all skin emojis so you can re-add fresh +// +// Run with: node "add-icons.js" +// ============================================= + +require('dotenv').config(); +const { Client, GatewayIntentBits, PermissionsBitField } = require('discord.js'); +const sharp = require('sharp'); + +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent + ] +}); + +// Direct cosmetic IDs — all verified to return valid icons from fortnite-api.com +// overrideUrl = use a specific variant image instead of the default icon +const roleIconMap = [ + { name: 'Fully Golden Peely', id: 'CID_701_Athena_Commando_M_BananaAgent', emoji: 'FullyGoldenPeely', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_701_athena_commando_m_bananaagent/variants/progressive/stage4.png' }, + { name: 'OG Aerial Assault Trooper', id: 'CID_017_Athena_Commando_M', emoji: 'AerialAssaultTrooper' }, + { name: 'OG Ghoul Trooper', id: 'CID_029_Athena_Commando_F_Halloween', emoji: 'GhoulTrooper', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_029_athena_commando_f_halloween/variants/material/mat3.png' }, + { name: 'OG Renegade Raider', id: 'CID_028_Athena_Commando_F', emoji: 'RenegadeRaider' }, + { name: 'OG Skull Trooper', id: 'CID_030_Athena_Commando_M_Halloween', emoji: 'SkullTrooper', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_030_athena_commando_m_halloween/variants/clothingcolor/mat1.png' }, + { name: 'Barricade', id: 'Character_RankedPhantom', emoji: 'Barricade' }, + { name: 'Double Helix', id: 'CID_183_Athena_Commando_M_ModernMilitaryRed', emoji: 'DoubleHelix' }, + { name: 'Honor Guard', id: 'CID_342_Athena_Commando_M_StreetRacerMetallic', emoji: 'HonorGuard' }, + { name: 'Wonder', id: 'CID_434_Athena_Commando_F_StealthHonor', emoji: 'Wonder' }, + { name: 'Surf Strider', id: 'CID_783_Athena_Commando_M_AquaJacket', emoji: 'SurfStrider' }, + { name: 'Stealth Reflex', id: 'CID_386_Athena_Commando_M_StreetOpsStealth', emoji: 'StealthReflex' }, + { name: 'Dark Vertex', id: 'CID_371_Athena_Commando_M_SpeedyMidnight', emoji: 'DarkVertex' }, + { name: 'Royale Bomber', id: 'CID_113_Athena_Commando_M_BlueAce', emoji: 'RoyaleBomber' }, + { name: 'Wildcat', id: 'CID_757_Athena_Commando_F_WildCat', emoji: 'Wildcat' }, + { name: 'Clyde', id: 'Character_UnbrokenTrash', emoji: 'Clyde' }, + { name: 'Eon', id: 'CID_174_Athena_Commando_F_CarbideWhite', emoji: 'Eon' }, + { name: 'Huntmaster Saber', id: 'Character_MasterKeyOrder', emoji: 'HuntmasterSaber' }, + { name: 'Dark Skully', id: 'CID_850_Athena_Commando_F_SkullBriteCube', emoji: 'DarkSkully' }, + { name: 'Galaxy', id: 'CID_175_Athena_Commando_M_Celestial', emoji: 'Galaxy' }, + { name: 'Ikonik', id: 'CID_313_Athena_Commando_M_KpopFashion', emoji: 'Ikonik' }, + { name: 'Black Knight', id: 'CID_035_Athena_Commando_M_Medieval', emoji: 'BlackKnight' }, + { name: 'Glow', id: 'CID_479_Athena_Commando_F_Davinci', emoji: 'Glow' }, + { name: 'Rogue Spider Knight', id: 'CID_516_Athena_Commando_M_BlackWidowRogue', emoji: 'RogueSpiderKnight' }, + { name: 'Thrilldiver', id: 'Character_SummerUnsuitable', emoji: 'Thrilldiver' }, + { name: 'Freediver', id: 'Character_CoolSuitable', emoji: 'Freediver' }, + { name: 'Neo Versa', id: 'CID_441_Athena_Commando_F_CyberScavengerBlue', emoji: 'NeoVersa' }, + { name: 'Cobalt Snowfoot', id: 'Character_SnowNinjaDark', emoji: 'CobaltSnowfoot' }, + { name: 'Florin', id: 'Character_AsterOrder', emoji: 'Florin' }, + { name: "What's Wrong, Toona Fish?", id: 'CID_A_201_Athena_Commando_M_TeriyakiFishToon', emoji: 'ToonaFish' }, + { name: 'Cameo Needs Loot', id: 'Emoji_S20_NeedLoot', emoji: 'Cameo', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/emoji_s20_needloot/smallicon.png' }, +]; + +// ── fetch with timeout so nothing ever hangs ────────────────────────────────── +async function fetchWithTimeout(url, ms = 12000) { + const ctrl = new AbortController(); + const timer = setTimeout(() => ctrl.abort(), ms); + try { + return await fetch(url, { signal: ctrl.signal }); + } finally { + clearTimeout(timer); + } +} + +// ── get icon URL from fortnite-api.com by direct ID ─────────────────────────── +async function fetchIconUrl(cosmeticId) { + const url = `https://fortnite-api.com/v2/cosmetics/br/${cosmeticId}`; + const res = await fetchWithTimeout(url); + if (!res.ok) throw new Error(`API returned ${res.status} for ${cosmeticId}`); + const json = await res.json(); + if (!json.data?.images?.icon) throw new Error(`No icon in response for ${cosmeticId}`); + return json.data.images.icon; +} + +// ── download image and upscale to 256x256 for crisp Discord emoji ───────────── +async function downloadAndProcess(imageUrl) { + const res = await fetchWithTimeout(imageUrl, 15000); + if (!res.ok) throw new Error(`Image download failed: ${res.status}`); + const raw = Buffer.from(await res.arrayBuffer()); + // Upscale to 256x256 with Lanczos resampling + sharpening + return await sharp(raw) + .resize(256, 256, { fit: 'cover', position: 'centre', kernel: 'lanczos3' }) + .sharpen({ sigma: 0.8, m1: 1.0, m2: 2.0 }) + .png({ compressionLevel: 6 }) + .toBuffer(); +} + +// ── create emoji with automatic rate-limit retry ────────────────────────────── +async function createEmojiSafe(guild, buffer, name, reason) { + for (let attempt = 1; attempt <= 6; attempt++) { + try { + return await guild.emojis.create({ attachment: buffer, name, reason }); + } catch (err) { + const isRateLimit = err.status === 429 || err.httpStatus === 429 || + (err.message || '').toLowerCase().includes('rate limit'); + if (isRateLimit) { + const wait = ((err.retryAfter || 5) * 1000) + 1000; + console.warn(` ⏳ Rate limited on "${name}", waiting ${wait}ms (attempt ${attempt}/6)...`); + await new Promise(r => setTimeout(r, wait)); + } else { + throw err; + } + } + } + throw new Error(`Gave up creating emoji "${name}" after 6 attempts`); +} + +// ───────────────────────────────────────────────────────────────────────────── +client.once('ready', () => { + console.log(`✅ Logged in as ${client.user.tag}`); + console.log('Commands: !addicons | !setroleicons | !removeoldemojis'); +}); + +// ── !removeoldemojis ────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!removeoldemojis') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + await message.reply('Removing old skin emojis...'); + const names = new Set(roleIconMap.map(e => e.emoji.toLowerCase())); + let removed = 0; + + // Fetch fresh emoji list + await message.guild.emojis.fetch(); + + for (const emoji of message.guild.emojis.cache.values()) { + if (!names.has(emoji.name.toLowerCase())) continue; + try { + await emoji.delete('Replacing with corrected icons'); + console.log(` 🗑 Deleted: ${emoji.name}`); + removed++; + await new Promise(r => setTimeout(r, 400)); + } catch (err) { + console.error(` ❌ Failed to delete ${emoji.name}: ${err.message}`); + } + } + + message.channel.send(`Removed **${removed}** emojis. Now run \`!addicons\`.`); +}); + +// ── !addicons ───────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!addicons') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + await message.reply(`Starting — uploading ${roleIconMap.length} skin icons. This takes a few minutes, watch the terminal for progress.`); + + // Always fetch a fresh copy of existing emojis + await message.guild.emojis.fetch(); + const existingNames = new Set( + message.guild.emojis.cache.map(e => e.name.toLowerCase()) + ); + + let added = 0, skipped = 0, failed = 0; + + for (const entry of roleIconMap) { + if (existingNames.has(entry.emoji.toLowerCase())) { + console.log(` ⏭ Already exists: ${entry.emoji}`); + skipped++; + continue; + } + + process.stdout.write(` 📥 ${entry.name} — fetching... `); + try { + const iconUrl = entry.overrideUrl || await fetchIconUrl(entry.id); + process.stdout.write(`downloading... `); + const buffer = await downloadAndProcess(iconUrl); + process.stdout.write(`uploading... `); + await createEmojiSafe(message.guild, buffer, entry.emoji, `Skin icon: ${entry.name}`); + console.log(`✅`); + added++; + } catch (err) { + console.log(`❌ ${err.message}`); + failed++; + } + + // 2s gap between uploads to stay under Discord rate limits + await new Promise(r => setTimeout(r, 2000)); + } + + message.channel.send( + `Done! ✅ Added **${added}** emojis. ` + + `⏭ Skipped **${skipped}** (already existed). ` + + `❌ **${failed}** failed.` + ); +}); + +// ── !setroleicons ───────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!setroleicons') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + await message.reply('Applying emojis to roles...'); + + // Refresh both caches + await message.guild.emojis.fetch(); + await message.guild.roles.fetch(); + + let updated = 0, skipped = 0, failed = 0; + + for (const entry of roleIconMap) { + const role = message.guild.roles.cache.find( + r => r.name.toLowerCase() === entry.name.toLowerCase() + ); + if (!role) { + console.log(` ⏭ Role not found: ${entry.name}`); + skipped++; + continue; + } + + const emoji = message.guild.emojis.cache.find( + e => e.name.toLowerCase() === entry.emoji.toLowerCase() + ); + if (!emoji) { + console.log(` ⚠ Emoji not found for: ${entry.name} — run !addicons first`); + skipped++; + continue; + } + + try { + await role.setIcon(emoji); + console.log(` ✅ ${entry.name} → :${entry.emoji}:`); + updated++; + } catch (err) { + console.error(` ❌ Failed "${entry.name}": ${err.message}`); + failed++; + } + + await new Promise(r => setTimeout(r, 500)); + } + + message.channel.send( + `Done! ✅ Set icons on **${updated}** roles. ` + + `⏭ Skipped **${skipped}**. ❌ **${failed}** failed.` + ); +}); + +client.login(process.env.TOKEN); diff --git a/src/bot.js b/src/bot.js new file mode 100644 index 0000000..587053d --- /dev/null +++ b/src/bot.js @@ -0,0 +1,2029 @@ +// ============================================= +// FORTNITE DISCORD BOT — ALL-IN-ONE +// ============================================= +// Commands: +// !setuproles — create all roles +// !addicons — upload skin icons as server emojis +// !setroleicons — apply emojis to roles +// !removeoldemojis — delete old skin emojis +// !verify — verify Fortnite account & auto-assign roles +// +// Run with: node bot.js +// ============================================= + +require('dotenv').config(); +const { Client, GatewayIntentBits, PermissionsBitField, EmbedBuilder, REST, Routes, SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, AttachmentBuilder } = require('discord.js'); +const sharp = require('sharp'); + +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent, + GatewayIntentBits.DirectMessages, + ], + partials: ['CHANNEL'], +}); + +// ───────────────────────────────────────────────────────────────────────────── +// ROLES TO CREATE +// ───────────────────────────────────────────────────────────────────────────── +const roles = [ + { name: 'Fully Golden Peely', color: 0xFFD700 }, + { name: 'OG Aerial Assault Trooper', color: 0x8A8A8A }, + { name: 'OG Ghoul Trooper', color: 0xA89DB8 }, + { name: 'OG Renegade Raider', color: 0x7B2D2D }, + { name: 'OG Skull Trooper', color: 0x9B59B6 }, + { name: 'Barricade', color: 0x9E9E9E }, + { name: 'Double Helix', color: 0xD0443C }, + { name: 'Honor Guard', color: 0x4A90D9 }, + { name: 'Wonder', color: 0x2ECC71 }, + { name: 'Surf Strider', color: 0x1ABC9C }, + { name: 'Stealth Reflex', color: 0xE8927C }, + { name: 'Dark Vertex', color: 0x8E44AD }, + { name: 'Royale Bomber', color: 0xE67E22 }, + { name: 'Wildcat', color: 0xE8832A }, + { name: 'Clyde', color: 0xE8832A }, + { name: 'Eon', color: 0x27AE60 }, + { name: 'Huntmaster Saber', color: 0xD4AC0D }, + { name: 'Dark Skully', color: 0x7D6B8A }, + { name: 'Galaxy', color: 0x5B7DD8 }, + { name: 'Ikonik', color: 0xD0443C }, + { name: 'Black Knight', color: 0xCCCCCC }, + { name: 'Glow', color: 0xBB8FCC }, + { name: 'Rogue Spider Knight', color: 0x2ECC71 }, + { name: 'Thrilldiver', color: 0x4A90D9 }, + { name: 'Freediver', color: 0x9E9E9E }, + { name: 'Neo Versa', color: 0x9B59B6 }, + { name: 'Cobalt Snowfoot', color: 0x1ABC9C }, + { name: 'Florin', color: 0x8E44AD }, + { name: "What's Wrong, Toona Fish?", color: 0xCCCCCC }, + { name: 'Cameo Needs Loot', color: 0x2ECC71 }, + { name: 'Victory!', color: 0x9B59B6 }, + { name: 'Collegiate items', color: 0x2ECC71 }, + { name: 'StreamElements', color: 0xF1C40F }, + { name: 'Llamas', color: 0xFF69B4 }, + { name: 'Repaz', color: 0xD4AC0D }, + { name: 'lollek', color: 0xFFFFFF }, + { name: 'Celebration Heart', color: 0x9B59B6 }, + { name: 'Funflower', color: 0xD4C227 }, + { name: 'Level 100', color: 0xBB44EE }, + { name: 'Alpha Banner', color: 0x777777 }, + { name: 'YouTube Banner', color: 0x777777 }, + { name: 'STW Founders', color: 0xE67E22 }, + { name: 'Ultimate STW Founders', color: 0x888888 }, + { name: 'Rare Usernames', color: 0xF1C40F }, + { name: 'Skin Collector', color: 0x888888 }, + { name: 'PS+ Pack Collector', color: 0x3498DB }, + { name: 'Spray Collector', color: 0xCCCCCC }, + { name: 'Rare Banners', color: 0x888888 }, + { name: 'Emote Collector', color: 0xCCCCCC }, + // --- Exclusive Pickaxes --- + { name: "Raider's Revenge", color: 0x7B2D2D }, + { name: 'Axe of Champions', color: 0xF1C40F }, + { name: 'Blade of Champions', color: 0xF1C40F }, + { name: 'Axecalibur', color: 0xCCCCCC }, + { name: 'EVA', color: 0x4A90D9 }, + { name: 'AC/DC', color: 0xF1C40F }, + { name: 'Resonator', color: 0x27AE60 }, + { name: 'Pinpoint', color: 0xD0443C }, + { name: 'Stellar Axe', color: 0x5B7DD8 }, + { name: 'Stealth Angular Axe', color: 0x9B59B6 }, + { name: 'Dark Razor', color: 0x7D6B8A }, + { name: 'Electri-claw', color: 0xE8832A }, + { name: 'Dark Splitter', color: 0x8E44AD }, + { name: 'Merry Mint Axe', color: 0x2ECC71 }, + { name: 'Indigo Inverter', color: 0x1ABC9C }, + { name: 'Rose Glow', color: 0xFF69B4 }, + { name: 'Controller', color: 0x3498DB }, + { name: 'Pneumatic Twin', color: 0x4A90D9 }, + { name: 'Perfect Point', color: 0x9E9E9E }, + { name: 'Petrol Pump', color: 0xE67E22 }, + { name: 'Future Relic Scythe', color: 0x8E44AD }, + // --- Exclusive Emoticons --- + { name: 'Skull Trooper Emoticon', color: 0x9B59B6 }, + { name: 'Maevys Emoticon', color: 0xD0443C }, + { name: 'ZetFar Emoticon', color: 0x4A90D9 }, + // --- PlayStation Exclusives --- + { name: 'Blue Team Leader', color: 0x3498DB }, // PS Plus Pack 1 + { name: 'Blue Striker', color: 0x3498DB }, // PS Plus Pack 2 + { name: 'Prodigy', color: 0x3498DB }, // PS Plus Pack 4 + { name: 'Carbon Commando', color: 0x3498DB }, // PS Plus Pack 5 + { name: 'Trilogy', color: 0x3498DB }, // PS Plus Pack 8 + { name: 'Point Patroller', color: 0x3498DB }, // PS Plus Pack 9 + { name: 'Cloud Striker', color: 0x3498DB }, // PS Plus Pack 12 + { name: 'Fixer', color: 0x3498DB }, // PS Plus Pack 14 + { name: 'Blizzard Bomber', color: 0x3498DB }, // PS Plus Pack 18 + { name: 'Jun-Hwan', color: 0x3498DB }, // Blue Phoenix Pack + { name: 'Lina Scorch', color: 0x3498DB }, // Blazin Wheels Pack + { name: 'Indigo Kuno', color: 0x9B59B6 }, // PS Generations Cup + // --- Twitch / Amazon Prime --- + { name: 'Sub Commander', color: 0x9146FF }, // Twitch Prime Pack 1 + { name: 'Havoc', color: 0x9146FF }, // Twitch Prime Pack 1 + { name: 'Trailblazer', color: 0x9146FF }, // Twitch Prime Pack 2 + // --- Intel / PC Exclusive --- + { name: 'Reflex', color: 0x0071C5 }, // Intel bundle + // --- OG Battle Pass (C1S2) --- + { name: 'Sparkle Specialist', color: 0xFF69B4 }, + { name: 'Royale Knight', color: 0xCCCCCC }, + { name: 'Blue Squire', color: 0x4A90D9 }, + // --- OG Battle Pass (C1S3) --- + { name: 'The Reaper', color: 0x888888 }, + { name: 'Elite Agent', color: 0x888888 }, + { name: 'Rogue Agent', color: 0x888888 }, + // --- OG Battle Pass (C1S4) --- + { name: 'Omega', color: 0x8E44AD }, + // --- Chapter 2 Season 2 Battle Pass (golden styles) --- + { name: 'Skye', color: 0xF1C40F }, + { name: 'TNTina', color: 0xF1C40F }, + { name: 'Meowscles', color: 0xF1C40F }, + { name: 'Midas', color: 0xFFD700 }, + // --- Gaming Legends / Collab Exclusives --- + { name: 'Travis Scott', color: 0xF1C40F }, // Icon Series, never returned + { name: 'Astro Jack', color: 0xF1C40F }, // Icon Series, never returned + { name: 'Kratos', color: 0xCCCCCC }, // PlayStation collab + { name: 'Master Chief', color: 0x4A90D9 }, // Xbox collab + // --- World Cup / Tournament --- + { name: 'World Warrior', color: 0xF1C40F }, // Fortnite World Cup 2019 + // --- V-Bucks Card Promo --- + { name: 'Color Splash Jellie', color: 0xFF69B4 }, + // --- Save the World Founders --- + { name: 'Rose Team Leader', color: 0xE67E22 }, + { name: 'Warpaint', color: 0xE67E22 }, + // --- OT Banners --- + { name: 'OT1 Banner', color: 0xFFD700 }, + { name: 'OT2 Banner', color: 0xFFD700 }, + { name: 'OT3 Banner', color: 0xFFD700 }, + { name: 'OT4 Banner', color: 0xFFD700 }, + { name: 'OT5 Banner', color: 0xFFD700 }, + { name: 'OT6 Banner', color: 0xFFD700 }, + { name: 'OT7 Banner', color: 0xFFD700 }, + { name: 'OT8 Banner', color: 0xFFD700 }, + { name: 'OT9 Banner', color: 0xFFD700 }, + { name: 'OT10 Banner', color: 0xFFD700 }, + { name: 'OT11 Banner', color: 0xFFD700 }, +]; + +// ───────────────────────────────────────────────────────────────────────────── +// EMOJI / ICON MAP +// ───────────────────────────────────────────────────────────────────────────── +const roleIconMap = [ + { + name: 'Fully Golden Peely', id: 'CID_701_Athena_Commando_M_BananaAgent', emoji: 'FullyGoldenPeely', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_701_athena_commando_m_bananaagent/variants/progressive/stage4.png' + }, + { name: 'OG Aerial Assault Trooper', id: 'CID_017_Athena_Commando_M', emoji: 'AerialAssaultTrooper' }, + { + name: 'OG Ghoul Trooper', id: 'CID_029_Athena_Commando_F_Halloween', emoji: 'GhoulTrooper', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_029_athena_commando_f_halloween/variants/material/mat3.png' + }, + { name: 'OG Renegade Raider', id: 'CID_028_Athena_Commando_F', emoji: 'RenegadeRaider' }, + { + name: 'OG Skull Trooper', id: 'CID_030_Athena_Commando_M_Halloween', emoji: 'SkullTrooper', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/cid_030_athena_commando_m_halloween/variants/clothingcolor/mat1.png' + }, + { name: 'Barricade', id: 'Character_RankedPhantom', emoji: 'Barricade' }, + { name: 'Double Helix', id: 'CID_183_Athena_Commando_M_ModernMilitaryRed', emoji: 'DoubleHelix' }, + { name: 'Honor Guard', id: 'CID_342_Athena_Commando_M_StreetRacerMetallic', emoji: 'HonorGuard' }, + { name: 'Wonder', id: 'CID_434_Athena_Commando_F_StealthHonor', emoji: 'Wonder' }, + { name: 'Surf Strider', id: 'CID_783_Athena_Commando_M_AquaJacket', emoji: 'SurfStrider' }, + { name: 'Stealth Reflex', id: 'CID_386_Athena_Commando_M_StreetOpsStealth', emoji: 'StealthReflex' }, + { name: 'Dark Vertex', id: 'CID_371_Athena_Commando_M_SpeedyMidnight', emoji: 'DarkVertex' }, + { name: 'Royale Bomber', id: 'CID_113_Athena_Commando_M_BlueAce', emoji: 'RoyaleBomber' }, + { name: 'Wildcat', id: 'CID_757_Athena_Commando_F_WildCat', emoji: 'Wildcat' }, + { name: 'Clyde', id: 'Character_UnbrokenTrash', emoji: 'Clyde' }, + { name: 'Eon', id: 'CID_174_Athena_Commando_F_CarbideWhite', emoji: 'Eon' }, + { name: 'Huntmaster Saber', id: 'Character_MasterKeyOrder', emoji: 'HuntmasterSaber' }, + { name: 'Dark Skully', id: 'CID_850_Athena_Commando_F_SkullBriteCube', emoji: 'DarkSkully' }, + { name: 'Galaxy', id: 'CID_175_Athena_Commando_M_Celestial', emoji: 'Galaxy' }, + { name: 'Ikonik', id: 'CID_313_Athena_Commando_M_KpopFashion', emoji: 'Ikonik' }, + // { name: 'Black Knight', id: 'CID_035_Athena_Commando_M_Medieval', emoji: 'BlackKnight' }, // temporarily disabled — upload stalls + { name: 'Glow', id: 'CID_479_Athena_Commando_F_Davinci', emoji: 'Glow' }, + { name: 'Rogue Spider Knight', id: 'CID_516_Athena_Commando_M_BlackWidowRogue', emoji: 'RogueSpiderKnight' }, + { name: 'Thrilldiver', id: 'Character_SummerUnsuitable', emoji: 'Thrilldiver' }, + { name: 'Freediver', id: 'Character_CoolSuitable', emoji: 'Freediver' }, + { name: 'Neo Versa', id: 'CID_441_Athena_Commando_F_CyberScavengerBlue', emoji: 'NeoVersa' }, + { name: 'Cobalt Snowfoot', id: 'Character_SnowNinjaDark', emoji: 'CobaltSnowfoot' }, + { name: 'Florin', id: 'Character_AsterOrder', emoji: 'Florin' }, + { name: "What's Wrong, Toona Fish?", id: 'CID_A_201_Athena_Commando_M_TeriyakiFishToon', emoji: 'ToonaFish' }, + { + name: 'Cameo Needs Loot', id: 'Emoji_S20_NeedLoot', emoji: 'Cameo', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/emoji_s20_needloot/smallicon.png' + }, + + // --- Exclusive Pickaxes --- + { name: "Raider's Revenge", id: 'Pickaxe_Lockjaw', emoji: 'RaidersRevenge' }, + { name: 'Axe of Champions', id: 'Pickaxe_ID_376_FNCS', emoji: 'AxeOfChampions' }, + { name: 'Blade of Champions', id: 'Pickaxe_FNCS_S32', emoji: 'BladeOfChampions' }, + { name: 'Axecalibur', id: 'Pickaxe_ID_011_Medieval', emoji: 'Axecalibur' }, + { name: 'EVA', id: 'Pickaxe_ID_028_Space', emoji: 'EVA' }, + { name: 'AC/DC', id: 'Pickaxe_ID_013_Teslacoil', emoji: 'ACDC' }, + { name: 'Resonator', id: 'Pickaxe_ID_077_CarbideWhite', emoji: 'Resonator' }, + { name: 'Pinpoint', id: 'Pickaxe_ID_099_ModernMilitaryRed', emoji: 'Pinpoint' }, + { name: 'Stellar Axe', id: 'Pickaxe_ID_116_Celestial', emoji: 'StellarAxe' }, + { name: 'Stealth Angular Axe', id: 'Pickaxe_ID_189_StreetOpsStealth', emoji: 'StealthAngularAxe' }, + { name: 'Dark Razor', id: 'Pickaxe_ID_178_SpeedyMidnight', emoji: 'DarkRazor' }, + { name: 'Electri-claw', id: 'Pickaxe_ID_398_WildCatFemale', emoji: 'Electriclaw' }, + { name: 'Dark Splitter', id: 'Pickaxe_ID_461_SkullBriteCube', emoji: 'DarkSplitter' }, + { name: 'Merry Mint Axe', id: 'Pickaxe_ID_294_CandyCane', emoji: 'MerryMintAxe' }, + { name: 'Indigo Inverter', id: 'Pickaxe_SnowNinjaDark', emoji: 'IndigoInverter' }, + { name: 'Rose Glow', id: 'Pickaxe_ID_153_RoseLeader', emoji: 'RoseGlow' }, + { name: 'Controller', id: 'Pickaxe_ID_088_PSBurnout', emoji: 'Controller' }, + { name: 'Pneumatic Twin', id: 'Pickaxe_ID_256_TechOpsBlue', emoji: 'PneumaticTwin' }, + { name: 'Perfect Point', id: 'Pickaxe_ID_464_LongShortsMale', emoji: 'PerfectPoint' }, + { name: 'Petrol Pump', id: 'Pickaxe_RetroWheels', emoji: 'PetrolPump' }, + { name: 'Future Relic Scythe', id: 'Pickaxe_SnowSoldierFashion', emoji: 'FutureRelicScythe' }, + + // --- OT Banners (OT1–OT11) --- + { name: 'OT1 Banner', id: 'OT1Banner', emoji: 'OT1Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot1banner/icon.png' }, + { name: 'OT2 Banner', id: 'OT2Banner', emoji: 'OT2Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot2banner/icon.png' }, + { name: 'OT3 Banner', id: 'OT3Banner', emoji: 'OT3Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot3banner/icon.png' }, + { name: 'OT4 Banner', id: 'OT4Banner', emoji: 'OT4Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot4banner/icon.png' }, + { name: 'OT5 Banner', id: 'OT5Banner', emoji: 'OT5Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot5banner/icon.png' }, + { name: 'OT6 Banner', id: 'OT6Banner', emoji: 'OT6Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot6banner/icon.png' }, + { name: 'OT7 Banner', id: 'OT7Banner', emoji: 'OT7Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot7banner/icon.png' }, + { name: 'OT8 Banner', id: 'OT8Banner', emoji: 'OT8Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot8banner/icon.png' }, + { name: 'OT9 Banner', id: 'OT9Banner', emoji: 'OT9Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot9banner/icon.png' }, + { name: 'OT10 Banner', id: 'OT10Banner', emoji: 'OT10Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot10banner/icon.png' }, + { name: 'OT11 Banner', id: 'OT11Banner', emoji: 'OT11Banner', bannerUrl: 'https://fortnite-api.com/images/banners/ot11banner/icon.png' }, + + // --- Exclusive Emoticons (in-game emoji cosmetics) --- + { + name: 'Skull Trooper Emoticon', id: 'Emoji_Skulltrooper', emoji: 'EmoticonSkullTrooper', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/emoji_skulltrooper/smallicon.png' + }, + { + name: 'Maevys Emoticon', id: 'Emoji_S22_Showdown_Mae', emoji: 'EmoticonMaevys', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/emoji_s22_showdown_mae/smallicon.png' + }, + { + name: 'ZetFar Emoticon', id: 'Emoji_S22_Showdown_Zet', emoji: 'EmoticonZetFar', + overrideUrl: 'https://fortnite-api.com/images/cosmetics/br/emoji_s22_showdown_zet/smallicon.png' + }, + + // --- PlayStation Exclusives --- + { name: 'Blue Team Leader', id: 'CID_052_Athena_Commando_F_PSBlue', emoji: 'BlueTeamLeader' }, + { name: 'Blue Striker', id: 'CID_138_Athena_Commando_M_PSBurnout', emoji: 'BlueStriker' }, + { name: 'Prodigy', id: 'CID_296_Athena_Commando_M_Math', emoji: 'Prodigy' }, + { name: 'Carbon Commando', id: 'CID_360_Athena_Commando_M_TechOpsBlue', emoji: 'CarbonCommando' }, + { name: 'Trilogy', id: 'CID_657_Athena_Commando_F_TechOpsBlue', emoji: 'Trilogy' }, + { name: 'Point Patroller', id: 'CID_711_Athena_Commando_M_LongShorts', emoji: 'PointPatroller' }, + { name: 'Cloud Striker', id: 'CID_926_Athena_Commando_F_StreetFashionDiamond', emoji: 'CloudStriker' }, + { name: 'Fixer', id: 'CID_A_101_Athena_Commando_M_TacticalWoodlandBlue', emoji: 'Fixer' }, + { name: 'Blizzard Bomber', id: 'CID_A_421_Athena_Commando_F_BlizzardBomber', emoji: 'BlizzardBomber' }, + { name: 'Jun-Hwan', id: 'Character_BlueJet', emoji: 'JunHwan' }, + { name: 'Lina Scorch', id: 'Character_RetroWheels', emoji: 'LinaScorch' }, + { name: 'Indigo Kuno', id: 'CID_660_Athena_Commando_F_BandageNinjaBlue', emoji: 'IndigoKuno' }, + + // --- Twitch / Amazon Prime --- + { name: 'Sub Commander', id: 'CID_085_Athena_Commando_M_Twitch', emoji: 'SubCommander' }, + { name: 'Havoc', id: 'CID_089_Athena_Commando_M_RetroGrey', emoji: 'Havoc' }, + { name: 'Trailblazer', id: 'CID_114_Athena_Commando_F_TacticalWoodland', emoji: 'Trailblazer' }, + + // --- Intel / PC Exclusive --- + { name: 'Reflex', id: 'CID_259_Athena_Commando_M_StreetOps', emoji: 'Reflex' }, + + // --- OG Battle Pass --- + { name: 'Sparkle Specialist', id: 'CID_039_Athena_Commando_F_Disco', emoji: 'SparkleSpecialist' }, + { name: 'Royale Knight', id: 'CID_033_Athena_Commando_F_Medieval', emoji: 'RoyaleKnight' }, + { name: 'Blue Squire', id: 'CID_032_Athena_Commando_M_Medieval', emoji: 'BlueSquire' }, + { name: 'The Reaper', id: 'CID_084_Athena_Commando_M_Assassin', emoji: 'TheReaper' }, + { name: 'Elite Agent', id: 'CID_083_Athena_Commando_F_Tactical', emoji: 'EliteAgent' }, + { name: 'Rogue Agent', id: 'CID_090_Athena_Commando_M_Tactical', emoji: 'RogueAgent' }, + { name: 'Omega', id: 'CID_116_Athena_Commando_M_CarbideBlack', emoji: 'Omega' }, + + // --- Ch2S2 Battle Pass gold styles --- + { name: 'Skye', id: 'CID_690_Athena_Commando_F_Photographer', emoji: 'Skye' }, + { name: 'TNTina', id: 'CID_691_Athena_Commando_F_TNTina', emoji: 'TNTina' }, + { name: 'Meowscles', id: 'CID_693_Athena_Commando_M_BuffCat', emoji: 'Meowscles' }, + { name: 'Midas', id: 'CID_694_Athena_Commando_M_CatBurglar', emoji: 'Midas' }, + + // --- Gaming Legends / Collab --- + { name: 'Travis Scott', id: 'CID_703_Athena_Commando_M_Cyclone', emoji: 'TravisScott' }, + { name: 'Astro Jack', id: 'CID_761_Athena_Commando_M_CycloneSpace', emoji: 'AstroJack' }, + { name: 'Kratos', id: 'CID_964_Athena_Commando_M_Historian_869BC', emoji: 'Kratos' }, + { name: 'Master Chief', id: 'CID_971_Athena_Commando_M_Jupiter_S0Z6M', emoji: 'MasterChief' }, + + // --- World Cup / Tournament --- + { name: 'World Warrior', id: 'CID_478_Athena_Commando_F_WorldCup', emoji: 'WorldWarrior' }, + + // --- V-Bucks Card Promo --- + { name: 'Color Splash Jellie', id: 'Character_TubaGummi', emoji: 'ColorSplashJellie' }, + + // --- Save the World Founders --- + { name: 'Rose Team Leader', id: 'CID_096_Athena_Commando_F_Founder', emoji: 'RoseTeamLeader' }, + { name: 'Warpaint', id: 'CID_095_Athena_Commando_M_Founder', emoji: 'Warpaint' }, +]; + +// ───────────────────────────────────────────────────────────────────────────── +// VERIFY ROLE REQUIREMENTS +// ───────────────────────────────────────────────────────────────────────────── +const ROLE_REQUIREMENTS = [ + // OG Season 1 skins (style required) + { role: 'OG Renegade Raider', id: 'cid_028_athena_commando_f', styleTag: 'Mat3' }, + { role: 'OG Aerial Assault Trooper', id: 'cid_017_athena_commando_m', styleTag: 'Stage2' }, + { role: 'OG Ghoul Trooper', id: 'cid_029_athena_commando_f_halloween', styleTag: 'Mat3' }, + { role: 'OG Skull Trooper', id: 'cid_030_athena_commando_m_halloween', styleTag: 'Mat1' }, + // OG Battle Pass skins + { role: 'Black Knight', id: 'cid_035_athena_commando_m_medieval' }, + { role: 'Blue Squire', id: 'cid_032_athena_commando_m_medieval' }, + { role: 'Royale Knight', id: 'cid_033_athena_commando_f_medieval' }, + { role: 'Sparkle Specialist', id: 'cid_039_athena_commando_f_disco' }, + { role: 'The Reaper', id: 'cid_084_athena_commando_m_assassin' }, + { role: 'Elite Agent', id: 'cid_083_athena_commando_f_tactical' }, + { role: 'Omega', id: 'cid_116_athena_commando_m_carbideblack', styleTag: 'Stage5' }, + { role: 'Carbide', id: 'cid_115_athena_commando_m_carbideblue', styleTag: 'Stage5' }, + // Samsung bundles + { role: 'Galaxy', id: 'cid_175_athena_commando_m_celestial' }, + { role: 'Stellar Axe', id: 'pickaxe_id_116_celestial' }, + { role: 'Ikonik', id: 'cid_313_athena_commando_m_kpopfashion' }, + { role: 'Scenario Emote', id: 'eid_kpopdance03' }, + { role: 'Glow', id: 'cid_479_athena_commando_f_davinci' }, + { role: 'Levitate Emote', id: 'eid_davinci' }, + // Device / Platform exclusives + { role: 'Honor Guard', id: 'cid_342_athena_commando_m_streetracermetallic' }, + { role: 'Wonder', id: 'cid_434_athena_commando_f_stealthhonor' }, + { role: 'Eon', id: 'cid_174_athena_commando_f_carbidewhite' }, + { role: 'Resonator', id: 'pickaxe_id_077_carbidewhite' }, + { role: 'Dark Vertex', id: 'cid_371_athena_commando_m_speedymidnight' }, + { role: 'Double Helix', id: 'cid_183_athena_commando_m_modernmilitaryred' }, + { role: 'Pinpoint', id: 'pickaxe_id_099_modernmilitaryred' }, + { role: 'Neo Versa', id: 'cid_441_athena_commando_f_cyberscavengerblue' }, + { role: 'Cobalt Snowfoot', id: 'character_snowninjadark' }, + { role: 'Royale Bomber', id: 'cid_113_athena_commando_m_blueace' }, + { role: 'Wildcat', id: 'cid_757_athena_commando_f_wildcat' }, + { role: 'Stealth Reflex', id: 'cid_386_athena_commando_m_streetopsstealth' }, + { role: 'Reflex', id: 'cid_259_athena_commando_m_streetops' }, + { role: 'Angular Axe', id: 'pickaxe_id_118_streetops' }, + { role: 'Surf Strider', id: 'cid_783_athena_commando_m_aquajacket' }, + { role: 'Rogue Spider Knight', id: 'cid_516_athena_commando_m_blackwidowrogue' }, + { role: 'Huntmaster Saber', id: 'character_masterkeyorder' }, + // PlayStation Plus exclusives + { role: 'Blue Team Leader', id: 'cid_052_athena_commando_f_psblue' }, + { role: 'Blue Striker', id: 'cid_138_athena_commando_m_psburnout' }, + { role: 'Carbon Commando', id: 'cid_360_athena_commando_m_techopsblue' }, + { role: 'Prodigy', id: 'cid_296_athena_commando_m_math' }, + { role: 'Cloud Striker', id: 'cid_926_athena_commando_f_streetfashiondiamond' }, + { role: 'Fixer', id: 'cid_a_101_athena_commando_m_tacticalwoodlandblue' }, + { role: 'Point Patroller', id: 'cid_711_athena_commando_m_longshorts' }, + // Twitch Prime exclusives + { role: 'Sub Commander', id: 'cid_085_athena_commando_m_twitch' }, + { role: 'Havoc', id: 'cid_089_athena_commando_m_retrogrey' }, + { role: 'Trailblazer', id: 'cid_114_athena_commando_f_tacticalwoodland' }, + // Exclusive Pickaxes + { role: "Raider's Revenge", id: 'pickaxe_lockjaw', styleTags: ['Stage2', 'Particle1', 'Particle.Particle1'] }, + { role: 'AC/DC', id: 'pickaxe_id_013_teslacoil' }, + { role: 'Merry Mint Axe', id: 'pickaxe_id_294_candycane' }, + { role: 'Tenderizer', id: 'pickaxe_id_044_tacticalurbanhammer' }, + { role: 'Axe of Champions', id: 'pickaxe_id_376_fncs' }, + { role: 'Blade of Champions', id: 'pickaxe_fncs_s32' }, + // OG / Exclusive Emotes + { role: 'Fresh Emote', id: 'eid_fresh' }, + { role: 'Rambunctious Emote', id: 'eid_zippy' }, + { role: 'Tidy Emote', id: 'eid_tidy' }, + { role: 'Floss Emote', id: 'eid_floss' }, + { role: 'Take the L Emote', id: 'eid_takethelathena' }, + { role: 'Orange Justice Emote', id: 'eid_goodvibes' }, + { role: 'Ride the Pony Emote', id: 'eid_ridethepony_athena' }, + { role: 'Pony Up Emote', id: 'eid_ridetheponymultiple' }, + { role: 'Evasive Maneuvers Emote', id: 'eid_temple' }, + // Exclusive Emoticons + { role: 'Cameo Needs Loot', id: 'emoji_s20_needloot' }, + // Founder exclusives + { role: 'Rose Team Leader', id: 'cid_096_athena_commando_f_founder' }, + { role: 'Warpaint', id: 'cid_095_athena_commando_m_founder' }, + { role: 'Fully Golden Peely', id: 'cid_701_athena_commando_m_bananaagent', styleTag: 'Stage4' }, + // Samsung Galaxy bundle items + { role: 'Galactic Disc', id: 'bid_138_celestial' }, + { role: 'Discovery Glider', id: 'glider_id_090_celestial' }, + // IKONIK bundle - Scenario already added above + // Glow bundle - Levitate already added above + // EON bundle + { role: 'Aurora Glider', id: 'glider_id_056_carbidewhite' }, + // Dark Vertex bundle + { role: 'Dark Deflector', id: 'bid_234_speedymidnight' }, + { role: 'Razor Edge', id: 'pickaxe_id_065_speedyred' }, + { role: 'Dark Forerunner Glider', id: 'glider_id_131_speedymidnight' }, + // Double Helix bundle + { role: 'Telemetry', id: 'bid_114_modernmilitaryred' }, + { role: 'Rotor Glider', id: 'glider_id_075_modernmilitaryred' }, + // Neo Versa bundle + { role: 'Neo Phrenzy', id: 'bid_288_cyberscavengerfemaleblue' }, + // Royale Bomber bundle + { role: 'Royale Air Glider', id: 'glider_id_105_snowboard' }, + // Reflex bundle + { role: 'Response Unit', id: 'bid_140_streetopsmale' }, + { role: 'Pivot Glider', id: 'glider_id_092_streetops' }, + // Wildcat bundle + { role: 'Sleek Strike', id: 'bid_521_wildcat' }, + // Rogue Spider Knight bundle + { role: 'Time Keeper', id: 'bid_395_phantom' }, + // Stealth Reflex bundle + { role: 'Stealth Response Unit', id: 'bid_249_streetopsstealth' }, + // Aerial Assault One glider (S1 exclusive) + { role: 'Aerial Assault One', id: 'glider_id_001', styleTag: 'Stage2' }, + // Extra exclusive pickaxes from master list + { role: 'Trusty No. 2', id: 'pickaxe_id_029_assassin' }, + { role: 'Party Animal', id: 'pickaxe_id_020_keg' }, + { role: 'Crowbar', id: 'pickaxe_id_092_bling' }, + { role: 'Instigator', id: 'pickaxe_id_039_tacticalblack' }, + // Missing emotes from master list + { role: "Widow's Pirouette Emote", id: 'eid_ashtonboardwalk' }, + { role: 'Hot Marat Emote', id: 'eid_wir' }, + { role: 'Kiss the Cup Emote', id: 'eid_trophycelebration' }, + // Missing skins from master list + { role: 'Gildedguy', id: 'cid_a_141_athena_commando_m_dojo' }, + { role: 'Tart Tycoon', id: 'cid_851_athena_commando_m_bittenhead' }, + // Gliders + { role: 'Mako Glider', id: 'glider_warthog' }, + // Rare / STW / Creator banners (checked via homebase_banners in common_core) + { role: 'Alpha Tester Banner', bannerId: 'OtherBanner51' }, + { role: 'World Cup Banner', bannerId: 'BRWorldCup2019' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner1' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner2' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner3' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner4' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner5' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner6' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner7' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner8' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner9' }, + // STW Founder banners + { role: 'STW Founder Banner', bannerId: 'FounderTier5Banner1' }, + { role: 'STW Founder Banner', bannerId: 'FounderTier4Banner1' }, + { role: 'STW Founder Banner', bannerId: 'FounderTier3Banner1' }, + { role: 'STW Founder Banner', bannerId: 'FounderTier2Banner1' }, + { role: 'STW Founder Banner', bannerId: 'FounderTier1Banner1' }, + // STW Endurance banners + { role: 'STW Endurance Banner', bannerId: 'EnduranceWave30Theater04' }, + { role: 'STW Endurance Banner', bannerId: 'EnduranceWave30Theater03' }, + { role: 'STW Endurance Banner', bannerId: 'EnduranceWave30Theater02' }, + { role: 'STW Endurance Banner', bannerId: 'EnduranceWave30Theater01' }, + // STW Survival / Wargames banners + { role: 'STW Event Banner', bannerId: 'SurvivalBannerStorm2018Hard' }, + { role: 'STW Event Banner', bannerId: 'SurvivalBannerHolidayHard' }, + { role: 'STW Event Banner', bannerId: 'WargamesTprifts' }, + { role: 'STW Event Banner', bannerId: 'WargamesTiki' }, + { role: 'STW Event Banner', bannerId: 'WargamesPods' }, + // STW Achievement banners + { role: 'STW Achievement Banner', bannerId: 'AchievementUnspeakableHorrors' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementWorldExplorer' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementGuardianAngel' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementPlaysWellWithOthers' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementTalentedBuilder' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementGoGnome' }, + { role: 'STW Achievement Banner', bannerId: 'AchievementLootLegend' }, + // FNCS / Skirmish / World Cup banners + { role: 'FNCS Banner', bannerId: 'BRS23_FNCS_Drops' }, + { role: 'FNCS Banner', bannerId: 'S11FNCS' }, + { role: 'Skirmish Banner', bannerId: 'BRSkirmishBushBandits' }, + { role: 'Skirmish Banner', bannerId: 'BRSkirmishDustyDogs' }, + { role: 'Skirmish Banner', bannerId: 'BRSkirmishFortKnights' }, + { role: 'Skirmish Banner', bannerId: 'BRSkirmishLuckyLlamas' }, + { role: 'Skirmish Banner', bannerId: 'BRSkirmishRiftRaiders' }, + // Season Level 100 banners + { role: 'Season Level 100 Banner', bannerId: 'BRS10Level100' }, + { role: 'Season Level 100 Banner', bannerId: 'BRS9Lvl100' }, + { role: 'Season Level 100 Banner', bannerId: 'BRS8Level100' }, + // Creator / Influencer banners 10-58 + { role: 'Creator Banner', bannerId: 'InfluencerBanner10' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner11' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner12' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner13' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner14' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner15' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner16' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner17' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner18' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner19' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner20' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner21' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner22' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner23' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner24' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner25' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner26' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner27' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner28' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner29' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner30' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner31' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner32' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner33' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner34' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner35' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner36' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner37' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner38' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner39' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner40' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner41' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner42' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner43' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner44' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner45' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner46' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner47' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner48' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner49' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner50' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner51' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner52' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner53' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner54' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner55' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner56' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner57' }, + { role: 'Creator Banner', bannerId: 'InfluencerBanner58' }, + // OT Banners + { role: 'OT1 Banner', bannerId: 'OT1Banner' }, + { role: 'OT2 Banner', bannerId: 'OT2Banner' }, + { role: 'OT3 Banner', bannerId: 'OT3Banner' }, + { role: 'OT4 Banner', bannerId: 'OT4Banner' }, + { role: 'OT5 Banner', bannerId: 'OT5Banner' }, + { role: 'OT6 Banner', bannerId: 'OT6Banner' }, + { role: 'OT7 Banner', bannerId: 'OT7Banner' }, + { role: 'OT8 Banner', bannerId: 'OT8Banner' }, + { role: 'OT9 Banner', bannerId: 'OT9Banner' }, + { role: 'OT10 Banner', bannerId: 'OT10Banner' }, + { role: 'OT11 Banner', bannerId: 'OT11Banner' }, + // STW Founders + { role: 'STW Founders', id: 'cid_095_athena_commando_m_founder' }, + { role: 'Ultimate STW Founders', id: 'tiertoken_collectionbook_ultimate', stw: true }, +] + +// ───────────────────────────────────────────────────────────────────────────── +// EPIC OAUTH CONSTANTS +// ───────────────────────────────────────────────────────────────────────────── +const SWITCH_TOKEN = 'OThmN2U0MmMyZTNhNGY4NmE3NGViNDNmYmI0MWVkMzk6MGEyNDQ5YTItMDAxYS00NTFlLWFmZWMtM2U4MTI5MDFjNGQ3'; +const IOS_TOKEN = 'M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU='; +const EPIC_OAUTH = 'https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token'; +const EPIC_OAUTH_PROD03 = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token'; +const EPIC_EXCHANGE = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/exchange'; +const EPIC_DEVICE_AUTH = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/deviceAuthorization'; + +const pending = new Map(); +const verifiedUsers = new Map(); // userId -> { guildId, assignedRoles: string[], epicName: string } +const LOG_CHANNEL_ID = '1517695849952706642'; + +// ───────────────────────────────────────────────────────────────────────────── +// SHARED HELPERS +// ───────────────────────────────────────────────────────────────────────────── +async function fetchWithTimeout(url, ms = 12000) { + const ctrl = new AbortController(); + const timer = setTimeout(() => ctrl.abort(), ms); + try { return await fetch(url, { signal: ctrl.signal }); } + finally { clearTimeout(timer); } +} + +// ─── get icon URL — build directly from known CDN pattern, no API roundtrip ── +async function fetchIconUrl(cosmeticId) { + // Direct CDN URL — fortnite-api.com images are always at this pattern + const url = `https://fortnite-api.com/images/cosmetics/br/${cosmeticId.toLowerCase()}/icon.png`; + const res = await fetchWithTimeout(url, 8000); + if (res.ok) return url; + // Fallback to API lookup if direct URL 404s + const apiRes = await fetchWithTimeout(`https://fortnite-api.com/v2/cosmetics/br/${cosmeticId}`, 8000); + if (!apiRes.ok) throw new Error(`API ${apiRes.status} for ${cosmeticId}`); + const json = await apiRes.json(); + if (!json.data?.images?.icon) throw new Error(`No icon for ${cosmeticId}`); + return json.data.images.icon; +} + +async function downloadAndProcess(imageUrl) { + const res = await fetchWithTimeout(imageUrl, 15000); + if (!res.ok) throw new Error(`Download failed ${res.status}`); + const raw = Buffer.from(await res.arrayBuffer()); + return sharp(raw) + .resize(128, 128, { fit: 'cover', position: 'centre', kernel: 'lanczos3' }) + .sharpen({ sigma: 0.8, m1: 1.0, m2: 2.0 }) + .png({ compressionLevel: 6 }) + .toBuffer(); +} + +async function createEmojiSafe(guild, buffer, name, reason) { + for (let attempt = 1; attempt <= 5; attempt++) { + try { + return await guild.emojis.create({ attachment: buffer, name, reason }); + } catch (err) { + const isRL = err.status === 429 || err.httpStatus === 429 || + (err.message || '').toLowerCase().includes('rate limit'); + if (isRL) { + const wait = ((err.retryAfter || 5) * 1000) + 1000; + console.warn(` ⏳ Rate limited "${name}", waiting ${Math.ceil(wait / 1000)}s...`); + await new Promise(r => setTimeout(r, wait)); + } else { + throw err; + } + } + } + throw new Error(`Gave up on emoji "${name}"`); +} + +// ─── Epic helpers ───────────────────────────────────────────────────────────── +async function getSwitchAccessToken() { + const res = await fetch(EPIC_OAUTH, { + method: 'POST', + headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': `basic ${SWITCH_TOKEN}` }, + body: 'grant_type=client_credentials', + }); + return (await res.json()).access_token; +} + +async function createDeviceCode(token) { + const res = await fetch(EPIC_DEVICE_AUTH, { + method: 'POST', + headers: { 'Authorization': `bearer ${token}`, 'Content-Type': 'application/x-www-form-urlencoded' }, + }); + return res.json(); +} + +async function waitForLogin(deviceCode, maxMs = 300000) { + const start = Date.now(); + while (Date.now() - start < maxMs) { + await new Promise(r => setTimeout(r, 10000)); + const res = await fetch(EPIC_OAUTH_PROD03, { + method: 'POST', + headers: { 'Authorization': `basic ${SWITCH_TOKEN}`, 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `grant_type=device_code&device_code=${deviceCode}`, + }); + const data = await res.json(); + if (res.status === 200 && data.access_token) return data; + const err = data.errorCode || ''; + if (err.includes('not_found') || err.includes('expired')) return null; + } + return null; +} + +async function exchangeForIosToken(accessToken) { + const exRes = await fetch(EPIC_EXCHANGE, { headers: { 'Authorization': `bearer ${accessToken}` } }); + const exData = await exRes.json(); + const res = await fetch(EPIC_OAUTH_PROD03, { + method: 'POST', + headers: { 'Authorization': `basic ${IOS_TOKEN}`, 'Content-Type': 'application/x-www-form-urlencoded' }, + body: `grant_type=exchange_code&exchange_code=${exData.code}`, + }); + return res.json(); +} + +async function getProfile(accountId, accessToken, profileId) { + const url = `https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/${accountId}/client/QueryProfile?profileId=${profileId}&rvn=-1`; + const res = await fetch(url, { + method: 'POST', + headers: { 'Authorization': `bearer ${accessToken}`, 'Content-Type': 'application/json' }, + body: '{}', + }); + return res.json(); +} + +// ───────────────────────────────────────────────────────────────────────────── +// SKIN CHECKER IMAGE RENDERER (RiftCheckerBot style) +// ───────────────────────────────────────────────────────────────────────────── +const { createCanvas, loadImage, GlobalFonts } = require('@napi-rs/canvas'); +const path = require('path'); + +// Register Fortnite font (Burbank Big Condensed Black) + Tahoma +GlobalFonts.registerFromPath( + path.join(__dirname, 'BurbankBigCondensed-Black.ttf'), 'Burbank' +); +GlobalFonts.registerFromPath('C:/Windows/Fonts/tahoma.ttf', 'Tahoma'); +GlobalFonts.registerFromPath('C:/Windows/Fonts/tahomabd.ttf', 'TahomaB'); + +// Custom background URL — set with !setbg , cleared with !clearbg +let customBgUrl = null; + +const ICON = 96; +const COLS = 12; // wider rows = shorter images +const LABEL = 26; +const CELL_H = ICON + LABEL; +const PAD = 14; +const HDR_H = 72; +const FTR_H = 36; + +const RC = { + common: '#c8c8c8', uncommon: '#60aa3a', rare: '#4990e2', + epic: '#874bd2', legendary: '#d3782e', mythic: '#ffd700', + icon: '#54ceec', marvel: '#e63c3c', dark: '#641464', + frozen: '#94dffc', lava: '#ca4d1d', shadow: '#505050', + gaming: '#1a8e48', slurp: '#00e9b0', +}; + +const OG_STYLE_ICONS = { + 'cid_029_athena_commando_f_halloween': 'https://fortnite-api.com/images/cosmetics/br/cid_029_athena_commando_f_halloween/variants/material/mat3.png', + 'cid_030_athena_commando_m_halloween': 'https://fortnite-api.com/images/cosmetics/br/cid_030_athena_commando_m_halloween/variants/clothingcolor/mat1.png', + 'cid_028_athena_commando_f': 'https://fortnite-api.com/images/cosmetics/br/cid_028_athena_commando_f/variants/material/mat3.png', + 'cid_701_athena_commando_m_bananaagent': 'https://fortnite-api.com/images/cosmetics/br/cid_701_athena_commando_m_bananaagent/variants/progressive/stage4.png', + 'cid_116_athena_commando_m_carbideblack': 'https://fortnite-api.com/images/cosmetics/br/cid_116_athena_commando_m_carbideblack/variants/parts/stage1.png', + 'cid_694_athena_commando_m_catburglar': 'https://fortnite-api.com/images/cosmetics/br/cid_694_athena_commando_m_catburglar/variants/progressive/stage4.png', + 'cid_693_athena_commando_m_buffcat': 'https://fortnite-api.com/images/cosmetics/br/cid_693_athena_commando_m_buffcat/variants/progressive/stage4.png', + 'cid_691_athena_commando_f_tntina': 'https://fortnite-api.com/images/cosmetics/br/cid_691_athena_commando_f_tntina/variants/progressive/stage7.png', + 'cid_690_athena_commando_f_photographer': 'https://fortnite-api.com/images/cosmetics/br/cid_690_athena_commando_f_photographer/variants/progressive/stage4.png', +}; + +// Cache the logo so we only fetch once per session +let _logoBuffer = null; +async function getLogoBuffer() { + if (_logoBuffer) return _logoBuffer; + try { + const res = await fetchWithTimeout( + 'https://fortnite-api.com/images/cosmetics/br/cid_028_athena_commando_f/variants/material/mat3.png', + 8000 + ); + if (res.ok) _logoBuffer = Buffer.from(await res.arrayBuffer()); + } catch { _logoBuffer = null; } + return _logoBuffer; +} + +const CACHE_DIR = path.join(__dirname, 'RiftCheckerBot-main', 'cache'); +const RARITY_DIR = path.join(__dirname, 'RiftCheckerBot-main', 'styles', 'rift', 'rarity'); +const ICON_DIR = path.join(__dirname, 'RiftCheckerBot-main', 'cosmetic_icons'); +const fs = require('fs'); + +// Cosmetics that have special OG variant images in local cache +// key = lowercase cosmetic ID, value = local cache filename +const LOCAL_OG_ICONS = { + 'cid_029_athena_commando_f_halloween': 'pink_ghoul.png', // Pink Ghoul + 'cid_030_athena_commando_m_halloween': 'purple_skull.png', // Purple Skull + 'cid_028_athena_commando_f': 'og_rene.png', // Black & Gold Renegade Raider + 'cid_017_athena_commando_m': 'og_aat.png', // OG Aerial Assault Trooper + 'cid_116_athena_commando_m_carbideblack': 'omega_max.png', // Max Omega + 'cid_701_athena_commando_m_bananaagent': 'gold_peely.png', // Gold Agent Peely +}; + +// Remote OG variant URLs for cosmetics not in local cache +const REMOTE_OG_ICONS = { + 'pickaxe_lockjaw': 'https://fortnite-api.com/images/cosmetics/br/pickaxe_lockjaw/variants/particle/particle1.png', + 'glider_id_001': 'https://fortnite-api.com/images/cosmetics/br/glider_id_001/variants/particle/particle1.png', + 'cid_694_athena_commando_m_catburglar': 'https://fortnite-api.com/images/cosmetics/br/cid_694_athena_commando_m_catburglar/variants/progressive/stage4.png', + 'cid_693_athena_commando_m_buffcat': 'https://fortnite-api.com/images/cosmetics/br/cid_693_athena_commando_m_buffcat/variants/progressive/stage4.png', + 'cid_691_athena_commando_f_tntina': 'https://fortnite-api.com/images/cosmetics/br/cid_691_athena_commando_f_tntina/variants/progressive/stage7.png', + 'cid_690_athena_commando_f_photographer': 'https://fortnite-api.com/images/cosmetics/br/cid_690_athena_commando_f_photographer/variants/progressive/stage4.png', +}; + +// Load a rarity background image from local cache +const rarityImageCache = {}; +async function getRarityImage(rarity) { + const key = (rarity || 'common').toLowerCase(); + if (rarityImageCache[key]) return rarityImageCache[key]; + const filePath = path.join(RARITY_DIR, `${key}.png`); + if (fs.existsSync(filePath)) { + try { + const img = await loadImage(fs.readFileSync(filePath)); + rarityImageCache[key] = img; + return img; + } catch { /* fall through */ } + } + // fallback to common + const fallback = path.join(RARITY_DIR, 'common.png'); + if (fs.existsSync(fallback)) { + const img = await loadImage(fs.readFileSync(fallback)); + rarityImageCache['common'] = img; + return img; + } + return null; +} + +// Get cosmetic icon — local cache first, then remote +async function fetchSkinImageBuffer(cosmeticId, useOgStyle = false) { + const id = cosmeticId.toLowerCase(); + + // 1. Try local OG variant if requested + if (useOgStyle && LOCAL_OG_ICONS[id]) { + const localPath = path.join(CACHE_DIR, LOCAL_OG_ICONS[id]); + if (fs.existsSync(localPath)) return fs.readFileSync(localPath); + } + + // 2. Try remote OG variant if requested + if (useOgStyle && REMOTE_OG_ICONS[id]) { + try { + const res = await fetchWithTimeout(REMOTE_OG_ICONS[id], 8000); + if (res.ok) return Buffer.from(await res.arrayBuffer()); + } catch { /* fall through */ } + } + + // 3. Check if this is a banner ID — fetch from banner API + const bannerPrefixes = ['ot', 'influencerbanner', 'foundertier', 'brs', 'survival', 'endurance', 'wargames', 'achievement', 'otherbanner', 'skirmish', 'worldcup', 'horde', 'starlight', 'winter', 'newsletter']; + if (bannerPrefixes.some(p => id.startsWith(p))) { + // Try local RiftCheckerBot cache first + try { + const files = fs.readdirSync(CACHE_DIR); + const match = files.find(f => f.toLowerCase() === id + '.png' || f.toLowerCase() === cosmeticId + '.png'); + if (match) return fs.readFileSync(path.join(CACHE_DIR, match)); + } catch { /* fall through */ } + // Fetch from banner API + try { + const bMeta = await getBannerMeta(); + const iconUrl = bMeta[id]?.icon; + if (iconUrl) { + const res = await fetchWithTimeout(iconUrl, 8000); + if (res.ok) return Buffer.from(await res.arrayBuffer()); + } + } catch { /* fall through */ } + return null; + } + + // 4. Try local cache with exact cosmetic ID match + try { + const files = fs.readdirSync(CACHE_DIR); + const baseName = cosmeticId + '.png'; + const match = files.find(f => f.toLowerCase() === baseName.toLowerCase()); + if (match) return fs.readFileSync(path.join(CACHE_DIR, match)); + } catch { /* fall through */ } + + // 5. Fortnite API CDN + const iconUrl = `https://fortnite-api.com/images/cosmetics/br/${id}/icon.png`; + try { + const res = await fetchWithTimeout(iconUrl, 8000); + if (res.ok) return Buffer.from(await res.arrayBuffer()); + } catch { /* fall through */ } + + // 6. Fallback: smallIcon + const smallUrl = `https://fortnite-api.com/images/cosmetics/br/${id}/smallicon.png`; + try { + const res = await fetchWithTimeout(smallUrl, 8000); + if (res.ok) return Buffer.from(await res.arrayBuffer()); + } catch { /* give up */ } + + return null; +} + +async function renderLockerImage(items, countLabel, subtitle, submittedBy = null, ogStyleOwned = null) { + if (!items || items.length === 0) return null; + + const LOGO_SIZE = HDR_H - 8; + const rows = Math.ceil(items.length / COLS); + const cols = Math.min(items.length, COLS); + const W = Math.max(cols * ICON + PAD * 2, 400); + const H = HDR_H + rows * CELL_H + PAD + FTR_H; + + const canvas = createCanvas(W, H); + const ctx = canvas.getContext('2d'); + + // ── Background ─────────────────────────────────────────────────────────── + if (customBgUrl) { + try { + const res = await fetchWithTimeout(customBgUrl, 10000); + if (res.ok) { + let rawBuf = Buffer.from(await res.arrayBuffer()); + const contentType = res.headers.get('content-type') || ''; + const isGif = customBgUrl.toLowerCase().endsWith('.gif') || contentType.includes('gif'); + // GIF backgrounds are flattened to their first frame for the generated PNG. + const processed = await sharp(rawBuf, isGif ? { pages: 1 } : {}) + .resize(W, H, { fit: 'cover', position: 'centre' }) + .png() + .toBuffer(); + ctx.drawImage(await loadImage(processed), 0, 0, W, H); + ctx.fillStyle = 'rgba(0,0,0,0.55)'; + ctx.fillRect(0, 0, W, H); + } else { throw new Error('bg fetch failed'); } + } catch { + const bg = ctx.createLinearGradient(0, 0, 0, H); + bg.addColorStop(0, '#1c1c28'); bg.addColorStop(1, '#0e0e18'); + ctx.fillStyle = bg; ctx.fillRect(0, 0, W, H); + } + } else { + const bg = ctx.createLinearGradient(0, 0, 0, H); + bg.addColorStop(0, '#1c1c28'); bg.addColorStop(1, '#0e0e18'); + ctx.fillStyle = bg; ctx.fillRect(0, 0, W, H); + } + + // Grid lines + ctx.strokeStyle = 'rgba(255,255,255,0.05)'; ctx.lineWidth = 1; + for (let c = 0; c <= cols; c++) { + ctx.beginPath(); ctx.moveTo(PAD + c * ICON, HDR_H); ctx.lineTo(PAD + c * ICON, HDR_H + rows * CELL_H); ctx.stroke(); + } + for (let r = 0; r <= rows; r++) { + ctx.beginPath(); ctx.moveTo(PAD, HDR_H + r * CELL_H); ctx.lineTo(PAD + cols * ICON, HDR_H + r * CELL_H); ctx.stroke(); + } + + // ── Logo ───────────────────────────────────────────────────────────────── + const logoBuf = await getLogoBuffer(); + let logoEndX = PAD; + if (logoBuf) { + try { + const logoResized = await sharp(logoBuf).resize(LOGO_SIZE, LOGO_SIZE, { fit: 'cover' }).png().toBuffer(); + const logoImg = await loadImage(logoResized); + const cx = PAD + LOGO_SIZE / 2, cy = 4 + LOGO_SIZE / 2, lr = LOGO_SIZE / 2; + ctx.save(); + ctx.beginPath(); ctx.arc(cx, cy, lr, 0, Math.PI * 2); ctx.clip(); + ctx.drawImage(logoImg, PAD, 4, LOGO_SIZE, LOGO_SIZE); + ctx.restore(); + ctx.strokeStyle = '#ffd700'; ctx.lineWidth = 2; + ctx.beginPath(); ctx.arc(cx, cy, lr, 0, Math.PI * 2); ctx.stroke(); + logoEndX = PAD + LOGO_SIZE + 10; + } catch { logoEndX = PAD; } + } + + // ── Header text ─────────────────────────────────────────────────────────── + ctx.fillStyle = '#ffffff'; + ctx.font = 'bold 26px TahomaB'; + ctx.fillText(countLabel, logoEndX, 40); + ctx.fillStyle = '#aaaaaa'; + ctx.font = '13px Tahoma'; + ctx.fillText(subtitle.toUpperCase(), logoEndX, 60); + + // ── Cosmetic grid ───────────────────────────────────────────────────────── + let idx = 0; + for (const item of items) { + const col = idx % COLS; + const row = Math.floor(idx / COLS); + const x = PAD + col * ICON; + const y = HDR_H + row * CELL_H; + const id = item.id.toLowerCase(); + + // Determine if we should show OG style for this item + const hasOgRequirement = !!OG_STYLE_REQUIREMENTS[id]; + const ownsOgStyle = ogStyleOwned ? ogStyleOwned.has(id) : false; + const useOg = hasOgRequirement && ownsOgStyle; + + // Effective rarity: mythic if OG style owned, otherwise use metaMap rarity + const effectiveRarity = useOg ? 'mythic' : (item.rarity || 'common'); + + // ── Draw rarity background from local cache ─────────────────────────── + const rarityFilePath = path.join(RARITY_DIR, `${effectiveRarity}.png`); + if (fs.existsSync(rarityFilePath)) { + try { + const rarBuf = await sharp(fs.readFileSync(rarityFilePath)) + .resize(ICON, ICON, { fit: 'fill' }).png().toBuffer(); + ctx.drawImage(await loadImage(rarBuf), x, y, ICON, ICON); + } catch { /* skip */ } + } else { + ctx.fillStyle = (RC[effectiveRarity] || RC.common) + '28'; + ctx.fillRect(x, y, ICON, ICON); + } + + // ── Gradient border around the cell ────────────────────────────────── + const borderColor = RC[effectiveRarity] || RC.common; + // Top edge gradient (left to right) + const topGrad = ctx.createLinearGradient(x, y, x + ICON, y); + topGrad.addColorStop(0, borderColor + '00'); + topGrad.addColorStop(0.3, borderColor + 'ff'); + topGrad.addColorStop(0.7, borderColor + 'ff'); + topGrad.addColorStop(1, borderColor + '00'); + ctx.strokeStyle = topGrad; ctx.lineWidth = 2; + ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + ICON, y); ctx.stroke(); + + // Bottom edge gradient + const botGrad = ctx.createLinearGradient(x, y + ICON, x + ICON, y + ICON); + botGrad.addColorStop(0, borderColor + '00'); + botGrad.addColorStop(0.3, borderColor + 'ff'); + botGrad.addColorStop(0.7, borderColor + 'ff'); + botGrad.addColorStop(1, borderColor + '00'); + ctx.strokeStyle = botGrad; + ctx.beginPath(); ctx.moveTo(x, y + ICON); ctx.lineTo(x + ICON, y + ICON); ctx.stroke(); + + // Left edge gradient (top to bottom) + const leftGrad = ctx.createLinearGradient(x, y, x, y + ICON); + leftGrad.addColorStop(0, borderColor + '00'); + leftGrad.addColorStop(0.3, borderColor + 'ff'); + leftGrad.addColorStop(0.7, borderColor + 'ff'); + leftGrad.addColorStop(1, borderColor + '00'); + ctx.strokeStyle = leftGrad; + ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x, y + ICON); ctx.stroke(); + + // Right edge gradient + const rightGrad = ctx.createLinearGradient(x + ICON, y, x + ICON, y + ICON); + rightGrad.addColorStop(0, borderColor + '00'); + rightGrad.addColorStop(0.3, borderColor + 'ff'); + rightGrad.addColorStop(0.7, borderColor + 'ff'); + rightGrad.addColorStop(1, borderColor + '00'); + ctx.strokeStyle = rightGrad; + ctx.beginPath(); ctx.moveTo(x + ICON, y); ctx.lineTo(x + ICON, y + ICON); ctx.stroke(); + + // ── Draw cosmetic icon ──────────────────────────────────────────────── + const buf = await fetchSkinImageBuffer(item.id, useOg); + if (buf) { + try { + const resized = await sharp(buf).resize(ICON - 6, ICON - 6, { fit: 'cover' }).png().toBuffer(); + ctx.drawImage(await loadImage(resized), x + 3, y + 3, ICON - 6, ICON - 6); + } catch { /* skip */ } + } + + // ── Name label ──────────────────────────────────────────────────────── + ctx.fillStyle = '#ffffff'; + ctx.font = '10px Tahoma'; + ctx.textAlign = 'center'; + const maxW = ICON - 4; + let name = item.name || ''; + while (name.length > 3 && ctx.measureText(name).width > maxW) name = name.slice(0, -1); + if (name !== item.name) name = name.slice(0, -1) + '..'; + ctx.fillText(name, x + ICON / 2, y + ICON + 17, maxW); + ctx.textAlign = 'left'; + idx++; + } + + // ── Footer ──────────────────────────────────────────────────────────────── + const footerY = H - FTR_H; + ctx.fillStyle = 'rgba(0,0,0,0.6)'; + ctx.fillRect(0, footerY, W, FTR_H); + ctx.strokeStyle = '#ffd700'; ctx.lineWidth = 1; + ctx.beginPath(); ctx.moveTo(0, footerY); ctx.lineTo(W, footerY); ctx.stroke(); + + ctx.fillStyle = '#ffffff'; + ctx.font = 'bold 11px TahomaB'; + ctx.fillText(submittedBy ? `Submitted by: ${submittedBy}` : 'Made by jitterbuxg', PAD, footerY + 14); + ctx.fillStyle = '#ffd700'; + ctx.font = '10px Tahoma'; + ctx.fillText('.gg/collecting', PAD, footerY + 28); + + ctx.fillStyle = '#888888'; + ctx.font = '10px Tahoma'; + ctx.textAlign = 'right'; + ctx.fillText(new Date().toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }), W - PAD, footerY + 21); + ctx.textAlign = 'left'; + + return canvas.toBuffer('image/png'); +} + +async function sendLockerImageEmbed(message, { title, description, imageBuffer, fileName }) { + const attachment = new AttachmentBuilder(imageBuffer, { name: fileName }); + const safeTitle = String(title || 'Locker Check').length > 250 + ? `${String(title).slice(0, 247)}...` + : String(title || 'Locker Check'); + const embed = new EmbedBuilder() + .setColor(0xFFD700) + .setTitle(safeTitle) + .setDescription(description) + .setImage(`attachment://${fileName}`) + .setTimestamp(); + + await message.author.send({ embeds: [embed], files: [attachment] }); +} + +// Banner metadata cache — fetched once from fortnite-api.com/v1/banners +let bannerMetaCache = null; +async function getBannerMeta() { + if (bannerMetaCache) return bannerMetaCache; + try { + const res = await fetchWithTimeout('https://fortnite-api.com/v1/banners', 10000); + if (res.ok) { + const json = await res.json(); + const map = {}; + for (const b of (json.data || [])) { + map[b.id.toLowerCase()] = { + name: b.devName || b.id, + icon: b.images?.icon || b.images?.smallIcon, + rarity: 'common', + }; + } + bannerMetaCache = map; + return map; + } + } catch { /* ignore */ } + return {}; +} + +const BASE_EXCLUSIVE_BANNER_IDS = [ + // OT Banners + 'ot1banner', 'ot2banner', 'ot3banner', 'ot4banner', 'ot5banner', + 'ot6banner', 'ot7banner', 'ot8banner', 'ot9banner', 'ot10banner', 'ot11banner', + // Alpha tester / rare + 'otherbanner51', + // World Cup / FNCS / Skirmish + 'brworldcup2019', 'brs9worldcup2019', 'brs23_fncs_drops', 's11fncs', + 'brskirmishbushbandits', 'brskirmishdustydogs', 'brskirmishfortknights', + 'brskirmishluckyllamas', 'brskirmishriftraiders', + // Season level 100 + 'brs8level100', 'brs9lvl100', 'brs10level100', +]; + +function looksLikeBannerId(rawId) { + const id = String(rawId || '').trim().toLowerCase(); + if (!id) return false; + return ( + id.includes('banner') || + id.startsWith('ot') || + id.startsWith('brs') || + id.startsWith('brseason') || + id.startsWith('brworldcup') || + id.startsWith('brskirmish') || + id.startsWith('endurance') || + id.startsWith('wargames') || + id.startsWith('survival') || + id.startsWith('achievement') || + id.startsWith('starlight') || + id.startsWith('winter2018') || + id.startsWith('newsletter') || + id.startsWith('horde') + ); +} + +function getExclusiveBannerIds() { + const ids = new Set(BASE_EXCLUSIVE_BANNER_IDS); + for (const req of ROLE_REQUIREMENTS) { + if (req.bannerId) ids.add(req.bannerId.toLowerCase()); + } + + return ids; +} + +function normalizeLooseName(value) { + return String(value || '') + .toLowerCase() + .normalize('NFKD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[^a-z0-9]+/g, ''); +} + +function readMasterListBannerNames() { + const names = new Set(); + const listPaths = [ + path.join(__dirname, 'Fortnite_Master_Exclusive_List.txt'), + path.join(__dirname, 'RiftCheckerBot-main', 'Fortnite_Master_Exclusive_List.txt'), + ]; + + for (const listPath of listPaths) { + try { + const text = fs.readFileSync(listPath, 'utf8'); + const entryMatches = text.matchAll(/-\s*([^-\r\n=]*?\bBanner)\b/g); + for (const match of entryMatches) { + const clean = match[1].replace(/^Missing\s+/i, '').trim(); + const normalized = normalizeLooseName(clean); + if ( + normalized && + normalized !== 'banner' && + normalized !== 'banners' && + normalized !== 'missingbanner' && + !normalized.includes('manysearch') && + !normalized.includes('founderspickaxes') + ) { + names.add(normalized); + } + } + if (/Founder.s Banners/i.test(text)) names.add(normalizeLooseName("Founder's Banner")); + } catch { /* list is optional */ } + } + + return names; +} + +function addMasterListBannerIds(ids, bannerMeta = {}) { + const wantedNames = readMasterListBannerNames(); + if (wantedNames.size === 0) return ids; + + for (const [id, info] of Object.entries(bannerMeta || {})) { + const normalizedName = normalizeLooseName(info?.name || id); + if (!normalizedName) continue; + for (const wanted of wantedNames) { + if (normalizedName === wanted || normalizedName.includes(wanted)) { + ids.add(id.toLowerCase()); + } + } + } + + return ids; +} + +function getOwnedBannerIdsFromCommonCore(ccItems) { + const owned = new Set(); + for (const item of Object.values(ccItems || {})) { + const candidates = [ + item.templateId, + item.attributes?.banner_id, + item.attributes?.bannerId, + item.attributes?.banner_icon, + item.attributes?.bannerIcon, + ]; + + for (const raw of candidates) { + const value = String(raw || '').toLowerCase(); + if (!value) continue; + const id = value.includes(':') ? value.split(':').pop() : value; + if (looksLikeBannerId(id) || value.includes('homebasebannericon') || value.includes('bannertoken')) { + owned.add(id); + } + } + } + return owned; +} + +function commonCoreOwnsId(ccItems, wantedId) { + const needle = wantedId.toLowerCase(); + if (getOwnedBannerIdsFromCommonCore(ccItems).has(needle)) return true; + return Object.values(ccItems || {}).some(item => { + const templateId = (item.templateId || '').toLowerCase(); + const itemId = templateId.split(':').pop(); + return itemId === needle || templateId.includes(needle); + }); +} + +function collectOwnedExclusiveBannerItems(ccItems, bannerMeta, metaMap = null) { + const items = []; + const seen = new Set(); + const bannerIds = addMasterListBannerIds(getExclusiveBannerIds(), bannerMeta); + const ownedBannerIds = getOwnedBannerIdsFromCommonCore(ccItems); + + for (const id of bannerIds) { + if (seen.has(id) || (!ownedBannerIds.has(id) && !commonCoreOwnsId(ccItems, id))) continue; + seen.add(id); + + const info = bannerMeta[id] || {}; + const name = info.name || id; + items.push({ id, name, rarity: 'mythic' }); + if (metaMap) metaMap[id] = { name, rarity: 'mythic' }; + } + + return items; +} + +// Batch fetch cosmetic metadata (name + rarity) for up to 50 IDs at once +async function fetchCosmeticMeta(ids) { + const map = {}; + if (!ids || ids.length === 0) return map; + for (let i = 0; i < ids.length; i += 50) { + const chunk = ids.slice(i, i + 50); + try { + const qs = chunk.map(id => `id=${encodeURIComponent(id)}`).join('&'); + const res = await fetchWithTimeout(`https://fortnite-api.com/v2/cosmetics/br/search/ids?language=en&${qs}`, 10000); + if (!res.ok) continue; + const json = await res.json(); + for (const item of (json.data || [])) { + map[item.id.toLowerCase()] = { name: item.name, rarity: item.rarity?.value || 'common' }; + } + } catch { /* skip chunk on error */ } + } + return map; +} + +// Cosmetics that have OG style requirements - id -> one or more owned style tags +const OG_STYLE_REQUIREMENTS = { + 'cid_029_athena_commando_f_halloween': ['Mat3', 'Material.Mat3'], // Pink Ghoul + 'cid_030_athena_commando_m_halloween': ['Mat1', 'ClothingColor.Mat1'], // Purple Skull + 'cid_028_athena_commando_f': ['Mat3', 'Material.Mat3'], // Black & Gold Renegade Raider + 'cid_017_athena_commando_m': ['Stage2', 'Progressive.Stage2'], // OG Aerial Assault Trooper + 'cid_116_athena_commando_m_carbideblack': ['Stage5', 'Progressive.Stage5'], // Max Omega + 'cid_701_athena_commando_m_bananaagent': ['Stage4', 'Progressive.Stage4'], // Gold Agent Peely + 'pickaxe_lockjaw': ['Stage2', 'Particle1', 'Particle.Particle1'], // Black & Gold Raider's Revenge + 'glider_id_001': ['Stage2', 'Particle.Particle1', 'Particle1'], // OG Aerial Assault One +}; + +function requiredStyleTags(reqOrTags) { + if (!reqOrTags) return []; + if (Array.isArray(reqOrTags)) return reqOrTags; + if (Array.isArray(reqOrTags.styleTags)) return reqOrTags.styleTags; + return reqOrTags.styleTag ? [reqOrTags.styleTag] : []; +} + +function ownsAnyStyleTag(ownedStyleSet, tags) { + const wanted = requiredStyleTags(tags).map(tag => String(tag).toLowerCase()); + if (wanted.length === 0) return true; + if (!ownedStyleSet) return false; + const normalizeTag = tag => String(tag || '').toLowerCase().replace(/[^a-z0-9]/g, ''); + const wantedNorm = wanted.map(normalizeTag); + const owned = [...ownedStyleSet].map(tag => String(tag).toLowerCase()); + const ownedNorm = owned.map(normalizeTag); + return wanted.some((tag, idx) => { + const normalized = wantedNorm[idx]; + return owned.some(ownedTag => ownedTag === tag || ownedTag.endsWith(`.${tag}`)) || + ownedNorm.some(ownedTag => ownedTag === normalized || ownedTag.endsWith(normalized)); + }); +} + +function qualifiesForRequirement(req, ownedMap) { + const id = req.id.toLowerCase(); + if (!ownedMap[id]) return false; + return ownsAnyStyleTag(ownedMap[id], req); +} + +function uniqueIds(ids) { + return [...new Set(ids.filter(Boolean))]; +} + +function addStyleTags(targetSet, value) { + if (!value) return; + if (Array.isArray(value)) { + for (const tag of value) addStyleTags(targetSet, tag); + return; + } + targetSet.add(String(value)); +} + +function buildOwnedMap(athenaData) { + const owned = {}; // id -> Set of owned style tags + const ogStyleOwned = new Set(); + const outfits = []; + const pickaxes = []; + const emotes = []; + const emoticons = []; // AthenaEmoji type (in-game emoticons, NOT emotes) + const backblings = []; + const gliders = []; + const sprays = []; + const items = athenaData?.profileChanges?.[0]?.profile?.items || {}; + for (const item of Object.values(items)) { + const tpl = (item.templateId || '').toLowerCase(); + if (!tpl.startsWith('athena') && !tpl.startsWith('character')) continue; + const id = tpl.split(':')[1] || ''; + if (!owned[id]) owned[id] = new Set(); + for (const v of (item.attributes?.variants || [])) { + addStyleTags(owned[id], v.owned); + addStyleTags(owned[id], v.active); + } + + if (tpl.startsWith('athenacharacter:') || tpl.startsWith('character:')) outfits.push(id); + else if (tpl.startsWith('athenapickaxe:')) pickaxes.push(id); + else if (tpl.startsWith('athenadance:')) { + if (id.startsWith('spray') || id.startsWith('spid_')) sprays.push(id); + else emotes.push(id); + } + else if (tpl.startsWith('athenaemoji:')) emoticons.push(id); + else if (tpl.startsWith('athenabackpack:')) backblings.push(id); + else if (tpl.startsWith('athenaglider:')) gliders.push(id); + else if (tpl.startsWith('athenasprays:') || tpl.startsWith('athenaspray:')) sprays.push(id); + } + // Populate ogStyleOwned after all variants are collected + for (const id of Object.keys(owned)) { + if (OG_STYLE_REQUIREMENTS[id] && ownsAnyStyleTag(owned[id], OG_STYLE_REQUIREMENTS[id])) { + ogStyleOwned.add(id); + } + } + return { + owned, + ogStyleOwned, + outfits: uniqueIds(outfits), + pickaxes: uniqueIds(pickaxes), + emotes: uniqueIds(emotes), + emoticons: uniqueIds(emoticons), + backblings: uniqueIds(backblings), + gliders: uniqueIds(gliders), + sprays: uniqueIds(sprays), + }; +} + +function getRolesForLocker(ownedMap, ccItems) { + const earned = []; + for (const req of ROLE_REQUIREMENTS) { + if (req.bannerId) { + const has = Object.values(ccItems).some(i => + (i.templateId || '').toLowerCase().includes(req.bannerId.toLowerCase()) + ); + if (has) earned.push(req.role); + continue; + } + if (req.stw) { + const ccIds = Object.values(ccItems).map(i => (i.templateId || '').toLowerCase()); + if (ccIds.some(cc => cc.includes(req.id.toLowerCase()))) earned.push(req.role); + continue; + } + if (qualifiesForRequirement(req, ownedMap)) earned.push(req.role); + } + const ccIds = Object.values(ccItems).map(i => (i.templateId || '').toLowerCase()); + const hasFounder = ccIds.some(cc => cc.includes('founder')); + const hasUltimate = ccIds.some(cc => cc.includes('tiertoken_collectionbook_ultimate')); + if (hasUltimate) { earned.push('Ultimate STW Founders'); earned.push('STW Founders'); } + else if (hasFounder) earned.push('STW Founders'); + return [...new Set(earned)]; +} + +// ───────────────────────────────────────────────────────────────────────────── +// BOT READY +// ───────────────────────────────────────────────────────────────────────────── +client.once('ready', async () => { + console.log(`✅ Logged in as ${client.user.tag}`); + console.log('Commands: !setuproles | !addicons | !skipemoji | !stopemojis | !setroleicons | !removeoldemojis | !verify'); + + // Set bot avatar to Renegade Raider Black & Gold style + try { + const imgRes = await fetch('https://fortnite-api.com/images/cosmetics/br/cid_028_athena_commando_f/variants/material/mat3.png'); + const imgBuf = Buffer.from(await imgRes.arrayBuffer()); + await client.user.setAvatar(imgBuf); + console.log('✅ Bot avatar set to Renegade Raider Black & Gold.'); + } catch (err) { + console.warn('Could not set avatar (may already be set or rate limited):', err.message); + } + + // Register /commands slash command to guild for instant availability + const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); + const slashCommands = [ + new SlashCommandBuilder() + .setName('commands') + .setDescription('List all bot commands') + .toJSON(), + ]; + try { + await rest.put(Routes.applicationGuildCommands(client.user.id, process.env.EMOJI_GUILD_ID), { body: slashCommands }); + console.log('✅ Slash commands registered to guild.'); + } catch (err) { + console.error('Failed to register slash commands:', err.message); + } +}); + +// ───────────────────────────────────────────────────────────────────────────── +// /commands slash command +// ───────────────────────────────────────────────────────────────────────────── +client.on('interactionCreate', async (interaction) => { + if (!interaction.isChatInputCommand() || interaction.commandName !== 'commands') return; + + const embed = new EmbedBuilder() + .setColor(0x1a1a2e) + .setAuthor({ + name: 'jitterbuxg', + iconURL: 'https://fortnite-api.com/images/cosmetics/br/cid_028_athena_commando_f/variants/material/mat3.png', + }) + .setTitle('Bot Commands') + .setThumbnail('https://fortnite-api.com/images/cosmetics/br/pickaxe_lockjaw/variants/particle/particle1.png') + .addFields( + { + name: 'Admin Setup', + value: [ + '`!setuproles` — Create all Fortnite roles', + '`!addicons` — Upload skin icons as server emojis', + '`!setroleicons` — Apply emojis as role icons', + '`!removeoldemojis` — Wipe all emojis for a fresh upload', + '`!setbg ` — Set custom background (supports GIFs)', + '`!clearbg` — Reset to default background', + ].join('\n'), + inline: false, + }, + { + name: 'During !addicons', + value: '`!skipemoji` — Skip current · `!stopemojis` — Cancel session', + inline: false, + }, + { + name: 'Verification', + value: '`!verify` — Link your Epic account and auto-assign roles based on your locker', + inline: false, + }, + { + name: 'What !verify checks', + value: [ + '**OG Skins** — Renegade Raider (B&G), Ghoul Trooper (Pink), Skull Trooper (Purple), + more', + '**Exclusives** — Galaxy, Ikonik, Glow, Honor Guard, Double Helix, Wildcat, + more', + '**Pickaxes** — Raider\'s Revenge (B&G), Axe of Champions, AC/DC, + more', + '**Emotes** — Fresh, Floss, Take the L, Orange Justice, + more', + '**Banners** — OT1–OT11, Creator Banners, STW Founders, + more', + ].join('\n'), + inline: false, + } + ) + .setImage('https://fortnite-api.com/images/cosmetics/br/pickaxe_lockjaw/variants/particle/particle1.png') + .setFooter({ text: 'Made by jitterbuxg • .gg/collecting' }) + .setTimestamp(); + + await interaction.reply({ embeds: [embed], ephemeral: false }); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !setbg / !clearbg — custom background for skin checker images +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot) return; + if (message.content.startsWith('!setbg ')) { + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + const url = message.content.slice(7).trim(); + if (!url.startsWith('http')) return message.reply('Please provide a valid image URL.'); + customBgUrl = url; + return message.reply(`Background set. All future skin checker images will use this background.`); + } + if (message.content === '!clearbg') { + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + customBgUrl = null; + return message.reply('Background cleared. Back to default dark gradient.'); + } +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !setuproles +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!setuproles') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + await message.reply(`Creating up to ${roles.length} roles...`); + let created = 0, skipped = 0; + const existing = message.guild.roles.cache.map(r => r.name.toLowerCase()); + + for (const role of roles) { + if (existing.includes(role.name.toLowerCase())) { skipped++; continue; } + try { + await message.guild.roles.create({ name: role.name, color: role.color, reason: 'Bulk role setup' }); + console.log(`Created: ${role.name}`); + created++; + await new Promise(r => setTimeout(r, 300)); + } catch (err) { + console.error(`Failed "${role.name}": ${err.message}`); + } + } + message.channel.send(`Done! Created **${created}** roles, skipped **${skipped}** existing.`); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !removeoldemojis +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!removeoldemojis') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + const emojiGuild = await client.guilds.fetch(process.env.EMOJI_GUILD_ID).catch(() => null); + if (!emojiGuild) return message.reply('Could not find the emoji server. Check EMOJI_GUILD_ID in .env'); + + await message.reply(`Removing ALL emojis from **${emojiGuild.name}**...`); + console.log(`🎯 Clearing all emojis from: ${emojiGuild.name} (${emojiGuild.id})`); + await emojiGuild.emojis.fetch(); + + const allEmojis = [...emojiGuild.emojis.cache.values()]; + console.log(`📋 Found ${allEmojis.length} emojis to delete`); + let removed = 0; + + for (const emoji of allEmojis) { + try { + await emoji.delete('Clearing all emojis for fresh upload'); + console.log(`🗑 Deleted: ${emoji.name}`); + removed++; + await new Promise(r => setTimeout(r, 400)); + } catch (err) { + console.error(`Failed to delete ${emoji.name}: ${err.message}`); + } + } + message.channel.send(`Removed **${removed}** emojis from **${emojiGuild.name}**. Run !addicons to re-upload.`); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !addicons + !skipemoji + !stopemojis +// ───────────────────────────────────────────────────────────────────────────── + +// Shared state for the active addicons session +let emojiSession = null; // { resolve, name, channel } + +// !skipemoji — skip the currently stuck emoji +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!skipemoji') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) return; + if (!emojiSession) return message.reply('No emoji upload is currently in progress.'); + message.reply(`Skipping **${emojiSession.name}**...`); + emojiSession.resolve('skip'); +}); + +// !stopemojis — stop the whole session +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!stopemojis') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) return; + if (!emojiSession) return message.reply('No emoji upload is currently in progress.'); + message.reply('Stopping emoji upload session.'); + emojiSession.resolve('stop'); +}); + +// Lock to prevent !addicons running multiple times simultaneously +let addIconsRunning = false; + +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!addicons') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + if (addIconsRunning) + return message.reply('An emoji upload is already in progress. Wait for it to finish or use `!stopemojis` to cancel.'); + + const emojiGuild = await client.guilds.fetch(process.env.EMOJI_GUILD_ID).catch(() => null); + if (!emojiGuild) return message.reply('Could not find the emoji server. Check EMOJI_GUILD_ID in .env'); + + await message.reply(`Uploading ${roleIconMap.length} skin icons to **${emojiGuild.name}**.\nType \`!skipemoji\` to skip a stuck one, or \`!stopemojis\` to cancel.`); + await emojiGuild.emojis.fetch(); + const existing = new Set(emojiGuild.emojis.cache.map(e => e.name.toLowerCase())); + let added = 0, skipped = 0, failed = 0; + + for (const entry of roleIconMap) { + if (existing.has(entry.emoji.toLowerCase())) { + console.log(`⏭ Exists: ${entry.emoji}`); + skipped++; + continue; + } + + // Set up skip/stop listener for this entry + let sessionResolve; + const skipPromise = new Promise(res => { sessionResolve = res; }); + emojiSession = { resolve: sessionResolve, name: entry.name, channel: message.channel }; + + process.stdout.write(`📥 ${entry.name} — fetching... `); + try { + const iconUrl = entry.overrideUrl || entry.bannerUrl || await fetchIconUrl(entry.id); + process.stdout.write(`processing... `); + const buffer = await downloadAndProcess(iconUrl); + process.stdout.write(`uploading... `); + + // Race the upload against a skip/stop signal + const result = await Promise.race([ + createEmojiSafe(emojiGuild, buffer, entry.emoji, `Skin icon: ${entry.name}`) + .then(() => 'done'), + skipPromise, + ]); + + if (result === 'stop') { + console.log('🛑 Stopped by user.'); + emojiSession = null; + return message.channel.send(`Stopped. Added **${added}**, skipped **${skipped}**, failed **${failed}**.`); + } + if (result === 'skip') { + console.log(`⏭ Skipped: ${entry.name}`); + skipped++; + emojiSession = null; + continue; + } + + console.log(`✅`); + added++; + } catch (err) { + console.log(`❌ ${err.message}`); + failed++; + } + + emojiSession = null; + await new Promise(r => setTimeout(r, 2000)); + } + + emojiSession = null; + message.channel.send(`Done. Added **${added}** emojis to **${emojiGuild.name}**. Skipped **${skipped}**. Failed **${failed}**.`); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !setroleicons +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!setroleicons') return; + if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) + return message.reply('Need Administrator permission.'); + + const emojiGuild = await client.guilds.fetch(process.env.EMOJI_GUILD_ID).catch(() => null); + if (!emojiGuild) return message.reply('Could not find the emoji server. Check EMOJI_GUILD_ID in .env'); + + await message.reply('Applying emojis to roles...'); + await emojiGuild.emojis.fetch(); + await message.guild.roles.fetch(); + let updated = 0, skipped = 0, failed = 0; + + for (const entry of roleIconMap) { + const role = message.guild.roles.cache.find(r => r.name.toLowerCase() === entry.name.toLowerCase()); + const emoji = emojiGuild.emojis.cache.find(e => e.name.toLowerCase() === entry.emoji.toLowerCase()); + if (!role) { console.log(`⏭ Role not found: ${entry.name}`); skipped++; continue; } + if (!emoji) { console.log(`⚠ Emoji missing: ${entry.emoji} — run !addicons first`); skipped++; continue; } + try { + await role.setIcon(emoji); + console.log(`✅ ${entry.name} → :${entry.emoji}:`); + updated++; + } catch (err) { + console.error(`❌ "${entry.name}": ${err.message}`); + failed++; + } + await new Promise(r => setTimeout(r, 500)); + } + message.channel.send(`Done. Applied icons to **${updated}** roles. Skipped **${skipped}**. Failed **${failed}**.`); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !unverify — remove verification and strip roles +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!unverify') return; + + const userId = message.author.id; + + if (!verifiedUsers.has(userId)) + return message.reply('You are not currently verified. Use `!verify` to link your account.'); + + const prev = verifiedUsers.get(userId); + const guild = client.guilds.cache.get(prev.guildId) || message.guild; + + if (guild) { + try { + const member = await guild.members.fetch(userId).catch(() => null); + if (member) { + for (const roleName of prev.assignedRoles) { + const role = guild.roles.cache.find(r => r.name.toLowerCase() === roleName.toLowerCase()); + if (role && member.roles.cache.has(role.id)) { + await member.roles.remove(role, 'User unverified').catch(() => null); + } + } + } + } catch (err) { + console.error('Unverify role removal error:', err.message); + } + } + + verifiedUsers.delete(userId); + message.reply(`Your verification as **${prev.epicName}** has been removed and your roles have been stripped. You can now use \`!verify\` to link a different account.`); +}); + +// ───────────────────────────────────────────────────────────────────────────── +// !verify +// ───────────────────────────────────────────────────────────────────────────── +client.on('messageCreate', async (message) => { + if (message.author.bot || message.content !== '!verify') return; + + const userId = message.author.id; + + // Support DMs — if in DM, we need to find the guild separately + let guild = message.guild; + if (!guild) { + // Try to find the main guild from EMOJI_GUILD_ID + guild = client.guilds.cache.get(process.env.EMOJI_GUILD_ID) || client.guilds.cache.first(); + if (!guild) return message.reply('Could not find the server. Please use !verify in the server.'); + } + + // Block if already verified + if (verifiedUsers.has(userId)) { + const prev = verifiedUsers.get(userId); + return message.reply(`You are already verified as **${prev.epicName}**. Use \`!unverify\` to unlink your account and verify a different one.`); + } + + if (pending.has(userId)) + return message.reply('you already have a verification in progress! please check your dms.'); + + await message.reply('<:check:1481811973447356496> a login link has been sent to your dms!'); + + await message.reply({ + content: null, embeds: [{ + color: 0x8aa2b3, + author: { + name: message.author.username, + icon_url: message.author.displayAvatarURL(), + }, + description: `<:no:1481811955592466492> successfully deleted ${deletedMessages.size - 1} messages!`, + footer: { + text: `twitter @ ${message.guild.name}`, + icon_url: client.user.displayAvatarURL(), + }, + timestamp: new Date(), + }], + }); + + try { + const switchToken = await getSwitchAccessToken(); + const deviceData = await createDeviceCode(switchToken); + if (!deviceData.user_code || !deviceData.device_code) + return message.author.send('failed to generate a login link! please try again later.'); + + const loginUrl = `https://www.epicgames.com/activate?userCode=${deviceData.user_code}`; + + const embed = new EmbedBuilder() + .setColor(0x5865F2) + .setDescription( + `**[click here to verify!](${loginUrl})**\n\n` + + `code: \`${deviceData.user_code}\`\n\n` + + `expires in **5 minutes**. the bot will check your locker and assign your roles automatically!` + ) + .setFooter({ text: `1-800 @ ${message.guild.name}`, icon_url: client.user.displayAvatarURL() }); + + await message.author.send({ embeds: [embed] }); + pending.set(userId, { guildId: guild.id, channelId: message.channel.id }); + + const tokenData = await waitForLogin(deviceData.device_code); + pending.delete(userId); + + if (!tokenData) + return message.author.send('Login expired. Use !verify to try again.'); + + const iosData = await exchangeForIosToken(tokenData.access_token); + if (!iosData.access_token) + return message.author.send('Authentication failed. Please try again.'); + + const { account_id: accountId, displayName = 'Unknown', access_token: accessToken } = iosData; + await message.author.send(`Logged in as **${displayName}**. Fetching locker...`); + + const [athenaData, commonCoreData] = await Promise.all([ + getProfile(accountId, accessToken, 'athena'), + getProfile(accountId, accessToken, 'common_core'), + ]); + + if (!athenaData?.profileChanges) + return message.author.send('Failed to read your locker. Please try again.'); + + const { owned: ownedMap, ogStyleOwned, outfits, pickaxes, emotes, emoticons, backblings, gliders, sprays } = buildOwnedMap(athenaData); + const ccItems = commonCoreData?.profileChanges?.[0]?.profile?.items || {}; + const earnedRoles = getRolesForLocker(ownedMap, ccItems); + + const member = await guild.members.fetch(userId).catch(() => null); + if (!member) + return message.author.send('Could not find you in the server. Make sure you are still a member.'); + + const assigned = [], notFound = []; + for (const roleName of earnedRoles) { + const role = guild.roles.cache.find(r => r.name.toLowerCase() === roleName.toLowerCase()); + if (!role) { notFound.push(roleName); continue; } + if (!member.roles.cache.has(role.id)) + await member.roles.add(role, 'Fortnite locker verification').catch(() => null); + assigned.push(roleName); + } + + // Store verified state so they can't re-verify without !unverify + verifiedUsers.set(userId, { guildId: guild.id, assignedRoles: assigned, epicName: displayName }); + + const verifyEmbed = new EmbedBuilder() + .setColor(0x2B2D31) + .setTitle(`${displayName}'s Verification`) + .setDescription( + assigned.length === 0 + ? 'No exclusive roles found.' + : assigned.map(r => `— ${r}`).join('\n') + ) + .addFields( + { name: 'Total Outfits', value: String(outfits.length), inline: true }, + { name: 'Total Pickaxes', value: String(pickaxes.length), inline: true }, + ) + .setFooter({ text: 'Made by jitterbuxg' }); + + await message.author.send({ embeds: [verifyEmbed] }); + + // Send verification log to designated channel + try { + const logChannel = await client.channels.fetch(LOG_CHANNEL_ID).catch(() => null); + if (logChannel) { + // Fetch server emojis to use next to role names + const emojiGuild = await client.guilds.fetch(process.env.EMOJI_GUILD_ID).catch(() => null); + await emojiGuild?.emojis.fetch().catch(() => null); + + const getServerEmoji = (roleName) => { + if (!emojiGuild) return ''; + // Map role names to emoji names we uploaded + const emojiNameMap = { + 'Galaxy': 'Galaxy', 'Ikonik': 'Ikonik', 'Glow': 'Glow', + 'OG Renegade Raider': 'RenegadeRaider', 'OG Ghoul Trooper': 'GhoulTrooper', + 'OG Skull Trooper': 'SkullTrooper', 'OG Aerial Assault Trooper': 'AerialAssaultTrooper', + 'Black Knight': 'BlackKnight', 'Double Helix': 'DoubleHelix', + 'Honor Guard': 'HonorGuard', 'Wonder': 'Wonder', 'Eon': 'Eon', + 'Dark Vertex': 'DarkVertex', 'Neo Versa': 'NeoVersa', + 'Royale Bomber': 'RoyaleBomber', 'Wildcat': 'Wildcat', + 'Stealth Reflex': 'StealthReflex', 'Reflex': 'Reflex', + "Raider's Revenge": 'RaidersRevenge', 'Stellar Axe': 'StellarAxe', + 'AC/DC': 'ACDC', 'Merry Mint Axe': 'MerryMintAxe', + 'Axe of Champions': 'AxeOfChampions', 'Blade of Champions': 'BladeOfChampions', + 'Fully Golden Peely': 'FullyGoldenPeely', + }; + const emojiName = emojiNameMap[roleName]; + if (!emojiName) return ''; + const emoji = emojiGuild.emojis.cache.find(e => e.name.toLowerCase() === emojiName.toLowerCase()); + return emoji ? `${emoji} ` : ''; + }; + + const logEmbed = new EmbedBuilder() + .setColor(assigned.length > 0 ? 0xFFD700 : 0x444444) + .setAuthor({ + name: displayName, + iconURL: 'https://fortnite-api.com/images/cosmetics/br/cid_028_athena_commando_f/variants/material/mat3.png', + }) + .setTitle('Account Verified') + .setDescription( + assigned.length === 0 + ? 'No exclusive cosmetics found on this account.' + : assigned.map(r => `${getServerEmoji(r)}${r}`).join('\n') + ) + .addFields( + { name: 'Discord', value: message.author.username, inline: true }, + { name: 'Epic Account', value: displayName, inline: true }, + { name: 'Roles Given', value: String(assigned.length), inline: true }, + ) + .setFooter({ text: '.gg/collecting • Made by jitterbuxg' }) + .setTimestamp(); + await logChannel.send({ embeds: [logEmbed] }); + } + } catch (err) { + console.error('Log channel error:', err.message); + } + + // ── 1. Fetch metadata for all owned cosmetics ───────────────────────── + const allIds = [...outfits, ...pickaxes]; + const metaMap = await fetchCosmeticMeta(allIds); + + // Override rarity to mythic for known exclusives + for (const req of ROLE_REQUIREMENTS) { + if (!req.bannerId) { + const id = req.id.toLowerCase(); + if (qualifiesForRequirement(req, ownedMap) && metaMap[id]) { + metaMap[id].rarity = 'mythic'; + if (requiredStyleTags(req).length > 0) metaMap[id].name = req.role; + } + } + } + + // ── 2. Exclusives rendered image ────────────────────────────────────── + try { + const exclusiveItems = []; + const exclusiveSeen = new Set(); + const addExclusiveItem = (item) => { + const key = item.id.toLowerCase(); + if (exclusiveSeen.has(key)) return; + exclusiveSeen.add(key); + exclusiveItems.push(item); + }; + + // Exclusive cosmetics (skins, pickaxes, emotes, emoticons) + for (const req of ROLE_REQUIREMENTS) { + if (req.bannerId || req.stw) continue; + const id = req.id.toLowerCase(); + if (!qualifiesForRequirement(req, ownedMap)) continue; + const meta = metaMap[id] || {}; + addExclusiveItem({ id, name: req.role || meta.name || id, rarity: 'mythic' }); + } + + // Exclusive & STW banners - pulled from role requirements and bundled master list + const bannerMeta = await getBannerMeta(); + for (const item of collectOwnedExclusiveBannerItems(ccItems, bannerMeta, metaMap)) { + addExclusiveItem(item); + } + + if (exclusiveItems.length > 0) { + await message.author.send('Building your exclusive cosmetics image...'); + const exclusiveImg = await renderLockerImage( + exclusiveItems, + `${exclusiveItems.length} (0)`, + 'EXCLUSIVES', + message.author.username, + ogStyleOwned + ); + if (exclusiveImg) { + const top5 = exclusiveItems.slice(0, 5).map(i => i.name).join(' + '); + const suffix = exclusiveItems.length > 5 ? ` + ${exclusiveItems.length - 5} more` : ''; + await sendLockerImageEmbed(message, { + title: `${top5}${suffix}`, + description: `${outfits.length} skin count`, + imageBuffer: exclusiveImg, + fileName: 'exclusives.png', + }); + } + } + } catch (err) { + console.error('Exclusive image error:', err.message); + } + + // ── 3. Full locker — all items, sorted by rarity, one image per category ── + try { + // Rarity sort order (matches RiftCheckerBot) + const RARITY_ORDER = ['mythic', 'legendary', 'dark', 'lava', 'slurp', 'starwars', 'marvel', 'frozen', 'gaminglegends', 'shadow', 'icon', 'dc', 'epic', 'rare', 'uncommon', 'common']; + const sortByRarity = (ids) => [...ids].sort((a, b) => { + const ra = RARITY_ORDER.indexOf(metaMap[a.toLowerCase()]?.rarity || 'common'); + const rb = RARITY_ORDER.indexOf(metaMap[b.toLowerCase()]?.rarity || 'common'); + return (ra === -1 ? 99 : ra) - (rb === -1 ? 99 : rb); + }); + + // Collect owned exclusive banners from role requirements, bundled IDs, and the master list. + const bannerMeta = await getBannerMeta(); + const ownedExclusiveBanners = collectOwnedExclusiveBannerItems(ccItems, bannerMeta, metaMap); + const ownedExclusiveBannerIds = ownedExclusiveBanners.map(item => item.id); + + // Fetch metadata for all cosmetic categories + const allCategoryIds = [...outfits, ...pickaxes, ...emotes, ...emoticons, ...backblings, ...gliders, ...sprays]; + const allMeta = await fetchCosmeticMeta(allCategoryIds); + for (const [k, v] of Object.entries(allMeta)) metaMap[k] = metaMap[k] || v; + + const categories = [ + { ids: sortByRarity(outfits), label: 'OUTFITS', subtitle: `${outfits.length} outfits` }, + { ids: sortByRarity(pickaxes), label: 'PICKAXES', subtitle: `${pickaxes.length} pickaxes` }, + { ids: sortByRarity(emotes), label: 'EMOTES', subtitle: `${emotes.length} emotes` }, + { ids: sortByRarity(emoticons), label: 'EMOTICONS', subtitle: `${emoticons.length} emoticons` }, + { ids: sortByRarity(backblings), label: 'BACK BLINGS', subtitle: `${backblings.length} back blings` }, + { ids: sortByRarity(gliders), label: 'GLIDERS', subtitle: `${gliders.length} gliders` }, + { ids: sortByRarity(sprays), label: 'SPRAYS', subtitle: `${sprays.length} sprays` }, + ...(ownedExclusiveBannerIds.length > 0 + ? [{ ids: ownedExclusiveBannerIds, label: 'BANNERS', subtitle: `${ownedExclusiveBannerIds.length} banners` }] + : []), + ].filter(c => c.ids.length > 0); + + if (categories.length === 0) { + await message.author.send('No cosmetics found in locker.'); + return; + } + + await message.author.send(`Building your full locker (${categories.length} categories)...`); + + for (const cat of categories) { + const items = cat.ids.map(id => ({ + id, + name: metaMap[id.toLowerCase()]?.name || id, + rarity: metaMap[id.toLowerCase()]?.rarity || 'common', + })); + + const img = await renderLockerImage( + items, + `${items.length} (0)`, + cat.label, + message.author.username, + ogStyleOwned + ); + + if (img) { + await sendLockerImageEmbed(message, { + title: `${displayName} - ${cat.label}`, + description: cat.subtitle, + imageBuffer: img, + fileName: `${cat.label.toLowerCase().replace(/\s/g, '_')}.png`, + }); + } + + await new Promise(r => setTimeout(r, 500)); + } + + } catch (err) { + console.error('Locker image error:', err.message); + } + + } catch (err) { + pending.delete(userId); + console.error('Verify error:', err); + message.author.send('Unexpected error. Try again.').catch(() => null); + } +}); + +client.login(process.env.TOKEN); diff --git a/src/verify.js b/src/verify.js new file mode 100644 index 0000000..6058a4f --- /dev/null +++ b/src/verify.js @@ -0,0 +1,402 @@ +// ============================================= +// FORTNITE SKIN VERIFY BOT +// ============================================= +// Verifies a user's Fortnite locker via Epic Games +// OAuth and auto-assigns Discord roles based on +// the skins and styles they own. +// +// Run with: node verify.js +// Users type: !verify in your server +// ============================================= + +require('dotenv').config(); +const { Client, GatewayIntentBits, PermissionsBitField, EmbedBuilder } = require('discord.js'); + +const client = new Client({ + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.MessageContent, + GatewayIntentBits.DirectMessages, + ], + partials: ['CHANNEL'], +}); + +// ─── Epic Games API tokens (from RiftCheckerBot source) ─────────────────────── +const SWITCH_TOKEN = 'OThmN2U0MmMyZTNhNGY4NmE3NGViNDNmYmI0MWVkMzk6MGEyNDQ5YTItMDAxYS00NTFlLWFmZWMtM2U4MTI5MDFjNGQ3'; +const IOS_TOKEN = 'M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU='; + +const EPIC_OAUTH = 'https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token'; +const EPIC_OAUTH_PROD03 = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token'; +const EPIC_EXCHANGE = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/exchange'; +const EPIC_DEVICE_AUTH = 'https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/deviceAuthorization'; + +// ─── Role → skin/style mapping ──────────────────────────────────────────────── +// Each entry defines what cosmetic ID (and optionally style tag) a user must +// own to receive the role. styleTag means they need that specific variant unlocked. +const ROLE_REQUIREMENTS = [ + // OG Season 1 skins — style required for the OG variant + { + role: 'OG Renegade Raider', + id: 'cid_028_athena_commando_f', + styleTag: 'Mat3', // Black & Gold style = OG + anyStyle: false, + }, + { + role: 'OG Aerial Assault Trooper', + id: 'cid_017_athena_commando_m', + styleTag: 'Stage2', // upgraded style = OG unlock + anyStyle: false, + }, + { + role: 'OG Ghoul Trooper', + id: 'cid_029_athena_commando_f_halloween', + styleTag: 'Mat3', // PINK Ghoul = OG + anyStyle: false, + }, + { + role: 'OG Skull Trooper', + id: 'cid_030_athena_commando_m_halloween', + styleTag: 'Mat1', // PURPLE GLOW = OG + anyStyle: false, + }, + + // Exclusive skins — just owning them is enough + { role: 'Black Knight', id: 'cid_035_athena_commando_m_medieval' }, + { role: 'Double Helix', id: 'cid_183_athena_commando_m_modernmilitaryred' }, + { role: 'Honor Guard', id: 'cid_342_athena_commando_m_streetracermetallic' }, + { role: 'Wonder', id: 'cid_434_athena_commando_f_stealthhonor' }, + { role: 'Surf Strider', id: 'cid_783_athena_commando_m_aquajacket' }, + { role: 'Stealth Reflex', id: 'cid_386_athena_commando_m_streetopsstealth' }, + { role: 'Dark Vertex', id: 'cid_371_athena_commando_m_speedymidnight' }, + { role: 'Royale Bomber', id: 'cid_113_athena_commando_m_blueace' }, + { role: 'Wildcat', id: 'cid_757_athena_commando_f_wildcat' }, + { role: 'Clyde', id: 'character_unbrokentrash' }, + { role: 'Eon', id: 'cid_174_athena_commando_f_carbidewhite' }, + { role: 'Huntmaster Saber', id: 'character_masterkeyorder' }, + { role: 'Dark Skully', id: 'cid_850_athena_commando_f_skullbritecube' }, + { role: 'Galaxy', id: 'cid_175_athena_commando_m_celestial' }, + { role: 'Ikonik', id: 'cid_313_athena_commando_m_kpopfashion' }, + { role: 'Glow', id: 'cid_479_athena_commando_f_davinci' }, + { role: 'Rogue Spider Knight', id: 'cid_516_athena_commando_m_blackwidowrogue' }, + { role: 'Thrilldiver', id: 'character_summerunsuitable' }, + { role: 'Freediver', id: 'character_coolsuitable' }, + { role: 'Neo Versa', id: 'cid_441_athena_commando_f_cyberscavengerblue' }, + { role: 'Cobalt Snowfoot', id: 'character_snowninjadark' }, + { role: 'Florin', id: 'character_asterorder' }, + { role: "What's Wrong, Toona Fish?", id: 'cid_a_201_athena_commando_m_teriyakifishtoon' }, + { role: 'Cameo Needs Loot', id: 'cid_571_athena_commando_f_sheath' }, + { role: 'Barricade', id: 'character_rankedphantom' }, + + // Fully Golden Peely = base Peely skin (golden style is a level-up variant) + { role: 'Fully Golden Peely', id: 'cid_349_athena_commando_m_banana' }, +]; + +// ─── STW Founders check (from common_core profile) ──────────────────────────── +// founder packs give specific items in common_core +const STW_FOUNDER_IDS = [ + 'cid_095_athena_commando_m_founder', // Standard Founder + 'cid_096_athena_commando_f_founder', // Standard Founder female +]; +const STW_ULTIMATE_IDS = [ + 'tiertoken_collectionbook_ultimate', // Ultimate founder token +]; + +// ─── pending verifications: Map ── +const pending = new Map(); + +// ─── Helper: get switch token access token ──────────────────────────────────── +async function getSwitchAccessToken() { + const res = await fetch(EPIC_OAUTH, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Authorization': `basic ${SWITCH_TOKEN}`, + }, + body: 'grant_type=client_credentials', + }); + const data = await res.json(); + return data.access_token; +} + +// ─── Helper: create device code ─────────────────────────────────────────────── +async function createDeviceCode(accessToken) { + const res = await fetch(EPIC_DEVICE_AUTH, { + method: 'POST', + headers: { + 'Authorization': `bearer ${accessToken}`, + 'Content-Type': 'application/x-www-form-urlencoded', + }, + }); + return res.json(); +} + +// ─── Helper: poll until user completes login ────────────────────────────────── +async function waitForLogin(deviceCode, maxWaitMs = 300000) { + const start = Date.now(); + while (Date.now() - start < maxWaitMs) { + await new Promise(r => setTimeout(r, 10000)); // poll every 10s + const res = await fetch(EPIC_OAUTH_PROD03, { + method: 'POST', + headers: { + 'Authorization': `basic ${SWITCH_TOKEN}`, + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `grant_type=device_code&device_code=${deviceCode}`, + }); + const data = await res.json(); + if (res.status === 200 && data.access_token) { + return data; + } + const err = data.errorCode || ''; + if (err.includes('not_found') || err.includes('expired')) { + return null; // link expired + } + // authorization_pending = still waiting, keep polling + } + return null; +} + +// ─── Helper: exchange token for iOS client token ────────────────────────────── +async function exchangeForIosToken(accessToken) { + // Get exchange code + const exRes = await fetch(EPIC_EXCHANGE, { + headers: { 'Authorization': `bearer ${accessToken}` }, + }); + const exData = await exRes.json(); + + // Use exchange code with iOS token + const res = await fetch(EPIC_OAUTH_PROD03, { + method: 'POST', + headers: { + 'Authorization': `basic ${IOS_TOKEN}`, + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `grant_type=exchange_code&exchange_code=${exData.code}`, + }); + return res.json(); +} + +// ─── Helper: get athena locker (owned skins + styles) ───────────────────────── +async function getLockerData(accountId, accessToken) { + const url = `https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/${accountId}/client/QueryProfile?profileId=athena&rvn=-1`; + const res = await fetch(url, { + method: 'POST', + headers: { + 'Authorization': `bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + body: '{}', + }); + return res.json(); +} + +// ─── Helper: get common_core (STW founders check) ──────────────────────────── +async function getCommonCoreData(accountId, accessToken) { + const url = `https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/game/v2/profile/${accountId}/client/QueryProfile?profileId=common_core&rvn=-1`; + const res = await fetch(url, { + method: 'POST', + headers: { + 'Authorization': `bearer ${accessToken}`, + 'Content-Type': 'application/json', + }, + body: '{}', + }); + return res.json(); +} + +// ─── Helper: build owned items map from athena profile ──────────────────────── +function buildOwnedMap(athenaData) { + const owned = {}; // id (lowercase) -> Set of owned style tags + const items = athenaData?.profileChanges?.[0]?.profile?.items || {}; + for (const item of Object.values(items)) { + const tpl = item.templateId || ''; + if (!tpl.toLowerCase().startsWith('athena') && !tpl.toLowerCase().startsWith('character')) continue; + const rawId = tpl.split(':')[1] || ''; + const id = rawId.toLowerCase(); + if (!owned[id]) owned[id] = new Set(); + const variants = item.attributes?.variants || []; + for (const v of variants) { + for (const tag of (v.owned || [])) { + owned[id].add(tag); + } + } + } + return owned; +} + +// ─── Helper: check which roles the user qualifies for ──────────────────────── +function getRolesForLocker(ownedMap, commonCoreItems) { + const earned = []; + + for (const req of ROLE_REQUIREMENTS) { + const id = req.id.toLowerCase(); + if (!ownedMap[id]) continue; // doesn't own this skin + + if (req.styleTag) { + // Must own the specific style + if (ownedMap[id].has(req.styleTag)) { + earned.push(req.role); + } + } else { + // Just owning the skin is enough + earned.push(req.role); + } + } + + // STW Founders check via common_core + const ccItems = commonCoreItems || {}; + const ccIds = Object.values(ccItems).map(i => (i.templateId || '').toLowerCase()); + + const hasFounder = STW_FOUNDER_IDS.some(id => ccIds.some(cc => cc.includes(id.toLowerCase()))); + const hasUltimate = STW_ULTIMATE_IDS.some(id => ccIds.some(cc => cc.includes(id.toLowerCase()))); + + // Also check for founder purchase via mtx receipts + const hasMtxFounder = ccIds.some(cc => cc.includes('founder')); + + if (hasUltimate) { + earned.push('Ultimate STW Founders'); + earned.push('STW Founders'); // ultimate implies standard too + } else if (hasFounder || hasMtxFounder) { + earned.push('STW Founders'); + } + + return [...new Set(earned)]; // deduplicate +} + +// ─── Bot event handlers ─────────────────────────────────────────────────────── +client.once('ready', () => { + console.log(`Logged in as ${client.user.tag}`); + console.log('Users can type !verify to verify their Fortnite account.'); +}); + +client.on('messageCreate', async (message) => { + if (message.author.bot) return; + if (message.content !== '!verify') return; + + const userId = message.author.id; + const guild = message.guild; + + if (!guild) return; + + // Prevent duplicate verifications + if (pending.has(userId)) { + return message.reply('You already have a verification in progress. Check your DMs for the login link.'); + } + + await message.reply('Check your DMs for a login link to verify your Fortnite account!'); + + try { + // Step 1: get switch token + const switchToken = await getSwitchAccessToken(); + + // Step 2: create device code + const deviceData = await createDeviceCode(switchToken); + if (!deviceData.user_code || !deviceData.device_code) { + return message.author.send('❌ Failed to generate a login link. Please try again later.'); + } + + const loginUrl = `https://www.epicgames.com/activate?userCode=${deviceData.user_code}`; + + // Step 3: DM the user the link + const embed = new EmbedBuilder() + .setColor(0x5865F2) + .setTitle('Fortnite Account Verification') + .setDescription( + `Click the link below to log into your Epic Games account.\n\n` + + `**[Click here to verify →](${loginUrl})**\n\n` + + `Your code: \`${deviceData.user_code}\`\n\n` + + `This link expires in **5 minutes**. Once you log in, the bot will automatically check your locker and assign your roles.` + ) + .setFooter({ text: 'Your login is read-only. The bot only checks your cosmetics.' }); + + await message.author.send({ embeds: [embed] }); + + pending.set(userId, { guildId: guild.id, channelId: message.channel.id }); + + // Step 4: poll for completion + const tokenData = await waitForLogin(deviceData.device_code); + pending.delete(userId); + + if (!tokenData) { + return message.author.send('❌ Login link expired or was not completed. Run `!verify` again to try again.'); + } + + // Step 5: exchange for iOS token (gives us full API access) + const iosData = await exchangeForIosToken(tokenData.access_token); + if (!iosData.access_token) { + return message.author.send('❌ Authentication failed. Please try again.'); + } + + const accountId = iosData.account_id; + const displayName = iosData.displayName || 'Unknown'; + const accessToken = iosData.access_token; + + await message.author.send(`✅ Logged in as **${displayName}**! Checking your locker...`); + + // Step 6: fetch locker data + const [athenaData, commonCoreData] = await Promise.all([ + getLockerData(accountId, accessToken), + getCommonCoreData(accountId, accessToken), + ]); + + if (!athenaData?.profileChanges) { + return message.author.send('❌ Failed to read your locker. Please try again.'); + } + + // Step 7: figure out which roles they earn + const ownedMap = buildOwnedMap(athenaData); + const ccItems = commonCoreData?.profileChanges?.[0]?.profile?.items || {}; + const earnedRoleNames = getRolesForLocker(ownedMap, ccItems); + + // Step 8: assign roles in the guild + const member = await guild.members.fetch(userId).catch(() => null); + if (!member) { + return message.author.send('❌ Could not find you in the server. Make sure you are still in the server.'); + } + + const assigned = []; + const notFound = []; + + for (const roleName of earnedRoleNames) { + const role = guild.roles.cache.find(r => r.name.toLowerCase() === roleName.toLowerCase()); + if (!role) { + notFound.push(roleName); + continue; + } + if (!member.roles.cache.has(role.id)) { + await member.roles.add(role, 'Fortnite locker verification').catch(() => null); + } + assigned.push(roleName); + } + + // Step 9: send result + if (assigned.length === 0) { + await message.author.send( + `✅ Verification complete for **${displayName}**!\n\n` + + `No matching exclusive roles were found for your account. ` + + `If you think this is wrong, contact a server admin.` + ); + } else { + await message.author.send( + `✅ Verification complete for **${displayName}**!\n\n` + + `**Roles assigned (${assigned.length}):**\n` + + assigned.map(r => `• ${r}`).join('\n') + + (notFound.length ? `\n\n⚠️ These roles were earned but not found in the server: ${notFound.join(', ')}` : '') + ); + } + + // Also send a confirmation in the original channel + const ch = guild.channels.cache.get(message.channel.id); + if (ch) { + ch.send(`✅ <@${userId}> has been verified and received **${assigned.length}** role(s).`).catch(() => null); + } + + } catch (err) { + pending.delete(userId); + console.error('Verify error:', err); + message.author.send('❌ An unexpected error occurred during verification. Please try again.').catch(() => null); + } +}); + +client.login(process.env.TOKEN); diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..e0e5f20 --- /dev/null +++ b/start.bat @@ -0,0 +1,4 @@ +@echo off +node "./src/bot.js" +echo. +pause >nul