From eeaa3390906fbe5c5e3488dcd802cc174bed65fd Mon Sep 17 00:00:00 2001 From: nrbdev Date: Wed, 8 Jan 2025 13:34:38 -0500 Subject: [PATCH 01/34] fix: can't open nightwave offerings (#754) --- src/services/serversideVendorsService.ts | 2 + ...dioLegionIntermission10VendorManifest.json | 82 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 static/fixed_responses/getVendorInfo/RadioLegionIntermission10VendorManifest.json diff --git a/src/services/serversideVendorsService.ts b/src/services/serversideVendorsService.ts index 3b4c3a61..5a250b0f 100644 --- a/src/services/serversideVendorsService.ts +++ b/src/services/serversideVendorsService.ts @@ -21,6 +21,7 @@ import MaskSalesmanManifest from "@/static/fixed_responses/getVendorInfo/MaskSal import OstronFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronFishmongerVendorManifest.json"; import OstronPetVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronPetVendorManifest.json"; import OstronProspectorVendorManifest from "@/static/fixed_responses/getVendorInfo/OstronProspectorVendorManifest.json"; +import RadioLegionIntermission10VendorManifest from "@/static/fixed_responses/getVendorInfo/RadioLegionIntermission10VendorManifest.json"; import SolarisDebtTokenVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorManifest.json"; import SolarisDebtTokenVendorRepossessionsManifest from "@/static/fixed_responses/getVendorInfo/SolarisDebtTokenVendorRepossessionsManifest.json"; import SolarisFishmongerVendorManifest from "@/static/fixed_responses/getVendorInfo/SolarisFishmongerVendorManifest.json"; @@ -62,6 +63,7 @@ const vendorManifests: IVendorManifest[] = [ OstronFishmongerVendorManifest, OstronPetVendorManifest, OstronProspectorVendorManifest, + RadioLegionIntermission10VendorManifest, SolarisDebtTokenVendorManifest, SolarisDebtTokenVendorRepossessionsManifest, SolarisFishmongerVendorManifest, diff --git a/static/fixed_responses/getVendorInfo/RadioLegionIntermission10VendorManifest.json b/static/fixed_responses/getVendorInfo/RadioLegionIntermission10VendorManifest.json new file mode 100644 index 00000000..d005eff2 --- /dev/null +++ b/static/fixed_responses/getVendorInfo/RadioLegionIntermission10VendorManifest.json @@ -0,0 +1,82 @@ +{ + "VendorInfo": { + "_id": { "$oid": "664190400000000000000000" }, + "TypeName": "/Lotus/Types/Game/VendorManifests/Events/RadioLegionIntermission10VendorManifest", + "ItemManifest": [ + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/WarframeRecipes/TrapperChassisBlueprint", + "ItemPrices": [{ "ItemCount": 25, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000048" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/WarframeRecipes/TrapperSystemsBlueprint", + "ItemPrices": [{ "ItemCount": 25, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000049" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/WarframeRecipes/TrapperHelmetBlueprint", + "ItemPrices": [{ "ItemCount": 25, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000050" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/OrokinCatalyst", + "ItemPrices": [{ "ItemCount": 75, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000051" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/OrokinReactor", + "ItemPrices": [{ "ItemCount": 75, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000052" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Alertium", + "ItemPrices": [{ "ItemCount": 15, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 5, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000053" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva", + "ItemPrices": [{ "ItemCount": 50, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_3", + "QuantityMultiplier": 10000, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "AllowMultipurchase": true, + "Id": { "$oid": "001300130000000000000054" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/Nightwave/GlassmakerShipDeco", + "ItemPrices": [{ "ItemCount": 60, "ItemType": "/Lotus/Types/Items/MiscItems/NoraIntermissionTenCreds", "ProductCategory": "MiscItems" }], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { "$date": { "$numberLong": "2051240400000" } }, + "PurchaseQuantityLimit": 1, + "AllowMultipurchase": false, + "Id": { "$oid": "001300130000000000000055" } + } + ], + "Expiry": { "$date": { "$numberLong": "2051240400000" } } + } +} -- 2.47.2 From e5d192fb2b30b16ef17d12e993d75fab5877c8da Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Thu, 9 Jan 2025 05:15:30 +0100 Subject: [PATCH 02/34] feat: more accurate inventory after skipTutorial --- src/models/inventoryModels/inventoryModel.ts | 58 ++++---- src/models/personalRoomsModel.ts | 41 +++-- src/services/inventoryService.ts | 100 ++++++++++--- src/services/loginService.ts | 14 +- src/types/personalRoomsTypes.ts | 2 +- src/types/shipTypes.ts | 4 +- static/fixed_responses/inbox.json | 39 +++-- static/fixed_responses/inventory.json | 131 ---------------- static/fixed_responses/new_inventory.json | 122 --------------- static/fixed_responses/personalRooms.json | 32 ---- .../postTutorialInventory.json | 140 ------------------ 11 files changed, 182 insertions(+), 501 deletions(-) delete mode 100644 static/fixed_responses/inventory.json delete mode 100644 static/fixed_responses/new_inventory.json delete mode 100644 static/fixed_responses/personalRooms.json delete mode 100644 static/fixed_responses/postTutorialInventory.json diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 964c89eb..d2d16dc5 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -718,7 +718,7 @@ const inventorySchema = new Schema( RewardSeed: Number, //Credit - RegularCredits: { type: Number, default: 3000 }, + RegularCredits: { type: Number, default: 0 }, //Platinum PremiumCredits: { type: Number, default: 50 }, //Gift Platinum(Non trade) @@ -729,18 +729,18 @@ const inventorySchema = new Schema( PrimeTokens: { type: Number, default: 0 }, //Slots - SuitBin: slotsBinSchema, - WeaponBin: slotsBinSchema, - SentinelBin: slotsBinSchema, - SpaceSuitBin: slotsBinSchema, - SpaceWeaponBin: slotsBinSchema, - PvpBonusLoadoutBin: slotsBinSchema, - PveBonusLoadoutBin: slotsBinSchema, - RandomModBin: slotsBinSchema, - OperatorAmpBin: slotsBinSchema, - CrewShipSalvageBin: slotsBinSchema, - MechBin: slotsBinSchema, - CrewMemberBin: slotsBinSchema, + SuitBin: { type: slotsBinSchema, default: { Slots: 3 } }, + WeaponBin: { type: slotsBinSchema, default: { Slots: 10 } }, + SentinelBin: { type: slotsBinSchema, default: { Slots: 10 } }, + SpaceSuitBin: { type: slotsBinSchema, default: { Slots: 4 } }, + SpaceWeaponBin: { type: slotsBinSchema, default: { Slots: 4 } }, + PvpBonusLoadoutBin: { type: slotsBinSchema, default: { Slots: 0 } }, + PveBonusLoadoutBin: { type: slotsBinSchema, default: { Slots: 0 } }, + RandomModBin: { type: slotsBinSchema, default: { Slots: 15 } }, + OperatorAmpBin: { type: slotsBinSchema, default: { Slots: 8 } }, + CrewShipSalvageBin: { type: slotsBinSchema, default: { Slots: 8 } }, + MechBin: { type: slotsBinSchema, default: { Slots: 4 } }, + CrewMemberBin: { type: slotsBinSchema, default: { Slots: 3 } }, //How many trades do you have left TradesRemaining: { type: Number, default: 0 }, @@ -756,20 +756,20 @@ const inventorySchema = new Schema( //Syndicates Missions complate(Navigation->Syndicate) CompletedSyndicates: [String], //Daily Syndicates Exp - DailyAffiliation: { type: Number, default: 0 }, - DailyAffiliationPvp: { type: Number, default: 0 }, - DailyAffiliationLibrary: { type: Number, default: 0 }, - DailyAffiliationCetus: { type: Number, default: 0 }, - DailyAffiliationQuills: { type: Number, default: 0 }, - DailyAffiliationSolaris: { type: Number, default: 0 }, - DailyAffiliationVentkids: { type: Number, default: 0 }, - DailyAffiliationVox: { type: Number, default: 0 }, - DailyAffiliationEntrati: { type: Number, default: 0 }, - DailyAffiliationNecraloid: { type: Number, default: 0 }, - DailyAffiliationZariman: { type: Number, default: 0 }, - DailyAffiliationKahl: { type: Number, default: 0 }, - DailyAffiliationCavia: { type: Number, default: 0 }, - DailyAffiliationHex: { type: Number, default: 0 }, + DailyAffiliation: { type: Number, default: 16000 }, + DailyAffiliationPvp: { type: Number, default: 16000 }, + DailyAffiliationLibrary: { type: Number, default: 16000 }, + DailyAffiliationCetus: { type: Number, default: 16000 }, + DailyAffiliationQuills: { type: Number, default: 16000 }, + DailyAffiliationSolaris: { type: Number, default: 16000 }, + DailyAffiliationVentkids: { type: Number, default: 16000 }, + DailyAffiliationVox: { type: Number, default: 16000 }, + DailyAffiliationEntrati: { type: Number, default: 16000 }, + DailyAffiliationNecraloid: { type: Number, default: 16000 }, + DailyAffiliationZariman: { type: Number, default: 16000 }, + DailyAffiliationKahl: { type: Number, default: 16000 }, + DailyAffiliationCavia: { type: Number, default: 16000 }, + DailyAffiliationHex: { type: Number, default: 16000 }, //Daily Focus limit DailyFocus: { type: Number, default: 250000 }, @@ -890,7 +890,7 @@ const inventorySchema = new Schema( //Item Mastery Rank exp XPInfo: [TypeXPItemSchema], //Mastery Rank next availability - TrainingDate: Date, + TrainingDate: { type: Date, default: new Date(0) }, //Retries rank up(3 time) TrainingRetriesLeft: Number, @@ -916,7 +916,7 @@ const inventorySchema = new Schema( CompletedAlerts: [String], //Warframe\Duviri - StoryModeChoice: String, + StoryModeChoice: { type: String, default: "WARFRAME" }, //Alert->Kuva Siphon PeriodicMissionCompletions: [periodicMissionCompletionsSchema], diff --git a/src/models/personalRoomsModel.ts b/src/models/personalRoomsModel.ts index 2388ae45..382083e8 100644 --- a/src/models/personalRoomsModel.ts +++ b/src/models/personalRoomsModel.ts @@ -74,6 +74,17 @@ const apartmentSchema = new Schema( }, { _id: false } ); +const apartmentDefault: IApartment = { + Rooms: [ + { Name: "ElevatorLanding", MaxCapacity: 1600 }, + { Name: "ApartmentRoomA", MaxCapacity: 1000 }, + { Name: "ApartmentRoomB", MaxCapacity: 1600 }, + { Name: "ApartmentRoomC", MaxCapacity: 1600 }, + { Name: "DuviriHallway", MaxCapacity: 1600 } + ], + FavouriteLoadouts: [], + Gardening: {} +}; const orbiterSchema = new Schema( { @@ -84,6 +95,17 @@ const orbiterSchema = new Schema( }, { _id: false } ); +const orbiterDefault: IOrbiter = { + Features: [], + Rooms: [ + { Name: "AlchemyRoom", MaxCapacity: 1600 }, + { Name: "BridgeRoom", MaxCapacity: 1600 }, + { Name: "LisetRoom", MaxCapacity: 1000 }, + { Name: "OperatorChamberRoom", MaxCapacity: 1600 }, + { Name: "OutsideRoom", MaxCapacity: 1600 }, + { Name: "PersonalQuartersRoom", MaxCapacity: 1600 } + ] +}; const favouriteLoadoutSchema = new Schema( { @@ -114,18 +136,9 @@ const tailorShopDefault: ITailorShopDatabase = { CustomJson: "{}", LevelDecosVisible: true, Rooms: [ - { - Name: "LabRoom", - MaxCapacity: 4000 - }, - { - Name: "LivingQuartersRoom", - MaxCapacity: 3000 - }, - { - Name: "HelminthRoom", - MaxCapacity: 2000 - } + { Name: "LabRoom", MaxCapacity: 4000 }, + { Name: "LivingQuartersRoom", MaxCapacity: 3000 }, + { Name: "HelminthRoom", MaxCapacity: 2000 } ] }; @@ -133,8 +146,8 @@ export const personalRoomsSchema = new Schema({ personalRoomsOwnerId: Schema.Types.ObjectId, activeShipId: Schema.Types.ObjectId, ShipInteriorColors: colorSchema, - Ship: orbiterSchema, - Apartment: apartmentSchema, + Ship: { type: orbiterSchema, default: orbiterDefault }, + Apartment: { type: apartmentSchema, default: apartmentDefault }, TailorShop: { type: tailorShopSchema, default: tailorShopDefault } }); diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 3968fc77..0e016376 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -1,5 +1,4 @@ import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; -import postTutorialInventory from "@/static/fixed_responses/postTutorialInventory.json"; import { config } from "@/src/services/configService"; import { Types } from "mongoose"; import { SlotNames, IInventoryChanges, IBinChanges, ICurrencyChanges } from "@/src/types/purchaseTypes"; @@ -45,25 +44,90 @@ export const createInventory = async ( defaultItemReferences: { loadOutPresetId: Types.ObjectId; ship: Types.ObjectId } ): Promise => { try { - const inventory = config.skipTutorial - ? new Inventory({ - accountOwnerId: accountOwnerId, - LoadOutPresets: defaultItemReferences.loadOutPresetId, - Ships: [defaultItemReferences.ship], - ...postTutorialInventory - }) - : new Inventory({ - accountOwnerId: accountOwnerId, - LoadOutPresets: defaultItemReferences.loadOutPresetId, - Ships: [defaultItemReferences.ship], - TrainingDate: 0 - }); + const inventory = new Inventory({ + accountOwnerId: accountOwnerId, + LoadOutPresets: defaultItemReferences.loadOutPresetId, + Ships: [defaultItemReferences.ship], + PlayedParkourTutorial: config.skipTutorial, + ReceivedStartingGear: config.skipTutorial + }); + + if (config.skipTutorial) { + const defaultEquipment = [ + // Awakening rewards + { ItemCount: 1, ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }, + { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }, + { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }, + { ItemCount: 1, ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }, + { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" }, + { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" }, + { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" }, + { ItemCount: 1, ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" }, + { ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" }, + + // Vor's Prize rewards + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityRangeMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityStrengthMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarAbilityDurationMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPickupBonusMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarPowerMaxMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarEnemyRadarMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponFireRateMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Melee/WeaponMeleeDamageMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageCorpus" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponFactionDamageGrineer" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Rifle/WeaponDamageAmountMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponFireDamageMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponElectricityDamageMod" }, + { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Pistol/WeaponDamageAmountMod" }, + { ItemCount: 1, ItemType: "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" }, + { ItemCount: 1, ItemType: "/Lotus/Types/Items/MiscItems/Morphic" }, + { ItemCount: 400, ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle" }, + { ItemCount: 150, ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate" } + ]; + + for (const equipment of defaultEquipment) { + await addItem(inventory, equipment.ItemType, equipment.ItemCount); + } + + // Missing in Public Export + inventory.Horses.push({ + ItemType: "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit" + }); + inventory.DataKnives.push({ + ItemType: "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", + XP: 450000 + }); + inventory.Scoops.push({ + ItemType: "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest" + }); + inventory.DrifterMelee.push({ + ItemType: "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords" + }); + + inventory.QuestKeys.push({ + Completed: true, + ItemType: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" + }); + + const completedMissions = ["SolNode27", "SolNode89", "SolNode63", "SolNode85", "SolNode15", "SolNode79"]; + + inventory.Missions.push( + ...completedMissions.map(tag => ({ + Completes: 1, + Tag: tag + })) + ); + + inventory.RegularCredits = 25000; + inventory.FusionPoints = 180; + } + await inventory.save(); } catch (error) { - if (error instanceof Error) { - throw new Error(`error creating inventory" ${error.message}`); - } - throw new Error("error creating inventory that is not of instance Error"); + throw new Error(`Error creating inventory: ${error instanceof Error ? error.message : "Unknown error"}`); } }; diff --git a/src/services/loginService.ts b/src/services/loginService.ts index 0e7fa5d4..202b45c0 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -5,7 +5,6 @@ import { createShip } from "./shipService"; import { Document, Types } from "mongoose"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { PersonalRooms } from "@/src/models/personalRoomsModel"; -import new_personal_rooms from "@/static/fixed_responses/personalRooms.json"; import { Request } from "express"; import { config } from "@/src/services/configService"; @@ -42,10 +41,21 @@ export const createLoadout = async (accountId: Types.ObjectId): Promise => { const personalRooms = new PersonalRooms({ - ...new_personal_rooms, personalRoomsOwnerId: accountId, activeShipId: shipId }); + if (config.skipTutorial) { + // Vor's Prize rewards + const defaultFeatures = [ + "/Lotus/Types/Items/ShipFeatureItems/EarthNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem", + "/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem" + ]; + personalRooms.Ship.Features.push(...defaultFeatures); + } await personalRooms.save(); }; diff --git a/src/types/personalRoomsTypes.ts b/src/types/personalRoomsTypes.ts index 9b44339d..f91a5b88 100644 --- a/src/types/personalRoomsTypes.ts +++ b/src/types/personalRoomsTypes.ts @@ -12,7 +12,7 @@ import { Model, Types } from "mongoose"; export interface IOrbiter { Features: string[]; Rooms: IRoom[]; - ContentUrlSignature: string; + ContentUrlSignature?: string; BootLocation?: TBootLocation; } diff --git a/src/types/shipTypes.ts b/src/types/shipTypes.ts index 1868e5f3..92f5f0cb 100644 --- a/src/types/shipTypes.ts +++ b/src/types/shipTypes.ts @@ -28,7 +28,7 @@ export interface IShip { ShipId: IOid; ShipInterior: IShipInterior; Rooms: IRoom[]; - ContentUrlSignature: string; + ContentUrlSignature?: string; BootLocation?: TBootLocation; } @@ -58,7 +58,7 @@ export interface IPlanters { } export interface IGardening { - Planters: IPlanters[]; + Planters?: IPlanters[]; } export interface IApartment { Gardening: IGardening; diff --git a/static/fixed_responses/inbox.json b/static/fixed_responses/inbox.json index a43fd2b1..f6334b54 100644 --- a/static/fixed_responses/inbox.json +++ b/static/fixed_responses/inbox.json @@ -1,23 +1,42 @@ { "Inbox": [ { - "sndr": "/Lotus/Language/Bosses/Ordis", - "msg": "/Lotus/Language/Inbox/ThankYouFreeMultipleContent", + "sub": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", + "sndr": "/Lotus/Language/Bosses/Darvo", + "msg": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc", + "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", "countedAtt": [ { - "ItemType": "/Lotus/Upgrades/Skins/Promo/Twitch/OgrisTwitchSkin", - "ItemCount": 1 + "ItemCount": 1, + "ItemType": "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" }, { - "ItemType": "/Lotus/Weapons/ClanTech/Chemical/RocketLauncher", - "ItemCount": 1 + "ItemCount": 1, + "ItemType": "/Lotus/Types/Items/MiscItems/Morphic" + }, + { + "ItemCount": 400, + "ItemType": "/Lotus/Types/Items/MiscItems/PolymerBundle" + }, + { + "ItemCount": 150, + "ItemType": "/Lotus/Types/Items/MiscItems/AlloyPlate" } ], - "sub": "/Lotus/Language/Inbox/ThankYouFreeMultipleSubject", - "icon": "/Lotus/Interface/Icons/Npcs/Ordis.png", "highPriority": true, - "messageId": "removed", - "date": { "$date": { "$numberLong": "removed" } }, + "messageId": "66d651800000000000000000", + "date": { "$date": { "$numberLong": "1725321600000" } }, + "r": true + }, + { + "sub": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", + "sndr": "/Lotus/Language/Menu/Mailbox_WarframeSender", + "msg": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc", + "icon": "/Lotus/Interface/Icons/Npcs/Lotus_d.png", + "transmission": "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus", + "highPriority": true, + "messageId": "66d651810000000000000000", + "date": { "$date": { "$numberLong": "1725321601000" } }, "r": true } ] diff --git a/static/fixed_responses/inventory.json b/static/fixed_responses/inventory.json deleted file mode 100644 index e19ac090..00000000 --- a/static/fixed_responses/inventory.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "SubscribedToEmails": 0, - "Created": { "$date": { "$numberLong": "removed" } }, - "SubscribedToEmailsPersonalized": 0, - "RewardSeed": -123123123123123, - "CrewMemberBin": { "Slots": 3 }, - "CrewShipSalvageBin": { "Slots": 8 }, - "DrifterMelee": [ - { - "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", - "ItemId": { "$oid": "removed" } - } - ], - "FusionPoints": 0, - "MechBin": { "Slots": 4 }, - "OperatorAmpBin": { "Slots": 8 }, - "PveBonusLoadoutBin": { "Slots": 0 }, - "PvpBonusLoadoutBin": { "Slots": 0 }, - "RandomModBin": { "Slots": 15 }, - "RegularCredits": 0, - "SentinelBin": { "Slots": 10 }, - "SpaceSuitBin": { "Slots": 4 }, - "SpaceWeaponBin": { "Slots": 4 }, - "SuitBin": { "Slots": 2 }, - "WeaponBin": { "Slots": 8 }, - "LastInventorySync": { "$oid": "removed" }, - "NextRefill": { "$date": { "$numberLong": "removed" } }, - "ActiveLandscapeTraps": [], - "ChallengeProgress": [], - "CrewMembers": [], - "CrewShips": [], - "CrewShipHarnesses": [], - "CrewShipSalvagedWeapons": [], - "CrewShipSalvagedWeaponSkins": [], - "CrewShipWeapons": [], - "CrewShipWeaponSkins": [], - "DataKnives": [], - "DrifterGuns": [], - "Drones": [], - "Horses": [], - "Hoverboards": [], - "KubrowPets": [], - "KubrowPetEggs": [], - "KubrowPetPrints": [], - "LongGuns": [], - "MechSuits": [], - "Melee": [], - "MoaPets": [], - "OperatorAmps": [], - "OperatorLoadOuts": [], - "AdultOperatorLoadOuts": [], - "KahlLoadOuts": [], - "PendingRecipes": [], - "PersonalGoalProgress": [], - "PersonalTechProjects": [], - "Pistols": [], - "QualifyingInvasions": [], - "RepVotes": [], - "Scoops": [], - "Sentinels": [], - "SentinelWeapons": [], - "Ships": [{ "ItemType": "/Lotus/Types/Items/Ships/DefaultShip", "ItemId": { "$oid": "123123" } }], - "SpaceGuns": [], - "SpaceMelee": [], - "SpaceSuits": [], - "SpecialItems": [], - "StepSequencers": [], - "Suits": [], - "Upgrades": [], - "WeaponSkins": [], - "Boosters": [], - "Consumables": [], - "EmailItems": [], - "FlavourItems": [], - "FocusUpgrades": [], - "FusionTreasures": [], - "LeagueTickets": [], - "LevelKeys": [], - "LoreFragmentScans": [], - "MiscItems": [], - "PendingSpectreLoadouts": [], - "Quests": [], - "QuestKeys": [], - "RawUpgrades": [], - "Recipes": [], - "Robotics": [], - "ShipDecorations": [], - "SpectreLoadouts": [], - "XPInfo": [], - "CrewShipAmmo": [], - "CrewShipRawSalvage": [], - "EvolutionProgress": [], - "Missions": [], - "TauntHistory": [], - "CompletedSyndicates": [], - "UsedDailyDeals": [], - "DailyAffiliation": 16000, - "DailyAffiliationPvp": 16000, - "DailyAffiliationLibrary": 16000, - "DailyAffiliationCetus": 16000, - "DailyAffiliationQuills": 16000, - "DailyAffiliationSolaris": 16000, - "DailyAffiliationVentkids": 16000, - "DailyAffiliationVox": 16000, - "DailyAffiliationEntrati": 16000, - "DailyAffiliationNecraloid": 16000, - "DailyAffiliationZariman": 16000, - "DailyAffiliationKahl": 16000, - "DailyFocus": 250000, - "GiftsRemaining": 8, - "LibraryAvailableDailyTaskInfo": { - "EnemyTypes": ["/Lotus/Types/Enemies/Orokin/OrokinBladeSawmanAvatar"], - "EnemyLocTag": "/Lotus/Language/Game/OrokinBladeSawman", - "EnemyIcon": "/Lotus/Interface/Icons/Npcs/Orokin/OrokinBladeSawman.png", - "ScansRequired": 4, - "RewardStoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle", - "RewardQuantity": 10, - "RewardStanding": 10000 - }, - "DuviriInfo": { "Seed": 123123123123123123, "NumCompletions": 0 }, - "TradesRemaining": 0, - "HasContributedToDojo": false, - "HasResetAccount": false, - "PendingCoupon": { - "Expiry": { "$date": { "$numberLong": "0" } }, - "Discount": 0 - }, - "PremiumCreditsFree": 0, - "ReceivedStartingGear": true, - "StoryModeChoice": "WARFRAME" -} diff --git a/static/fixed_responses/new_inventory.json b/static/fixed_responses/new_inventory.json deleted file mode 100644 index fb2e616e..00000000 --- a/static/fixed_responses/new_inventory.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "SubscribedToEmails": 0, - "Created": { "$date": { "$numberLong": "1685829131" } }, - "SubscribedToEmailsPersonalized": 0, - "RewardSeed": -5604904486637265640, - "CrewMemberBin": { "Slots": 3 }, - "CrewShipSalvageBin": { "Slots": 8 }, - "DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bb619e15fa43f0ee4b1b1" } }], - "FusionPoints": 0, - "MechBin": { "Slots": 4 }, - "OperatorAmpBin": { "Slots": 8 }, - "PveBonusLoadoutBin": { "Slots": 0 }, - "PvpBonusLoadoutBin": { "Slots": 0 }, - "RandomModBin": { "Slots": 15 }, - "RegularCredits": 0, - "SentinelBin": { "Slots": 10 }, - "SpaceSuitBin": { "Slots": 4 }, - "SpaceWeaponBin": { "Slots": 4 }, - "SuitBin": { "Slots": 2 }, - "WeaponBin": { "Slots": 8 }, - "LastInventorySync": { "$oid": "647bb5d79f963c9d24668257" }, - "NextRefill": { "$date": { "$numberLong": "1685829131" } }, - "ActiveLandscapeTraps": [], - "ChallengeProgress": [], - "CrewMembers": [], - "CrewShips": [], - "CrewShipHarnesses": [], - "CrewShipSalvagedWeapons": [], - "CrewShipSalvagedWeaponSkins": [], - "CrewShipWeapons": [], - "CrewShipWeaponSkins": [], - "DataKnives": [], - "DrifterGuns": [], - "Drones": [], - "Horses": [], - "Hoverboards": [], - "KubrowPets": [], - "KubrowPetEggs": [], - "KubrowPetPrints": [], - "LongGuns": [], - "MechSuits": [], - "Melee": [], - "MoaPets": [], - "OperatorAmps": [], - "OperatorLoadOuts": [], - "AdultOperatorLoadOuts": [], - "KahlLoadOuts": [], - "PendingRecipes": [], - "PersonalGoalProgress": [], - "PersonalTechProjects": [], - "Pistols": [], - "QualifyingInvasions": [], - "RepVotes": [], - "Scoops": [], - "Sentinels": [], - "SentinelWeapons": [], - "Ships": [], - "SpaceGuns": [], - "SpaceMelee": [], - "SpaceSuits": [], - "SpecialItems": [], - "StepSequencers": [], - "Suits": [], - "Upgrades": [], - "WeaponSkins": [], - "Boosters": [], - "Consumables": [], - "EmailItems": [], - "FlavourItems": [], - "FocusUpgrades": [], - "FusionTreasures": [], - "LeagueTickets": [], - "LevelKeys": [], - "LoreFragmentScans": [], - "MiscItems": [], - "PendingSpectreLoadouts": [], - "Quests": [], - "QuestKeys": [], - "RawUpgrades": [], - "Recipes": [], - "Robotics": [], - "ShipDecorations": [], - "SpectreLoadouts": [], - "XPInfo": [], - "CrewShipAmmo": [], - "CrewShipRawSalvage": [], - "EvolutionProgress": [], - "Missions": [], - "TauntHistory": [], - "CompletedSyndicates": [], - "UsedDailyDeals": [], - "DailyAffiliation": 16000, - "DailyAffiliationPvp": 16000, - "DailyAffiliationLibrary": 16000, - "DailyAffiliationCetus": 16000, - "DailyAffiliationQuills": 16000, - "DailyAffiliationSolaris": 16000, - "DailyAffiliationVentkids": 16000, - "DailyAffiliationVox": 16000, - "DailyAffiliationEntrati": 16000, - "DailyAffiliationNecraloid": 16000, - "DailyAffiliationZariman": 16000, - "DailyAffiliationKahl": 16000, - "DailyAffiliationCavia": 16000, - "DailyFocus": 250000, - "GiftsRemaining": 8, - "LibraryAvailableDailyTaskInfo": { - "EnemyTypes": ["/Lotus/Types/Enemies/Orokin/OrokinBladeSawmanAvatar"], - "EnemyLocTag": "/Lotus/Language/Game/OrokinBladeSawman", - "EnemyIcon": "/Lotus/Interface/Icons/Npcs/Orokin/OrokinBladeSawman.png", - "ScansRequired": 4, - "RewardStoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle", - "RewardQuantity": 10, - "RewardStanding": 10000 - }, - "DuviriInfo": { "Seed": 5898912197983600352, "NumCompletions": 0 }, - "TradesRemaining": 0, - "HasContributedToDojo": false, - "HasResetAccount": false, - "PendingCoupon": { "Expiry": { "$date": { "$numberLong": "0" } }, "Discount": 0 }, - "PremiumCreditsFree": 0 -} diff --git a/static/fixed_responses/personalRooms.json b/static/fixed_responses/personalRooms.json deleted file mode 100644 index b42bc27e..00000000 --- a/static/fixed_responses/personalRooms.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "Ship": { - "Features": [ - "/Lotus/Types/Items/ShipFeatureItems/EarthNavigationFeatureItem", - "/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem", - "/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem", - "/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem", - "/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem", - "/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem" - ], - "Rooms": [ - { "Name": "AlchemyRoom", "MaxCapacity": 1600 }, - { "Name": "BridgeRoom", "MaxCapacity": 1600 }, - { "Name": "LisetRoom", "MaxCapacity": 1000 }, - { "Name": "OperatorChamberRoom", "MaxCapacity": 1600 }, - { "Name": "OutsideRoom", "MaxCapacity": 1600 }, - { "Name": "PersonalQuartersRoom", "MaxCapacity": 1600 } - ], - "ContentUrlSignature": "removed" - }, - "Apartment": { - "Rooms": [ - { "Name": "ElevatorLanding", "MaxCapacity": 1600 }, - { "Name": "ApartmentRoomA", "MaxCapacity": 1000 }, - { "Name": "ApartmentRoomB", "MaxCapacity": 1600 }, - { "Name": "ApartmentRoomC", "MaxCapacity": 1600 }, - { "Name": "DuviriHallway", "MaxCapacity": 1600 } - ], - "FavouriteLoadouts": [], - "Gardening": {} - } -} diff --git a/static/fixed_responses/postTutorialInventory.json b/static/fixed_responses/postTutorialInventory.json deleted file mode 100644 index a9c76ee9..00000000 --- a/static/fixed_responses/postTutorialInventory.json +++ /dev/null @@ -1,140 +0,0 @@ -{ - "SubscribedToEmails": 0, - "SubscribedToEmailsPersonalized": 0, - "RewardSeed": -5604904486637265640, - "CrewMemberBin": { "Slots": 3 }, - "CrewShipSalvageBin": { "Slots": 8 }, - "DrifterMelee": [{ "ItemType": "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "MechBin": { "Slots": 4 }, - "OperatorAmpBin": { "Slots": 8 }, - "PveBonusLoadoutBin": { "Slots": 0 }, - "PvpBonusLoadoutBin": { "Slots": 0 }, - "RandomModBin": { "Slots": 15 }, - "SentinelBin": { "Slots": 10 }, - "SpaceSuitBin": { "Slots": 4 }, - "SpaceWeaponBin": { "Slots": 4 }, - "SuitBin": { "Slots": 1 }, - "WeaponBin": { "Slots": 5 }, - "DuviriInfo": { "Seed": 5898912197983600352, "NumCompletions": 0 }, - "Recipes": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Recipes/Weapons/BoltonfaBlueprint" }], - "SeasonChallengeHistory": [ - { "challenge": "SeasonDailySolveCiphers", "id": "001000220000000000000308" }, - { "challenge": "SeasonDailyVisitFeaturedDojo", "id": "001000230000000000000316" }, - { "challenge": "SeasonDailyKillEnemiesWithRadiation", "id": "001000230000000000000317" }, - { "challenge": "SeasonWeeklyCompleteSortie", "id": "001000230000000000000309" }, - { "challenge": "SeasonWeeklyVenusBounties", "id": "001000230000000000000310" }, - { "challenge": "SeasonWeeklyZarimanBountyHunter", "id": "001000230000000000000311" }, - { "challenge": "SeasonWeeklyCatchRarePlainsFish", "id": "001000230000000000000312" }, - { "challenge": "SeasonWeeklyKillArchgunEnemies", "id": "001000230000000000000313" }, - { "challenge": "SeasonWeeklyHardKillSilverGroveSpecters", "id": "001000230000000000000314" }, - { "challenge": "SeasonWeeklyHardKillRopalolyst", "id": "001000230000000000000315" } - ], - "StoryModeChoice": "WARFRAME", - "ChallengeProgress": [{ "Progress": 2, "Name": "EMGetKills" }], - "ChallengesFixVersion": 6, - "ActiveQuest": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", - "Consumables": [{ "ItemCount": 1, "ItemType": "/Lotus/Types/Restoratives/LisetAutoHack" }], - "DataKnives": [{ "ItemType": "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon", "XP": 450000, "ItemId": { "$oid": "647bd274f22fc794a2cd3d33" } }], - "FlavourItems": [ - { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" }, - { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" }, - { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" }, - { "ItemType": "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" } - ], - "LongGuns": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Paris", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "Melee": [{ "ItemType": "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "Pistols": [{ "ItemType": "/Lotus/Weapons/MK1Series/MK1Kunai", "XP": 0, "Configs": [{}, {}, {}], "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "PlayedParkourTutorial": true, - "QuestKeys": [{ "ItemType": "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" }], - "RawUpgrades": [{ "ItemCount": 1, "LastAdded": { "$oid": "6450f9bfe0714a4d6703f05f" }, "ItemType": "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod" }], - "ReceivedStartingGear": true, - "Scoops": [{ "ItemType": "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "Suits": [{ "ItemType": "/Lotus/Powersuits/Volt/Volt", "XP": 0, "Configs": [{}, {}, {}], "UpgradeVer": 101, "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "TrainingRetriesLeft": 0, - "WeaponSkins": [{ "ItemType": "/Lotus/Upgrades/Skins/Volt/VoltHelmet", "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } }], - "LastInventorySync": { "$oid": "647bd27cf856530b4f3bf343" }, - "NextRefill": { "$date": { "$numberLong": "1685829131" } }, - "ActiveLandscapeTraps": [], - "CrewMembers": [], - "CrewShips": [], - "CrewShipHarnesses": [], - "CrewShipSalvagedWeapons": [], - "CrewShipSalvagedWeaponSkins": [], - "CrewShipWeapons": [], - "CrewShipWeaponSkins": [], - "DrifterGuns": [], - "Drones": [], - "Horses": [ - { - "ItemType": "/Lotus/Types/NeutralCreatures/ErsatzHorse/ErsatzHorsePowerSuit", - "Configs": [ - { - "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] - }, - { - "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] - }, - { - "Skins": ["", "", "/Lotus/Upgrades/Skins/Horse/ErsatzHorseTailDefault"] - } - ], - "UpgradeVer": 101, - "ItemId": { "$oid": "647bd27cf856530b4f3bf343" } - } - ], - "Hoverboards": [], - "KubrowPets": [], - "KubrowPetEggs": [], - "KubrowPetPrints": [], - "MechSuits": [], - "MoaPets": [], - "OperatorAmps": [], - "OperatorLoadOuts": [], - "AdultOperatorLoadOuts": [], - "KahlLoadOuts": [], - "PendingRecipes": [], - "TrainingDate": 0, - "PersonalGoalProgress": [], - "PersonalTechProjects": [], - "QualifyingInvasions": [], - "RepVotes": [], - "Sentinels": [], - "SentinelWeapons": [], - "SpaceGuns": [], - "SpaceMelee": [], - "SpaceSuits": [], - "SpecialItems": [], - "StepSequencers": [], - "Upgrades": [], - "Boosters": [], - "EmailItems": [], - "FocusUpgrades": [], - "FusionTreasures": [], - "LeagueTickets": [], - "LevelKeys": [], - "LoreFragmentScans": [], - "MiscItems": [], - "PendingSpectreLoadouts": [], - "Quests": [], - "Robotics": [], - "ShipDecorations": [], - "SpectreLoadouts": [], - "XPInfo": [], - "CrewShipAmmo": [], - "CrewShipRawSalvage": [], - "EvolutionProgress": [], - "Missions": [], - "TauntHistory": [], - "CompletedSyndicates": [], - "UsedDailyDeals": [], - "LibraryAvailableDailyTaskInfo": { - "EnemyTypes": ["/Lotus/Types/Enemies/Orokin/OrokinBladeSawmanAvatar"], - "EnemyLocTag": "/Lotus/Language/Game/OrokinBladeSawman", - "EnemyIcon": "/Lotus/Interface/Icons/Npcs/Orokin/OrokinBladeSawman.png", - "ScansRequired": 4, - "RewardStoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/UncommonFusionBundle", - "RewardQuantity": 10, - "RewardStanding": 10000 - }, - "PendingCoupon": { "Expiry": { "$date": { "$numberLong": "0" } }, "Discount": 0 } -} -- 2.47.2 From ff9d2cddf13b787ed03fa78bb0ec565c5c5acfde Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Thu, 9 Jan 2025 05:22:39 +0100 Subject: [PATCH 03/34] Update personalRoomsModel.ts --- src/models/personalRoomsModel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/personalRoomsModel.ts b/src/models/personalRoomsModel.ts index 382083e8..448cd52f 100644 --- a/src/models/personalRoomsModel.ts +++ b/src/models/personalRoomsModel.ts @@ -90,7 +90,7 @@ const orbiterSchema = new Schema( { Features: [String], Rooms: [roomSchema], - ContentUrlSignature: String, + ContentUrlSignature: { type: String, required: false }, BootLocation: String }, { _id: false } -- 2.47.2 From cd5aaaa6cfff08bf1c54eca444142a730677a215 Mon Sep 17 00:00:00 2001 From: Sainan Date: Thu, 9 Jan 2025 05:54:29 +0100 Subject: [PATCH 04/34] fix: change cavia bounties every 2.5 hours (#748) --- src/controllers/dynamic/worldStateController.ts | 10 +++++++++- static/fixed_responses/worldState.json | 8 -------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index 9bc7f137..b95e621b 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -22,7 +22,7 @@ export const worldStateController: RequestHandler = (req, res) => { Seed: week // unfaithful }); - // Holdfast & Hex bounties cycling every 2.5 hours; unfaithful implementation + // Holdfast, Cavia, & Hex bounties cycling every 2.5 hours; unfaithful implementation const bountyCycle = Math.trunc(new Date().getTime() / 9000000); const bountyCycleStart = bountyCycle * 9000000; const bountyCycleEnd = bountyCycleStart + 9000000; @@ -34,6 +34,14 @@ export const worldStateController: RequestHandler = (req, res) => { Seed: bountyCycle, Nodes: [] }); + worldState.SyndicateMissions.push({ + _id: { $oid: bountyCycleStart.toString(16) + "0000000000000004" }, + Activation: { $date: { $numberLong: bountyCycleStart.toString() } }, + Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } }, + Tag: "EntratiLabSyndicate", + Seed: bountyCycle, + Nodes: [] + }); worldState.SyndicateMissions.push({ _id: { $oid: bountyCycleStart.toString(16) + "0000000000000006" }, Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } }, diff --git a/static/fixed_responses/worldState.json b/static/fixed_responses/worldState.json index 4f272b4e..54b6903a 100644 --- a/static/fixed_responses/worldState.json +++ b/static/fixed_responses/worldState.json @@ -340,14 +340,6 @@ } ] }, - { - "_id": { "$oid": "663a71c80000000000000004" }, - "Activation": { "$date": { "$numberLong": "1715106248403" } }, - "Expiry": { "$date": { "$numberLong": "2000000000000" } }, - "Tag": "EntratiLabSyndicate", - "Seed": 99562, - "Nodes": [] - }, { "_id": { "$oid": "663a71c80000000000000008" }, "Activation": { "$date": { "$numberLong": "1715106248403" } }, -- 2.47.2 From 56906a0f69a0b7c2df0f38572bd05f5e195ad694 Mon Sep 17 00:00:00 2001 From: Sainan Date: Thu, 9 Jan 2025 07:17:29 +0100 Subject: [PATCH 05/34] chore: npm run prettier --- .../TeshinHardModeVendorManifest.json | 1198 ++++++++--------- 1 file changed, 599 insertions(+), 599 deletions(-) diff --git a/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json b/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json index abfd1cab..e6f944e6 100644 --- a/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json +++ b/static/fixed_responses/getVendorInfo/TeshinHardModeVendorManifest.json @@ -1,603 +1,603 @@ { - "VendorInfo":{ - "_id":{ - "$oid":"63ed01efbdaa38891767bac9" - }, - "TypeName":"/Lotus/Types/Game/VendorManifests/Hubs/TeshinHardModeVendorManifest", - "ItemManifest":[ - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinArmsBlueprint", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9947" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinBodyBlueprint", - "ItemPrices":[ - { - "ItemCount":25, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9948" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinHeadBlueprint", - "ItemPrices":[ - { - "ItemCount":20, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9949" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinLegsBlueprint", - "ItemPrices":[ - { - "ItemCount":25, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994a" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994b" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994c" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/Components/FormaStanceBlueprint", - "ItemPrices":[ - { - "ItemCount":10, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994d" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Skins/Effects/OrbsEphemera", - "ItemPrices":[ - { - "ItemCount":3, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994e" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Skins/Effects/TatsuSkullEphemera", - "ItemPrices":[ - { - "ItemCount":85, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e994f" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/Randomized/RawShotgunRandomMod", - "ItemPrices":[ - { - "ItemCount":75, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9950" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Recipes/Components/UmbraFormaBlueprint", - "ItemPrices":[ - { - "ItemCount":150, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9951" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/Kuva", - "ItemPrices":[ - { - "ItemCount":55, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":50000, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9952" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularPistolRandomMod", - "ItemPrices":[ - { - "ItemCount":75, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9953" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/Forma", - "ItemPrices":[ - { - "ItemCount":75, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":3, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9954" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularMeleeRandomMod", - "ItemPrices":[ - { - "ItemCount":75, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9955" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/FusionBundles/EvergreenLoginRewardFusionBundle", - "ItemPrices":[ - { - "ItemCount":150, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9956" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/Randomized/RawRifleRandomMod", - "ItemPrices":[ - { - "ItemCount":75, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9957" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Upgrades/Mods/Shotgun/WeaponRecoilReductionMod", - "ItemPrices":[ - { - "ItemCount":35, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9958" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/ShipDecos/TeshinBobbleHead", - "ItemPrices":[ - { - "ItemCount":35, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e9959" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageGaussVED", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995a" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageGrendelVED", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995b" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageProteaAction", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995c" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/ShipDecos/TeaSet", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995d" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageXakuAction", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995e" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/RivenIdentifier", - "ItemPrices":[ - { - "ItemCount":20, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"2051240400000" - } - }, - "PurchaseQuantityLimit":1, - "RotatedWeekly":true, - "AllowMultipurchase":false, - "Id":{ - "$oid":"66fd60b20ba592c4c95e995f" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/BoosterPacks/RandomSyndicateProjectionPack", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":1, - "Expiry":{ - "$date":{ - "$numberLong":"1736726400000" - } - }, - "PurchaseQuantityLimit":25, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e997c" - } - }, - { - "StoreItem":"/Lotus/StoreItems/Types/Items/MiscItems/Kuva", - "ItemPrices":[ - { - "ItemCount":15, - "ItemType":"/Lotus/Types/Items/MiscItems/SteelEssence", - "ProductCategory":"MiscItems" - } - ], - "Bin":"BIN_0", - "QuantityMultiplier":10000, - "Expiry":{ - "$date":{ - "$numberLong":"1736726400000" - } - }, - "PurchaseQuantityLimit":25, - "AllowMultipurchase":true, - "Id":{ - "$oid":"66fd60b20ba592c4c95e997d" - } - } + "VendorInfo": { + "_id": { + "$oid": "63ed01efbdaa38891767bac9" + }, + "TypeName": "/Lotus/Types/Game/VendorManifests/Hubs/TeshinHardModeVendorManifest", + "ItemManifest": [ + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinArmsBlueprint", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } ], - "PropertyTextHash":"0A0F20AFA748FBEE490510DBF5A33A0D", - "Expiry":{ - "$date":{ - "$numberLong":"1736726400000" - } + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e9947" } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinBodyBlueprint", + "ItemPrices": [ + { + "ItemCount": 25, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e9948" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinHeadBlueprint", + "ItemPrices": [ + { + "ItemCount": 20, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e9949" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/OperatorArmour/HardMode/OperatorTeshinLegsBlueprint", + "ItemPrices": [ + { + "ItemCount": 25, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994a" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994b" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994c" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/Components/FormaStanceBlueprint", + "ItemPrices": [ + { + "ItemCount": 10, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994d" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Effects/OrbsEphemera", + "ItemPrices": [ + { + "ItemCount": 3, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994e" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Skins/Effects/TatsuSkullEphemera", + "ItemPrices": [ + { + "ItemCount": 85, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e994f" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawShotgunRandomMod", + "ItemPrices": [ + { + "ItemCount": 75, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9950" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Recipes/Components/UmbraFormaBlueprint", + "ItemPrices": [ + { + "ItemCount": 150, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9951" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva", + "ItemPrices": [ + { + "ItemCount": 55, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 50000, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9952" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularPistolRandomMod", + "ItemPrices": [ + { + "ItemCount": 75, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9953" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Forma", + "ItemPrices": [ + { + "ItemCount": 75, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 3, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9954" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawModularMeleeRandomMod", + "ItemPrices": [ + { + "ItemCount": 75, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9955" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/EvergreenLoginRewardFusionBundle", + "ItemPrices": [ + { + "ItemCount": 150, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9956" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/Randomized/RawRifleRandomMod", + "ItemPrices": [ + { + "ItemCount": 75, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e9957" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Upgrades/Mods/Shotgun/WeaponRecoilReductionMod", + "ItemPrices": [ + { + "ItemCount": 35, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e9958" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/TeshinBobbleHead", + "ItemPrices": [ + { + "ItemCount": 35, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e9959" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageGaussVED", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e995a" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/ImageGrendelVED", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e995b" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageProteaAction", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e995c" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/ShipDecos/TeaSet", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e995d" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageXakuAction", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e995e" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/RivenIdentifier", + "ItemPrices": [ + { + "ItemCount": 20, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "2051240400000" + } + }, + "PurchaseQuantityLimit": 1, + "RotatedWeekly": true, + "AllowMultipurchase": false, + "Id": { + "$oid": "66fd60b20ba592c4c95e995f" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/BoosterPacks/RandomSyndicateProjectionPack", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 1, + "Expiry": { + "$date": { + "$numberLong": "1736726400000" + } + }, + "PurchaseQuantityLimit": 25, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e997c" + } + }, + { + "StoreItem": "/Lotus/StoreItems/Types/Items/MiscItems/Kuva", + "ItemPrices": [ + { + "ItemCount": 15, + "ItemType": "/Lotus/Types/Items/MiscItems/SteelEssence", + "ProductCategory": "MiscItems" + } + ], + "Bin": "BIN_0", + "QuantityMultiplier": 10000, + "Expiry": { + "$date": { + "$numberLong": "1736726400000" + } + }, + "PurchaseQuantityLimit": 25, + "AllowMultipurchase": true, + "Id": { + "$oid": "66fd60b20ba592c4c95e997d" + } + } + ], + "PropertyTextHash": "0A0F20AFA748FBEE490510DBF5A33A0D", + "Expiry": { + "$date": { + "$numberLong": "1736726400000" + } } -} \ No newline at end of file + } +} -- 2.47.2 From c07f7502a4a8343dba435d88b32709772bd46679 Mon Sep 17 00:00:00 2001 From: Sainan Date: Thu, 9 Jan 2025 07:29:10 +0100 Subject: [PATCH 06/34] fix(coderabbit): disable commit_status as it now indicates failure on rate limit --- .coderabbit.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index bef7714d..29d9043a 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -8,6 +8,7 @@ reviews: high_level_summary: false poem: false review_status: true + commit_status: false collapse_walkthrough: false sequence_diagrams: false related_prs: false -- 2.47.2 From 1c654650d4559c4a8c0e2ede5f22f0db2cecb2f6 Mon Sep 17 00:00:00 2001 From: Sainan Date: Thu, 9 Jan 2025 14:02:12 +0100 Subject: [PATCH 07/34] fix: cap helminth resources at 100% (#757) --- src/controllers/api/infestedFoundryController.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/controllers/api/infestedFoundryController.ts b/src/controllers/api/infestedFoundryController.ts index 04144475..16c356fe 100644 --- a/src/controllers/api/infestedFoundryController.ts +++ b/src/controllers/api/infestedFoundryController.ts @@ -176,6 +176,7 @@ export const infestedFoundryController: RequestHandler = async (req, res) => { totalPercentagePointsGained += snack.gain * 100 * apetiteFactor; // 30% would be gain=0.3, so percentage points is equal to gain * 100. resource.Count += Math.trunc(snack.gain * 1000 * apetiteFactor); // 30% would be gain=0.3 or Count=300, so Count=gain*1000. + if (resource.Count > 1000) resource.Count = 1000; } const recipeChanges = addInfestedFoundryXP(inventory.InfestedFoundry, 666 * totalPercentagePointsGained); -- 2.47.2 From eafdd9f75562ab778ce3677de35b8e3c0c803bb6 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 10 Jan 2025 06:23:25 +0100 Subject: [PATCH 08/34] fix: worldState growing with every request (#760) --- .../dynamic/worldStateController.ts | 23 +++++++--------- static/fixed_responses/worldState.json | 26 ++++++++++++++++++- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index b95e621b..8ad722be 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -5,51 +5,48 @@ import { IMongoDate, IOid } from "@/src/types/commonTypes"; export const worldStateController: RequestHandler = (req, res) => { const worldState: IWorldState = { - ...staticWorldState, BuildLabel: typeof req.query.buildLabel == "string" ? req.query.buildLabel.split(" ").join("+") : buildConfig.buildLabel, - Time: Math.round(Date.now() / 1000) + Time: Math.round(Date.now() / 1000), + EndlessXpChoices: [], + ...staticWorldState }; const week = Math.trunc(new Date().getTime() / 604800000); // Elite Sanctuary Onslaught cycling every week - worldState.NodeOverrides.push({ - _id: { $oid: "5ad9f9bb6df82a56eabf3d44" }, - Node: "SolNode802", - Seed: week // unfaithful - }); + worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = week; // unfaithful // Holdfast, Cavia, & Hex bounties cycling every 2.5 hours; unfaithful implementation const bountyCycle = Math.trunc(new Date().getTime() / 9000000); const bountyCycleStart = bountyCycle * 9000000; const bountyCycleEnd = bountyCycleStart + 9000000; - worldState.SyndicateMissions.push({ + worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "ZarimanSyndicate")] = { _id: { $oid: bountyCycleStart.toString(16) + "0000000000000029" }, Activation: { $date: { $numberLong: bountyCycleStart.toString() } }, Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } }, Tag: "ZarimanSyndicate", Seed: bountyCycle, Nodes: [] - }); - worldState.SyndicateMissions.push({ + }; + worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "EntratiLabSyndicate")] = { _id: { $oid: bountyCycleStart.toString(16) + "0000000000000004" }, Activation: { $date: { $numberLong: bountyCycleStart.toString() } }, Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } }, Tag: "EntratiLabSyndicate", Seed: bountyCycle, Nodes: [] - }); - worldState.SyndicateMissions.push({ + }; + worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "HexSyndicate")] = { _id: { $oid: bountyCycleStart.toString(16) + "0000000000000006" }, Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } }, Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } }, Tag: "HexSyndicate", Seed: bountyCycle, Nodes: [] - }); + }; // Circuit choices cycling every week worldState.EndlessXpChoices.push({ diff --git a/static/fixed_responses/worldState.json b/static/fixed_responses/worldState.json index 54b6903a..bde87f8a 100644 --- a/static/fixed_responses/worldState.json +++ b/static/fixed_responses/worldState.json @@ -340,6 +340,14 @@ } ] }, + { + "_id": { "$oid": "663a71c80000000000000004" }, + "Activation": { "$date": { "$numberLong": "1715106248403" } }, + "Expiry": { "$date": { "$numberLong": "2000000000000" } }, + "Tag": "EntratiLabSyndicate", + "Seed": 99562, + "Nodes": [] + }, { "_id": { "$oid": "663a71c80000000000000008" }, "Activation": { "$date": { "$numberLong": "1715106248403" } }, @@ -471,6 +479,22 @@ "xpAmounts": [780, 780, 780, 780, 1540] } ] + }, + { + "_id": { "$oid": "663a71c80000000000000029" }, + "Activation": { "$date": { "$numberLong": "1715106248403" } }, + "Expiry": { "$date": { "$numberLong": "2000000000000" } }, + "Tag": "ZarimanSyndicate", + "Seed": 99562, + "Nodes": [] + }, + { + "_id": { "$oid": "676b8d340000000000000006" }, + "Activation": { "$date": { "$numberLong": "1735101748215" } }, + "Expiry": { "$date": { "$numberLong": "2000000000000" } }, + "Tag": "HexSyndicate", + "Seed": 33872, + "Nodes": [] } ], "ActiveMissions": [ @@ -666,6 +690,7 @@ { "_id": { "$oid": "549b18e9b029cef5991d6aec" }, "Node": "EuropaHUB", "Hide": true }, { "_id": { "$oid": "54a1737aeb658f6cbccf70ff" }, "Node": "ErisHUB", "Hide": true }, { "_id": { "$oid": "54a736ddec12f80bd6e9e326" }, "Node": "VenusHUB", "Hide": true }, + { "_id": { "$oid": "5ad9f9bb6df82a56eabf3d44" }, "Node": "SolNode802", "Seed": 9969639 }, { "_id": { "$oid": "5b8817c2bd4f253264d6aa91" }, "Node": "EarthHUB", @@ -1078,7 +1103,6 @@ "ConstructionProjects": [], "TwitchPromos": [], "ExperimentRecommended": [], - "EndlessXpChoices": [], "ForceLogoutVersion": 0, "SeasonInfo": { "Activation": { "$date": { "$numberLong": "1715796000000" } }, -- 2.47.2 From fb8e19403e9e54e1aee815704cbe98a3da209af4 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 11 Jan 2025 07:18:42 +0100 Subject: [PATCH 09/34] feat: cycle 1999 calendar season every week (#756) --- .../dynamic/worldStateController.ts | 32 +++++++- src/services/purchaseService.ts | 2 +- .../worldState/1999_fall_days.json | 77 +++++++++++++++++++ .../worldState/1999_spring_days.json | 75 ++++++++++++++++++ .../worldState/1999_summer_days.json | 75 ++++++++++++++++++ .../worldState/1999_winter_days.json | 75 ++++++++++++++++++ .../{ => worldState}/worldState.json | 0 7 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 static/fixed_responses/worldState/1999_fall_days.json create mode 100644 static/fixed_responses/worldState/1999_spring_days.json create mode 100644 static/fixed_responses/worldState/1999_summer_days.json create mode 100644 static/fixed_responses/worldState/1999_winter_days.json rename static/fixed_responses/{ => worldState}/worldState.json (100%) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index 8ad722be..4dc8ec09 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -1,5 +1,9 @@ import { RequestHandler } from "express"; -import staticWorldState from "@/static/fixed_responses/worldState.json"; +import staticWorldState from "@/static/fixed_responses/worldState/worldState.json"; +import static1999FallDays from "@/static/fixed_responses/worldState/1999_fall_days.json"; +import static1999SpringDays from "@/static/fixed_responses/worldState/1999_spring_days.json"; +import static1999SummerDays from "@/static/fixed_responses/worldState/1999_summer_days.json"; +import static1999WinterDays from "@/static/fixed_responses/worldState/1999_winter_days.json"; import { buildConfig } from "@/src/services/buildConfigService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; @@ -14,7 +18,10 @@ export const worldStateController: RequestHandler = (req, res) => { ...staticWorldState }; - const week = Math.trunc(new Date().getTime() / 604800000); + const day = Math.trunc(new Date().getTime() / 86400000); + const week = Math.trunc((day + 4) / 7); // week begins on mondays + const weekStart = week * 604800000; + const weekEnd = weekStart + 604800000; // Elite Sanctuary Onslaught cycling every week worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = week; // unfaithful @@ -79,6 +86,17 @@ export const worldStateController: RequestHandler = (req, res) => { ][week % 8] }); + // 1999 Calendar Season cycling every week + worldState.KnownCalendarSeasons[0].Activation = { $date: { $numberLong: weekStart.toString() } }; + worldState.KnownCalendarSeasons[0].Expiry = { $date: { $numberLong: weekEnd.toString() } }; + worldState.KnownCalendarSeasons[0].Season = ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][week % 4]; + worldState.KnownCalendarSeasons[0].Days = [ + static1999WinterDays, + static1999SpringDays, + static1999SummerDays, + static1999FallDays + ][week % 4]; + res.json(worldState); }; @@ -88,6 +106,7 @@ interface IWorldState { SyndicateMissions: ISyndicateMission[]; NodeOverrides: INodeOverride[]; EndlessXpChoices: IEndlessXpChoice[]; + KnownCalendarSeasons: ICalendarSeason[]; } interface ISyndicateMission { @@ -115,3 +134,12 @@ interface IEndlessXpChoice { Category: string; Choices: string[]; } + +interface ICalendarSeason { + Activation: IMongoDate; + Expiry: IMongoDate; + Season: string; // "CST_UNDEFINED" | "CST_WINTER" | "CST_SPRING" | "CST_SUMMER" | "CST_FALL" + Days: { + day: number; + }[]; +} diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 6e8a38f6..2d2e4beb 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -14,7 +14,7 @@ import { getVendorManifestByOid } from "@/src/services/serversideVendorsService" import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IPurchaseRequest, IPurchaseResponse, SlotPurchase, IInventoryChanges } from "@/src/types/purchaseTypes"; import { logger } from "@/src/utils/logger"; -import worldState from "@/static/fixed_responses/worldState.json"; +import worldState from "@/static/fixed_responses/worldState/worldState.json"; import { ExportBoosterPacks, ExportBundles, diff --git a/static/fixed_responses/worldState/1999_fall_days.json b/static/fixed_responses/worldState/1999_fall_days.json new file mode 100644 index 00000000..3bcd30eb --- /dev/null +++ b/static/fixed_responses/worldState/1999_fall_days.json @@ -0,0 +1,77 @@ +[ + { "day": 276, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] }, + { + "day": 283, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GasChanceToPrimaryAndSecondary" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricStatusDamageAndChance" } + ] + }, + { + "day": 289, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" } + ] + }, + { "day": 295, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithMeleeEasy" }] }, + { + "day": 302, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" } + ] + }, + { "day": 305, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusMedium" }] }, + { "day": 306, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/EleanorDialogue_rom.dialogue", "dialogueConvo": "EleanorBirthdayConvo" }] }, + { "day": 307, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/ArthurDialogue_rom.dialogue", "dialogueConvo": "ArthurBirthdayConvo" }] }, + { + "day": 309, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal" } + ] + }, + { + "day": 314, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/PowerStrengthAndEfficiencyPerEnergySpent" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricalDamageOnBulletJump" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeSlideFowardMomentumOnEnemyHit" } + ] + }, + { "day": 322, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesMedium" }] }, + { + "day": 328, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" } + ] + }, + { "day": 337, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesHard" }] }, + { "day": 338, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/QuincyDialogue_rom.dialogue", "dialogueConvo": "QuincyBirthdayConvo" }] }, + { + "day": 340, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeCritChance" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/RadiationProcOnTakeDamage" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" } + ] + }, + { + "day": 343, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/FormaAura" } + ] + }, + { "day": 352, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTankHard" }] }, + { + "day": 364, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/ModDropChanceBooster3DayStoreItem" } + ] + } +] diff --git a/static/fixed_responses/worldState/1999_spring_days.json b/static/fixed_responses/worldState/1999_spring_days.json new file mode 100644 index 00000000..4386f2a4 --- /dev/null +++ b/static/fixed_responses/worldState/1999_spring_days.json @@ -0,0 +1,75 @@ +[ + { "day": 100, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] }, + { + "day": 101, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/ElectricStatusDamageAndChance" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyRestoration" } + ] + }, + { + "day": 102, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" } + ] + }, + { "day": 106, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesEasy" }] }, + { + "day": 107, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" } + ] + }, + { "day": 122, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeMedium" }] }, + { + "day": 127, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarVosforPack" } + ] + }, + { "day": 129, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium" }] }, + { + "day": 135, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker" } + ] + }, + { + "day": 142, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/BlastEveryXShots" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MagnitizeWithinRangeEveryXCasts" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GenerateOmniOrbsOnWeakKill" } + ] + }, + { "day": 143, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/JabirDialogue_rom.dialogue", "dialogueConvo": "AmirBirthdayConvo" }] }, + { "day": 161, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithAbilitiesHard" }] }, + { + "day": 165, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/Forma" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/ModDropChanceBooster3DayStoreItem" } + ] + }, + { "day": 169, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsHard" }] }, + { + "day": 171, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/GasChanceToPrimaryAndSecondary" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeCritChance" } + ] + }, + { + "day": 176, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" } + ] + } +] diff --git a/static/fixed_responses/worldState/1999_summer_days.json b/static/fixed_responses/worldState/1999_summer_days.json new file mode 100644 index 00000000..99beee4a --- /dev/null +++ b/static/fixed_responses/worldState/1999_summer_days.json @@ -0,0 +1,75 @@ +[ + { "day": 186, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] }, + { "day": 191, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/AoiDialogue_rom.dialogue", "dialogueConvo": "AoiBirthdayConvo" }] }, + { + "day": 193, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalAmar" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" } + ] + }, + { + "day": 197, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeAttackSpeed" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/AbilityStrength" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" } + ] + }, + { "day": 199, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium" }] }, + { + "day": 210, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle" } + ] + }, + { "day": 215, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesWithMeleeEasy" }] }, + { + "day": 228, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarRivenPack" } + ] + }, + { "day": 236, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium" }] }, + { + "day": 237, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleLarge" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" } + ] + }, + { + "day": 240, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/RadialJavelinOnHeavy" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/SharedFreeAbilityEveryXCasts" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionsRadiationChance" } + ] + }, + { "day": 245, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesHard" }] }, + { + "day": 250, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint" } + ] + }, + { "day": 254, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTankHard" }] }, + { + "day": 267, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" } + ] + }, + { + "day": 270, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/PunchToPrimary" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/OvershieldCap" } + ] + } +] diff --git a/static/fixed_responses/worldState/1999_winter_days.json b/static/fixed_responses/worldState/1999_winter_days.json new file mode 100644 index 00000000..700866d3 --- /dev/null +++ b/static/fixed_responses/worldState/1999_winter_days.json @@ -0,0 +1,75 @@ +[ + { "day": 6, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEximusEasy" }] }, + { + "day": 15, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MagazineCapacity" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/Armor" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyRestoration" } + ] + }, + { "day": 21, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesEasy" }] }, + { + "day": 25, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Gameplay/NarmerSorties/ArchonCrystalGreen" } + ] + }, + { + "day": 31, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/WeaponUtilityUnlockerBlueprint" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" } + ] + }, + { "day": 43, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillEnemiesWithAbilitiesMedium" }] }, + { "day": 45, "events": [{ "type": "CET_PLOT", "dialogueName": "/Lotus/Types/Gameplay/1999Wf/Dialogue/LettieDialogue_rom.dialogue", "dialogueConvo": "LettieBirthdayConvo" }] }, + { + "day": 47, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Boosters/AffinityBooster3DayStoreItem" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarMajorArtifactPack" } + ] + }, + { "day": 48, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillScaldraEnemiesWithMeleeMedium" }] }, + { + "day": 54, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionsBuffNearbyPlayer" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/OrbsDuplicateOnPickup" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/FinisherChancePerComboMultiplier" } + ] + }, + { + "day": 56, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/BoosterPacks/CalendarArtifactPack" }, + { "type": "CET_REWARD", "reward": "/Lotus/Types/StoreItems/Packages/Calendar/CalendarKuvaBundleSmall" } + ] + }, + { "day": 71, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarKillTechrotEnemiesHard" }] }, + { + "day": 77, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Upgrades/Mods/FusionBundles/CircuitSilverSteelPathFusionBundle" } + ] + }, + { "day": 80, "events": [{ "type": "CET_CHALLENGE", "challenge": "/Lotus/Types/Challenges/Calendar1999/CalendarDestroyPropsMedium" }] }, + { + "day": 83, + "events": [ + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Recipes/Components/OrokinReactorBlueprint" }, + { "type": "CET_REWARD", "reward": "/Lotus/StoreItems/Types/Items/MiscItems/WeaponUtilityUnlocker" } + ] + }, + { + "day": 87, + "events": [ + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/EnergyOrbToAbilityRange" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/MeleeAttackSpeed" }, + { "type": "CET_UPGRADE", "upgrade": "/Lotus/Upgrades/Calendar/CompanionDamage" } + ] + } +] diff --git a/static/fixed_responses/worldState.json b/static/fixed_responses/worldState/worldState.json similarity index 100% rename from static/fixed_responses/worldState.json rename to static/fixed_responses/worldState/worldState.json -- 2.47.2 From e8e918ff0cce3b3fd93c7d8ef32cb8be3a9b0431 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 11 Jan 2025 12:54:11 +0100 Subject: [PATCH 10/34] fix: purchasing of ship decorations (#761) --- src/services/inventoryService.ts | 42 ++++++++++---------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 3968fc77..28c6cbba 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -142,6 +142,19 @@ export const addItem = async ( } else if (ExportResources[typeName].productCategory == "CrewShips") { const inventoryChanges = addCrewShip(inventory, typeName); return { InventoryChanges: inventoryChanges }; + } else if (ExportResources[typeName].productCategory == "ShipDecorations") { + const changes = [ + { + ItemType: typeName, + ItemCount: quantity + } satisfies IMiscItem + ]; + addShipDecorations(inventory, changes); + return { + InventoryChanges: { + ShipDecorations: changes + } + }; } else { const miscItemChanges = [ { @@ -253,21 +266,6 @@ export const addItem = async ( } }; } - case "Objects": { - // /Lotus/Objects/Tenno/Props/TnoLisetTextProjector (Note Beacon) - const changes = [ - { - ItemType: typeName, - ItemCount: quantity - } satisfies IMiscItem - ]; - addShipDecorations(inventory, changes); - return { - InventoryChanges: { - ShipDecorations: changes - } - }; - } case "Types": switch (typeName.substr(1).split("/")[2]) { case "Sentinels": { @@ -282,20 +280,6 @@ export const addItem = async ( } case "Items": { switch (typeName.substr(1).split("/")[3]) { - case "ShipDecos": { - const changes = [ - { - ItemType: typeName, - ItemCount: quantity - } satisfies IMiscItem - ]; - addShipDecorations(inventory, changes); - return { - InventoryChanges: { - ShipDecorations: changes - } - }; - } default: { const miscItemChanges = [ { -- 2.47.2 From 25459503d18a93fc327232737eaa4d0142f855ac Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 11 Jan 2025 12:54:32 +0100 Subject: [PATCH 11/34] feat: changing equipped shawzin/instrument (#762) --- .../api/setEquippedInstrumentController.ts | 17 +++++++++++++++++ src/routes/api.ts | 2 ++ src/types/inventoryTypes/inventoryTypes.ts | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/controllers/api/setEquippedInstrumentController.ts diff --git a/src/controllers/api/setEquippedInstrumentController.ts b/src/controllers/api/setEquippedInstrumentController.ts new file mode 100644 index 00000000..0781825a --- /dev/null +++ b/src/controllers/api/setEquippedInstrumentController.ts @@ -0,0 +1,17 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; + +export const setEquippedInstrumentController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + const body = getJSONfromString(String(req.body)) as ISetEquippedInstrumentRequest; + inventory.EquippedInstrument = body.Instrument; + await inventory.save(); + res.end(); +}; + +interface ISetEquippedInstrumentRequest { + Instrument: string; +} diff --git a/src/routes/api.ts b/src/routes/api.ts index 2cc428a7..b6e2613c 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -56,6 +56,7 @@ import { sellController } from "@/src/controllers/api/sellController"; import { setActiveQuestController } from "@/src/controllers/api/setActiveQuestController"; import { setActiveShipController } from "@/src/controllers/api/setActiveShipController"; import { setBootLocationController } from "@/src/controllers/api/setBootLocationController"; +import { setEquippedInstrumentController } from "@/src/controllers/api/setEquippedInstrumentController"; import { setPlacedDecoInfoController } from "@/src/controllers/api/setPlacedDecoInfoController"; import { setShipCustomizationsController } from "@/src/controllers/api/setShipCustomizationsController"; import { setShipFavouriteLoadoutController } from "@/src/controllers/api/setShipFavouriteLoadoutController"; @@ -141,6 +142,7 @@ apiRouter.post("/purchase.php", purchaseController); apiRouter.post("/rerollRandomMod.php", rerollRandomModController); apiRouter.post("/saveLoadout.php", saveLoadoutController); apiRouter.post("/sell.php", sellController); +apiRouter.post("/setEquippedInstrument.php", setEquippedInstrumentController); apiRouter.post("/setPlacedDecoInfo.php", setPlacedDecoInfoController); apiRouter.post("/setShipCustomizations.php", setShipCustomizationsController); apiRouter.post("/setShipFavouriteLoadout.php", setShipFavouriteLoadoutController); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 89088da2..dc9e6ef3 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -250,7 +250,7 @@ export interface IInventoryResponse { CompletedJobChains: ICompletedJobChain[]; SeasonChallengeHistory: ISeasonChallenge[]; MoaPets: IEquipmentDatabase[]; - EquippedInstrument: string; + EquippedInstrument?: string; InvasionChainProgress: IInvasionChainProgress[]; DataKnives: IEquipmentDatabase[]; Motorcycles: IEquipmentDatabase[]; -- 2.47.2 From f6265d57ec297984d1ce8b03e5e8cc255cbab34f Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Sat, 11 Jan 2025 23:01:33 +0100 Subject: [PATCH 12/34] feat: Sentient Anomaly rotation (#759) Co-authored-by: Sainan --- .../dynamic/worldStateController.ts | 32 +++++++++++++++++++ .../worldState/worldState.json | 3 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index 4dc8ec09..a102caf0 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -6,6 +6,7 @@ import static1999SummerDays from "@/static/fixed_responses/worldState/1999_summe import static1999WinterDays from "@/static/fixed_responses/worldState/1999_winter_days.json"; import { buildConfig } from "@/src/services/buildConfigService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; +import { unixTimesInMs } from "@/src/constants/timeConstants"; export const worldStateController: RequestHandler = (req, res) => { const worldState: IWorldState = { @@ -97,6 +98,36 @@ export const worldStateController: RequestHandler = (req, res) => { static1999FallDays ][week % 4]; + // Sentient Anomaly cycling every 30 minutes + const halfHour = Math.trunc(new Date().getTime() / (unixTimesInMs.hour / 2)); + const tmp = { + cavabegin: "1690761600", + PurchasePlatformLockEnabled: true, + tcsn: true, + pgr: { + ts: "1732572900", + en: "CUSTOM DECALS @ ZEVILA", + fr: "DECALS CUSTOM @ ZEVILA", + it: "DECALCOMANIE PERSONALIZZATE @ ZEVILA", + de: "AUFKLEBER NACH WUNSCH @ ZEVILA", + es: "CALCOMANÍAS PERSONALIZADAS @ ZEVILA", + pt: "DECALQUES PERSONALIZADOS NA ZEVILA", + ru: "ПОЛЬЗОВАТЕЛЬСКИЕ НАКЛЕЙКИ @ ЗеВиЛа", + pl: "NOWE NAKLEJKI @ ZEVILA", + uk: "КОРИСТУВАЦЬКІ ДЕКОЛІ @ ЗІВІЛА", + tr: "ÖZEL ÇIKARTMALAR @ ZEVILA", + ja: "カスタムデカール @ ゼビラ", + zh: "定制贴花认准泽威拉", + ko: "커스텀 데칼 @ ZEVILA", + tc: "自訂貼花 @ ZEVILA", + th: "รูปลอกสั่งทำที่ ZEVILA" + }, + ennnd: true, + mbrt: true, + sfn: [550, 553, 554, 555][halfHour % 4] + }; + worldState.Tmp = JSON.stringify(tmp); + res.json(worldState); }; @@ -107,6 +138,7 @@ interface IWorldState { NodeOverrides: INodeOverride[]; EndlessXpChoices: IEndlessXpChoice[]; KnownCalendarSeasons: ICalendarSeason[]; + Tmp?: string; } interface ISyndicateMission { diff --git a/static/fixed_responses/worldState/worldState.json b/static/fixed_responses/worldState/worldState.json index bde87f8a..f37f77fe 100644 --- a/static/fixed_responses/worldState/worldState.json +++ b/static/fixed_responses/worldState/worldState.json @@ -1261,6 +1261,5 @@ "Version": 17, "UpgradeAvaliabilityRequirements": ["/Lotus/Upgrades/Calendar/1999UpgradeApplicationRequirement"] } - ], - "Tmp": "{\"cavabegin\":\"1690761600\",\"PurchasePlatformLockEnabled\":true,\"tcsn\":true,\"pgr\":{\"ts\":\"1732572900\",\"en\":\"CUSTOM DECALS @ ZEVILA\",\"fr\":\"DECALS CUSTOM @ ZEVILA\",\"it\":\"DECALCOMANIE PERSONALIZZATE @ ZEVILA\",\"de\":\"AUFKLEBER NACH WUNSCH @ ZEVILA\",\"es\":\"CALCOMANÍAS PERSONALIZADAS @ ZEVILA\",\"pt\":\"DECALQUES PERSONALIZADOS NA ZEVILA\",\"ru\":\"ПОЛЬЗОВАТЕЛЬСКИЕ НАКЛЕЙКИ @ ЗеВиЛа\",\"pl\":\"NOWE NAKLEJKI @ ZEVILA\",\"uk\":\"КОРИСТУВАЦЬКІ ДЕКОЛІ @ ЗІВІЛА\",\"tr\":\"ÖZEL ÇIKARTMALAR @ ZEVILA\",\"ja\":\"カスタムデカール @ ゼビラ\",\"zh\":\"定制贴花认准泽威拉\",\"ko\":\"커스텀 데칼 @ ZEVILA\",\"tc\":\"自訂貼花 @ ZEVILA\",\"th\":\"รูปลอกสั่งทำที่ ZEVILA\"},\"ennnd\":true,\"mbrt\":true,\"sfn\":550}" + ] } -- 2.47.2 From 53d5e7c3f0ea0c1228ea95f1bbe47306bc05bf41 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 11 Jan 2025 23:08:17 +0100 Subject: [PATCH 13/34] fix: make crew member slots optional (#766) --- src/models/inventoryModels/inventoryModel.ts | 26 ++++++++++---------- src/types/inventoryTypes/inventoryTypes.ts | 16 ++++++++---- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 964c89eb..65a5d3d2 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -42,11 +42,12 @@ import { ICrewShipPortGuns, ICrewShipCustomization, ICrewShipWeapon, - ICrewShipMembers, + ICrewShipMembersClient, ICrewShip, ICrewShipPilotWeapon, IShipExterior, - IHelminthFoodRecord + IHelminthFoodRecord, + ICrewShipMembersDatabase } from "../../types/inventoryTypes/inventoryTypes"; import { IOid } from "../../types/commonTypes"; import { @@ -670,23 +671,22 @@ const crewShipCustomizationSchema = new Schema( { _id: false } ); -const crewShipMembersSchema = new Schema( +const crewShipMembersSchema = new Schema( { - SLOT_A: Schema.Types.ObjectId, - SLOT_B: Schema.Types.ObjectId, - SLOT_C: Schema.Types.ObjectId + SLOT_A: { type: Schema.Types.ObjectId, required: false }, + SLOT_B: { type: Schema.Types.ObjectId, required: false }, + SLOT_C: { type: Schema.Types.ObjectId, required: false } }, { _id: false } ); crewShipMembersSchema.set("toJSON", { virtuals: true, - transform(_doc, ret) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - ret.SLOT_A = { ItemId: toOid(ret.SLOT_A) }; - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - ret.SLOT_B = { ItemId: toOid(ret.SLOT_B) }; - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - ret.SLOT_C = { ItemId: toOid(ret.SLOT_C) }; + transform(_doc, obj) { + const db = obj as ICrewShipMembersDatabase; + const client = obj as ICrewShipMembersClient; + client.SLOT_A = db.SLOT_A ? { ItemId: toOid(db.SLOT_A) } : undefined; + client.SLOT_B = db.SLOT_B ? { ItemId: toOid(db.SLOT_B) } : undefined; + client.SLOT_C = db.SLOT_C ? { ItemId: toOid(db.SLOT_C) } : undefined; } }); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index dc9e6ef3..6463a156 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -426,21 +426,27 @@ export interface ICrewShip { Customization?: ICrewShipCustomization; ItemName: string; RailjackImage?: IFlavourItem; - CrewMembers?: ICrewShipMembers; + CrewMembers?: ICrewShipMembersClient; ItemId: IOid; _id: Types.ObjectId; } -export interface ICrewShipMembers { - SLOT_A: ISlot; - SLOT_B: ISlot; - SLOT_C: ISlot; +export interface ICrewShipMembersClient { + SLOT_A?: ISlot; + SLOT_B?: ISlot; + SLOT_C?: ISlot; } export interface ISlot { ItemId: IOid; } +export interface ICrewShipMembersDatabase { + SLOT_A?: Types.ObjectId; + SLOT_B?: Types.ObjectId; + SLOT_C?: Types.ObjectId; +} + export interface ICrewShipCustomization { CrewshipInterior: IShipExterior; } -- 2.47.2 From 2cd47c8ae2e196363100c81fa3373526a298c9e3 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 12 Jan 2025 02:42:27 +0100 Subject: [PATCH 14/34] fix: reproducible oids for unlockAllSkins (#769) --- src/controllers/api/inventoryController.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 4b35a54a..547a38b4 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -158,12 +158,10 @@ export const inventoryController: RequestHandler = async (request, response) => if (config.unlockAllSkins) { inventoryResponse.WeaponSkins = []; - let i = 0; for (const uniqueName in ExportCustoms) { - i++; inventoryResponse.WeaponSkins.push({ ItemId: { - $oid: i.toString().padStart(24, "0") + $oid: "ca70ca70ca70ca70" + catBreadHash(uniqueName).toString(16).padStart(8, "0") }, ItemType: uniqueName }); @@ -251,3 +249,13 @@ const resourceGetParent = (resourceName: string): string | undefined => { } return ExportVirtuals[resourceName]?.parentName; }; + +// This is FNV1a-32 except operating under modulus 2^31 because JavaScript is stinky and likes producing negative integers out of nowhere. +const catBreadHash = (name: string): number => { + let hash = 2166136261; + for (let i = 0; i != name.length; ++i) { + hash = (hash ^ name.charCodeAt(i)) & 0x7fffffff; + hash = (hash * 16777619) & 0x7fffffff; + } + return hash; +}; -- 2.47.2 From 8ebd7068e2cb44731a70e07783b648e0da5f79bb Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 12 Jan 2025 05:54:52 +0100 Subject: [PATCH 15/34] fix: premature week rollover (#771) --- src/controllers/dynamic/worldStateController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index a102caf0..5af6734f 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -20,7 +20,7 @@ export const worldStateController: RequestHandler = (req, res) => { }; const day = Math.trunc(new Date().getTime() / 86400000); - const week = Math.trunc((day + 4) / 7); // week begins on mondays + const week = Math.trunc((day + 3) / 7); // week begins on mondays const weekStart = week * 604800000; const weekEnd = weekStart + 604800000; -- 2.47.2 From 5cbececb0459f31f30b956e266e588f0aa90ab40 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 12 Jan 2025 08:30:56 +0100 Subject: [PATCH 16/34] fix(webui): error on unrevealed riven mod (#773) --- static/webui/script.js | 159 +++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 78 deletions(-) diff --git a/static/webui/script.js b/static/webui/script.js index b0fa52c6..642d1d13 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -327,90 +327,93 @@ function updateInventory() { if (item.ItemType.substr(0, 32) == "/Lotus/Upgrades/Mods/Randomized/") { const rivenType = item.ItemType.substr(32); const fingerprint = JSON.parse(item.UpgradeFingerprint); - - const tr = document.createElement("tr"); - { - const td = document.createElement("td"); - td.textContent = itemMap[fingerprint.compat]?.name ?? fingerprint.compat; - td.textContent += " " + RivenParser.parseRiven(rivenType, fingerprint, 1).name; - td.innerHTML += " ▲ " + fingerprint.buffs.length + ""; - td.innerHTML += " ▼ " + fingerprint.curses.length + ""; - td.innerHTML += - " ⟳ " + parseInt(fingerprint.rerolls) + ""; - tr.appendChild(td); - } - { - const td = document.createElement("td"); - td.classList = "text-end"; + if (fingerprint.buffs) { + // Riven has been revealed? + const tr = document.createElement("tr"); { - const a = document.createElement("a"); - a.href = - "riven-tool/#" + - encodeURIComponent( - JSON.stringify({ - rivenType: rivenType, - omegaAttenuation: 1, - fingerprint: fingerprint - }) - ); - a.target = "_blank"; - a.title = "View Stats"; - a.innerHTML = ``; - td.appendChild(a); + const td = document.createElement("td"); + td.textContent = itemMap[fingerprint.compat]?.name ?? fingerprint.compat; + td.textContent += " " + RivenParser.parseRiven(rivenType, fingerprint, 1).name; + td.innerHTML += " ▲ " + fingerprint.buffs.length + ""; + td.innerHTML += + " ▼ " + fingerprint.curses.length + ""; + td.innerHTML += + " ⟳ " + parseInt(fingerprint.rerolls) + ""; + tr.appendChild(td); } { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - disposeOfGear("Upgrades", item.ItemId.$oid); - }; - a.title = "Remove"; - a.innerHTML = ``; - td.appendChild(a); + const td = document.createElement("td"); + td.classList = "text-end"; + { + const a = document.createElement("a"); + a.href = + "riven-tool/#" + + encodeURIComponent( + JSON.stringify({ + rivenType: rivenType, + omegaAttenuation: 1, + fingerprint: fingerprint + }) + ); + a.target = "_blank"; + a.title = "View Stats"; + a.innerHTML = ``; + td.appendChild(a); + } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + disposeOfGear("Upgrades", item.ItemId.$oid); + }; + a.title = "Remove"; + a.innerHTML = ``; + td.appendChild(a); + } + tr.appendChild(td); } - tr.appendChild(td); + document.getElementById("riven-list").appendChild(tr); + return; } - document.getElementById("riven-list").appendChild(tr); - } else { - const tr = document.createElement("tr"); - const rank = parseInt(JSON.parse(item.UpgradeFingerprint).lvl); - const maxRank = itemMap[item.ItemType]?.fusionLimit ?? 5; - { - const td = document.createElement("td"); - td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; - td.innerHTML += " ★ " + rank + "/" + maxRank + ""; - tr.appendChild(td); - } - { - const td = document.createElement("td"); - td.classList = "text-end"; - if (rank < maxRank) { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - setFingerprint(item.ItemType, item.ItemId, { lvl: maxRank }); - }; - a.title = "Max Rank"; - a.innerHTML = ``; - td.appendChild(a); - } - { - const a = document.createElement("a"); - a.href = "#"; - a.onclick = function (event) { - event.preventDefault(); - disposeOfGear("Upgrades", item.ItemId.$oid); - }; - a.title = "Remove"; - a.innerHTML = ``; - td.appendChild(a); - } - tr.appendChild(td); - } - document.getElementById("mods-list").appendChild(tr); } + const tr = document.createElement("tr"); + const rank = parseInt(JSON.parse(item.UpgradeFingerprint).lvl); + const maxRank = itemMap[item.ItemType]?.fusionLimit ?? 5; + { + const td = document.createElement("td"); + td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType; + td.innerHTML += " ★ " + rank + "/" + maxRank + ""; + tr.appendChild(td); + } + { + const td = document.createElement("td"); + td.classList = "text-end"; + if (rank < maxRank) { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + setFingerprint(item.ItemType, item.ItemId, { lvl: maxRank }); + }; + a.title = "Max Rank"; + a.innerHTML = ``; + td.appendChild(a); + } + { + const a = document.createElement("a"); + a.href = "#"; + a.onclick = function (event) { + event.preventDefault(); + disposeOfGear("Upgrades", item.ItemId.$oid); + }; + a.title = "Remove"; + a.innerHTML = ``; + td.appendChild(a); + } + tr.appendChild(td); + } + document.getElementById("mods-list").appendChild(tr); }); data.RawUpgrades.forEach(item => { if (item.ItemCount > 0) { -- 2.47.2 From e201279eeef2d81ea486bb3abfd57976a36a2203 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sun, 12 Jan 2025 13:38:05 +0100 Subject: [PATCH 17/34] fix: remove ship decos from inventory when placed and vice-versa (#770) --- src/services/shipCustomizationsService.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/services/shipCustomizationsService.ts b/src/services/shipCustomizationsService.ts index 26aef04e..2d3ab5b5 100644 --- a/src/services/shipCustomizationsService.ts +++ b/src/services/shipCustomizationsService.ts @@ -8,6 +8,8 @@ import { } from "@/src/types/shipTypes"; import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; +import { addShipDecorations, getInventory } from "./inventoryService"; +import { config } from "./configService"; export const setShipCustomizations = async ( accountId: string, @@ -106,17 +108,28 @@ export const handleSetShipDecorations = async ( }; } - //TODO: check whether to remove from shipitems - if (placedDecoration.RemoveId) { roomToPlaceIn.PlacedDecos.pull({ _id: placedDecoration.RemoveId }); await personalRooms.save(); + + if (!config.unlockAllShipDecorations) { + const inventory = await getInventory(accountId); + addShipDecorations(inventory, [{ ItemType: placedDecoration.Type, ItemCount: 1 }]); + await inventory.save(); + } + return { DecoId: placedDecoration.RemoveId, Room: placedDecoration.Room, IsApartment: placedDecoration.IsApartment, MaxCapacityIncrease: 0 }; + } else { + if (!config.unlockAllShipDecorations) { + const inventory = await getInventory(accountId); + addShipDecorations(inventory, [{ ItemType: placedDecoration.Type, ItemCount: -1 }]); + await inventory.save(); + } } // TODO: handle capacity -- 2.47.2 From 5d43627805175bee6f09016667d66fd1ada6a279 Mon Sep 17 00:00:00 2001 From: Sainan Date: Mon, 13 Jan 2025 04:17:06 +0100 Subject: [PATCH 18/34] fix: 1999 calendar not working properly (#777) --- src/controllers/dynamic/worldStateController.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index 5af6734f..94b6c59a 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -19,9 +19,10 @@ export const worldStateController: RequestHandler = (req, res) => { ...staticWorldState }; - const day = Math.trunc(new Date().getTime() / 86400000); - const week = Math.trunc((day + 3) / 7); // week begins on mondays - const weekStart = week * 604800000; + const EPOCH = 1734307200 * 1000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be winter in 1999 iteration 0 + const day = Math.trunc((new Date().getTime() - EPOCH) / 86400000); + const week = Math.trunc(day / 7); + const weekStart = EPOCH + week * 604800000; const weekEnd = weekStart + 604800000; // Elite Sanctuary Onslaught cycling every week @@ -87,7 +88,7 @@ export const worldStateController: RequestHandler = (req, res) => { ][week % 8] }); - // 1999 Calendar Season cycling every week + // 1999 Calendar Season cycling every week + YearIteration every 4 weeks worldState.KnownCalendarSeasons[0].Activation = { $date: { $numberLong: weekStart.toString() } }; worldState.KnownCalendarSeasons[0].Expiry = { $date: { $numberLong: weekEnd.toString() } }; worldState.KnownCalendarSeasons[0].Season = ["CST_WINTER", "CST_SPRING", "CST_SUMMER", "CST_FALL"][week % 4]; @@ -97,6 +98,7 @@ export const worldStateController: RequestHandler = (req, res) => { static1999SummerDays, static1999FallDays ][week % 4]; + worldState.KnownCalendarSeasons[0].YearIteration = Math.trunc(week / 4); // Sentient Anomaly cycling every 30 minutes const halfHour = Math.trunc(new Date().getTime() / (unixTimesInMs.hour / 2)); @@ -174,4 +176,5 @@ interface ICalendarSeason { Days: { day: number; }[]; + YearIteration: number; } -- 2.47.2 From a988f3e899cc82741d468a09707c545ba01d9651 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:51:18 +0100 Subject: [PATCH 19/34] build(deps-dev): bump typescript from 5.5.3 to 5.5.4 (#778) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b444baf9..5ab26144 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3713,9 +3713,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", -- 2.47.2 From a8d5bafc29ae2735dfcf9bfb518a2995ee6c82a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:51:35 +0100 Subject: [PATCH 20/34] build(deps): bump mongoose from 8.9.3 to 8.9.4 (#779) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ab26144..611e3521 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "copyfiles": "^2.4.1", "express": "^5", - "mongoose": "^8.9.3", + "mongoose": "^8.9.4", "warframe-public-export-plus": "^0.5.21", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", @@ -2507,9 +2507,9 @@ } }, "node_modules/mongoose": { - "version": "8.9.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.3.tgz", - "integrity": "sha512-G50GNPdMqhoiRAJ/24GYAzg13yxXDD3FOOFeYiFwtHmHpAJem3hxbYIxAhLJGWbYEiUZL0qFMu2LXYkgGAmo+Q==", + "version": "8.9.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.4.tgz", + "integrity": "sha512-DndoI01aV/q40P9DiYDXsYjhj8vZjmmuFwcC3Tro5wFznoE1z6Fe2JgMnbLR6ghglym5ziYizSfAJykp+UPZWg==", "dependencies": { "bson": "^6.10.1", "kareem": "2.6.3", diff --git a/package.json b/package.json index bddd647f..dd93ebdd 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "dependencies": { "copyfiles": "^2.4.1", "express": "^5", - "mongoose": "^8.9.3", + "mongoose": "^8.9.4", "warframe-public-export-plus": "^0.5.21", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", -- 2.47.2 From 4698578599d934dfb6937806997dfcefe96f4721 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 17:54:20 +0100 Subject: [PATCH 21/34] build(deps): bump warframe-public-export-plus from 0.5.21 to 0.5.22 (#780) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 611e3521..cd584f6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "copyfiles": "^2.4.1", "express": "^5", "mongoose": "^8.9.4", - "warframe-public-export-plus": "^0.5.21", + "warframe-public-export-plus": "^0.5.22", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" @@ -3778,9 +3778,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.21.tgz", - "integrity": "sha512-06k63L99wfX+lPx7ReYzGiMK/7NtNEiO97r+kemrtn4QIEKCfvBvmKiJcYbkSo79x35CQ+6FQfMtDilf6DGz6Q==" + "version": "0.5.22", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.22.tgz", + "integrity": "sha512-IbOW7ndE17ceyd7IjRy1U1p3P0Q7Q1/E26N04+ha/gG5FIdLpZDR9kLzyHGlnBLDSl2Jro6rxgOq0wZ/0i0w3g==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", diff --git a/package.json b/package.json index dd93ebdd..d831da5b 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "copyfiles": "^2.4.1", "express": "^5", "mongoose": "^8.9.4", - "warframe-public-export-plus": "^0.5.21", + "warframe-public-export-plus": "^0.5.22", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0" -- 2.47.2 From 26f20bfbb57ef2f5ca501a121d50793118beda1c Mon Sep 17 00:00:00 2001 From: Sainan Date: Mon, 13 Jan 2025 17:57:59 +0100 Subject: [PATCH 22/34] fix: limit standing gain from medallions for title's max (#772) --- .../api/syndicateStandingBonusController.ts | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/controllers/api/syndicateStandingBonusController.ts b/src/controllers/api/syndicateStandingBonusController.ts index 50854951..4513f25f 100644 --- a/src/controllers/api/syndicateStandingBonusController.ts +++ b/src/controllers/api/syndicateStandingBonusController.ts @@ -24,16 +24,19 @@ export const syndicateStandingBonusController: RequestHandler = async (req, res) const inventory = await getInventory(accountId); addMiscItems(inventory, request.Operation.Items); - const syndicate = inventory.Affiliations.find(x => x.Tag == request.Operation.AffiliationTag); - if (syndicate !== undefined) { - syndicate.Standing += gainedStanding; - } else { - inventory.Affiliations.push({ - Tag: request.Operation.AffiliationTag, - Standing: gainedStanding - }); + let syndicate = inventory.Affiliations.find(x => x.Tag == request.Operation.AffiliationTag); + if (!syndicate) { + syndicate = + inventory.Affiliations[inventory.Affiliations.push({ Tag: request.Operation.AffiliationTag, Standing: 0 })]; } + const max = getMaxStanding(request.Operation.AffiliationTag, syndicate.Title ?? 0); + if (syndicate.Standing + gainedStanding > max) { + gainedStanding = max - syndicate.Standing; + } + + syndicate.Standing += gainedStanding; + // TODO: Subtract from daily limit bin; maybe also a cheat to skip that. await inventory.save(); @@ -59,3 +62,15 @@ interface ISyndicateStandingBonusRequest { }; ModularWeaponId: IOid; // Seems to just be "000000000000000000000000", also note there's a "Category" query field } + +const getMaxStanding = (affiliationTag: string, title: number): number => { + const syndicate = ExportSyndicates[affiliationTag]; + if (!syndicate.titles) { + // LibrarySyndicate + return 125000; + } + if (title == 0) { + return syndicate.titles.find(x => x.level == 1)!.minStanding; + } + return syndicate.titles.find(x => x.level == title)!.maxStanding; +}; -- 2.47.2 From eab4eb2e5b8ec5bcf0f2c1d1ce4c3d924064a3a4 Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 15 Jan 2025 05:19:27 +0100 Subject: [PATCH 23/34] fix(webui): spacing --- static/webui/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/webui/index.html b/static/webui/index.html index 9ffd8e88..254209f2 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -200,7 +200,7 @@
Server
-

You must be an administrator to use this feature. To become an administrator, add "" to administratorNames in the config.json.

+

You must be an administrator to use this feature. To become an administrator, add "" to administratorNames in the config.json.

-- 2.47.2 From 215b83974c231d96af7a48f8c0df9a6b1d748efb Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 15 Jan 2025 05:20:17 +0100 Subject: [PATCH 24/34] feat(webui): add "add missing warframes" & "add missing weapons" (#775) --- src/controllers/custom/addItemController.ts | 33 ---------- src/controllers/custom/addItemsController.ts | 33 ++++++++++ src/helpers/customHelpers/addItemHelpers.ts | 46 ------------- src/routes/custom.ts | 4 +- static/webui/index.html | 37 ++++++----- static/webui/script.js | 69 +++++++++++++++++--- 6 files changed, 116 insertions(+), 106 deletions(-) delete mode 100644 src/controllers/custom/addItemController.ts create mode 100644 src/controllers/custom/addItemsController.ts delete mode 100644 src/helpers/customHelpers/addItemHelpers.ts diff --git a/src/controllers/custom/addItemController.ts b/src/controllers/custom/addItemController.ts deleted file mode 100644 index a045739c..00000000 --- a/src/controllers/custom/addItemController.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { getAccountIdForRequest } from "@/src/services/loginService"; -import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers"; -import { getWeaponType } from "@/src/services/itemDataService"; -import { addPowerSuit, addEquipment, getInventory } from "@/src/services/inventoryService"; -import { RequestHandler } from "express"; - -const addItemController: RequestHandler = async (req, res) => { - const accountId = await getAccountIdForRequest(req); - const request = toAddItemRequest(req.body); - - switch (request.type) { - case ItemType.Powersuit: { - const inventory = await getInventory(accountId); - const inventoryChanges = addPowerSuit(inventory, request.InternalName); - await inventory.save(); - res.json(inventoryChanges); - return; - } - case ItemType.Weapon: { - const inventory = await getInventory(accountId); - const weaponType = getWeaponType(request.InternalName); - const inventoryChanges = addEquipment(inventory, weaponType, request.InternalName); - await inventory.save(); - res.json(inventoryChanges); - break; - } - default: - res.status(400).json({ error: "something went wrong" }); - break; - } -}; - -export { addItemController }; diff --git a/src/controllers/custom/addItemsController.ts b/src/controllers/custom/addItemsController.ts new file mode 100644 index 00000000..bc033174 --- /dev/null +++ b/src/controllers/custom/addItemsController.ts @@ -0,0 +1,33 @@ +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getWeaponType } from "@/src/services/itemDataService"; +import { addPowerSuit, addEquipment, getInventory } from "@/src/services/inventoryService"; +import { RequestHandler } from "express"; + +export const addItemsController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const requests = req.body as IAddItemRequest[]; + const inventory = await getInventory(accountId); + for (const request of requests) { + switch (request.type) { + case ItemType.Powersuit: + addPowerSuit(inventory, request.internalName); + break; + + case ItemType.Weapon: + addEquipment(inventory, getWeaponType(request.internalName), request.internalName); + break; + } + } + await inventory.save(); + res.end(); +}; + +enum ItemType { + Powersuit = "Powersuit", + Weapon = "Weapon" +} + +interface IAddItemRequest { + type: ItemType; + internalName: string; +} diff --git a/src/helpers/customHelpers/addItemHelpers.ts b/src/helpers/customHelpers/addItemHelpers.ts deleted file mode 100644 index 5ce2378f..00000000 --- a/src/helpers/customHelpers/addItemHelpers.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { isString } from "@/src/helpers/general"; - -export enum ItemType { - Powersuit = "Powersuit", - Weapon = "Weapon" -} - -export const isItemType = (itemType: string): itemType is ItemType => { - return Object.keys(ItemType).includes(itemType); -}; - -const parseItemType = (itemType: unknown): ItemType => { - if (!itemType || !isString(itemType) || !isItemType(itemType)) { - throw new Error("incorrect item type"); - } - - return itemType; -}; - -interface IAddItemRequest { - type: ItemType; - InternalName: string; -} - -const parseInternalItemName = (internalName: unknown): string => { - if (!isString(internalName)) { - throw new Error("incorrect internal name"); - } - - return internalName; -}; - -export const toAddItemRequest = (body: unknown): IAddItemRequest => { - if (!body || typeof body !== "object") { - throw new Error("incorrect or missing add item request data"); - } - - if ("type" in body && "internalName" in body) { - return { - type: parseItemType(body.type), - InternalName: parseInternalItemName(body.internalName) - }; - } - - throw new Error("malformed add item request"); -}; diff --git a/src/routes/custom.ts b/src/routes/custom.ts index c8f87a56..e4299412 100644 --- a/src/routes/custom.ts +++ b/src/routes/custom.ts @@ -8,7 +8,7 @@ import { deleteAccountController } from "@/src/controllers/custom/deleteAccountC import { renameAccountController } from "@/src/controllers/custom/renameAccountController"; import { createAccountController } from "@/src/controllers/custom/createAccountController"; -import { addItemController } from "@/src/controllers/custom/addItemController"; +import { addItemsController } from "@/src/controllers/custom/addItemsController"; import { getConfigDataController } from "@/src/controllers/custom/getConfigDataController"; import { updateConfigDataController } from "@/src/controllers/custom/updateConfigDataController"; @@ -23,7 +23,7 @@ customRouter.get("/deleteAccount", deleteAccountController); customRouter.get("/renameAccount", renameAccountController); customRouter.post("/createAccount", createAccountController); -customRouter.post("/addItem", addItemController); +customRouter.post("/addItems", addItemsController); customRouter.get("/config", getConfigDataController); customRouter.post("/config", updateConfigDataController); diff --git a/static/webui/index.html b/static/webui/index.html index 254209f2..b6188114 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -82,11 +82,11 @@
-

+

Note: Changes made here will only be reflected in-game when the game re-downloads your inventory. Visiting the navigation should be the easiest way to trigger that.

-
+
Add Items
@@ -94,9 +94,9 @@
-
+
-
+
Warframes
@@ -108,9 +108,16 @@
+
+
Bulk Actions
+
+ + +
+
-
+
Weapons
@@ -128,7 +135,7 @@

-
+
Archon Shard Slots

You can use these unlimited slots to apply a wide range of upgrades.

@@ -145,13 +152,13 @@
-

+

Note: Changes made here will only be reflected in-game when the game re-downloads your inventory. Visiting the navigation should be the easiest way to trigger that.

-
+
-
+
Add Riven
+ +
+
+ + +
+
+ + +
-
+
Warframes
-
+
@@ -108,18 +108,11 @@
-
-
Bulk Actions
-
- - -
-
-
+
Weapons
-
+
@@ -131,6 +124,15 @@
+
+
Bulk Actions
+
+ + + + +
+

diff --git a/static/webui/script.js b/static/webui/script.js index 84b1a8c7..a6b87312 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -605,6 +605,46 @@ function addMissingWarframes() { } } +function maxRankAllWarframes() { + const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1"); + + req.done(data => { + window.itemListPromise.then(itemMap => { + const batchData = { Suits: [], SpecialItems: [] }; + + data.Suits.forEach(item => { + if (item.XP < 1_600_000) { + batchData.Suits.push({ + ItemId: { $oid: item.ItemId.$oid }, + XP: 1_600_000 - item.XP + }); + } + + if ("exalted" in itemMap[item.ItemType]) { + for (const exaltedType of itemMap[item.ItemType].exalted) { + const exaltedItem = data.SpecialItems.find(x => x.ItemType == exaltedType); + if (exaltedItem) { + const exaltedCap = itemMap[exaltedType]?.type == "weapons" ? 800_000 : 1_600_000; + if (exaltedItem.XP < exaltedCap) { + batchData.SpecialItems.push({ + ItemId: { $oid: exaltedItem.ItemId.$oid }, + XP: exaltedCap + }); + } + } + } + } + }); + + if (batchData.Suits.length > 0 || batchData.SpecialItems.length > 0) { + return sendBatchGearExp(batchData); + } + + alert("No Warframes to rank up."); + }); + }); +} + function addMissingWeapons() { const requests = []; document.querySelectorAll("#datalist-weapons option").forEach(elm => { @@ -620,6 +660,34 @@ function addMissingWeapons() { } } +function maxRankAllWeapons() { + const req = $.get("/api/inventory.php?" + window.authz + "&xpBasedLevelCapDisabled=1"); + + req.done(data => { + const batchData = {}; + + ["LongGuns", "Pistols", "Melee"].forEach(category => { + data[category].forEach(item => { + if (item.XP < 800_000) { + if (!batchData[category]) { + batchData[category] = []; + } + batchData[category].push({ + ItemId: { $oid: item.ItemId.$oid }, + XP: 800_000 - item.XP + }); + } + }); + }); + + if (Object.keys(batchData).length > 0) { + return sendBatchGearExp(batchData); + } + + alert("No weapons to rank up."); + }); +} + function addGearExp(category, oid, xp) { const data = {}; data[category] = [ @@ -641,6 +709,18 @@ function addGearExp(category, oid, xp) { }); } +function sendBatchGearExp(data) { + revalidateAuthz(() => { + $.post({ + url: "/api/missionInventoryUpdate.php?" + window.authz, + contentType: "text/plain", + data: JSON.stringify(data) + }).done(() => { + updateInventory(); + }); + }); +} + function renameGear(category, oid, name) { revalidateAuthz(() => { $.post({ -- 2.47.2 From 9633d307a20f972f272cb68c988bb56688bc153c Mon Sep 17 00:00:00 2001 From: Sainan Date: Thu, 16 Jan 2025 09:21:04 +0100 Subject: [PATCH 29/34] fix: incomplete circuit weapon names --- src/controllers/dynamic/worldStateController.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controllers/dynamic/worldStateController.ts b/src/controllers/dynamic/worldStateController.ts index eebfa8f5..a954aae9 100644 --- a/src/controllers/dynamic/worldStateController.ts +++ b/src/controllers/dynamic/worldStateController.ts @@ -79,8 +79,8 @@ export const worldStateController: RequestHandler = (req, res) => { Choices: [ ["Boar", "Gammacor", "Angstrum", "Gorgon", "Anku"], ["Bo", "Latron", "Furis", "Furax", "Strun"], - ["Lex", "Magistar", "Boltor", "Bronco", "Dagger"], - ["Torid", "Toxocyst", "Ichor", "Miter", "Atomos"], + ["Lex", "Magistar", "Boltor", "Bronco", "CeramicDagger"], + ["Torid", "DualToxocyst", "DualIchor", "Miter", "Atomos"], ["AckAndBrunt", "Soma", "Vasto", "NamiSolo", "Burston"], ["Zylok", "Sibear", "Dread", "Despair", "Hate"], ["Dera", "Sybaris", "Cestra", "Sicarus", "Okina"], -- 2.47.2 From 6ee28e5864f78ab3dae977a3bd7aa73484215bf7 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 17 Jan 2025 05:09:11 +0100 Subject: [PATCH 30/34] fix: syndicate sacrifice doesn't persist new title (#787) --- src/controllers/api/syndicateSacrificeController.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/controllers/api/syndicateSacrificeController.ts b/src/controllers/api/syndicateSacrificeController.ts index 6b1db768..4ccc3aaf 100644 --- a/src/controllers/api/syndicateSacrificeController.ts +++ b/src/controllers/api/syndicateSacrificeController.ts @@ -47,7 +47,8 @@ export const syndicateSacrificeController: RequestHandler = async (request, resp res.InventoryChanges.MiscItems = miscItemChanges; } - if (syndicate?.Title !== undefined) syndicate.Title += 1; + syndicate.Title ??= 0; + syndicate.Title += 1; await inventory.save(); -- 2.47.2 From 534f7d8cceee838fb954e30c749ed4f6dbf12abb Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 17 Jan 2025 05:09:25 +0100 Subject: [PATCH 31/34] feat: archon shard fusion (#785) --- src/controllers/api/archonFusionController.ts | 51 ++++++++++++++ .../api/infestedFoundryController.ts | 16 +---- src/helpers/shardHelper.ts | 66 +++++++++++++++++++ src/routes/api.ts | 2 + 4 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 src/controllers/api/archonFusionController.ts create mode 100644 src/helpers/shardHelper.ts diff --git a/src/controllers/api/archonFusionController.ts b/src/controllers/api/archonFusionController.ts new file mode 100644 index 00000000..04c92384 --- /dev/null +++ b/src/controllers/api/archonFusionController.ts @@ -0,0 +1,51 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { addMiscItems, getInventory } from "@/src/services/inventoryService"; +import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; +import { colorToShard, combineColors, shardToColor } from "@/src/helpers/shardHelper"; + +export const archonFusionController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const request = JSON.parse(String(req.body)) as IArchonFusionRequest; + const inventory = await getInventory(accountId); + request.Consumed.forEach(x => { + x.ItemCount *= -1; + }); + addMiscItems(inventory, request.Consumed); + const newArchons: IMiscItem[] = []; + switch (request.FusionType) { + case "AFT_ASCENT": + newArchons.push({ + ItemType: request.Consumed[0].ItemType + "Mythic", + ItemCount: 1 + }); + break; + + case "AFT_COALESCENT": + newArchons.push({ + ItemType: + colorToShard[ + combineColors( + shardToColor[request.Consumed[0].ItemType], + shardToColor[request.Consumed[1].ItemType] + ) + ], + ItemCount: 1 + }); + break; + + default: + throw new Error(`unknown archon fusion type: ${request.FusionType}`); + } + addMiscItems(inventory, newArchons); + await inventory.save(); + res.json({ + NewArchons: newArchons + }); +}; + +interface IArchonFusionRequest { + Consumed: IMiscItem[]; + FusionType: string; + StatResultType: "SRT_NEW_STAT"; // ??? +} diff --git a/src/controllers/api/infestedFoundryController.ts b/src/controllers/api/infestedFoundryController.ts index 16c356fe..35b0d3d9 100644 --- a/src/controllers/api/infestedFoundryController.ts +++ b/src/controllers/api/infestedFoundryController.ts @@ -15,6 +15,7 @@ import { getRecipe } from "@/src/services/itemDataService"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { logger } from "@/src/utils/logger"; +import { colorToShard } from "@/src/helpers/shardHelper"; export const infestedFoundryController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); @@ -355,21 +356,6 @@ interface IHelminthFeedRequest { }[]; } -const colorToShard: Record = { - ACC_RED: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmar", - ACC_RED_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmarMythic", - ACC_YELLOW: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNira", - ACC_YELLOW_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNiraMythic", - ACC_BLUE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal", - ACC_BLUE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBorealMythic", - ACC_GREEN: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreen", - ACC_GREEN_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreenMythic", - ACC_ORANGE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrange", - ACC_ORANGE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrangeMythic", - ACC_PURPLE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalViolet", - ACC_PURPLE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalVioletMythic" -}; - export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundry, delta: number): ITypeCount[] => { const recipeChanges: ITypeCount[] = []; infestedFoundry.XP ??= 0; diff --git a/src/helpers/shardHelper.ts b/src/helpers/shardHelper.ts new file mode 100644 index 00000000..0971f7b7 --- /dev/null +++ b/src/helpers/shardHelper.ts @@ -0,0 +1,66 @@ +export const colorToShard: Record = { + ACC_RED: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmar", + ACC_RED_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmarMythic", + ACC_YELLOW: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNira", + ACC_YELLOW_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNiraMythic", + ACC_BLUE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal", + ACC_BLUE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBorealMythic", + ACC_GREEN: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreen", + ACC_GREEN_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreenMythic", + ACC_ORANGE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrange", + ACC_ORANGE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrangeMythic", + ACC_PURPLE: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalViolet", + ACC_PURPLE_MYTHIC: "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalVioletMythic" +}; + +export const shardToColor: Record = { + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmar": "ACC_RED", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalAmarMythic": "ACC_RED_MYTHIC", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNira": "ACC_YELLOW", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalNiraMythic": "ACC_YELLOW_MYTHIC", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBoreal": "ACC_BLUE", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalBorealMythic": "ACC_BLUE_MYTHIC", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreen": "ACC_GREEN", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalGreenMythic": "ACC_GREEN_MYTHIC", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrange": "ACC_ORANGE", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalOrangeMythic": "ACC_ORANGE_MYTHIC", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalViolet": "ACC_PURPLE", + "/Lotus/Types/Gameplay/NarmerSorties/ArchonCrystalVioletMythic": "ACC_PURPLE_MYTHIC" +}; + +export const combineColors = (a: string, b: string): string => { + return ( + combinePlainColors(a.replace("_MYTHIC", ""), b.replace("_MYTHIC", "")) + + (a.indexOf("_MYTHIC") != -1 ? "_MYTHIC" : "") + ); +}; + +const combinePlainColors = (a: string, b: string): string => { + switch (a) { + case "ACC_RED": + switch (b) { + case "ACC_YELLOW": + return "ACC_ORANGE"; + case "ACC_BLUE": + return "ACC_PURPLE"; + } + break; + case "ACC_YELLOW": + switch (b) { + case "ACC_RED": + return "ACC_ORANGE"; + case "ACC_BLUE": + return "ACC_GREEN"; + } + break; + case "ACC_BLUE": + switch (b) { + case "ACC_RED": + return "ACC_PURPLE"; + case "ACC_YELLOW": + return "ACC_GREEN"; + } + break; + } + throw new Error(`invalid color combination request: ${a} and ${b}`); +}; diff --git a/src/routes/api.ts b/src/routes/api.ts index b6e2613c..c6b644ec 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -2,6 +2,7 @@ import express from "express"; import { activateRandomModController } from "@/src/controllers/api/activateRandomModController"; import { addFriendImageController } from "@/src/controllers/api/addFriendImageController"; import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonController"; +import { archonFusionController } from "@/src/controllers/api/archonFusionController"; import { artifactsController } from "../controllers/api/artifactsController"; import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController"; import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController"; @@ -114,6 +115,7 @@ apiRouter.get("/updateSession.php", updateSessionGetController); apiRouter.post("/activateRandomMod.php", activateRandomModController); apiRouter.post("/addFriendImage.php", addFriendImageController); apiRouter.post("/arcaneCommon.php", arcaneCommonController); +apiRouter.post("/archonFusion.php", archonFusionController); apiRouter.post("/artifacts.php", artifactsController); apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController); apiRouter.post("/createGuild.php", createGuildController); -- 2.47.2 From d8845bc4786bfadad9f29ff771b936ef80f96ae9 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 17 Jan 2025 05:27:12 +0100 Subject: [PATCH 32/34] feat: apply & track daily standing limit when trading in medallions (#788) --- .../api/syndicateStandingBonusController.ts | 24 ++++++----- src/services/inventoryService.ts | 43 ++++++++++++++++++- src/types/inventoryTypes/inventoryTypes.ts | 34 ++++++++------- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/src/controllers/api/syndicateStandingBonusController.ts b/src/controllers/api/syndicateStandingBonusController.ts index 4513f25f..5fafd89d 100644 --- a/src/controllers/api/syndicateStandingBonusController.ts +++ b/src/controllers/api/syndicateStandingBonusController.ts @@ -1,19 +1,19 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { addMiscItems, getInventory } from "@/src/services/inventoryService"; +import { addMiscItems, getInventory, getStandingLimit, updateStandingLimit } from "@/src/services/inventoryService"; import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IOid } from "@/src/types/commonTypes"; -import { ExportSyndicates } from "warframe-public-export-plus"; +import { ExportSyndicates, ISyndicate } from "warframe-public-export-plus"; export const syndicateStandingBonusController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const request = JSON.parse(String(req.body)) as ISyndicateStandingBonusRequest; + const syndicateMeta = ExportSyndicates[request.Operation.AffiliationTag]; + let gainedStanding = 0; request.Operation.Items.forEach(item => { - const medallion = (ExportSyndicates[request.Operation.AffiliationTag].medallions ?? []).find( - medallion => medallion.itemType == item.ItemType - ); + const medallion = (syndicateMeta.medallions ?? []).find(medallion => medallion.itemType == item.ItemType); if (medallion) { gainedStanding += medallion.standing * item.ItemCount; } @@ -27,17 +27,22 @@ export const syndicateStandingBonusController: RequestHandler = async (req, res) let syndicate = inventory.Affiliations.find(x => x.Tag == request.Operation.AffiliationTag); if (!syndicate) { syndicate = - inventory.Affiliations[inventory.Affiliations.push({ Tag: request.Operation.AffiliationTag, Standing: 0 })]; + inventory.Affiliations[ + inventory.Affiliations.push({ Tag: request.Operation.AffiliationTag, Standing: 0 }) - 1 + ]; } - const max = getMaxStanding(request.Operation.AffiliationTag, syndicate.Title ?? 0); + const max = getMaxStanding(syndicateMeta, syndicate.Title ?? 0); if (syndicate.Standing + gainedStanding > max) { gainedStanding = max - syndicate.Standing; } + if (gainedStanding > getStandingLimit(inventory, syndicateMeta.dailyLimitBin)) { + gainedStanding = getStandingLimit(inventory, syndicateMeta.dailyLimitBin); + } syndicate.Standing += gainedStanding; - // TODO: Subtract from daily limit bin; maybe also a cheat to skip that. + updateStandingLimit(inventory, syndicateMeta.dailyLimitBin, gainedStanding); await inventory.save(); @@ -63,8 +68,7 @@ interface ISyndicateStandingBonusRequest { ModularWeaponId: IOid; // Seems to just be "000000000000000000000000", also note there's a "Category" query field } -const getMaxStanding = (affiliationTag: string, title: number): number => { - const syndicate = ExportSyndicates[affiliationTag]; +const getMaxStanding = (syndicate: ISyndicate, title: number): number => { if (!syndicate.titles) { // LibrarySyndicate return 125000; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 28c6cbba..754473c9 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -16,7 +16,8 @@ import { IWeaponSkinClient, TEquipmentKey, equipmentKeys, - IFusionTreasure + IFusionTreasure, + IDailyAffiliations } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -36,7 +37,8 @@ import { ExportRecipes, ExportResources, ExportSentinels, - ExportUpgrades + ExportUpgrades, + TStandingLimitBin } from "warframe-public-export-plus"; import { createShip } from "./shipService"; @@ -492,6 +494,43 @@ export const updateCurrencyByAccountId = async ( return currencyChanges; }; +const standingLimitBinToInventoryKey: Record< + Exclude, + keyof IDailyAffiliations +> = { + STANDING_LIMIT_BIN_NORMAL: "DailyAffiliation", + STANDING_LIMIT_BIN_PVP: "DailyAffiliationPvp", + STANDING_LIMIT_BIN_LIBRARY: "DailyAffiliationLibrary", + STANDING_LIMIT_BIN_CETUS: "DailyAffiliationCetus", + STANDING_LIMIT_BIN_QUILLS: "DailyAffiliationQuills", + STANDING_LIMIT_BIN_SOLARIS: "DailyAffiliationSolaris", + STANDING_LIMIT_BIN_VENTKIDS: "DailyAffiliationVentkids", + STANDING_LIMIT_BIN_VOX: "DailyAffiliationVox", + STANDING_LIMIT_BIN_ENTRATI: "DailyAffiliationEntrati", + STANDING_LIMIT_BIN_NECRALOID: "DailyAffiliationNecraloid", + STANDING_LIMIT_BIN_ZARIMAN: "DailyAffiliationZariman", + STANDING_LIMIT_BIN_KAHL: "DailyAffiliationKahl", + STANDING_LIMIT_BIN_CAVIA: "DailyAffiliationCavia", + STANDING_LIMIT_BIN_HEX: "DailyAffiliationHex" +}; + +export const getStandingLimit = (inventory: IDailyAffiliations, bin: TStandingLimitBin): number => { + if (bin == "STANDING_LIMIT_BIN_NONE") { + return Number.MAX_SAFE_INTEGER; + } + return inventory[standingLimitBinToInventoryKey[bin]]; +}; + +export const updateStandingLimit = ( + inventory: IDailyAffiliations, + bin: TStandingLimitBin, + subtrahend: number +): void => { + if (bin != "STANDING_LIMIT_BIN_NONE") { + inventory[standingLimitBinToInventoryKey[bin]] -= subtrahend; + } +}; + // TODO: AffiliationMods support (Nightwave). export const updateGeneric = async (data: IGenericUpdate, accountId: string): Promise => { const inventory = await getInventory(accountId); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 6463a156..de789419 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -110,7 +110,25 @@ export type TSolarMapRegion = export interface IPendingRecipeResponse extends Omit { CompletionDate: IMongoDate; } -export interface IInventoryResponse { + +export interface IDailyAffiliations { + DailyAffiliation: number; + DailyAffiliationPvp: number; + DailyAffiliationLibrary: number; + DailyAffiliationCetus: number; + DailyAffiliationQuills: number; + DailyAffiliationSolaris: number; + DailyAffiliationVentkids: number; + DailyAffiliationVox: number; + DailyAffiliationEntrati: number; + DailyAffiliationNecraloid: number; + DailyAffiliationZariman: number; + DailyAffiliationKahl: number; + DailyAffiliationCavia: number; + DailyAffiliationHex: number; +} + +export interface IInventoryResponse extends IDailyAffiliations { Horses: IEquipmentDatabase[]; DrifterMelee: IEquipmentDatabase[]; DrifterGuns: IEquipmentDatabase[]; @@ -138,9 +156,6 @@ export interface IInventoryResponse { OperatorAmpBin: ISlots; CrewShipSalvageBin: ISlots; TradesRemaining: number; - DailyAffiliation: number; - DailyAffiliationPvp: number; - DailyAffiliationLibrary: number; DailyFocus: number; GiftsRemaining: number; HandlerPoints: number; @@ -220,8 +235,6 @@ export interface IInventoryResponse { ActiveAvatarImageType: string; KubrowPets: IEquipmentDatabase[]; ShipDecorations: IConsumable[]; - DailyAffiliationCetus: number; - DailyAffiliationQuills: number; DiscoveredMarkers: IDiscoveredMarker[]; CompletedJobs: ICompletedJob[]; FocusAbility: string; @@ -232,7 +245,6 @@ export interface IInventoryResponse { KubrowPetPrints: IKubrowPetPrint[]; AlignmentReplay: IAlignment; PersonalGoalProgress: IPersonalGoalProgress[]; - DailyAffiliationSolaris: number; SpecialItems: IEquipmentDatabase[]; ThemeStyle: string; ThemeBackground: string; @@ -241,8 +253,6 @@ export interface IInventoryResponse { ChallengeInstanceStates: IChallengeInstanceState[]; LoginMilestoneRewards: string[]; OperatorLoadOuts: IOperatorConfigClient[]; - DailyAffiliationVentkids: number; - DailyAffiliationVox: number; RecentVendorPurchases: Array; Hoverboards: IEquipmentDatabase[]; NodeIntrosCompleted: string[]; @@ -268,8 +278,6 @@ export interface IInventoryResponse { TradeBannedUntil?: IMongoDate; PlayedParkourTutorial: boolean; SubscribedToEmailsPersonalized: number; - DailyAffiliationEntrati: number; - DailyAffiliationNecraloid: number; MechSuits: IEquipmentDatabase[]; InfestedFoundry?: IInfestedFoundry; BlessingCooldown: IMongoDate; @@ -279,11 +287,7 @@ export interface IInventoryResponse { AdultOperatorLoadOuts: IOperatorConfigClient[]; LotusCustomization: ILotusCustomization; UseAdultOperatorLoadout?: boolean; - DailyAffiliationZariman: number; NemesisAbandonedRewards: string[]; - DailyAffiliationKahl: number; - DailyAffiliationCavia: number; - DailyAffiliationHex: number; LastInventorySync: IOid; NextRefill: IMongoDate; // Next time argon crystals will have a decay tick FoundToday?: IMiscItem[]; // for Argon Crystals -- 2.47.2 From 1a8e0f33b95e263df04831d70420908c5d68f6cc Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 17 Jan 2025 07:02:19 +0100 Subject: [PATCH 33/34] feat: noDailyStandingLimits cheat (#791) --- config.json.example | 1 + src/controllers/api/inventoryController.ts | 24 +++++++++------------- src/services/configService.ts | 1 + src/services/inventoryService.ts | 8 ++++++-- static/webui/index.html | 6 ++++++ 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/config.json.example b/config.json.example index f3803e0b..660da015 100644 --- a/config.json.example +++ b/config.json.example @@ -28,5 +28,6 @@ "unlockDoubleCapacityPotatoesEverywhere": true, "unlockExilusEverywhere": true, "unlockArcanesEverywhere": true, + "noDailyStandingLimits": true, "spoofMasteryRank": -1 } diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 631cd45e..5b143728 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -15,6 +15,7 @@ import { ExportVirtuals } from "warframe-public-export-plus"; import { handleSubsumeCompletion } from "./infestedFoundryController"; +import { allDailyAffiliationKeys } from "@/src/services/inventoryService"; export const inventoryController: RequestHandler = async (request, response) => { const account = await getAccountForRequest(request); @@ -32,20 +33,9 @@ export const inventoryController: RequestHandler = async (request, response) => account.LastLoginDay = today; await account.save(); - inventory.DailyAffiliation = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationPvp = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationLibrary = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationCetus = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationQuills = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationSolaris = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationVentkids = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationVox = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationEntrati = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationNecraloid = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationZariman = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationKahl = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationCavia = 16000 + inventory.PlayerLevel * 500; - inventory.DailyAffiliationHex = 16000 + inventory.PlayerLevel * 500; + for (const key of allDailyAffiliationKeys) { + inventory[key] = 16000 + inventory.PlayerLevel * 500; + } inventory.DailyFocus = 250000 + inventory.PlayerLevel * 5000; await inventory.save(); } @@ -244,6 +234,12 @@ export const inventoryController: RequestHandler = async (request, response) => } } + if (config.noDailyStandingLimits) { + for (const key of allDailyAffiliationKeys) { + inventoryResponse[key] = 999_999; + } + } + // Fix for #380 inventoryResponse.NextRefill = { $date: { $numberLong: "9999999999999" } }; diff --git a/src/services/configService.ts b/src/services/configService.ts index 123e02d3..89d81e8d 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -54,6 +54,7 @@ interface IConfig { unlockDoubleCapacityPotatoesEverywhere?: boolean; unlockExilusEverywhere?: boolean; unlockArcanesEverywhere?: boolean; + noDailyStandingLimits?: boolean; spoofMasteryRank?: number; } diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 754473c9..e9c4ceb2 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -514,8 +514,12 @@ const standingLimitBinToInventoryKey: Record< STANDING_LIMIT_BIN_HEX: "DailyAffiliationHex" }; +export const allDailyAffiliationKeys: (keyof IDailyAffiliations)[] = Object.entries(standingLimitBinToInventoryKey).map( + arr => arr[1] +); + export const getStandingLimit = (inventory: IDailyAffiliations, bin: TStandingLimitBin): number => { - if (bin == "STANDING_LIMIT_BIN_NONE") { + if (bin == "STANDING_LIMIT_BIN_NONE" || config.noDailyStandingLimits) { return Number.MAX_SAFE_INTEGER; } return inventory[standingLimitBinToInventoryKey[bin]]; @@ -526,7 +530,7 @@ export const updateStandingLimit = ( bin: TStandingLimitBin, subtrahend: number ): void => { - if (bin != "STANDING_LIMIT_BIN_NONE") { + if (bin != "STANDING_LIMIT_BIN_NONE" && !config.noDailyStandingLimits) { inventory[standingLimitBinToInventoryKey[bin]] -= subtrahend; } }; diff --git a/static/webui/index.html b/static/webui/index.html index 114464ba..319f4f61 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -298,6 +298,12 @@ Arcane Adapters Everywhere
+
+ + +