diff --git a/src/controllers/api/getShipController.ts b/src/controllers/api/getShipController.ts index 7439acf1..18e99d2f 100644 --- a/src/controllers/api/getShipController.ts +++ b/src/controllers/api/getShipController.ts @@ -1,10 +1,14 @@ import { Ship } from "@/src/models/shipModel"; +import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const getShipController: RequestHandler = async (req, res) => { const accountId = req.query.accountId; - const ship = await Ship.findOne({ ShipOwnerId: accountId }); + const ship = await Ship.findOne({ ShipOwnerId: accountId }).populate<{ + LoadOutInventory: { LoadOutPresets: ILoadoutDatabase }; + }>("LoadOutInventory.LoadOutPresets"); + if (!ship) { res.status(500).json({ error: "error finding a corresponding ship" }); return; diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index 21099e1e..77ae6372 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -31,7 +31,7 @@ const inventoryController: RequestHandler = async (request: Request, response: R if (config.testMission) inventoryResponse.Missions = testMissions; if (config.testQuestKey) inventoryResponse.QuestKeys = testQuestKeys; - inventoryResponse.DuviriInfo = { Seed: -5049874987509758080, NumCompletions: 0 }; + inventoryResponse.DuviriInfo = { Seed: -123123123123123123, NumCompletions: 0 }; response.json(inventoryResponse); }; diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index 0f029472..5aa4ccb4 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -1,147 +1,19 @@ -import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { RequestHandler } from "express"; import util from "util"; -import { - EquipmentCategories, - IConfigEntry, - ILoadoutRequest, - ILoadoutKey, - ISaveLoadoutRequest, - ISaveLoadoutRequestNoUpgradeVer, - ILoadoutConfigDatabase -} from "@/src/types/saveLoadoutTypes"; -import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; -import { Types } from "mongoose"; - -export const isEmptyObject = (obj: unknown): boolean => { - return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); -}; - -//setup default items on account creation or like originally in giveStartingItems.php - -//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; - -export const handleInventoryItemConfigChange = async (equipmentChanges: ISaveLoadoutRequestNoUpgradeVer) => { - for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { - const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; - const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; - - if (isEmptyObject(equipment)) { - continue; - } - // non-empty is a change in loadout(or suit...) - - switch (equipmentName) { - case "LoadOuts": { - console.log("loadout received"); - - for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { - const loadoutSlot = _loadoutSlot as keyof ILoadoutRequest; - const loadout = _loadout as ILoadoutKey; - - //console.log("key", loadoutSlot, "value", loadout); - - if (isEmptyObject(loadout)) { - continue; - } - // all non-empty entries are one loadout slot - for (const [loadoutId, loadoutConfig] of Object.entries(loadout)) { - // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); - const loadout = await LoadoutModel.findById("656a184a9cefa0e5627689af"); - if (!loadout) { - throw new Error("loadout not found"); - } - - const oldLoadoutConfig = loadout[loadoutSlot].find( - loadout => loadout._id.toString() === loadoutId - ); - - // if no config with this id exists, create a new one - if (!oldLoadoutConfig) { - const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; - loadout[loadoutSlot].push({ - _id: ItemId.$oid, - ...loadoutConfigItemIdRemoved - }); - await loadout.save(); - continue; - } - - const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); - - if (loadoutIndex === undefined || loadoutIndex === -1) { - throw new Error("loadout index not found"); - } - - //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); - loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); - //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); - //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); - - await loadout.save(); - //({ _id: loadoutId }, loadoutConfig); - } - } - break; - } - case "LongGuns": { - console.log("longgun received"); - console.log(equipmentName, equipment); - - const longGun = equipment as IConfigEntry; - // longGun["key"].PvpUpgrades; - break; - } - case "OperatorAmps": - case "Pistols": - case "Suits": - case "Melee": - case "Sentinels": - case "SentinelWeapons": - case "KubrowPets": - case "SpaceSuits": - case "SpaceGuns": - case "SpaceMelee": - case "Scoops": - case "SpecialItems": - case "MoaPets": - case "Hoverboards": - case "DataKnives": - case "MechSuits": - case "CrewShipHarnesses": - case "Horses": - case "DrifterMelee": - case "OperatorLoadOuts": - case "AdultOperatorLoadOuts": - case "KahlLoadOuts": - case "CrewShips": - - default: { - console.log("category not implemented", equipmentName); - } - } - // Object.keys(value).forEach(element => { - // console.log("name of inner objects keys", element); - // }); - // for (const innerValue of Object.values(value)) { - // console.log(innerValue); - // } - - // console.log(innerObjects); - // if (isObjectEmpty(innerObjects)) { - // console.log(innerObjects, "is empty"); - // } - } -}; +import { ISaveLoadoutRequest } from "@/src/types/saveLoadoutTypes"; +import { handleInventoryItemConfigChange } from "@/src/services/saveLoadoutService"; +import { parseString } from "@/src/helpers/general"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const saveLoadoutController: RequestHandler = async (req, res) => { //validate here + const accountId = parseString(req.query.accountId); const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { UpgradeVer, ...equipmentChanges } = body; - handleInventoryItemConfigChange(equipmentChanges); + await handleInventoryItemConfigChange(equipmentChanges, accountId); res.status(200).end(); }; diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index f39eb97f..21aed851 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -7,176 +7,206 @@ import { IBooster, IInventoryResponse, IInventoryDatabaseDocument, - IInventoryResponseDocument + ISlots } from "../../types/inventoryTypes/inventoryTypes"; import { IMongoDate, IOid } from "../../types/commonTypes"; -import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes"; +import { + IItemConfig, + ISuitDatabase, + IOperatorConfigClient, + IOperatorConfigDatabase +} from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; +import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -const abilityOverrideSchema = new Schema({ +const polaritySchema = new Schema({ + Slot: Number, + Value: String +}); + +const abilityOverrideSchema = new Schema({ Ability: String, Index: Number }); -const colorSchema = new Schema({ - t0: Number, - t1: Number, - t2: Number, - t3: Number, - en: Number, - e1: Number, - m0: Number, - m1: Number +const colorSchema = new Schema( + { + t0: Number, + t1: Number, + t2: Number, + t3: Number, + en: Number, + e1: Number, + m0: Number, + m1: Number + }, + { _id: false } +); + +const operatorConfigSchema = new Schema( + { + Skins: [String], + pricol: colorSchema, + attcol: colorSchema, + sigcol: colorSchema, + eyecol: colorSchema, + facial: colorSchema, + syancol: colorSchema, + Upgrades: [String], + Name: String, // not sure if possible in operator + ugly: Boolean // not sure if possible in operator + }, + { id: false } +); + +operatorConfigSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); -const weaponConfigSchema = new Schema({ - Skins: [String], - pricol: colorSchema, - attcol: colorSchema, - eyecol: colorSchema, - sigcol: colorSchema, - Upgrades: [String], - Songs: [ - { - m: String, - b: String, - p: String, - s: String - } - ], - Name: String, - AbilityOverride: abilityOverrideSchema, - PvpUpgrades: [String], - ugly: Boolean -}); - -// longGunConfigSchema.set("toJSON", { -// transform(_document, returnedObject: ISuitDocument) { -// // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call -// returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies Oid; -// delete returnedObject._id; -// delete returnedObject.__v; -// } -// }); - -const WeaponSchema = new Schema({ - ItemType: String, - Configs: [weaponConfigSchema], - UpgradeVer: Number, - XP: Number, - Features: Number, - Polarized: Number, - Polarity: Schema.Types.Mixed, //todo - FocusLens: String, - ModSlotPurchases: Number, - UpgradeType: Schema.Types.Mixed, //todo - UpgradeFingerprint: String, - ItemName: String, - ModularParts: [String], - UnlockLevel: Number -}); - -const BoosterSchema = new Schema({ - ExpiryDate: Number, - ItemType: String -}); - -const RawUpgrades = new Schema({ - ItemType: String, - ItemCount: Number -}); - -RawUpgrades.set("toJSON", { +operatorConfigSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.LastAdded = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; delete returnedObject.__v; } }); +///TODO: clearly seperate the different config schemas. (suit and weapon and so on) +const ItemConfigSchema = new Schema( + { + Skins: [String], + pricol: colorSchema, + attcol: colorSchema, + sigcol: colorSchema, + eyecol: colorSchema, + facial: colorSchema, + syancol: colorSchema, + Upgrades: [String], + Songs: [ + { + m: String, + b: String, + p: String, + s: String + } + ], + Name: String, + AbilityOverride: abilityOverrideSchema, + PvpUpgrades: [String], + ugly: Boolean + }, + { _id: false } +); + +ItemConfigSchema.set("toJSON", { + transform(_document, returnedObject) { + delete returnedObject.__v; + } +}); + +//TODO: migrate to one schema for weapons and suits.. and possibly others +const WeaponSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: Number, + XP: Number, + Features: Number, + Polarized: Number, + Polarity: [polaritySchema], + FocusLens: String, + ModSlotPurchases: Number, + UpgradeType: Schema.Types.Mixed, //todo + UpgradeFingerprint: String, + ItemName: String, + ModularParts: [String], + UnlockLevel: Number + }, + { id: false } +); + +WeaponSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +WeaponSchema.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + } +}); + +const BoosterSchema = new Schema({ + ExpiryDate: Number, + ItemType: String +}); + +const RawUpgrades = new Schema({ + ItemType: String, + ItemCount: Number +}); + +RawUpgrades.virtual("LastAdded").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + +RawUpgrades.set("toJSON", { + virtuals: true, + transform(_document, returnedObject) { + delete returnedObject._id; + delete returnedObject.__v; + } +}); + +//TODO: validate what this is const Upgrade = new Schema({ UpgradeFingerprint: String, ItemType: String }); +Upgrade.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; +}); + Upgrade.set("toJSON", { - transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; - delete returnedObject._id; - delete returnedObject.__v; - } -}); - -WeaponSchema.set("toJSON", { - transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; - delete returnedObject._id; - delete returnedObject.__v; - } -}); - -const polaritySchema = new Schema({ - Slot: Number, - Value: String -}); - -const suitConfigSchema = new Schema({ - Skins: [String], - pricol: colorSchema, - attcol: colorSchema, - eyecol: colorSchema, - sigcol: colorSchema, - Upgrades: [String], - Songs: [ - { - m: String, - b: String, - p: String, - s: String - } - ], - Name: String, - AbilityOverride: abilityOverrideSchema, - PvpUpgrades: [String], - ugly: Boolean -}); - -suitConfigSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { delete returnedObject._id; delete returnedObject.__v; } }); -const suitSchema = new Schema({ - ItemType: String, - Configs: { - type: [suitConfigSchema], - default: [{}, {}, {}] +//TODO: reduce weapon and suit schemas to one schema if reasonable +const suitSchema = new Schema( + { + ItemType: String, + Configs: [ItemConfigSchema], + UpgradeVer: Number, + XP: Number, + InfestationDate: Date, + Features: Number, + Polarity: [polaritySchema], + Polarized: Number, + ModSlotPurchases: Number, + FocusLens: String, + UnlockLevel: Number }, - UpgradeVer: Number, - XP: Number, - InfestationDate: Date, - Features: Number, - Polarity: [polaritySchema], - Polarized: Number, - ModSlotPurchases: Number, - FocusLens: String, - UnlockLevel: Number + { id: false } +); + +suitSchema.virtual("ItemId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); suitSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ItemId = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; delete returnedObject.__v; } }); -const slotsBinSchema = new Schema( +const slotsBinSchema = new Schema( { Slots: Number }, @@ -305,7 +335,7 @@ const inventorySchema = new Schema({ BountyScore: Number, ChallengeInstanceStates: [Schema.Types.Mixed], LoginMilestoneRewards: [String], - OperatorLoadOuts: [Schema.Types.Mixed], + OperatorLoadOuts: [operatorConfigSchema], DailyAffiliationVentkids: Number, DailyAffiliationVox: Number, RecentVendorPurchases: [Schema.Types.Mixed], @@ -342,7 +372,7 @@ const inventorySchema = new Schema({ CrewShipHarnesses: [Schema.Types.Mixed], CrewShipRawSalvage: [Schema.Types.Mixed], CrewMembers: [Schema.Types.Mixed], - AdultOperatorLoadOuts: [Schema.Types.Mixed], + AdultOperatorLoadOuts: [operatorConfigSchema], LotusCustomization: Schema.Types.Mixed, UseAdultOperatorLoadout: Boolean, DailyAffiliationZariman: Number, @@ -363,7 +393,10 @@ const inventorySchema = new Schema({ HasResetAccount: Boolean, PendingCoupon: Schema.Types.Mixed, Harvestable: Boolean, - DeathSquadable: Boolean + DeathSquadable: Boolean, + Horses: [Schema.Types.Mixed], + DrifterMelee: [Schema.Types.Mixed], + KahlLoadOuts: [Schema.Types.Mixed] }); inventorySchema.set("toJSON", { @@ -390,9 +423,11 @@ type InventoryDocumentProps = { RawUpgrades: Types.DocumentArray; MiscItems: Types.DocumentArray; Boosters: Types.DocumentArray; + OperatorLoadOuts: Types.DocumentArray; + AdultOperatorLoadOuts: Types.DocumentArray; }; -type InventoryModelType = Model; +type InventoryModelType = Model; const Inventory = model("Inventory", inventorySchema); diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index 44082497..37a8d104 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -53,7 +53,7 @@ loadoutConfigSchema.set("toJSON", { } }); -const loadoutSchema = new Schema({ +export const loadoutSchema = new Schema({ NORMAL: [loadoutConfigSchema], SENTINEL: [loadoutConfigSchema], ARCHWING: [loadoutConfigSchema], @@ -64,18 +64,15 @@ const loadoutSchema = new Schema({ DATAKNIFE: [loadoutConfigSchema], MECH: [loadoutConfigSchema], OPERATOR_ADULT: [loadoutConfigSchema], - DRIFTER: [loadoutConfigSchema] -}); - -loadoutSchema.virtual("ItemId").get(function (): string { - return this._id.toString(); + DRIFTER: [loadoutConfigSchema], + loadoutOwnerId: Schema.Types.ObjectId }); loadoutSchema.set("toJSON", { - virtuals: true, transform(_doc, ret, _options) { delete ret._id; delete ret.__v; + delete ret.loadoutOwnerId; } }); diff --git a/src/models/shipModel.ts b/src/models/shipModel.ts index bd56d933..4b16ebd2 100644 --- a/src/models/shipModel.ts +++ b/src/models/shipModel.ts @@ -1,6 +1,7 @@ import { Schema, model } from "mongoose"; import { IShip } from "../types/shipTypes"; import { IOid } from "../types/commonTypes"; +import { loadoutSchema } from "@/src/models/inventoryModels/loadoutModel"; const roomSchema = new Schema( { @@ -10,16 +11,22 @@ const roomSchema = new Schema( { _id: false } ); -const shipSchema = new Schema({ - Rooms: [roomSchema], - Features: [String], - ContentUrlSignature: String +const shipSchema = new Schema( + { + Rooms: [roomSchema], + Features: [String], + ContentUrlSignature: String + }, + { id: false } +); + +shipSchema.virtual("ShipId").get(function () { + return { $oid: this._id.toString() } satisfies IOid; }); shipSchema.set("toJSON", { + virtuals: true, transform(_document, returnedObject) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call - returnedObject.ShipId = { $oid: returnedObject._id.toString() } satisfies IOid; delete returnedObject._id; } }); @@ -35,10 +42,16 @@ apartmentSchema.set("toJSON", { } }); -const shipDatabaseSchema = new Schema({ +const shipDatabaseSchema = new Schema({ ShipOwnerId: Schema.Types.ObjectId, Ship: shipSchema, - Apartment: apartmentSchema + Apartment: apartmentSchema, + LoadOutInventory: { + LoadOutPresets: { + type: Schema.Types.ObjectId, + ref: "Loadout" + } + } }); shipDatabaseSchema.set("toJSON", { diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 1edb4acf..534dbfa8 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -2,9 +2,9 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import new_inventory from "@/static/fixed_responses/postTutorialInventory.json"; import config from "@/config.json"; import { Types } from "mongoose"; -import { ISuitDatabase, ISuitResponse } from "@/src/types/inventoryTypes/SuitTypes"; +import { ISuitDatabase, ISuitClient } from "@/src/types/inventoryTypes/SuitTypes"; import { SlotType } from "@/src/types/purchaseTypes"; -import { IWeaponDatabase, IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes"; +import { IWeaponDatabase, IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes"; import { IChallengeProgress, IConsumable, @@ -17,9 +17,13 @@ import { import { IGenericUpdate } from "../types/genericUpdate"; import { IArtifactsRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes"; -const createInventory = async (accountOwnerId: Types.ObjectId) => { +const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => { try { - const inventory = new Inventory({ ...new_inventory, accountOwnerId: accountOwnerId }); + const inventory = new Inventory({ + ...new_inventory, + accountOwnerId: accountOwnerId, + LoadOutPresets: loadOutPresetId + }); if (config.skipStoryModeChoice) { inventory.StoryModeChoice = "WARFRAME"; } @@ -27,6 +31,7 @@ const createInventory = async (accountOwnerId: Types.ObjectId) => { inventory.PlayedParkourTutorial = true; inventory.ReceivedStartingGear = true; } + await inventory.save(); } catch (error) { if (error instanceof Error) { @@ -48,7 +53,7 @@ export const getInventory = async (accountOwnerId: string) => { return inventory; }; -const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { +const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const suitIndex = inventory.Suits.push({ ItemType: powersuitName, Configs: [], UpgradeVer: 101, XP: 0 }); const changedInventory = await inventory.save(); @@ -107,7 +112,7 @@ export const addWeapon = async ( weaponType: WeaponTypeInternal, weaponName: string, accountId: string -): Promise => { +): Promise => { const inventory = await getInventory(accountId); let weaponIndex; @@ -139,7 +144,7 @@ export const addCustomization = async (customizatonName: string, accountId: stri const addGearExpByCategory = ( inventory: IInventoryDatabaseDocument, - gearArray: ISuitDatabase[] | IWeaponDatabase[] | undefined, + gearArray: ISuitClient[] | IWeaponClient[] | undefined, categoryName: "Pistols" | "LongGuns" | "Melee" | "Suits" ) => { const category = inventory[categoryName]; @@ -242,7 +247,6 @@ const addMissionComplete = (inventory: IInventoryDatabaseDocument, { Tag, Comple }; const gearKeys = ["Suits", "Pistols", "LongGuns", "Melee"] as const; -type GearKeysType = (typeof gearKeys)[number]; export const missionInventoryUpdate = async (data: IMissionInventoryUpdateRequest, accountId: string) => { const { RawUpgrades, MiscItems, RegularCredits, ChallengeProgress, FusionPoints, Consumables, Recipes, Missions } = @@ -256,7 +260,7 @@ export const missionInventoryUpdate = async (data: IMissionInventoryUpdateReques inventory.FusionPoints += FusionPoints || 0; // Gear XP - gearKeys.forEach((key: GearKeysType) => addGearExpByCategory(inventory, data[key], key)); + gearKeys.forEach(key => addGearExpByCategory(inventory, data[key], key)); // other addMods(inventory, RawUpgrades); diff --git a/src/services/loginService.ts b/src/services/loginService.ts index 9e7959f0..1753c85b 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -2,6 +2,8 @@ import { Account } from "@/src/models/loginModel"; import { createInventory } from "@/src/services/inventoryService"; import { IDatabaseAccount } from "@/src/types/loginTypes"; import { createShip } from "./shipService"; +import { Types } from "mongoose"; +import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => { return requestPassword === databasePassword; @@ -11,8 +13,9 @@ const createAccount = async (accountData: IDatabaseAccount) => { const account = new Account(accountData); try { await account.save(); - await createInventory(account._id); - await createShip(account._id); + const loadoutId = await createLoadout(account._id); + await createInventory(account._id, loadoutId); + await createShip(account._id, loadoutId); return account.toJSON(); } catch (error) { if (error instanceof Error) { @@ -23,3 +26,9 @@ const createAccount = async (accountData: IDatabaseAccount) => { }; export { isCorrectPassword, createAccount }; + +export const createLoadout = async (accountId: Types.ObjectId) => { + const loadout = new LoadoutModel({ loadoutOwnerId: accountId }); + const savedLoadout = await loadout.save(); + return savedLoadout._id; +}; diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index e69de29b..d47254e9 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -0,0 +1,179 @@ +import { + IItemEntry, + ILoadoutClient, + ILoadoutEntry, + IOperatorConfigEntry, + ISaveLoadoutRequestNoUpgradeVer +} from "@/src/types/saveLoadoutTypes"; +import { LoadoutModel } from "@/src/models/inventoryModels/loadoutModel"; +import { getInventory } from "@/src/services/inventoryService"; +import { IOid } from "@/src/types/commonTypes"; + +export const isEmptyObject = (obj: unknown): boolean => { + return Boolean(obj && Object.keys(obj).length === 0 && obj.constructor === Object); +}; + +//setup default items on account creation or like originally in giveStartingItems.php + +//export const updateLoadout = (loadout: ISaveLoadoutRequest, accountId: string) => {}; + +//support multiple loadouts and multiple items and multiple configs per item +export const handleInventoryItemConfigChange = async ( + equipmentChanges: ISaveLoadoutRequestNoUpgradeVer, + accountId: string +) => { + for (const [_equipmentName, _equipment] of Object.entries(equipmentChanges)) { + const equipment = _equipment as ISaveLoadoutRequestNoUpgradeVer[keyof ISaveLoadoutRequestNoUpgradeVer]; + const equipmentName = _equipmentName as keyof ISaveLoadoutRequestNoUpgradeVer; + + if (isEmptyObject(equipment)) { + continue; + } + // non-empty is a change in loadout(or suit...) + + switch (equipmentName) { + case "OperatorLoadOuts": + case "AdultOperatorLoadOuts": { + console.log("loadout received", equipmentName); + + const inventory = await getInventory(accountId); + const operatorConfig = equipment as IOperatorConfigEntry; + const operatorLoadout = inventory[equipmentName]; + + // all non-empty entries are one loadout slot + for (const [loadoutId, loadoutConfig] of Object.entries(operatorConfig)) { + // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); + const loadout = operatorLoadout.find(loadout => loadout._id?.toString() === loadoutId); + + // if no config with this id exists, create a new one + if (!loadout) { + const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; + operatorLoadout.push({ + _id: ItemId.$oid, + ...loadoutConfigItemIdRemoved + }); + await inventory.save(); + continue; + } + loadout.set(loadoutConfig); + + //({ _id: loadoutId }, loadoutConfig); + } + await inventory.save(); + break; + } + case "LoadOuts": { + console.log("loadout received"); + + for (const [_loadoutSlot, _loadout] of Object.entries(equipment)) { + const loadoutSlot = _loadoutSlot as keyof ILoadoutClient; + const newLoadout = _loadout as ILoadoutEntry; + + //console.log("key", loadoutSlot, "value", loadout); + + // empty loadout slot like: "NORMAL": {} + if (isEmptyObject(newLoadout)) { + continue; + } + + const loadout = await LoadoutModel.findOne({ loadoutOwnerId: accountId }); + //const {, ...loadout } = loadoutWithLoadoutOwnerId; + + if (!loadout) { + throw new Error("loadout not found"); + } + // all non-empty entries are one loadout slot + for (const [loadoutId, loadoutConfig] of Object.entries(newLoadout)) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + //const { loadoutOwnerId, ...loadout } = loadoutWithLoadoutOwnerId; + // console.log("loadoutId", loadoutId, "loadoutconfig", loadoutConfig); + + const oldLoadoutConfig = loadout[loadoutSlot].find( + loadout => loadout._id.toString() === loadoutId + ); + + // if no config with this id exists, create a new one + if (!oldLoadoutConfig) { + const { ItemId, ...loadoutConfigItemIdRemoved } = loadoutConfig; + loadout[loadoutSlot].push({ + _id: ItemId.$oid, + ...loadoutConfigItemIdRemoved + }); + await loadout.save(); + continue; + } + + const loadoutIndex = loadout[loadoutSlot].indexOf(oldLoadoutConfig); + + if (loadoutIndex === undefined || loadoutIndex === -1) { + throw new Error("loadout index not found"); + } + + //console.log("parent id", oldLoadoutConfig.ownerDocument()._id); + loadout[loadoutSlot][loadoutIndex].set(loadoutConfig); + //loadout.NORMAL[loadoutIndex].overwrite(loadoutConfig); + //console.log("db", loadout[loadoutSlot][loadoutIndex].schema); + + await loadout.save(); + //({ _id: loadoutId }, loadoutConfig); + } + } + break; + } + case "LongGuns": + case "Pistols": + case "Suits": + case "Melee": { + console.log("? ???? ?", equipmentName, equipment); + + const itemEntry = equipment as IItemEntry; + const inventory = await getInventory(accountId); + for (const [itemId, itemConfig] of Object.entries(itemEntry)) { + 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(itemConfig)) { + inventoryItem.Configs[parseInt(configId)] = config; + } + } + await inventory.save(); + break; + } + case "CurrentLoadOutIds": { + //TODO: remove duplicate getInventory after finding out when currentloadOutId is sent + const loadoutIds = equipment as IOid[]; + const inventory = await getInventory(accountId); + inventory.CurrentLoadOutIds = loadoutIds; + await inventory.save(); + break; + } + default: { + console.log("category not implemented", equipmentName); + } + } + + //case "OperatorAmps": + // case "Sentinels": + // case "SentinelWeapons": + // case "KubrowPets": + // case "SpaceSuits": + // case "SpaceGuns": + // case "SpaceMelee": + // case "Scoops": + // case "SpecialItems": + // case "MoaPets": + // case "Hoverboards": + // case "DataKnives": + // case "MechSuits": + // case "CrewShipHarnesses": + // case "Horses": + // case "DrifterMelee": + + // case "CrewShips": + //case "KahlLoadOuts": not sure yet how to handle kahl: it is not sent in inventory + } +}; diff --git a/src/services/shipService.ts b/src/services/shipService.ts index bce95805..5b35cce3 100644 --- a/src/services/shipService.ts +++ b/src/services/shipService.ts @@ -2,9 +2,13 @@ import { Ship } from "@/src/models/shipModel"; import new_ship from "@/static/fixed_responses/ship.json"; import { Types } from "mongoose"; -const createShip = async (accountOwnerId: Types.ObjectId) => { +const createShip = async (accountOwnerId: Types.ObjectId, loadoutId: Types.ObjectId) => { try { - const ship = new Ship({ ...new_ship, ShipOwnerId: accountOwnerId }); + const ship = new Ship({ + ...new_ship, + ShipOwnerId: accountOwnerId, + LoadOutInventory: { LoadOutPresets: loadoutId } + }); await ship.save(); } catch (error) { if (error instanceof Error) { diff --git a/src/types/inventoryTypes/SuitTypes.ts b/src/types/inventoryTypes/SuitTypes.ts index dc71db19..fb63283a 100644 --- a/src/types/inventoryTypes/SuitTypes.ts +++ b/src/types/inventoryTypes/SuitTypes.ts @@ -1,20 +1,14 @@ import { IOid } from "@/src/types/commonTypes"; import { IAbilityOverride, IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { Document, Types } from "mongoose"; +import { Types } from "mongoose"; -// export interface ISuitDocument extends ISuitResponse, Document {} -export interface ISuitDocument extends Document, ISuitResponse { - _id: Types.ObjectId; -} - -export interface ISuitResponse extends ISuitDatabase { +export interface ISuitClient extends ISuitDatabase { ItemId: IOid; - //should omit _id which is not present in response } export interface ISuitDatabase { ItemType: string; - Configs: SuitConfig[]; + Configs: IItemConfig[]; UpgradeVer?: number; XP?: number; InfestationDate?: Date; @@ -25,26 +19,43 @@ export interface ISuitDatabase { FocusLens?: string; UnlockLevel?: number; _id: Types.ObjectId; - ItemId?: IOid; } -export interface SuitConfig { - Skins?: string[]; +interface IItemConfigBase { + Skins: string[]; pricol?: IColor; attcol?: IColor; - eyecol?: IColor; sigcol?: IColor; + eyecol?: IColor; + facial?: IColor; + syancol?: IColor; + cloth?: IColor; Upgrades?: string[]; - Songs?: Song[]; Name?: string; + ugly?: boolean; +} + +export interface IItemConfig extends IItemConfigBase { + Songs?: ISong[]; AbilityOverride?: IAbilityOverride; PvpUpgrades?: string[]; ugly?: boolean; } -export interface Song { +export interface ISong { m?: string; b?: string; p?: string; s: string; } + +//TODO: Consider renaming it to loadout instead of config +export interface IOperatorConfigDatabase extends IItemConfigBase { + _id: Types.ObjectId; + AbilityOverride?: IAbilityOverride; // not present in adultOperator + OperatorAmp?: IOid; // not present in adultOperator +} + +export interface IOperatorConfigClient extends Omit { + ItemId: IOid; +} diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 450b6e10..db0383f8 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -2,19 +2,33 @@ import { Document, Types } from "mongoose"; import { IOid, IMongoDate } from "../commonTypes"; import { IAbilityOverride, IColor, FocusSchool, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; +import { IOperatorConfigClient, ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IOperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; +import { IItemConfig } from "@/src/types/saveLoadoutTypes"; +//Document extends will be deleted soon. TODO: delete and migrate uses to ... export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {} -export interface IInventoryDatabase extends Omit { +export interface IInventoryDatabase extends Omit { accountOwnerId: Types.ObjectId; - TrainingDate: Date; + TrainingDate: Date; // TrainingDate changed from IMongoDate to Date + LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population } export interface IInventoryResponseDocument extends IInventoryResponse, Document {} +export interface IGenericItem { + ItemType: string; + XP?: number; + Configs: IItemConfig[]; + UpgradeVer: number; + ItemId: IOid; +} + export interface IInventoryResponse { - DuviriInfo: { Seed: number; NumCompletions: number }; + KahlLoadOuts: IGenericItem[]; + DrifterMelee: IGenericItem[]; + Horses: IGenericItem[]; + DuviriInfo: { Seed: number; NumCompletions: number }; // TODO: add to schema SubscribedToEmails: number; Created: IMongoDate; RewardSeed: number; @@ -22,14 +36,14 @@ export interface IInventoryResponse { PremiumCredits: number; PremiumCreditsFree: number; FusionPoints: number; - SuitBin: ICrewShipSalvageBinClass; - WeaponBin: ICrewShipSalvageBinClass; - SentinelBin: ICrewShipSalvageBinClass; - SpaceSuitBin: ICrewShipSalvageBinClass; - SpaceWeaponBin: ICrewShipSalvageBinClass; + SuitBin: ISlots; + WeaponBin: ISlots; + SentinelBin: ISlots; + SpaceSuitBin: ISlots; + SpaceWeaponBin: ISlots; PvpBonusLoadoutBin: ICrewMemberBinClass; - PveBonusLoadoutBin: ICrewShipSalvageBinClass; - RandomModBin: ICrewShipSalvageBinClass; + PveBonusLoadoutBin: ISlots; + RandomModBin: ISlots; TradesRemaining: number; DailyAffiliation: number; DailyAffiliationPvp: number; @@ -103,7 +117,7 @@ export interface IInventoryResponse { ActiveAvatarImageType: string; KubrowPets: IKubrowPet[]; ShipDecorations: IConsumable[]; - OperatorAmpBin: ICrewShipSalvageBinClass; + OperatorAmpBin: ISlots; DailyAffiliationCetus: number; DailyAffiliationQuills: number; DiscoveredMarkers: IDiscoveredMarker[]; @@ -124,7 +138,7 @@ export interface IInventoryResponse { BountyScore: number; ChallengeInstanceStates: IChallengeInstanceState[]; LoginMilestoneRewards: string[]; - OperatorLoadOuts: IOperatorLoadOut[]; + OperatorLoadOuts: IOperatorConfigClient[]; DailyAffiliationVentkids: number; DailyAffiliationVox: number; RecentVendorPurchases: Array; @@ -141,7 +155,7 @@ export interface IInventoryResponse { Settings: ISettings; PersonalTechProjects: IPersonalTechProject[]; CrewShips: ICrewShip[]; - CrewShipSalvageBin: ICrewShipSalvageBinClass; + CrewShipSalvageBin: ISlots; PlayerSkills: IPlayerSkills; CrewShipAmmo: IConsumable[]; CrewShipSalvagedWeaponSkins: ICrewShipSalvagedWeaponSkin[]; @@ -161,7 +175,7 @@ export interface IInventoryResponse { CrewShipHarnesses: ICrewShipHarness[]; CrewShipRawSalvage: IConsumable[]; CrewMembers: ICrewMember[]; - AdultOperatorLoadOuts: IAdultOperatorLoadOut[]; + AdultOperatorLoadOuts: IOperatorConfigClient[]; LotusCustomization: ILotusCustomization; UseAdultOperatorLoadout: boolean; DailyAffiliationZariman: number; @@ -311,8 +325,8 @@ export interface ICrewShipHarnessConfig { Upgrades?: string[]; } -export interface ICrewShipSalvageBinClass { - Extra: number; +export interface ISlots { + Extra?: number; Slots: number; } @@ -624,6 +638,7 @@ export interface ILibraryPersonalProgress { Completed: boolean; } +//this needs to be checked against ILoadoutDatabase export interface ILoadOutPresets { NORMAL: INormal[]; NORMAL_PVP: IArchwing[]; @@ -871,7 +886,7 @@ export enum GivingSlotOrderInfo { LotusUpgradesModsPistolDualStatElectEventPistolMod = "/Lotus/Upgrades/Mods/Pistol/DualStat/ElectEventPistolMod" } -export interface PeriodicMissionCompletion { +export interface IPeriodicMissionCompletion { date: IMongoDate; tag: string; count?: number; diff --git a/src/types/inventoryTypes/weaponTypes.ts b/src/types/inventoryTypes/weaponTypes.ts index 365c869b..0d92ef6d 100644 --- a/src/types/inventoryTypes/weaponTypes.ts +++ b/src/types/inventoryTypes/weaponTypes.ts @@ -1,14 +1,15 @@ import { IOid } from "@/src/types/commonTypes"; -import { IColor, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IItemConfig } from "@/src/types/inventoryTypes/SuitTypes"; +import { IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Types } from "mongoose"; -export interface IWeaponResponse extends IWeaponDatabase { +export interface IWeaponClient extends Omit { ItemId: IOid; } export interface IWeaponDatabase { ItemType: string; - Configs: WeaponConfig[]; + Configs: IItemConfig[]; UpgradeVer?: number; XP?: number; Features?: number; @@ -21,18 +22,7 @@ export interface IWeaponDatabase { ItemName?: string; ModularParts?: string[]; UnlockLevel?: number; - _id?: Types.ObjectId; - ItemId?: IOid; -} - -export interface WeaponConfig { - Skins?: string[]; - pricol?: IColor; - Upgrades?: string[]; - attcol?: IColor; - eyecol?: IOperatorLoadOutSigcol; - Name?: string; - PvpUpgrades?: string[]; + _id: Types.ObjectId; } export interface IOperatorLoadOutSigcol { diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index 6df9719d..ca98dc95 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -1,6 +1,6 @@ import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes"; import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IWeaponResponse } from "@/src/types/inventoryTypes/weaponTypes"; +import { IWeaponClient } from "@/src/types/inventoryTypes/weaponTypes"; export interface IPurchaseRequest { PurchaseParams: IPurchaseParams; @@ -23,9 +23,9 @@ export interface IPurchaseResponse { SuitBin?: IBinChanges; WeaponBin?: IBinChanges; Suits?: ISuitDatabase[]; - LongGuns?: IWeaponResponse[]; - Pistols?: IWeaponResponse[]; - Melee?: IWeaponResponse[]; + LongGuns?: IWeaponClient[]; + Pistols?: IWeaponClient[]; + Melee?: IWeaponClient[]; PremiumCredits?: number; RegularCredits?: number; FlavourItems?: IFlavourItem[]; diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 050955d9..ecbd35e0 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -7,8 +7,8 @@ import { IMission, IRawUpgrade } from "./inventoryTypes/inventoryTypes"; -import { IWeaponDatabase } from "./inventoryTypes/weaponTypes"; -import { ISuitDatabase } from "./inventoryTypes/SuitTypes"; +import { IWeaponClient } from "./inventoryTypes/weaponTypes"; +import { ISuitClient } from "./inventoryTypes/SuitTypes"; interface IArtifactsRequest { Upgrade: ICrewShipSalvagedWeaponSkin; @@ -20,10 +20,10 @@ interface IArtifactsRequest { interface IMissionInventoryUpdateRequest { rewardsMultiplier?: number; ActiveBoosters?: IBooster[]; - LongGuns?: IWeaponDatabase[]; - Pistols?: IWeaponDatabase[]; - Suits?: ISuitDatabase[]; - Melee?: IWeaponDatabase[]; + LongGuns?: IWeaponClient[]; + Pistols?: IWeaponClient[]; + Suits?: ISuitClient[]; + Melee?: IWeaponClient[]; RawUpgrades?: IRawUpgrade[]; MiscItems?: IMiscItem[]; Consumables?: IConsumable[]; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 92f496e9..5e630be5 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,64 +1,76 @@ import { IOid } from "@/src/types/commonTypes"; -import { Document, Mongoose, Types } from "mongoose"; +import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/SuitTypes"; +import { Types } from "mongoose"; export interface ISaveLoadoutRequest { - LoadOuts: ILoadoutRequest; - LongGuns: IConfigEntry; - OperatorAmps: IConfigEntry; - Pistols: IConfigEntry; - Suits: IConfigEntry; - Melee: IConfigEntry; - Sentinels: IConfigEntry; - SentinelWeapons: IConfigEntry; - KubrowPets: IConfigEntry; - SpaceSuits: IConfigEntry; - SpaceGuns: IConfigEntry; - SpaceMelee: IConfigEntry; - Scoops: IConfigEntry; - SpecialItems: IConfigEntry; - MoaPets: IConfigEntry; - Hoverboards: IConfigEntry; - DataKnives: IConfigEntry; - MechSuits: IConfigEntry; - CrewShipHarnesses: IConfigEntry; - Horses: IConfigEntry; - DrifterMelee: IConfigEntry; + LoadOuts: ILoadoutClient; + LongGuns: IItemEntry; + OperatorAmps: IItemEntry; + Pistols: IItemEntry; + Suits: IItemEntry; + Melee: IItemEntry; + Sentinels: IItemEntry; + SentinelWeapons: IItemEntry; + KubrowPets: IItemEntry; + SpaceSuits: IItemEntry; + SpaceGuns: IItemEntry; + SpaceMelee: IItemEntry; + Scoops: IItemEntry; + SpecialItems: IItemEntry; + MoaPets: IItemEntry; + Hoverboards: IItemEntry; + DataKnives: IItemEntry; + MechSuits: IItemEntry; + CrewShipHarnesses: IItemEntry; + Horses: IItemEntry; + DrifterMelee: IItemEntry; UpgradeVer: number; - OperatorLoadOuts: IConfigEntry; - AdultOperatorLoadOuts: IConfigEntry; - KahlLoadOuts: IConfigEntry; - CrewShips: IConfigEntry; + OperatorLoadOuts: IOperatorConfigEntry; + AdultOperatorLoadOuts: IOperatorConfigEntry; + KahlLoadOuts: IItemEntry; + CrewShips: IItemEntry; + CurrentLoadOutIds: IOid[]; + ValidNewLoadoutId: string; } export interface ISaveLoadoutRequestNoUpgradeVer extends Omit {} +export interface IOperatorConfigEntry { + [configId: string]: IOperatorConfigClient; +} + +export interface IItemEntry { + [itemId: string]: IConfigEntry; +} + export interface IConfigEntry { - [key: string]: Config; + [configId: string]: IItemConfig; } -export interface ILoadoutRequest extends Omit {} - -export interface ILoadoutResponse extends ILoadoutDatabase { - ItemId: IOid; -} +export interface ILoadoutClient extends Omit {} export interface ILoadoutDatabase { - NORMAL: ILoadoutConfigDatabase; - SENTINEL: ILoadoutConfigDatabase; - ARCHWING: ILoadoutConfigDatabase; - NORMAL_PVP: ILoadoutConfigDatabase; - LUNARO: ILoadoutConfigDatabase; - OPERATOR: ILoadoutConfigDatabase; - KDRIVE: ILoadoutConfigDatabase; - DATAKNIFE: ILoadoutConfigDatabase; - MECH: ILoadoutConfigDatabase; - OPERATOR_ADULT: ILoadoutConfigDatabase; - DRIFTER: ILoadoutConfigDatabase; + NORMAL: ILoadoutEntry; + SENTINEL: ILoadoutEntry; + ARCHWING: ILoadoutEntry; + NORMAL_PVP: ILoadoutEntry; + LUNARO: ILoadoutEntry; + OPERATOR: ILoadoutEntry; + KDRIVE: ILoadoutEntry; + DATAKNIFE: ILoadoutEntry; + MECH: ILoadoutEntry; + OPERATOR_ADULT: ILoadoutEntry; + DRIFTER: ILoadoutEntry; + _id: Types.ObjectId; + loadoutOwnerId: Types.ObjectId; } -export interface ILoadoutKey { +export interface ILoadoutEntry { [key: string]: ILoadoutConfigClient; } +export interface ILoadoutConfigDatabase extends Omit { + _id: Types.ObjectId; +} // for request and response from and to client export interface ILoadoutConfigClient { @@ -72,70 +84,9 @@ export interface ILoadoutConfigClient { m: IEquipmentSelection; } -export interface ILoadoutConfigDatabase extends Omit { - _id: Types.ObjectId; -} - export interface IEquipmentSelection { ItemId: IOid; mod: number; cus: number; } - -export interface Config { - Upgrades: any[]; - PvpUpgrades: any[]; - Skins: string[]; - pricol: Pricol; - attcol: Pricol; - sigcol: Sigcol; - eyecol: Pricol; - facial: Pricol; - cloth: Pricol; - syancol: Pricol; - Songs: any[]; -} - -export interface Pricol { - t0: number; - t1: number; - t2: number; - t3: number; - m0: number; - m1: number; - en: number; -} - -export interface Sigcol { - t0: number; - t1: number; - m0: number; - en: number; -} - -export interface Col { - t0: number; - t1: number; - t2: number; - t3: number; - m0?: number; - m1?: number; - en: number; - e1?: number; -} - -export type EquipmentCategories = - | { LoadOuts: { [key in keyof ILoadoutRequest]: LoadOut } } - | { LongGuns: Config } - | { OperatorAmps: Config } // Replace 'any' with the actual type - | { Pistols: Config } // Replace 'any' with the actual type - | { Suits: { [key: string]: Config } } - | { Melee: Config } // Replace 'any' with the actual type - | { Sentinels: Config } // Replace 'any' with the actual type - | { SentinelWeapons: Config } // Replace 'any' with the actual type - // Add other categories based on your needs - | { UpgradeVer: number } - | { OperatorLoadOuts: Config } // Replace 'any' with the actual type - | { AdultOperatorLoadOuts: Config } // Replace 'any' with the actual type - | { KahlLoadOuts: Config } // Replace 'any' with the actual type - | { CrewShips: Config }; // Replace 'any' with the actual type +export { IItemConfig }; diff --git a/src/types/shipTypes.ts b/src/types/shipTypes.ts index aac1ef27..522837e5 100644 --- a/src/types/shipTypes.ts +++ b/src/types/shipTypes.ts @@ -3,26 +3,28 @@ import { IOid } from "@/src/types/commonTypes"; export interface IShip { ShipOwnerId: Types.ObjectId; - Ship: IShipClassResponse; - Apartment: IApartmentClass; + Ship: IShipResponse; + Apartment: IApartment; + LoadOutInventory: { LoadOutPresets: Types.ObjectId }; } -export interface IShipClassResponse extends IShipClassDatabase { +export interface IShipResponse extends IShipDatabase { ShipId: IOid; } -export interface IShipClassDatabase { - Rooms: IRoomsClass[]; +export interface IShipDatabase { + Rooms: IRooms[]; Features: string[]; ContentUrlSignature: string; } -export interface IRoomsClass { +// TODO: add Apartment.Gardening +export interface IRooms { Name: string; MaxCapacity: number; } -export interface IApartmentClass { - Rooms: IRoomsClass[]; +export interface IApartment { + Rooms: IRooms[]; FavouriteLoadouts: string[]; }