From b72a0d12eff3a3aa598f5fd59e79e9420b18a374 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 24 Jan 2025 21:09:34 +0100 Subject: [PATCH 1/6] fix: apply spoofing stuff to missionInventoryUpdate's InventoryJson (#866) --- src/controllers/api/inventoryController.ts | 13 ++++++++++--- .../api/missionInventoryUpdateController.ts | 18 +++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 11ba1378..60d02aeb 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -59,6 +59,15 @@ export const inventoryController: RequestHandler = async (request, response) => ); const inventoryResponse = inventoryWithLoadOutPresetsAndShips.toJSON(); + applyInventoryResponseOverrides(inventoryResponse, "xpBasedLevelCapDisabled" in request.query); + + response.json(inventoryResponse); +}; + +export const applyInventoryResponseOverrides = ( + inventoryResponse: IInventoryClient, + xpBasedLevelCapDisabled: boolean +): void => { if (config.infiniteCredits) { inventoryResponse.RegularCredits = 999999999; } @@ -175,7 +184,7 @@ export const inventoryController: RequestHandler = async (request, response) => if (typeof config.spoofMasteryRank === "number" && config.spoofMasteryRank >= 0) { inventoryResponse.PlayerLevel = config.spoofMasteryRank; - if (!("xpBasedLevelCapDisabled" in request.query)) { + if (!xpBasedLevelCapDisabled) { // This client has not been patched to accept any mastery rank, need to fake the XP. inventoryResponse.XPInfo = []; let numFrames = getExpRequiredForMr(Math.min(config.spoofMasteryRank, 5030)) / 6000; @@ -251,8 +260,6 @@ export const inventoryController: RequestHandler = async (request, response) => inventoryResponse.HasOwnedVoidProjectionsPreviously = true; inventoryResponse.LastInventorySync = toOid(new Types.ObjectId()); - - response.json(inventoryResponse); }; const addString = (arr: string[], str: string): void => { diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index 837e449e..ba2ae9bc 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -8,6 +8,8 @@ import { calculateFinalCredits } from "@/src/services/missionInventoryUpdateService"; import { getInventory } from "@/src/services/inventoryService"; +import { applyInventoryResponseOverrides } from "./inventoryController"; +import { IInventoryClient } from "@/src/types/inventoryTypes/inventoryTypes"; /* **** INPUT **** @@ -58,9 +60,13 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) const inventoryUpdates = addMissionInventoryUpdates(inventory, missionReport); if (missionReport.MissionStatus !== "GS_SUCCESS") { - const InventoryJson = JSON.stringify((await inventory.save()).toJSON()); - - res.json({ InventoryJson, MissionRewards: [] }); + await inventory.save(); + const inventoryResponse = inventory.toJSON(); + applyInventoryResponseOverrides(inventoryResponse, true); + res.json({ + InventoryJson: JSON.stringify(inventoryResponse), + MissionRewards: [] + }); return; } const missionRewardsResults = await addMissionRewards(inventory, missionReport); @@ -76,11 +82,13 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) rngRewardCredits: inventoryChanges.RegularCredits as number }); - const InventoryJson = JSON.stringify((await inventory.save()).toJSON()); + await inventory.save(); + const inventoryResponse = inventory.toJSON(); + applyInventoryResponseOverrides(inventoryResponse, true); //TODO: figure out when to send inventory. it is needed for many cases. res.json({ - InventoryJson, + InventoryJson: JSON.stringify(inventoryResponse), InventoryChanges: inventoryChanges, MissionRewards, ...credits, From 6a427018e39dbc54e8382d0e1b859b208b5b8821 Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 25 Jan 2025 06:25:13 +0100 Subject: [PATCH 2/6] fix: can't acquire Sun & Moon (#865) --- src/services/inventoryService.ts | 28 ++++++++++++++++------------ src/services/itemDataService.ts | 15 --------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 3426ee29..48854778 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -29,7 +29,7 @@ import { IUpdateChallengeProgressRequest } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { getWeaponType, getExalted, getKeyChainItems } from "@/src/services/itemDataService"; +import { getExalted, getKeyChainItems } from "@/src/services/itemDataService"; import { IEquipmentClient, IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; import { ExportArcanes, @@ -40,6 +40,7 @@ import { ExportResources, ExportSentinels, ExportUpgrades, + ExportWeapons, TStandingLimitBin } from "warframe-public-export-plus"; import { createShip } from "./shipService"; @@ -288,6 +289,20 @@ export const addItem = async ( } }; } + if (typeName in ExportWeapons) { + const weapon = ExportWeapons[typeName]; + // Many non-weapon items are "Pistols" in Public Export, so some duck typing is needed. + if (weapon.totalDamage != 0) { + const inventoryChanges = addEquipment(inventory, weapon.productCategory, typeName); + updateSlots(inventory, InventorySlot.WEAPONS, 0, 1); + return { + InventoryChanges: { + ...inventoryChanges, + WeaponBin: { count: 1, platinum: 0, Slots: -1 } + } + }; + } + } if (typeName in creditBundles) { const creditsTotal = creditBundles[typeName] * quantity; inventory.RegularCredits += creditsTotal; @@ -355,17 +370,6 @@ export const addItem = async ( } } break; - case "Weapons": { - const weaponType = getWeaponType(typeName); - const inventoryChanges = addEquipment(inventory, weaponType, typeName); - updateSlots(inventory, InventorySlot.WEAPONS, 0, 1); - return { - InventoryChanges: { - ...inventoryChanges, - WeaponBin: { count: 1, platinum: 0, Slots: -1 } - } - }; - } case "Upgrades": { // Needed to add Traumatic Peculiar const changes = [ diff --git a/src/services/itemDataService.ts b/src/services/itemDataService.ts index a9bddd1d..a8e94df0 100644 --- a/src/services/itemDataService.ts +++ b/src/services/itemDataService.ts @@ -44,21 +44,6 @@ export type WeaponTypeInternal = | "OperatorAmps" | "SpecialItems"; -export const getWeaponType = (weaponName: string): WeaponTypeInternal => { - const weaponInfo = ExportWeapons[weaponName]; - - if (!weaponInfo) { - throw new Error(`unknown weapon ${weaponName}`); - } - - // Many non-weapon items are "Pistols" in Public Export, so some duck typing is needed. - if (weaponInfo.totalDamage == 0) { - throw new Error(`${weaponName} doesn't quack like a weapon`); - } - - return weaponInfo.productCategory; -}; - export const getRecipe = (uniqueName: string): IRecipe | undefined => { return ExportRecipes[uniqueName]; }; From cb7c15a382dc1fe066071628e33713cdab55d1ef Mon Sep 17 00:00:00 2001 From: Sainan Date: Sat, 25 Jan 2025 13:12:49 +0100 Subject: [PATCH 3/6] fix: provide LoadOutPresets & Ships in missionInventoryUpdate response (#869) --- src/controllers/api/inventoryController.ts | 20 +++++++++---------- .../api/missionInventoryUpdateController.ts | 9 +++------ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 60d02aeb..08b9386e 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -1,6 +1,6 @@ import { RequestHandler } from "express"; import { getAccountForRequest } from "@/src/services/loginService"; -import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; +import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { config } from "@/src/services/configService"; import allDialogue from "@/static/fixed_responses/allDialogue.json"; import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; @@ -51,6 +51,13 @@ export const inventoryController: RequestHandler = async (request, response) => await inventory.save(); } + response.json(await getInventoryResponse(inventory, "xpBasedLevelCapDisabled" in request.query)); +}; + +export const getInventoryResponse = async ( + inventory: TInventoryDatabaseDocument, + xpBasedLevelCapDisabled: boolean +): Promise => { const inventoryWithLoadOutPresets = await inventory.populate<{ LoadOutPresets: ILoadoutDatabase }>( "LoadOutPresets" ); @@ -59,15 +66,6 @@ export const inventoryController: RequestHandler = async (request, response) => ); const inventoryResponse = inventoryWithLoadOutPresetsAndShips.toJSON(); - applyInventoryResponseOverrides(inventoryResponse, "xpBasedLevelCapDisabled" in request.query); - - response.json(inventoryResponse); -}; - -export const applyInventoryResponseOverrides = ( - inventoryResponse: IInventoryClient, - xpBasedLevelCapDisabled: boolean -): void => { if (config.infiniteCredits) { inventoryResponse.RegularCredits = 999999999; } @@ -260,6 +258,8 @@ export const applyInventoryResponseOverrides = ( inventoryResponse.HasOwnedVoidProjectionsPreviously = true; inventoryResponse.LastInventorySync = toOid(new Types.ObjectId()); + + return inventoryResponse; }; const addString = (arr: string[], str: string): void => { diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index ba2ae9bc..63579caf 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -8,8 +8,7 @@ import { calculateFinalCredits } from "@/src/services/missionInventoryUpdateService"; import { getInventory } from "@/src/services/inventoryService"; -import { applyInventoryResponseOverrides } from "./inventoryController"; -import { IInventoryClient } from "@/src/types/inventoryTypes/inventoryTypes"; +import { getInventoryResponse } from "./inventoryController"; /* **** INPUT **** @@ -61,8 +60,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) if (missionReport.MissionStatus !== "GS_SUCCESS") { await inventory.save(); - const inventoryResponse = inventory.toJSON(); - applyInventoryResponseOverrides(inventoryResponse, true); + const inventoryResponse = await getInventoryResponse(inventory, true); res.json({ InventoryJson: JSON.stringify(inventoryResponse), MissionRewards: [] @@ -83,8 +81,7 @@ export const missionInventoryUpdateController: RequestHandler = async (req, res) }); await inventory.save(); - const inventoryResponse = inventory.toJSON(); - applyInventoryResponseOverrides(inventoryResponse, true); + const inventoryResponse = await getInventoryResponse(inventory, true); //TODO: figure out when to send inventory. it is needed for many cases. res.json({ From 97bec71b0502a5ddebec70b17a8b88460dca15b9 Mon Sep 17 00:00:00 2001 From: AMelonInsideLemon <166175391+AMelonInsideLemon@users.noreply.github.com> Date: Mon, 27 Jan 2025 13:18:16 +0100 Subject: [PATCH 4/6] feat: more supported equipment types (#867) --- src/models/inventoryModels/inventoryModel.ts | 304 ++++++++---------- src/services/importService.ts | 36 ++- src/services/missionInventoryUpdateService.ts | 24 +- src/services/saveLoadoutService.ts | 70 ++-- .../inventoryTypes/commonInventoryTypes.ts | 21 +- src/types/inventoryTypes/inventoryTypes.ts | 80 ++--- src/types/requestTypes.ts | 15 +- src/types/saveLoadoutTypes.ts | 4 +- 8 files changed, 261 insertions(+), 293 deletions(-) diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index ebc9f01e..2bb888d2 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -51,9 +51,13 @@ import { ICompletedDialogue, IDialogueClient, IUpgradeDatabase, - ICrewShipDatabase, ICrewShipMemberDatabase, - ICrewShipMemberClient + ICrewShipMemberClient, + TEquipmentKey, + equipmentKeys, + IKubrowPetDetailsDatabase, + ITraits, + IKubrowPetDetailsClient } from "../../types/inventoryTypes/inventoryTypes"; import { IOid } from "../../types/commonTypes"; import { @@ -223,55 +227,6 @@ ArchonCrystalUpgradeSchema.set("toJSON", { } }); -const EquipmentSchema = new Schema( - { - ItemType: String, - Configs: [ItemConfigSchema], - UpgradeVer: Number, - XP: Number, - Features: Number, - Polarized: Number, - Polarity: [polaritySchema], - FocusLens: String, - ModSlotPurchases: Number, - CustomizationSlotPurchases: Number, - UpgradeType: String, - UpgradeFingerprint: String, - ItemName: String, - InfestationDate: Date, - InfestationDays: Number, - InfestationType: String, - ModularParts: { type: [String], default: undefined }, - UnlockLevel: Number, - Expiry: Date, - SkillTree: String, - OffensiveUpgrade: String, - DefensiveUpgrade: String, - UpgradesExpiry: Date, - ArchonCrystalUpgrades: { type: [ArchonCrystalUpgradeSchema], default: undefined } - }, - { id: false } -); - -EquipmentSchema.virtual("ItemId").get(function () { - return { $oid: this._id.toString() } satisfies IOid; -}); - -EquipmentSchema.set("toJSON", { - virtuals: true, - transform(_document, returnedObject) { - delete returnedObject._id; - delete returnedObject.__v; - - const db = returnedObject as IEquipmentDatabase; - const client = returnedObject as IEquipmentClient; - - if (db.InfestationDate) { - client.InfestationDate = toMongoDate(db.InfestationDate); - } - } -}); - const boosterSchema = new Schema( { ExpiryDate: Number, @@ -505,31 +460,6 @@ const helminthResourceSchema = new Schema( { _id: false } ); -const infestedFoundrySchema = new Schema( - { - Name: String, - Resources: { type: [helminthResourceSchema], default: undefined }, - Slots: Number, - XP: Number, - ConsumedSuits: { type: [consumedSchuitsSchema], default: undefined }, - InvigorationIndex: Number, - InvigorationSuitOfferings: { type: [String], default: undefined }, - InvigorationsApplied: Number, - LastConsumedSuit: { type: EquipmentSchema, default: undefined }, - AbilityOverrideUnlockCooldown: Date - }, - { _id: false } -); - -infestedFoundrySchema.set("toJSON", { - transform(_doc, ret, _options) { - if (ret.AbilityOverrideUnlockCooldown) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown); - } - } -}); - const questProgressSchema = new Schema({ c: Number, i: Boolean, @@ -715,26 +645,6 @@ const crewShipMembersSchema = new Schema( { _id: false } ); -const crewShipSchema = new Schema({ - ItemType: { type: String, required: true }, - Configs: { type: [ItemConfigSchema], default: [] }, - Weapon: { type: crewShipWeaponSchema, default: undefined }, - Customization: { type: crewShipCustomizationSchema, default: undefined }, - ItemName: { type: String, default: "" }, - RailjackImage: { type: FlavourItemSchema, default: undefined }, - CrewMembers: { type: crewShipMembersSchema, default: undefined } -}); -crewShipSchema.virtual("ItemId").get(function () { - return { $oid: this._id.toString() }; -}); -crewShipSchema.set("toJSON", { - virtuals: true, - transform(_doc, ret, _options) { - delete ret._id; - delete ret.__v; - } -}); - const dialogueGiftSchema = new Schema( { Item: String, @@ -789,6 +699,134 @@ const dialogueHistorySchema = new Schema( { _id: false } ); +const traitsSchema = new Schema( + { + BaseColor: String, + SecondaryColor: String, + TertiaryColor: String, + AccentColor: String, + EyeColor: String, + FurPattern: String, + Personality: String, + BodyType: String, + Head: { type: String, required: false }, + Tail: { type: String, required: false } + }, + { _id: false } +); + +const detailsSchema = new Schema( + { + Name: String, + IsPuppy: Boolean, + HasCollar: Boolean, + PrintsRemaining: Number, + Status: String, + HatchDate: Date, + DominantTraits: traitsSchema, + RecessiveTraits: traitsSchema, + IsMale: Boolean, + Size: Number + }, + { _id: false } +); + +detailsSchema.set("toJSON", { + transform(_doc, returnedObject) { + delete returnedObject.__v; + + const db = returnedObject as IKubrowPetDetailsDatabase; + const client = returnedObject as IKubrowPetDetailsClient; + + client.HatchDate = toMongoDate(db.HatchDate); + } +}); + +const EquipmentSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: { type: Number, default: 101 }, + XP: { type: Number, default: 0 }, + Features: Number, + Polarized: Number, + Polarity: [polaritySchema], + FocusLens: String, + ModSlotPurchases: Number, + CustomizationSlotPurchases: Number, + UpgradeType: String, + UpgradeFingerprint: String, + ItemName: String, + InfestationDate: Date, + InfestationDays: Number, + InfestationType: String, + ModularParts: { type: [String], default: undefined }, + UnlockLevel: Number, + Expiry: Date, + SkillTree: String, + OffensiveUpgrade: String, + DefensiveUpgrade: String, + UpgradesExpiry: Date, + ArchonCrystalUpgrades: { type: [ArchonCrystalUpgradeSchema], default: undefined }, + Weapon: crewShipWeaponSchema, + Customization: crewShipCustomizationSchema, + RailjackImage: FlavourItemSchema, + CrewMembers: crewShipMembersSchema, + Details: detailsSchema + }, + { id: false } +); + +EquipmentSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +EquipmentSchema.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + + const db = returnedObject as IEquipmentDatabase; + const client = returnedObject as IEquipmentClient; + + if (db.InfestationDate) { + client.InfestationDate = toMongoDate(db.InfestationDate); + } + } +}); + +const equipmentFields: Record = {}; + +equipmentKeys.forEach(key => { + equipmentFields[key] = { type: [EquipmentSchema] }; +}); + +const infestedFoundrySchema = new Schema( + { + Name: String, + Resources: { type: [helminthResourceSchema], default: undefined }, + Slots: Number, + XP: Number, + ConsumedSuits: { type: [consumedSchuitsSchema], default: undefined }, + InvigorationIndex: Number, + InvigorationSuitOfferings: { type: [String], default: undefined }, + InvigorationsApplied: Number, + LastConsumedSuit: { type: EquipmentSchema, default: undefined }, + AbilityOverrideUnlockCooldown: Date + }, + { _id: false } +); + +infestedFoundrySchema.set("toJSON", { + transform(_doc, ret, _options) { + if (ret.AbilityOverrideUnlockCooldown) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + ret.AbilityOverrideUnlockCooldown = toMongoDate(ret.AbilityOverrideUnlockCooldown); + } + } +}); + const inventorySchema = new Schema( { accountOwnerId: Schema.Types.ObjectId, @@ -821,6 +859,8 @@ const inventorySchema = new Schema( MechBin: { type: slotsBinSchema, default: { Slots: 4 } }, CrewMemberBin: { type: slotsBinSchema, default: { Slots: 3 } }, + ...equipmentFields, + //How many trades do you have left TradesRemaining: { type: Number, default: 0 }, //How many Gift do you have left*(gift spends the trade) @@ -870,29 +910,10 @@ const inventorySchema = new Schema( //Upgrade Mods\Riven\Arcane Example:"UpgradeFingerprint"+"ItemType"+"" Upgrades: [upgradeSchema], - //Warframe - Suits: [EquipmentSchema], - //Primary Weapon - LongGuns: [EquipmentSchema], - //Secondary Weapon - Pistols: [EquipmentSchema], - //Melee Weapon - Melee: [EquipmentSchema], - //Ability Weapon like Ultimate Mech\Excalibur\Ivara etc - SpecialItems: [EquipmentSchema], //The Mandachord(Octavia) is a step sequencer StepSequencers: [StepSequencersSchema], - //Sentinel(like Helios or modular) - Sentinels: [EquipmentSchema], - //Any /Sentinels/SentinelWeapons/ (like warframe weapon) - SentinelWeapons: [EquipmentSchema], - //Modular Pets - MoaPets: [EquipmentSchema], - KubrowPetEggs: [Schema.Types.Mixed], - //Like PowerSuit Cat\Kubrow or etc Pets - KubrowPets: [EquipmentSchema], //Prints Cat(3 Prints)\Kubrow(2 Prints) Pets KubrowPetPrints: [Schema.Types.Mixed], @@ -905,42 +926,26 @@ const inventorySchema = new Schema( EquippedInstrument: String, ReceivedStartingGear: Boolean, - //to use add SummonItem to Consumables+EquippedGear - //Archwing need Suits+Melee+Guns - SpaceSuits: [EquipmentSchema], - SpaceMelee: [EquipmentSchema], - SpaceGuns: [EquipmentSchema], ArchwingEnabled: Boolean, - //Mech need Suits+SpaceGuns+SpecialItem - MechSuits: [EquipmentSchema], - ///Restoratives/HoverboardSummon (like Suit) - Hoverboards: [EquipmentSchema], //Use Operator\Drifter UseAdultOperatorLoadout: Boolean, - //Operator\Drifter Weapon - OperatorAmps: [EquipmentSchema], //Operator OperatorLoadOuts: [operatorConfigSchema], //Drifter AdultOperatorLoadOuts: [operatorConfigSchema], - DrifterMelee: [EquipmentSchema], - DrifterGuns: [EquipmentSchema], - //ErsatzHorsePowerSuit - Horses: [EquipmentSchema], + // Kahl + KahlLoadOuts: [operatorConfigSchema], //LandingCraft like Liset Ships: { type: [Schema.Types.ObjectId], ref: "Ships" }, // /Lotus/Types/Items/ShipDecos/ ShipDecorations: [typeCountSchema], - //RailJack Setting(Mods,Skin,Weapon,etc) - CrewShipHarnesses: [EquipmentSchema], //Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components) CrewShipRawSalvage: [Schema.Types.Mixed], //Default RailJack - CrewShips: [crewShipSchema], CrewShipAmmo: [typeCountSchema], CrewShipWeapons: [Schema.Types.Mixed], CrewShipWeaponSkins: [Schema.Types.Mixed], @@ -962,9 +967,6 @@ const inventorySchema = new Schema( //Cosmetics like profile glyphs\Kavasa Prime Kubrow Collar\Game Theme etc FlavourItems: [FlavourItemSchema], - //Lunaro Weapon - Scoops: [EquipmentSchema], - //Mastery Rank*(Need item XPInfo to rank up) PlayerLevel: { type: Number, default: 0 }, //Item Mastery Rank exp @@ -1075,11 +1077,6 @@ const inventorySchema = new Schema( //https://warframe.fandom.com/wiki/Invasion InvasionChainProgress: [Schema.Types.Mixed], - //https://warframe.fandom.com/wiki/Parazon - DataKnives: [EquipmentSchema], - - Motorcycles: [EquipmentSchema], - //CorpusLich or GrineerLich NemesisAbandonedRewards: [String], //CorpusLich\KuvaLich @@ -1116,7 +1113,6 @@ const inventorySchema = new Schema( //Unknown and system DuviriInfo: DuviriInfoSchema, Mailbox: MailboxSchema, - KahlLoadOuts: [Schema.Types.Mixed], HandlerPoints: Number, ChallengesFixVersion: Number, PlayedParkourTutorial: Boolean, @@ -1175,37 +1171,17 @@ inventorySchema.set("toJSON", { // type overwrites for subdocuments/subdocument arrays export type InventoryDocumentProps = { - Suits: Types.DocumentArray; - LongGuns: Types.DocumentArray; - Pistols: Types.DocumentArray; - Melee: Types.DocumentArray; - OperatorAmps: Types.DocumentArray; FlavourItems: Types.DocumentArray; RawUpgrades: Types.DocumentArray; Upgrades: Types.DocumentArray; MiscItems: Types.DocumentArray; Boosters: Types.DocumentArray; OperatorLoadOuts: Types.DocumentArray; - SpecialItems: Types.DocumentArray; AdultOperatorLoadOuts: Types.DocumentArray; - MechSuits: Types.DocumentArray; - Scoops: Types.DocumentArray; - DataKnives: Types.DocumentArray; - Motorcycles: Types.DocumentArray; - DrifterMelee: Types.DocumentArray; - Sentinels: Types.DocumentArray; - Horses: Types.DocumentArray; + KahlLoadOuts: Types.DocumentArray; PendingRecipes: Types.DocumentArray; - SpaceSuits: Types.DocumentArray; - SpaceGuns: Types.DocumentArray; - SpaceMelee: Types.DocumentArray; - SentinelWeapons: Types.DocumentArray; - Hoverboards: Types.DocumentArray; - MoaPets: Types.DocumentArray; WeaponSkins: Types.DocumentArray; - CrewShips: Types.DocumentArray; - CrewShipHarnesses: Types.DocumentArray; -}; +} & { [K in TEquipmentKey]: Types.DocumentArray }; // eslint-disable-next-line @typescript-eslint/ban-types type InventoryModelType = Model; diff --git a/src/services/importService.ts b/src/services/importService.ts index 225f3898..08ef3f80 100644 --- a/src/services/importService.ts +++ b/src/services/importService.ts @@ -8,8 +8,6 @@ import { import { IMongoDate } from "../types/commonTypes"; import { equipmentKeys, - ICrewShipClient, - ICrewShipDatabase, ICrewShipMemberClient, ICrewShipMemberDatabase, ICrewShipMembersClient, @@ -21,6 +19,8 @@ import { IInfestedFoundryClient, IInfestedFoundryDatabase, IInventoryClient, + IKubrowPetDetailsClient, + IKubrowPetDetailsDatabase, ILoadoutConfigClient, ILoadOutPresets, ISlots, @@ -47,7 +47,16 @@ const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => { _id: new Types.ObjectId(ItemId.$oid), InfestationDate: convertOptionalDate(client.InfestationDate), Expiry: convertOptionalDate(client.Expiry), - UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry) + UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry), + CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined, + Details: client.Details ? convertKubrowDetails(client.Details) : undefined, + Configs: client.Configs + ? client.Configs.map(obj => + Object.fromEntries( + Object.entries(obj).filter(([_, value]) => !Array.isArray(value) || value.length > 0) + ) + ) + : [] }; }; @@ -102,15 +111,6 @@ const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMember }; }; -const convertCrewShip = (client: ICrewShipClient): ICrewShipDatabase => { - const { ItemId, ...rest } = client; - return { - ...rest, - _id: new Types.ObjectId(ItemId.$oid), - CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined - }; -}; - const convertInfestedFoundry = (client: IInfestedFoundryClient): IInfestedFoundryDatabase => { return { ...client, @@ -136,6 +136,13 @@ const convertDialogueHistory = (client: IDialogueHistoryClient): IDialogueHistor }; }; +const convertKubrowDetails = (client: IKubrowPetDetailsClient): IKubrowPetDetailsDatabase => { + return { + ...client, + HatchDate: convertDate(client.HatchDate) + }; +}; + export const importInventory = (db: TInventoryDatabaseDocument, client: Partial): void => { for (const key of equipmentKeys) { if (client[key] !== undefined) { @@ -159,7 +166,7 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial< }); } } - for (const key of ["OperatorLoadOuts", "AdultOperatorLoadOuts"] as const) { + for (const key of ["AdultOperatorLoadOuts", "OperatorLoadOuts", "KahlLoadOuts"] as const) { if (client[key] !== undefined) { replaceArray(db[key], client[key].map(convertOperatorConfig)); } @@ -222,9 +229,6 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial< if (client.FocusUpgrades !== undefined) { db.FocusUpgrades = client.FocusUpgrades; } - if (client.CrewShips !== undefined) { - replaceArray(db.CrewShips, client.CrewShips.map(convertCrewShip)); - } if (client.InfestedFoundry !== undefined) { db.InfestedFoundry = convertInfestedFoundry(client.InfestedFoundry); } diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index dc78d55a..ed2700fd 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -2,7 +2,7 @@ import { ExportRegions, ExportRewards, IReward } from "warframe-public-export-pl import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; import { IRngResult, getRandomReward } from "@/src/services/rngService"; -import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; +import { equipmentKeys, IInventoryDatabase, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { addChallenges, addConsumables, @@ -22,6 +22,7 @@ import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { getLevelKeyRewards, getNode } from "@/src/services/itemDataService"; import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { getEntriesUnsafe } from "@/src/utils/ts-utils"; +import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; const getRotations = (rotationCount: number): number[] => { if (rotationCount === 0) return [0]; @@ -144,23 +145,12 @@ export const addMissionInventoryUpdates = ( inventoryChanges.FusionPoints = fusionPoints; break; } - // Equipment XP updates - case "Suits": - case "LongGuns": - case "Pistols": - case "Melee": - case "SpecialItems": - case "Sentinels": - case "SentinelWeapons": - case "SpaceSuits": - case "SpaceGuns": - case "SpaceMelee": - case "Hoverboards": - case "OperatorAmps": - case "MoaPets": - addGearExpByCategory(inventory, value, key); - break; default: + // Equipment XP updates + if (equipmentKeys.includes(key as TEquipmentKey)) { + addGearExpByCategory(inventory, value as IEquipmentClient[], key as TEquipmentKey); + } + break; // if ( // (ignoredInventoryUpdateKeys as readonly string[]).includes(key) || // knownUnhandledKeys.includes(key) diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index 204bbe00..188b06ae 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -12,6 +12,7 @@ import { IOid } from "@/src/types/commonTypes"; import { Types } from "mongoose"; import { isEmptyObject } from "@/src/helpers/general"; import { logger } from "@/src/utils/logger"; +import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; //TODO: setup default items on account creation or like originally in giveStartingItems.php @@ -36,8 +37,9 @@ export const handleInventoryItemConfigChange = async ( } // non-empty is a change in loadout(or suit...) switch (equipmentName) { + case "AdultOperatorLoadOuts": case "OperatorLoadOuts": - case "AdultOperatorLoadOuts": { + case "KahlLoadOuts": { const operatorConfig = equipment as IOperatorConfigEntry; const operatorLoadout = inventory[equipmentName]; logger.debug(`operator loadout received ${equipmentName} `, operatorConfig); @@ -124,45 +126,6 @@ export const handleInventoryItemConfigChange = async ( } break; } - case "LongGuns": - case "Pistols": - case "Suits": - case "Melee": - case "Scoops": - case "DataKnives": - case "DrifterMelee": - case "Sentinels": - case "Horses": - case "OperatorAmps": - case "SentinelWeapons": - case "KubrowPets": - case "SpaceSuits": - case "SpaceGuns": - case "SpaceMelee": - case "SpecialItems": - case "MoaPets": - case "Hoverboards": - case "MechSuits": - case "CrewShipHarnesses": - case "CrewShips": - case "Motorcycles": { - logger.debug(`general Item config saved of type ${equipmentName}`, { config: equipment }); - - const itemEntries = equipment as IItemEntry; - for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) { - const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId); - - if (!inventoryItem) { - throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`); - } - - //config ids are 0,1,2 can there be a 3? - for (const [configId, config] of Object.entries(itemConfigEntries)) { - inventoryItem.Configs[parseInt(configId)] = config; - } - } - break; - } case "CurrentLoadOutIds": { const loadoutIds = equipment as IOid[]; // TODO: Check for more than just an array of oids, I think i remember one instance inventory.CurrentLoadOutIds = loadoutIds; @@ -178,11 +141,30 @@ export const handleInventoryItemConfigChange = async ( break; } default: { - logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, { - config: equipment - }); + if (equipmentKeys.includes(equipmentName as TEquipmentKey) && equipmentName != "ValidNewLoadoutId") { + logger.debug(`general Item config saved of type ${equipmentName}`, { + config: equipment + }); + + const itemEntries = equipment as IItemEntry; + for (const [itemId, itemConfigEntries] of Object.entries(itemEntries)) { + const inventoryItem = inventory[equipmentName].find(item => item._id?.toString() === itemId); + + if (!inventoryItem) { + throw new Error(`inventory item ${equipmentName} not found with id ${itemId}`); + } + + for (const [configId, config] of Object.entries(itemConfigEntries)) { + inventoryItem.Configs[parseInt(configId)] = config; + } + } + break; + } else { + logger.warn(`loadout category not implemented, changes may be lost: ${equipmentName}`, { + config: equipment + }); + } } - //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory } } await inventory.save(); diff --git a/src/types/inventoryTypes/commonInventoryTypes.ts b/src/types/inventoryTypes/commonInventoryTypes.ts index e1603816..5f3aeac0 100644 --- a/src/types/inventoryTypes/commonInventoryTypes.ts +++ b/src/types/inventoryTypes/commonInventoryTypes.ts @@ -1,5 +1,14 @@ import { IMongoDate, IOid } from "@/src/types/commonTypes"; import { Types } from "mongoose"; +import { + ICrewShipCustomization, + ICrewShipMembersClient, + ICrewShipMembersDatabase, + ICrewShipWeapon, + IFlavourItem, + IKubrowPetDetailsClient, + IKubrowPetDetailsDatabase +} from "@/src/types/inventoryTypes/inventoryTypes"; export interface IPolarity { Slot: number; @@ -79,11 +88,16 @@ export interface IEquipmentSelection { } export interface IEquipmentClient - extends Omit { + extends Omit< + IEquipmentDatabase, + "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "CrewMembers" | "Details" + > { ItemId: IOid; InfestationDate?: IMongoDate; Expiry?: IMongoDate; UpgradesExpiry?: IMongoDate; + CrewMembers?: ICrewShipMembersClient; + Details?: IKubrowPetDetailsClient; } export enum EquipmentFeatures { @@ -120,6 +134,11 @@ export interface IEquipmentDatabase { DefensiveUpgrade?: string; UpgradesExpiry?: Date; ArchonCrystalUpgrades?: IArchonCrystalUpgrade[]; + Weapon?: ICrewShipWeapon; + Customization?: ICrewShipCustomization; + RailjackImage?: IFlavourItem; + CrewMembers?: ICrewShipMembersDatabase; + Details?: IKubrowPetDetailsDatabase; _id: Types.ObjectId; } diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index da400863..b80134be 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -28,9 +28,9 @@ export interface IInventoryDatabase | "Upgrades" | "CrewShipSalvagedWeaponSkins" | "CrewShipWeaponSkins" - | "OperatorLoadOuts" | "AdultOperatorLoadOuts" - | "CrewShips" + | "OperatorLoadOuts" + | "KahlLoadOuts" | "InfestedFoundry" | "DialogueHistory" | TEquipmentKey @@ -49,9 +49,9 @@ export interface IInventoryDatabase Upgrades: IUpgradeDatabase[]; CrewShipSalvagedWeaponSkins: IUpgradeDatabase[]; CrewShipWeaponSkins: IUpgradeDatabase[]; - OperatorLoadOuts: IOperatorConfigDatabase[]; AdultOperatorLoadOuts: IOperatorConfigDatabase[]; - CrewShips: ICrewShipDatabase[]; + OperatorLoadOuts: IOperatorConfigDatabase[]; + KahlLoadOuts: IOperatorConfigDatabase[]; InfestedFoundry?: IInfestedFoundryDatabase; DialogueHistory?: IDialogueHistoryDatabase; @@ -68,6 +68,16 @@ export interface IInventoryDatabase Hoverboards: IEquipmentDatabase[]; OperatorAmps: IEquipmentDatabase[]; MoaPets: IEquipmentDatabase[]; + Scoops: IEquipmentDatabase[]; + Horses: IEquipmentDatabase[]; + DrifterGuns: IEquipmentDatabase[]; + DrifterMelee: IEquipmentDatabase[]; + Motorcycles: IEquipmentDatabase[]; + CrewShips: IEquipmentDatabase[]; + DataKnives: IEquipmentDatabase[]; + MechSuits: IEquipmentDatabase[]; + CrewShipHarnesses: IEquipmentDatabase[]; + KubrowPets: IEquipmentDatabase[]; } export interface IQuestKeyDatabase { @@ -97,7 +107,17 @@ export const equipmentKeys = [ "SpaceMelee", "Hoverboards", "OperatorAmps", - "MoaPets" + "MoaPets", + "Scoops", + "Horses", + "DrifterGuns", + "DrifterMelee", + "Motorcycles", + "CrewShips", + "DataKnives", + "MechSuits", + "CrewShipHarnesses", + "KubrowPets" ] as const; export type TEquipmentKey = (typeof equipmentKeys)[number]; @@ -167,13 +187,22 @@ export interface IInventoryClient extends IDailyAffiliations { Hoverboards: IEquipmentClient[]; OperatorAmps: IEquipmentClient[]; MoaPets: IEquipmentClient[]; + Scoops: IEquipmentClient[]; + Horses: IEquipmentClient[]; + DrifterGuns: IEquipmentClient[]; + DrifterMelee: IEquipmentClient[]; + Motorcycles: IEquipmentClient[]; + CrewShips: IEquipmentClient[]; + DataKnives: IEquipmentClient[]; + MechSuits: IEquipmentClient[]; + CrewShipHarnesses: IEquipmentClient[]; + KubrowPets: IEquipmentClient[]; + AdultOperatorLoadOuts: IOperatorConfigClient[]; + OperatorLoadOuts: IOperatorConfigClient[]; + KahlLoadOuts: IOperatorConfigClient[]; - Horses: IEquipmentDatabase[]; - DrifterMelee: IEquipmentDatabase[]; - DrifterGuns: IEquipmentDatabase[]; DuviriInfo: IDuviriInfo; Mailbox: IMailbox; - KahlLoadOuts: IEquipmentDatabase[]; SubscribedToEmails: number; Created: IMongoDate; RewardSeed: number; @@ -208,7 +237,6 @@ export interface IInventoryClient extends IDailyAffiliations { QuestKeys: IQuestKeyClient[]; ActiveQuest: string; FlavourItems: IFlavourItem[]; - Scoops: IEquipmentDatabase[]; LoadOutPresets: ILoadOutPresets; CurrentLoadOutIds: IOid[]; // we store it in the database using this representation as well :/ Missions: IMission[]; @@ -263,7 +291,6 @@ export interface IInventoryClient extends IDailyAffiliations { Drones: IDrone[]; StepSequencers: IStepSequencer[]; ActiveAvatarImageType: string; - KubrowPets: IEquipmentDatabase[]; ShipDecorations: IConsumable[]; DiscoveredMarkers: IDiscoveredMarker[]; CompletedJobs: ICompletedJob[]; @@ -280,7 +307,6 @@ export interface IInventoryClient extends IDailyAffiliations { BountyScore: number; ChallengeInstanceStates: IChallengeInstanceState[]; LoginMilestoneRewards: string[]; - OperatorLoadOuts: IOperatorConfigClient[]; RecentVendorPurchases: Array; NodeIntrosCompleted: string[]; GuildId?: IOid; @@ -288,13 +314,10 @@ export interface IInventoryClient extends IDailyAffiliations { SeasonChallengeHistory: ISeasonChallenge[]; EquippedInstrument?: string; InvasionChainProgress: IInvasionChainProgress[]; - DataKnives: IEquipmentDatabase[]; - Motorcycles: IEquipmentDatabase[]; NemesisHistory: INemesisHistory[]; LastNemesisAllySpawnTime?: IMongoDate; Settings: ISettings; PersonalTechProjects: IPersonalTechProject[]; - CrewShips: ICrewShipClient[]; PlayerSkills: IPlayerSkills; CrewShipAmmo: IConsumable[]; CrewShipSalvagedWeaponSkins: IUpgradeClient[]; @@ -304,13 +327,10 @@ export interface IInventoryClient extends IDailyAffiliations { TradeBannedUntil?: IMongoDate; PlayedParkourTutorial: boolean; SubscribedToEmailsPersonalized: number; - MechSuits: IEquipmentDatabase[]; InfestedFoundry?: IInfestedFoundryClient; BlessingCooldown: IMongoDate; - CrewShipHarnesses: IEquipmentDatabase[]; CrewShipRawSalvage: IConsumable[]; CrewMembers: ICrewMember[]; - AdultOperatorLoadOuts: IOperatorConfigClient[]; LotusCustomization: ILotusCustomization; UseAdultOperatorLoadout?: boolean; NemesisAbandonedRewards: string[]; @@ -454,22 +474,6 @@ export interface IUpgradeDatabase extends Omit { _id: Types.ObjectId; } -export interface ICrewShipClient { - ItemType: string; - Configs: IItemConfig[]; - Weapon?: ICrewShipWeapon; - Customization?: ICrewShipCustomization; - ItemName: string; - RailjackImage?: IFlavourItem; - CrewMembers?: ICrewShipMembersClient; - ItemId: IOid; -} - -export interface ICrewShipDatabase extends Omit { - CrewMembers?: ICrewShipMembersDatabase; - _id: Types.ObjectId; -} - export interface ICrewShipMembersClient { SLOT_A?: ICrewShipMemberClient; SLOT_B?: ICrewShipMemberClient; @@ -643,19 +647,23 @@ export enum KubrowPetPrintItemType { LotusTypesGameKubrowPetImprintedTraitPrint = "/Lotus/Types/Game/KubrowPet/ImprintedTraitPrint" } -export interface IDetails { +export interface IKubrowPetDetailsDatabase { Name: string; IsPuppy: boolean; HasCollar: boolean; PrintsRemaining: number; Status: Status; - HatchDate: IMongoDate; + HatchDate: Date; DominantTraits: ITraits; RecessiveTraits: ITraits; IsMale: boolean; Size: number; } +export interface IKubrowPetDetailsClient extends Omit { + HatchDate: IMongoDate; +} + export enum Status { StatusAvailable = "STATUS_AVAILABLE", StatusStasis = "STATUS_STASIS" diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index a58c499a..7958a91c 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -39,19 +39,6 @@ export type IMissionInventoryUpdateRequest = { GoalTag: string; LevelKeyName: string; ActiveBoosters?: IBooster[]; - Suits?: IEquipmentClient[]; - LongGuns?: IEquipmentClient[]; - Pistols?: IEquipmentClient[]; - Melee?: IEquipmentClient[]; - SpecialItems?: IEquipmentClient[]; - Sentinels?: IEquipmentClient[]; - SentinelWeapons?: IEquipmentClient[]; - SpaceSuits?: IEquipmentClient[]; - SpaceGuns?: IEquipmentClient[]; - SpaceMelee?: IEquipmentClient[]; - Hoverboards?: IEquipmentClient[]; - OperatorAmps?: IEquipmentClient[]; - MoaPets?: IEquipmentClient[]; FusionBundles?: ITypeCount[]; RawUpgrades?: IRawUpgrade[]; MiscItems?: ITypeCount[]; @@ -85,6 +72,8 @@ export type IMissionInventoryUpdateRequest = { FpsMax: number; FpsSamples: number; EvolutionProgress?: IEvolutionProgress[]; +} & { + [K in TEquipmentKey]?: IEquipmentClient[]; }; export interface IRewardInfo { diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index cd32b5c1..e04ec6a2 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -27,9 +27,9 @@ export interface ISaveLoadoutRequest { Horses: IItemEntry; DrifterMelee: IItemEntry; UpgradeVer: number; - OperatorLoadOuts: IOperatorConfigEntry; AdultOperatorLoadOuts: IOperatorConfigEntry; - KahlLoadOuts: IItemEntry; + OperatorLoadOuts: IOperatorConfigEntry; + KahlLoadOuts: IOperatorConfigEntry; CrewShips: IItemEntry; CurrentLoadOutIds: IOid[]; ValidNewLoadoutId: string; From de7758684b7cf277723738bb2f1e387b15a34f21 Mon Sep 17 00:00:00 2001 From: Sainan Date: Mon, 27 Jan 2025 18:11:05 +0100 Subject: [PATCH 5/6] feat: earn focus xp with a lens (#871) --- src/services/inventoryService.ts | 24 +++++++++++++++++++ src/services/missionInventoryUpdateService.ts | 5 ++++ src/types/requestTypes.ts | 1 + 3 files changed, 30 insertions(+) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 48854778..ddd5acc4 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -909,6 +909,30 @@ export const addFusionTreasures = ( }); }; +export const addFocusXpIncreases = (inventory: TInventoryDatabaseDocument, focusXpPlus: number[] | undefined): void => { + enum FocusType { + AP_UNIVERSAL, + AP_ATTACK, + AP_DEFENSE, + AP_TACTIC, + AP_POWER, + AP_PRECEPT, + AP_FUSION, + AP_WARD, + AP_UMBRA, + AP_ANY + } + + if (focusXpPlus) { + inventory.FocusXP ??= { AP_ATTACK: 0, AP_DEFENSE: 0, AP_TACTIC: 0, AP_POWER: 0, AP_WARD: 0 }; + inventory.FocusXP.AP_ATTACK += focusXpPlus[FocusType.AP_ATTACK]; + inventory.FocusXP.AP_DEFENSE += focusXpPlus[FocusType.AP_DEFENSE]; + inventory.FocusXP.AP_TACTIC += focusXpPlus[FocusType.AP_TACTIC]; + inventory.FocusXP.AP_POWER += focusXpPlus[FocusType.AP_POWER]; + inventory.FocusXP.AP_WARD += focusXpPlus[FocusType.AP_WARD]; + } +}; + export const updateChallengeProgress = async ( challenges: IUpdateChallengeProgressRequest, accountId: string diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index ed2700fd..8f34c83c 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -6,6 +6,7 @@ import { equipmentKeys, IInventoryDatabase, TEquipmentKey } from "@/src/types/in import { addChallenges, addConsumables, + addFocusXpIncreases, addFusionTreasures, addGearExpByCategory, addItem, @@ -145,6 +146,10 @@ export const addMissionInventoryUpdates = ( inventoryChanges.FusionPoints = fusionPoints; break; } + case "FocusXpIncreases": { + addFocusXpIncreases(inventory, value); + break; + } default: // Equipment XP updates if (equipmentKeys.includes(key as TEquipmentKey)) { diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 7958a91c..b2b0a3c1 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -72,6 +72,7 @@ export type IMissionInventoryUpdateRequest = { FpsMax: number; FpsSamples: number; EvolutionProgress?: IEvolutionProgress[]; + FocusXpIncreases?: number[]; } & { [K in TEquipmentKey]?: IEquipmentClient[]; }; From cf196430b71bbecbca075e1bb92eb19001b2a5e7 Mon Sep 17 00:00:00 2001 From: Sainan Date: Fri, 31 Jan 2025 09:37:51 +0100 Subject: [PATCH 6/6] fix: sort api imports alphabetically --- src/routes/api.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/api.ts b/src/routes/api.ts index a81ec037..f22b475f 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -31,6 +31,7 @@ import { getShipController } from "@/src/controllers/api/getShipController"; import { getVendorInfoController } from "@/src/controllers/api/getVendorInfoController"; import { getVoidProjectionRewardsController } from "@/src/controllers/api/getVoidProjectionRewardsController"; import { gildWeaponController } from "@/src/controllers/api/gildWeaponController"; +import { giveKeyChainTriggeredItemsController } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { guildTechController } from "../controllers/api/guildTechController"; import { hostSessionController } from "@/src/controllers/api/hostSessionController"; import { hubController } from "@/src/controllers/api/hubController"; @@ -74,13 +75,12 @@ import { syndicateSacrificeController } from "../controllers/api/syndicateSacrif import { syndicateStandingBonusController } from "../controllers/api/syndicateStandingBonusController"; import { tauntHistoryController } from "@/src/controllers/api/tauntHistoryController"; import { trainingResultController } from "@/src/controllers/api/trainingResultController"; +import { unlockShipFeatureController } from "@/src/controllers/api/unlockShipFeatureController"; import { updateChallengeProgressController } from "@/src/controllers/api/updateChallengeProgressController"; +import { updateQuestController } from "@/src/controllers/api/updateQuestController"; import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController"; import { updateThemeController } from "../controllers/api/updateThemeController"; import { upgradesController } from "@/src/controllers/api/upgradesController"; -import { updateQuestController } from "@/src/controllers/api/updateQuestController"; -import { giveKeyChainTriggeredItemsController } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; -import { unlockShipFeatureController } from "@/src/controllers/api/unlockShipFeatureController"; const apiRouter = express.Router();