diff --git a/src/models/inventoryModel.ts b/src/models/inventoryModel.ts index 0b7f52d6..f73dd1fb 100644 --- a/src/models/inventoryModel.ts +++ b/src/models/inventoryModel.ts @@ -1,5 +1,5 @@ import { Model, Schema, Types, model } from "mongoose"; -import { FlavourItem, RawUpgrade, MiscItem, IInventoryDatabase } from "../types/inventoryTypes/inventoryTypes"; +import { FlavourItem, RawUpgrade, MiscItem, IInventoryDatabase, Booster } from "../types/inventoryTypes/inventoryTypes"; import { Oid } from "../types/commonTypes"; import { ISuitDatabase, ISuitDocument } from "@/src/types/inventoryTypes/SuitTypes"; import { IWeaponDatabase } from "@/src/types/inventoryTypes/weaponTypes"; @@ -66,6 +66,11 @@ const WeaponSchema = new Schema({ UnlockLevel: Number }); +const BoosterSchema = new Schema({ + ExpiryDate: Number, + ItemType: String +}); + WeaponSchema.set("toJSON", { transform(_document, returnedObject) { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call @@ -213,7 +218,7 @@ const inventorySchema = new Schema({ LoreFragmentScans: [Schema.Types.Mixed], EquippedEmotes: [String], PendingTrades: [Schema.Types.Mixed], - Boosters: [Schema.Types.Mixed], + Boosters: [BoosterSchema], ActiveDojoColorResearch: String, SentientSpawnChanceBoosters: Schema.Types.Mixed, Affiliations: [Schema.Types.Mixed], @@ -336,6 +341,7 @@ type InventoryDocumentProps = { FlavourItems: Types.DocumentArray; RawUpgrades: Types.DocumentArray; MiscItems: Types.DocumentArray; + Boosters: Types.DocumentArray; }; type InventoryModelType = Model; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 9f4ff713..39ca196f 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -186,4 +186,30 @@ export const missionInventoryUpdate = async (data: MissionInventoryUpdate, accou await inventory.save(); }; +export const addBooster = async (boosterName: string, accountId: string): Promise => { + const match = boosterName.match(/(\d+)Day/); + if (!match) return; + + const extractedDigit = Number(match[1]); + const ItemType = boosterName.replace(`${extractedDigit}Day`, ""); + const plusTime = 86400 * extractedDigit; + const currentTime = Math.floor(Date.now() / 1000); + + const inventory = await getInventory(accountId); + const { Boosters } = inventory; + + let itemIndex = Boosters.findIndex(i => i.ItemType === ItemType); + + if (itemIndex !== -1) { + const existingBooster = Boosters[itemIndex]; + existingBooster.ExpiryDate = Math.max(existingBooster.ExpiryDate, currentTime) + plusTime; + inventory.markModified(`Boosters.${itemIndex}.ExpiryDate`); + } else { + itemIndex = Boosters.push({ ItemType, ExpiryDate: currentTime + plusTime }) - 1; + } + + const changedInventory = await inventory.save(); + return changedInventory.Boosters[itemIndex].toJSON(); +}; + export { createInventory, addPowerSuit }; diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 16716573..5c002a0b 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -1,13 +1,7 @@ import { getWeaponType } from "@/src/helpers/purchaseHelpers"; import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers"; -import { - addCustomization, - addPowerSuit, - addWeapon, - updateCurrency, - updateSlots -} from "@/src/services/inventoryService"; -import { IPurchaseRequest, IPurchaseResponse, SlotType } from "@/src/types/purchaseTypes"; +import { addBooster, addCustomization, addPowerSuit, addWeapon, updateSlots } from "@/src/services/inventoryService"; +import { IPurchaseRequest, SlotType } from "@/src/types/purchaseTypes"; export const getStoreItemCategory = (storeItem: string) => { const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/"); @@ -41,6 +35,9 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI case "Types": purchaseResponse = await handleTypesPurchase(internalName, accountId); break; + case "Boosters": + purchaseResponse = await handleBoostersPurchase(internalName, accountId); + break; default: throw new Error(`unknown store category: ${storeCategory} not implemented or new`); @@ -114,3 +111,13 @@ const handleSuitCustomizationsPurchase = async (customizationName: string, accou } }; }; + +const handleBoostersPurchase = async (boosterName: string, accountId: string) => { + const addedBooster = await addBooster(boosterName, accountId); + + return { + InventoryChanges: { + Boosters: [addedBooster] + } + }; +};