From 6ee6cce7dbdb75951ab1c37870702cabfa449cd5 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Sat, 23 Aug 2025 08:55:44 +0200 Subject: [PATCH] chore: avoid using client oid representation in database --- src/controllers/api/nemesisController.ts | 8 +- .../getProfileViewingDataController.ts | 25 +++--- src/helpers/inventoryHelpers.ts | 5 ++ src/models/inventoryModels/inventoryModel.ts | 25 +++--- src/models/inventoryModels/loadoutModel.ts | 27 ++++--- src/services/importService.ts | 80 ++++++++++++++----- src/services/inventoryService.ts | 3 + src/services/missionInventoryUpdateService.ts | 8 +- src/services/saveLoadoutService.ts | 24 ++---- src/types/equipmentTypes.ts | 50 ++++++++---- src/types/inventoryTypes/inventoryTypes.ts | 4 +- src/types/saveLoadoutTypes.ts | 38 ++++++--- 12 files changed, 191 insertions(+), 106 deletions(-) diff --git a/src/controllers/api/nemesisController.ts b/src/controllers/api/nemesisController.ts index 2d361c80..c63c4776 100644 --- a/src/controllers/api/nemesisController.ts +++ b/src/controllers/api/nemesisController.ts @@ -1,4 +1,4 @@ -import { version_compare } from "@/src/helpers/inventoryHelpers"; +import { fromDbOid, version_compare } from "@/src/helpers/inventoryHelpers"; import { antivirusMods, decodeNemesisGuess, @@ -130,7 +130,9 @@ export const nemesisController: RequestHandler = async (req, res) => { if (result1 == GUESS_CORRECT || result2 == GUESS_CORRECT || result3 == GUESS_CORRECT) { let antivirusGain = 5; const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; - const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid); + const dataknifeLoadout = loadout.DATAKNIFE.id( + fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE]) + ); const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; for (const upgrade of body.knife!.AttachedUpgrades) { @@ -219,7 +221,7 @@ export const nemesisController: RequestHandler = async (req, res) => { // Subtract a charge from all requiem mods installed on parazon const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; const dataknifeLoadout = loadout.DATAKNIFE.id( - inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid + fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE]) ); const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; diff --git a/src/controllers/dynamic/getProfileViewingDataController.ts b/src/controllers/dynamic/getProfileViewingDataController.ts index b89ab917..7ec94f45 100644 --- a/src/controllers/dynamic/getProfileViewingDataController.ts +++ b/src/controllers/dynamic/getProfileViewingDataController.ts @@ -1,4 +1,4 @@ -import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; +import { fromDbOid, toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { Guild, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel"; import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; @@ -13,7 +13,8 @@ import { IDailyAffiliations, IMission, IPlayerSkills, - ITypeXPItem + ITypeXPItem, + LoadoutIndex } from "@/src/types/inventoryTypes/inventoryTypes"; import { RequestHandler } from "express"; import { catBreadHash, getJSONfromString } from "@/src/helpers/stringHelpers"; @@ -298,30 +299,32 @@ const populateLoadout = async ( ): Promise => { if (inventory.CurrentLoadOutIds.length) { const loadout = (await Loadout.findById(inventory.LoadOutPresets, "NORMAL"))!; - result.LoadOutPreset = loadout.NORMAL.id(inventory.CurrentLoadOutIds[0].$oid)!.toJSON(); + result.LoadOutPreset = loadout.NORMAL.id( + fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.NORMAL]) + )!.toJSON(); result.LoadOutPreset.ItemId = undefined; const skins = new Set(); - if (result.LoadOutPreset.s) { + if (result.LoadOutPreset.s?.ItemId) { result.LoadOutInventory.Suits = [ - inventory.Suits.id(result.LoadOutPreset.s.ItemId.$oid)!.toJSON() + inventory.Suits.id(fromDbOid(result.LoadOutPreset.s.ItemId))!.toJSON() ]; resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Suits[0]); } - if (result.LoadOutPreset.p) { + if (result.LoadOutPreset.p?.ItemId) { result.LoadOutInventory.Pistols = [ - inventory.Pistols.id(result.LoadOutPreset.p.ItemId.$oid)!.toJSON() + inventory.Pistols.id(fromDbOid(result.LoadOutPreset.p.ItemId))!.toJSON() ]; resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Pistols[0]); } - if (result.LoadOutPreset.l) { + if (result.LoadOutPreset.l?.ItemId) { result.LoadOutInventory.LongGuns = [ - inventory.LongGuns.id(result.LoadOutPreset.l.ItemId.$oid)!.toJSON() + inventory.LongGuns.id(fromDbOid(result.LoadOutPreset.l.ItemId))!.toJSON() ]; resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.LongGuns[0]); } - if (result.LoadOutPreset.m) { + if (result.LoadOutPreset.m?.ItemId) { result.LoadOutInventory.Melee = [ - inventory.Melee.id(result.LoadOutPreset.m.ItemId.$oid)!.toJSON() + inventory.Melee.id(fromDbOid(result.LoadOutPreset.m.ItemId))!.toJSON() ]; resolveAndCollectSkins(inventory, skins, result.LoadOutInventory.Melee[0]); } diff --git a/src/helpers/inventoryHelpers.ts b/src/helpers/inventoryHelpers.ts index 552ab3ec..d888b217 100644 --- a/src/helpers/inventoryHelpers.ts +++ b/src/helpers/inventoryHelpers.ts @@ -44,6 +44,11 @@ export const fromOid = (oid: IOidWithLegacySupport): string => { return (oid.$oid ?? oid.$id)!; }; +// For oids that may have been stored incorrectly +export const fromDbOid = (x: Types.ObjectId | IOid): Types.ObjectId => { + return "$oid" in x ? new Types.ObjectId(x.$oid) : x; +}; + export const toMongoDate = (date: Date): IMongoDate => { return { $date: { $numberLong: date.getTime().toString() } }; }; diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 5d4bf32e..91b2a651 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -100,8 +100,8 @@ import { IOperatorConfigDatabase, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; -import { EquipmentSelectionSchema, oidSchema } from "@/src/models/inventoryModels/loadoutModel"; +import { fromDbOid, toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; +import { EquipmentSelectionSchema } from "@/src/models/inventoryModels/loadoutModel"; import { ICountedStoreItem } from "warframe-public-export-plus"; import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel"; import { @@ -109,8 +109,8 @@ import { ICrewShipMemberClient, ICrewShipMemberDatabase, ICrewShipMembersDatabase, - ICrewShipWeapon, - ICrewShipWeaponEmplacements, + ICrewShipWeaponDatabase, + ICrewShipWeaponEmplacementsDatabase, IEquipmentClient, IEquipmentDatabase, IKubrowPetDetailsClient, @@ -847,7 +847,6 @@ const endlessXpProgressSchema = new Schema( }, { _id: false } ); - endlessXpProgressSchema.set("toJSON", { transform(_doc, ret: Record) { const db = ret as IEndlessXpProgressDatabase; @@ -861,7 +860,8 @@ endlessXpProgressSchema.set("toJSON", { } } }); -const crewShipWeaponEmplacementsSchema = new Schema( + +const crewShipWeaponEmplacementsSchema = new Schema( { PRIMARY_A: EquipmentSelectionSchema, PRIMARY_B: EquipmentSelectionSchema, @@ -871,7 +871,7 @@ const crewShipWeaponEmplacementsSchema = new Schema { _id: false } ); -const crewShipWeaponSchema = new Schema( +const crewShipWeaponSchema = new Schema( { PILOT: crewShipWeaponEmplacementsSchema, PORT_GUNS: crewShipWeaponEmplacementsSchema, @@ -1748,7 +1748,7 @@ const inventorySchema = new Schema( HasContributedToDojo: Boolean, HWIDProtectEnabled: Boolean, LoadOutPresets: { type: Schema.Types.ObjectId, ref: "Loadout" }, - CurrentLoadOutIds: [oidSchema], + CurrentLoadOutIds: [Schema.Types.Mixed], // should be Types.ObjectId[] but might be IOid[] because of old commits RandomUpgradesIdentified: Number, BountyScore: Number, //ChallengeInstanceStates: [Schema.Types.Mixed], @@ -1808,12 +1808,15 @@ inventorySchema.set("toJSON", { const inventoryDatabase = returnedObject as Partial; const inventoryResponse = returnedObject as IInventoryClient; - if (inventoryDatabase.TrainingDate) { - inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate); - } if (inventoryDatabase.Created) { inventoryResponse.Created = toMongoDate(inventoryDatabase.Created); } + if (inventoryDatabase.CurrentLoadOutIds) { + inventoryResponse.CurrentLoadOutIds = inventoryDatabase.CurrentLoadOutIds.map(x => toOid(fromDbOid(x))); + } + if (inventoryDatabase.TrainingDate) { + inventoryResponse.TrainingDate = toMongoDate(inventoryDatabase.TrainingDate); + } if (inventoryDatabase.GuildId) { inventoryResponse.GuildId = toOid(inventoryDatabase.GuildId); } diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index c98a8025..5e32be1d 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -1,21 +1,13 @@ +import { fromDbOid, toOid } from "@/src/helpers/inventoryHelpers"; import { IOid } from "@/src/types/commonTypes"; -import { IEquipmentSelection } from "@/src/types/equipmentTypes"; +import { IEquipmentSelectionClient, IEquipmentSelectionDatabase } from "@/src/types/equipmentTypes"; import { ILoadoutConfigDatabase, ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { Document, Model, Schema, Types, model } from "mongoose"; -export const oidSchema = new Schema( - { - $oid: String - }, - { - _id: false - } -); - //create a mongoose schema based on interface M -export const EquipmentSelectionSchema = new Schema( +export const EquipmentSelectionSchema = new Schema( { - ItemId: oidSchema, + ItemId: Schema.Types.Mixed, // should be Types.ObjectId but might be IOid because of old commits mod: Number, cus: Number, hide: Boolean @@ -24,6 +16,17 @@ export const EquipmentSelectionSchema = new Schema( _id: false } ); +EquipmentSelectionSchema.set("toJSON", { + virtuals: true, + transform(_doc, ret: Record) { + const db = ret as IEquipmentSelectionDatabase; + const client = ret as IEquipmentSelectionClient; + + if (db.ItemId) { + client.ItemId = toOid(fromDbOid(db.ItemId)); + } + } +}); export const loadoutConfigSchema = new Schema( { diff --git a/src/services/importService.ts b/src/services/importService.ts index 6d5d9b0d..0801500c 100644 --- a/src/services/importService.ts +++ b/src/services/importService.ts @@ -39,8 +39,14 @@ import { ICrewShipMemberDatabase, ICrewShipMembersClient, ICrewShipMembersDatabase, + ICrewShipWeaponClient, + ICrewShipWeaponDatabase, + ICrewShipWeaponEmplacementsClient, + ICrewShipWeaponEmplacementsDatabase, IEquipmentClient, IEquipmentDatabase, + IEquipmentSelectionClient, + IEquipmentSelectionDatabase, IKubrowPetDetailsClient, IKubrowPetDetailsDatabase } from "@/src/types/equipmentTypes"; @@ -84,7 +90,8 @@ const convertEquipment = (client: IEquipmentClient): IEquipmentDatabase => { Expiry: convertOptionalDate(client.Expiry), UpgradesExpiry: convertOptionalDate(client.UpgradesExpiry), UmbraDate: convertOptionalDate(client.UmbraDate), - CrewMembers: client.CrewMembers ? convertCrewShipMembers(client.CrewMembers) : undefined, + Weapon: client.Weapon ? importCrewShipWeapon(client.Weapon) : undefined, + CrewMembers: client.CrewMembers ? importCrewShipMembers(client.CrewMembers) : undefined, Details: client.Details ? convertKubrowDetails(client.Details) : undefined, // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition Configs: client.Configs @@ -133,14 +140,43 @@ const replaceSlots = (db: ISlots, client: ISlots): void => { db.Slots = client.Slots; }; -export const importCrewMemberId = (crewMemberId: ICrewShipMemberClient): ICrewShipMemberDatabase => { +const convertEquipmentSelection = (es: IEquipmentSelectionClient): IEquipmentSelectionDatabase => { + const { ItemId, ...rest } = es; + return { + ...rest, + ItemId: ItemId ? new Types.ObjectId(ItemId.$oid) : undefined + }; +}; + +const convertCrewShipWeaponEmplacements = ( + obj: ICrewShipWeaponEmplacementsClient +): ICrewShipWeaponEmplacementsDatabase => { + return { + PRIMARY_A: obj.PRIMARY_A ? convertEquipmentSelection(obj.PRIMARY_A) : undefined, + PRIMARY_B: obj.PRIMARY_B ? convertEquipmentSelection(obj.PRIMARY_B) : undefined, + SECONDARY_A: obj.SECONDARY_A ? convertEquipmentSelection(obj.SECONDARY_A) : undefined, + SECONDARY_B: obj.SECONDARY_B ? convertEquipmentSelection(obj.SECONDARY_B) : undefined + }; +}; + +export const importCrewShipWeapon = (weapon: ICrewShipWeaponClient): ICrewShipWeaponDatabase => { + return { + PILOT: weapon.PILOT ? convertCrewShipWeaponEmplacements(weapon.PILOT) : undefined, + PORT_GUNS: weapon.PORT_GUNS ? convertCrewShipWeaponEmplacements(weapon.PORT_GUNS) : undefined, + STARBOARD_GUNS: weapon.STARBOARD_GUNS ? convertCrewShipWeaponEmplacements(weapon.STARBOARD_GUNS) : undefined, + ARTILLERY: weapon.ARTILLERY ? convertCrewShipWeaponEmplacements(weapon.ARTILLERY) : undefined, + SCANNER: weapon.SCANNER ? convertCrewShipWeaponEmplacements(weapon.SCANNER) : undefined + }; +}; + +const importCrewMemberId = (crewMemberId: ICrewShipMemberClient): ICrewShipMemberDatabase => { if (crewMemberId.ItemId) { return { ItemId: new Types.ObjectId(crewMemberId.ItemId.$oid) }; } return { NemesisFingerprint: BigInt(crewMemberId.NemesisFingerprint ?? 0) }; }; -const convertCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => { +export const importCrewShipMembers = (client: ICrewShipMembersClient): ICrewShipMembersDatabase => { return { SLOT_A: client.SLOT_A ? importCrewMemberId(client.SLOT_A) : undefined, SLOT_B: client.SLOT_B ? importCrewMemberId(client.SLOT_B) : undefined, @@ -429,34 +465,40 @@ export const importInventory = (db: TInventoryDatabaseDocument, client: Partial< } }; -const convertLoadOutConfig = (client: ILoadoutConfigClient): ILoadoutConfigDatabase => { +export const importLoadOutConfig = (client: ILoadoutConfigClient): ILoadoutConfigDatabase => { const { ItemId, ...rest } = client; return { ...rest, - _id: new Types.ObjectId(ItemId.$oid) + _id: new Types.ObjectId(ItemId.$oid), + s: client.s ? convertEquipmentSelection(client.s) : undefined, + p: client.p ? convertEquipmentSelection(client.p) : undefined, + l: client.l ? convertEquipmentSelection(client.l) : undefined, + m: client.m ? convertEquipmentSelection(client.m) : undefined, + h: client.h ? convertEquipmentSelection(client.h) : undefined, + a: client.a ? convertEquipmentSelection(client.a) : undefined }; }; export const importLoadOutPresets = (db: ILoadoutDatabase, client: ILoadOutPresets): void => { - db.NORMAL = client.NORMAL.map(convertLoadOutConfig); - db.SENTINEL = client.SENTINEL.map(convertLoadOutConfig); - db.ARCHWING = client.ARCHWING.map(convertLoadOutConfig); - db.NORMAL_PVP = client.NORMAL_PVP.map(convertLoadOutConfig); - db.LUNARO = client.LUNARO.map(convertLoadOutConfig); - db.OPERATOR = client.OPERATOR.map(convertLoadOutConfig); - db.GEAR = client.GEAR?.map(convertLoadOutConfig); - db.KDRIVE = client.KDRIVE.map(convertLoadOutConfig); - db.DATAKNIFE = client.DATAKNIFE.map(convertLoadOutConfig); - db.MECH = client.MECH.map(convertLoadOutConfig); - db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(convertLoadOutConfig); - db.DRIFTER = client.DRIFTER.map(convertLoadOutConfig); + db.NORMAL = client.NORMAL.map(importLoadOutConfig); + db.SENTINEL = client.SENTINEL.map(importLoadOutConfig); + db.ARCHWING = client.ARCHWING.map(importLoadOutConfig); + db.NORMAL_PVP = client.NORMAL_PVP.map(importLoadOutConfig); + db.LUNARO = client.LUNARO.map(importLoadOutConfig); + db.OPERATOR = client.OPERATOR.map(importLoadOutConfig); + db.GEAR = client.GEAR?.map(importLoadOutConfig); + db.KDRIVE = client.KDRIVE.map(importLoadOutConfig); + db.DATAKNIFE = client.DATAKNIFE.map(importLoadOutConfig); + db.MECH = client.MECH.map(importLoadOutConfig); + db.OPERATOR_ADULT = client.OPERATOR_ADULT.map(importLoadOutConfig); + db.DRIFTER = client.DRIFTER.map(importLoadOutConfig); }; export const convertCustomizationInfo = (client: ICustomizationInfoClient): ICustomizationInfoDatabase => { return { ...client, - LoadOutPreset: client.LoadOutPreset ? convertLoadOutConfig(client.LoadOutPreset) : undefined, - VehiclePreset: client.VehiclePreset ? convertLoadOutConfig(client.VehiclePreset) : undefined + LoadOutPreset: client.LoadOutPreset ? importLoadOutConfig(client.LoadOutPreset) : undefined, + VehiclePreset: client.VehiclePreset ? importLoadOutConfig(client.VehiclePreset) : undefined }; }; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index bf679f1b..7014377e 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -63,6 +63,7 @@ import { import { createShip } from "@/src/services/shipService"; import { catbrowDetails, + fromDbOid, fromMongoDate, fromOid, kubrowDetails, @@ -2232,6 +2233,8 @@ export const setupKahlSyndicate = (inventory: TInventoryDatabaseDocument): void }; export const cleanupInventory = (inventory: TInventoryDatabaseDocument): void => { + inventory.CurrentLoadOutIds = inventory.CurrentLoadOutIds.map(fromDbOid); + let index = inventory.MiscItems.findIndex(x => x.ItemType == ""); if (index != -1) { inventory.MiscItems.splice(index, 1); diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index bccbed42..600d3426 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -65,7 +65,6 @@ import { getNemesisPasscode } from "@/src/helpers/nemesisHelpers"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; -import { ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes"; import { getLiteSortie, getSortie, @@ -84,6 +83,7 @@ import { ITypeCount } from "@/src/types/commonTypes"; import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { Guild } from "@/src/models/guildModel"; import { handleGuildGoalProgress } from "@/src/services/guildService"; +import { importLoadOutConfig } from "./importService"; const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => { // Disruption missions just tell us (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2599) @@ -602,11 +602,7 @@ export const addMissionInventoryUpdates = async ( const loadout = await Loadout.findOne({ loadoutOwnerId: inventory.accountOwnerId }); if (loadout) { for (const [loadoutId, loadoutConfig] of Object.entries(value.LoadOuts.NORMAL)) { - const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; - const loadoutConfigDatabase: ILoadoutConfigDatabase = { - _id: new Types.ObjectId(ItemId.$oid), - ...loadoutConfigItemIdRemoved - }; + const loadoutConfigDatabase = importLoadOutConfig(loadoutConfig); const dbConfig = loadout.NORMAL.id(loadoutId); if (dbConfig) { dbConfig.overwrite(loadoutConfigDatabase); diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index c3f63a0a..da9e7f43 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -2,7 +2,6 @@ import { IItemEntry, ILoadoutClient, ILoadoutEntry, - ILoadoutConfigDatabase, IOperatorConfigEntry, ISaveLoadoutRequestNoUpgradeVer } from "@/src/types/saveLoadoutTypes"; @@ -14,7 +13,7 @@ import { isEmptyObject } from "@/src/helpers/general"; import { logger } from "@/src/utils/logger"; import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { importCrewMemberId } from "@/src/services/importService"; +import { importCrewShipMembers, importCrewShipWeapon, importLoadOutConfig } from "@/src/services/importService"; //TODO: setup default items on account creation or like originally in giveStartingItems.php @@ -88,20 +87,17 @@ export const handleInventoryItemConfigChange = async ( const oldLoadoutConfig = loadout[loadoutSlot].id(loadoutId); - const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; - const loadoutConfigDatabase: ILoadoutConfigDatabase = { - _id: new Types.ObjectId(ItemId.$oid), - ...loadoutConfigItemIdRemoved - }; + const loadoutConfigDatabase = importLoadOutConfig(loadoutConfig); // if no config with this id exists, create a new one if (!oldLoadoutConfig) { //save the new object id and assign it for every ffff return at the end - if (ItemId.$oid === "ffffffffffffffffffffffff") { + if (loadoutConfigDatabase._id.toString() === "ffffffffffffffffffffffff") { if (!newLoadoutId) { newLoadoutId = new Types.ObjectId(); } - loadout[loadoutSlot].push({ _id: newLoadoutId, ...loadoutConfigItemIdRemoved }); + loadoutConfigDatabase._id = newLoadoutId; + loadout[loadoutSlot].push(loadoutConfigDatabase); continue; } @@ -218,15 +214,11 @@ export const handleInventoryItemConfigChange = async ( if ("Customization" in itemConfigEntries) { inventoryItem.Customization = itemConfigEntries.Customization; } - if ("Weapon" in itemConfigEntries) { - inventoryItem.Weapon = itemConfigEntries.Weapon; + if (itemConfigEntries.Weapon) { + inventoryItem.Weapon = importCrewShipWeapon(itemConfigEntries.Weapon); } if (itemConfigEntries.CrewMembers) { - inventoryItem.CrewMembers = { - SLOT_A: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_A ?? {}), - SLOT_B: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_B ?? {}), - SLOT_C: importCrewMemberId(itemConfigEntries.CrewMembers.SLOT_C ?? {}) - }; + inventoryItem.CrewMembers = importCrewShipMembers(itemConfigEntries.CrewMembers); } } break; diff --git a/src/types/equipmentTypes.ts b/src/types/equipmentTypes.ts index 4053430a..e937019c 100644 --- a/src/types/equipmentTypes.ts +++ b/src/types/equipmentTypes.ts @@ -7,14 +7,18 @@ import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -export interface IEquipmentSelection { - ItemId: IOid; +export interface IEquipmentSelectionClient { + ItemId?: IOid; mod?: number; cus?: number; ItemType?: string; hide?: boolean; } +export interface IEquipmentSelectionDatabase extends Omit { + ItemId?: Types.ObjectId | IOid; // should be Types.ObjectId but might be IOid because of old commits +} + export enum EquipmentFeatures { DOUBLE_CAPACITY = 1, UTILITY_SLOT = 2, @@ -51,7 +55,7 @@ export interface IEquipmentDatabase { UpgradesExpiry?: Date; UmbraDate?: Date; // related to scrapped "echoes of umbra" feature ArchonCrystalUpgrades?: IArchonCrystalUpgrade[]; - Weapon?: ICrewShipWeapon; + Weapon?: ICrewShipWeaponDatabase; Customization?: ICrewShipCustomization; RailjackImage?: IFlavourItem; CrewMembers?: ICrewShipMembersDatabase; @@ -64,13 +68,14 @@ export interface IEquipmentDatabase { export interface IEquipmentClient extends Omit< IEquipmentDatabase, - "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details" + "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "Weapon" | "CrewMembers" | "Details" > { ItemId: IOidWithLegacySupport; InfestationDate?: IMongoDate; Expiry?: IMongoDate; UpgradesExpiry?: IMongoDate; UmbraDate?: IMongoDate; + Weapon?: ICrewShipWeaponClient; CrewMembers?: ICrewShipMembersClient; Details?: IKubrowPetDetailsClient; } @@ -117,19 +122,34 @@ export enum Status { } // inventory.CrewShips[0].Weapon -export interface ICrewShipWeapon { - PILOT?: ICrewShipWeaponEmplacements; - PORT_GUNS?: ICrewShipWeaponEmplacements; - STARBOARD_GUNS?: ICrewShipWeaponEmplacements; - ARTILLERY?: ICrewShipWeaponEmplacements; - SCANNER?: ICrewShipWeaponEmplacements; +export interface ICrewShipWeaponClient { + PILOT?: ICrewShipWeaponEmplacementsClient; + PORT_GUNS?: ICrewShipWeaponEmplacementsClient; + STARBOARD_GUNS?: ICrewShipWeaponEmplacementsClient; + ARTILLERY?: ICrewShipWeaponEmplacementsClient; + SCANNER?: ICrewShipWeaponEmplacementsClient; } -export interface ICrewShipWeaponEmplacements { - PRIMARY_A?: IEquipmentSelection; - PRIMARY_B?: IEquipmentSelection; - SECONDARY_A?: IEquipmentSelection; - SECONDARY_B?: IEquipmentSelection; +export interface ICrewShipWeaponDatabase { + PILOT?: ICrewShipWeaponEmplacementsDatabase; + PORT_GUNS?: ICrewShipWeaponEmplacementsDatabase; + STARBOARD_GUNS?: ICrewShipWeaponEmplacementsDatabase; + ARTILLERY?: ICrewShipWeaponEmplacementsDatabase; + SCANNER?: ICrewShipWeaponEmplacementsDatabase; +} + +export interface ICrewShipWeaponEmplacementsClient { + PRIMARY_A?: IEquipmentSelectionClient; + PRIMARY_B?: IEquipmentSelectionClient; + SECONDARY_A?: IEquipmentSelectionClient; + SECONDARY_B?: IEquipmentSelectionClient; +} + +export interface ICrewShipWeaponEmplacementsDatabase { + PRIMARY_A?: IEquipmentSelectionDatabase; + PRIMARY_B?: IEquipmentSelectionDatabase; + SECONDARY_A?: IEquipmentSelectionDatabase; + SECONDARY_B?: IEquipmentSelectionDatabase; } export interface ICrewShipMembersClient { diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 9139a677..9323cf79 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -68,12 +68,14 @@ export interface IInventoryDatabase | "LastInventorySync" | "EndlessXP" | "PersonalGoalProgress" + | "CurrentLoadOutIds" | TEquipmentKey >, InventoryDatabaseEquipment, IAccountCheats { accountOwnerId: Types.ObjectId; Created: Date; + CurrentLoadOutIds: Types.ObjectId[] | IOid[]; // should be Types.ObjectId[] but might be IOid[] because of old commits TrainingDate: Date; LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population //Mailbox?: IMailboxDatabase; @@ -254,7 +256,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu ActiveQuest: string; FlavourItems: IFlavourItem[]; LoadOutPresets: ILoadOutPresets; - CurrentLoadOutIds: IOid[]; // we store it in the database using this representation as well :/ + CurrentLoadOutIds: IOid[]; Missions: IMission[]; RandomUpgradesIdentified?: number; LastRegionPlayed: TSolarMapRegion; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 33ff9708..ed21533f 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -7,7 +7,12 @@ import { IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; -import { ICrewShipMembersClient, ICrewShipWeapon, IEquipmentSelection } from "@/src/types/equipmentTypes"; +import { + ICrewShipMembersClient, + ICrewShipWeaponClient, + IEquipmentSelectionClient, + IEquipmentSelectionDatabase +} from "@/src/types/equipmentTypes"; export interface ISaveLoadoutRequest { LoadOuts: ILoadoutClient; @@ -53,10 +58,12 @@ export interface IOperatorConfigEntry { [configId: string]: IOperatorConfigClient; } +// client export interface IItemEntry { [itemId: string]: IConfigEntry; } +// client export type IConfigEntry = { [configId in "0" | "1" | "2" | "3" | "4" | "5"]: IItemConfig; } & { @@ -66,7 +73,7 @@ export type IConfigEntry = { ItemName?: string; RailjackImage?: IFlavourItem; Customization?: ICrewShipCustomization; - Weapon?: ICrewShipWeapon; + Weapon?: ICrewShipWeaponClient; CrewMembers?: ICrewShipMembersClient; }; @@ -108,10 +115,6 @@ export interface ILoadoutEntry { [key: string]: ILoadoutConfigClient; } -export interface ILoadoutConfigDatabase extends Omit { - _id: Types.ObjectId; -} - export enum FocusSchool { Attack = "AP_ATTACK", Defense = "AP_DEFENSE", @@ -125,12 +128,23 @@ export interface ILoadoutConfigClient { PresetIcon?: string; Favorite?: boolean; n?: string; // Loadout name - s?: IEquipmentSelection; // Suit - p?: IEquipmentSelection; // Secondary weapon - l?: IEquipmentSelection; // Primary weapon - m?: IEquipmentSelection; // Melee weapon - h?: IEquipmentSelection; // Gravimag weapon - a?: IEquipmentSelection; // Necromech exalted weapon + s?: IEquipmentSelectionClient; // Suit + p?: IEquipmentSelectionClient; // Secondary weapon + l?: IEquipmentSelectionClient; // Primary weapon + m?: IEquipmentSelectionClient; // Melee weapon + h?: IEquipmentSelectionClient; // Gravimag weapon + a?: IEquipmentSelectionClient; // Necromech exalted weapon ItemId: IOid; Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove. } + +export interface ILoadoutConfigDatabase + extends Omit { + _id: Types.ObjectId; + s?: IEquipmentSelectionDatabase; + p?: IEquipmentSelectionDatabase; + l?: IEquipmentSelectionDatabase; + m?: IEquipmentSelectionDatabase; + h?: IEquipmentSelectionDatabase; + a?: IEquipmentSelectionDatabase; +}