chore: switch purchaseService to take inventory document (#848)

This commit is contained in:
Sainan 2025-01-24 15:24:29 +01:00 committed by GitHub
parent 249d2056ed
commit 5649c5bf86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 42 additions and 61 deletions

View File

@ -27,18 +27,17 @@ export const getVoidProjectionRewardsController: RequestHandler = async (req, re
logger.debug(`relic rolled`, reward); logger.debug(`relic rolled`, reward);
response.ParticipantInfo.Reward = reward.type; response.ParticipantInfo.Reward = reward.type;
// Remove relic
const inventory = await getInventory(accountId); const inventory = await getInventory(accountId);
// Remove relic
addMiscItems(inventory, [ addMiscItems(inventory, [
{ {
ItemType: data.ParticipantInfo.VoidProjection, ItemType: data.ParticipantInfo.VoidProjection,
ItemCount: -1 ItemCount: -1
} }
]); ]);
await inventory.save();
// Give reward // Give reward
await handleStoreItemAcquisition(reward.type, accountId, reward.itemCount); await handleStoreItemAcquisition(reward.type, inventory, reward.itemCount);
await inventory.save();
} }
res.json(response); res.json(response);
}; };

View File

@ -2,10 +2,13 @@ import { RequestHandler } from "express";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountIdForRequest } from "@/src/services/loginService";
import { IPurchaseRequest } from "@/src/types/purchaseTypes"; import { IPurchaseRequest } from "@/src/types/purchaseTypes";
import { handlePurchase } from "@/src/services/purchaseService"; import { handlePurchase } from "@/src/services/purchaseService";
import { getInventory } from "@/src/services/inventoryService";
export const purchaseController: RequestHandler = async (req, res) => { export const purchaseController: RequestHandler = async (req, res) => {
const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest; const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
const accountId = await getAccountIdForRequest(req); const accountId = await getAccountIdForRequest(req);
const response = await handlePurchase(purchaseRequest, accountId); const inventory = await getInventory(accountId);
const response = await handlePurchase(purchaseRequest, inventory);
await inventory.save();
res.json(response); res.json(response);
}; };

View File

@ -57,15 +57,15 @@ export const syndicateSacrificeController: RequestHandler = async (request, resp
} }
} }
await inventory.save();
if (reward) { if (reward) {
combineInventoryChanges( combineInventoryChanges(
res.InventoryChanges, res.InventoryChanges,
(await handleStoreItemAcquisition(reward, accountId)).InventoryChanges (await handleStoreItemAcquisition(reward, inventory)).InventoryChanges
); );
} }
await inventory.save();
response.json(res); response.json(res);
}; };

View File

@ -949,10 +949,9 @@ export const addMissionComplete = (inventory: TInventoryDatabaseDocument, { Tag,
} }
}; };
export const addBooster = async (ItemType: string, time: number, accountId: string): Promise<void> => { export const addBooster = (ItemType: string, time: number, inventory: TInventoryDatabaseDocument): void => {
const currentTime = Math.floor(Date.now() / 1000) - 129600; // Value is wrong without 129600. Figure out why, please. :) const currentTime = Math.floor(Date.now() / 1000) - 129600; // Value is wrong without 129600. Figure out why, please. :)
const inventory = await getInventory(accountId);
const { Boosters } = inventory; const { Boosters } = inventory;
const itemIndex = Boosters.findIndex(booster => booster.ItemType === ItemType); const itemIndex = Boosters.findIndex(booster => booster.ItemType === ItemType);
@ -964,8 +963,6 @@ export const addBooster = async (ItemType: string, time: number, accountId: stri
} else { } else {
Boosters.push({ ItemType, ExpiryDate: currentTime + time }); Boosters.push({ ItemType, ExpiryDate: currentTime + time });
} }
await inventory.save();
}; };
export const updateSyndicate = ( export const updateSyndicate = (

View File

@ -5,8 +5,7 @@ import {
addItem, addItem,
addMiscItems, addMiscItems,
combineInventoryChanges, combineInventoryChanges,
getInventory, updateCurrency,
updateCurrencyByAccountId,
updateSlots updateSlots
} from "@/src/services/inventoryService"; } from "@/src/services/inventoryService";
import { getRandomWeightedReward } from "@/src/services/rngService"; import { getRandomWeightedReward } from "@/src/services/rngService";
@ -25,6 +24,7 @@ import {
TRarity TRarity
} from "warframe-public-export-plus"; } from "warframe-public-export-plus";
import { config } from "./configService"; import { config } from "./configService";
import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
export const getStoreItemCategory = (storeItem: string): string => { export const getStoreItemCategory = (storeItem: string): string => {
const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/"); const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/");
@ -43,7 +43,7 @@ export const getStoreItemTypesCategory = (typesItem: string): string => {
export const handlePurchase = async ( export const handlePurchase = async (
purchaseRequest: IPurchaseRequest, purchaseRequest: IPurchaseRequest,
accountId: string inventory: TInventoryDatabaseDocument
): Promise<IPurchaseResponse> => { ): Promise<IPurchaseResponse> => {
logger.debug("purchase request", purchaseRequest); logger.debug("purchase request", purchaseRequest);
@ -58,8 +58,8 @@ export const handlePurchase = async (
throw new Error(`unknown vendor offer: ${ItemId}`); throw new Error(`unknown vendor offer: ${ItemId}`);
} }
if (offer.ItemPrices) { if (offer.ItemPrices) {
await handleItemPrices( handleItemPrices(
accountId, inventory,
offer.ItemPrices, offer.ItemPrices,
purchaseRequest.PurchaseParams.Quantity, purchaseRequest.PurchaseParams.Quantity,
inventoryChanges inventoryChanges
@ -73,17 +73,17 @@ export const handlePurchase = async (
const purchaseResponse = await handleStoreItemAcquisition( const purchaseResponse = await handleStoreItemAcquisition(
purchaseRequest.PurchaseParams.StoreItem, purchaseRequest.PurchaseParams.StoreItem,
accountId, inventory,
purchaseRequest.PurchaseParams.Quantity purchaseRequest.PurchaseParams.Quantity
); );
combineInventoryChanges(purchaseResponse.InventoryChanges, inventoryChanges); combineInventoryChanges(purchaseResponse.InventoryChanges, inventoryChanges);
if (!purchaseResponse) throw new Error("purchase response was undefined"); if (!purchaseResponse) throw new Error("purchase response was undefined");
const currencyChanges = await updateCurrencyByAccountId( const currencyChanges = updateCurrency(
inventory,
purchaseRequest.PurchaseParams.ExpectedPrice, purchaseRequest.PurchaseParams.ExpectedPrice,
purchaseRequest.PurchaseParams.UsePremium, purchaseRequest.PurchaseParams.UsePremium
accountId
); );
purchaseResponse.InventoryChanges = { purchaseResponse.InventoryChanges = {
...currencyChanges, ...currencyChanges,
@ -95,7 +95,6 @@ export const handlePurchase = async (
{ {
const syndicateTag = purchaseRequest.PurchaseParams.SyndicateTag!; const syndicateTag = purchaseRequest.PurchaseParams.SyndicateTag!;
if (purchaseRequest.PurchaseParams.UseFreeFavor!) { if (purchaseRequest.PurchaseParams.UseFreeFavor!) {
const inventory = await getInventory(accountId);
const affiliation = inventory.Affiliations.find(x => x.Tag == syndicateTag)!; const affiliation = inventory.Affiliations.find(x => x.Tag == syndicateTag)!;
affiliation.FreeFavorsUsed ??= []; affiliation.FreeFavorsUsed ??= [];
const lastTitle = affiliation.FreeFavorsEarned![affiliation.FreeFavorsUsed.length]; const lastTitle = affiliation.FreeFavorsEarned![affiliation.FreeFavorsUsed.length];
@ -106,7 +105,6 @@ export const handlePurchase = async (
Title: lastTitle Title: lastTitle
} }
]; ];
await inventory.save();
} else { } else {
const syndicate = ExportSyndicates[syndicateTag]; const syndicate = ExportSyndicates[syndicateTag];
if (syndicate) { if (syndicate) {
@ -114,7 +112,6 @@ export const handlePurchase = async (
x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem
); );
if (favour) { if (favour) {
const inventory = await getInventory(accountId);
const affiliation = inventory.Affiliations.find(x => x.Tag == syndicateTag); const affiliation = inventory.Affiliations.find(x => x.Tag == syndicateTag);
if (affiliation) { if (affiliation) {
purchaseResponse.Standing = [ purchaseResponse.Standing = [
@ -124,7 +121,6 @@ export const handlePurchase = async (
} }
]; ];
affiliation.Standing -= favour.standingCost; affiliation.Standing -= favour.standingCost;
await inventory.save();
} }
} }
} }
@ -136,8 +132,8 @@ export const handlePurchase = async (
const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!]; const vendor = ExportVendors[purchaseRequest.PurchaseParams.SourceId!];
const offer = vendor.items.find(x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem); const offer = vendor.items.find(x => x.storeItem == purchaseRequest.PurchaseParams.StoreItem);
if (offer && offer.itemPrices) { if (offer && offer.itemPrices) {
await handleItemPrices( handleItemPrices(
accountId, inventory,
offer.itemPrices, offer.itemPrices,
purchaseRequest.PurchaseParams.Quantity, purchaseRequest.PurchaseParams.Quantity,
purchaseResponse.InventoryChanges purchaseResponse.InventoryChanges
@ -157,7 +153,6 @@ export const handlePurchase = async (
x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem
); );
if (offer) { if (offer) {
const inventory = await getInventory(accountId);
if (offer.RegularPrice) { if (offer.RegularPrice) {
const invItem: IMiscItem = { const invItem: IMiscItem = {
ItemType: "/Lotus/Types/Items/MiscItems/SchismKey", ItemType: "/Lotus/Types/Items/MiscItems/SchismKey",
@ -171,7 +166,6 @@ export const handlePurchase = async (
} else if (!config.infiniteRegalAya) { } else if (!config.infiniteRegalAya) {
inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity; inventory.PrimeTokens -= offer.PrimePrice! * purchaseRequest.PurchaseParams.Quantity;
} }
await inventory.save();
} }
break; break;
} }
@ -180,13 +174,12 @@ export const handlePurchase = async (
return purchaseResponse; return purchaseResponse;
}; };
const handleItemPrices = async ( const handleItemPrices = (
accountId: string, inventory: TInventoryDatabaseDocument,
itemPrices: IMiscItem[], itemPrices: IMiscItem[],
purchaseQuantity: number, purchaseQuantity: number,
inventoryChanges: IInventoryChanges inventoryChanges: IInventoryChanges
): Promise<void> => { ): void => {
const inventory = await getInventory(accountId);
for (const item of itemPrices) { for (const item of itemPrices) {
const invItem: IMiscItem = { const invItem: IMiscItem = {
ItemType: item.ItemType, ItemType: item.ItemType,
@ -203,12 +196,11 @@ const handleItemPrices = async (
(inventoryChanges.MiscItems as IMiscItem[]).push(invItem); (inventoryChanges.MiscItems as IMiscItem[]).push(invItem);
} }
} }
await inventory.save();
}; };
export const handleStoreItemAcquisition = async ( export const handleStoreItemAcquisition = async (
storeItemName: string, storeItemName: string,
accountId: string, inventory: TInventoryDatabaseDocument,
quantity: number = 1, quantity: number = 1,
durability: TRarity = "COMMON", durability: TRarity = "COMMON",
ignorePurchaseQuantity: boolean = false ignorePurchaseQuantity: boolean = false
@ -226,7 +218,7 @@ export const handleStoreItemAcquisition = async (
( (
await handleStoreItemAcquisition( await handleStoreItemAcquisition(
component.typeName, component.typeName,
accountId, inventory,
component.purchaseQuantity * quantity, component.purchaseQuantity * quantity,
component.durability, component.durability,
true true
@ -247,16 +239,14 @@ export const handleStoreItemAcquisition = async (
} }
switch (storeCategory) { switch (storeCategory) {
default: { default: {
const inventory = await getInventory(accountId);
purchaseResponse = await addItem(inventory, internalName, quantity); purchaseResponse = await addItem(inventory, internalName, quantity);
await inventory.save();
break; break;
} }
case "Types": case "Types":
purchaseResponse = await handleTypesPurchase(internalName, accountId, quantity); purchaseResponse = await handleTypesPurchase(internalName, inventory, quantity);
break; break;
case "Boosters": case "Boosters":
purchaseResponse = await handleBoostersPurchase(internalName, accountId, durability); purchaseResponse = handleBoostersPurchase(internalName, inventory, durability);
break; break;
} }
} }
@ -280,11 +270,11 @@ export const slotPurchaseNameToSlotName: SlotPurchase = {
// // new slot above base = extra + 1 and slots +1 // // new slot above base = extra + 1 and slots +1
// // new frame = slots -1 // // new frame = slots -1
// // number of frames = extra - slots + 2 // // number of frames = extra - slots + 2
const handleSlotPurchase = async ( const handleSlotPurchase = (
slotPurchaseNameFull: string, slotPurchaseNameFull: string,
accountId: string, inventory: TInventoryDatabaseDocument,
quantity: number quantity: number
): Promise<IPurchaseResponse> => { ): IPurchaseResponse => {
logger.debug(`slot name ${slotPurchaseNameFull}`); logger.debug(`slot name ${slotPurchaseNameFull}`);
const slotPurchaseName = parseSlotPurchaseName( const slotPurchaseName = parseSlotPurchaseName(
slotPurchaseNameFull.substring(slotPurchaseNameFull.lastIndexOf("/") + 1) slotPurchaseNameFull.substring(slotPurchaseNameFull.lastIndexOf("/") + 1)
@ -294,9 +284,7 @@ const handleSlotPurchase = async (
const slotName = slotPurchaseNameToSlotName[slotPurchaseName].name; const slotName = slotPurchaseNameToSlotName[slotPurchaseName].name;
const slotsPurchased = slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase * quantity; const slotsPurchased = slotPurchaseNameToSlotName[slotPurchaseName].slotsPerPurchase * quantity;
const inventory = await getInventory(accountId);
updateSlots(inventory, slotName, slotsPurchased, slotsPurchased); updateSlots(inventory, slotName, slotsPurchased, slotsPurchased);
await inventory.save();
logger.debug(`added ${slotsPurchased} slot ${slotName}`); logger.debug(`added ${slotsPurchased} slot ${slotName}`);
@ -314,7 +302,7 @@ const handleSlotPurchase = async (
const handleBoosterPackPurchase = async ( const handleBoosterPackPurchase = async (
typeName: string, typeName: string,
accountId: string, inventory: TInventoryDatabaseDocument,
quantity: number quantity: number
): Promise<IPurchaseResponse> => { ): Promise<IPurchaseResponse> => {
const pack = ExportBoosterPacks[typeName]; const pack = ExportBoosterPacks[typeName];
@ -325,7 +313,6 @@ const handleBoosterPackPurchase = async (
BoosterPackItems: "", BoosterPackItems: "",
InventoryChanges: {} InventoryChanges: {}
}; };
const inventory = await getInventory(accountId);
for (let i = 0; i != quantity; ++i) { for (let i = 0; i != quantity; ++i) {
for (const weights of pack.rarityWeightsPerRoll) { for (const weights of pack.rarityWeightsPerRoll) {
const result = getRandomWeightedReward(pack.components, weights); const result = getRandomWeightedReward(pack.components, weights);
@ -340,29 +327,24 @@ const handleBoosterPackPurchase = async (
} }
} }
} }
await inventory.save();
return purchaseResponse; return purchaseResponse;
}; };
//TODO: change to getInventory, apply changes then save at the end //TODO: change to getInventory, apply changes then save at the end
const handleTypesPurchase = async ( const handleTypesPurchase = async (
typesName: string, typesName: string,
accountId: string, inventory: TInventoryDatabaseDocument,
quantity: number quantity: number
): Promise<IPurchaseResponse> => { ): Promise<IPurchaseResponse> => {
const typeCategory = getStoreItemTypesCategory(typesName); const typeCategory = getStoreItemTypesCategory(typesName);
logger.debug(`type category ${typeCategory}`); logger.debug(`type category ${typeCategory}`);
switch (typeCategory) { switch (typeCategory) {
default: { default:
const inventory = await getInventory(accountId); return await addItem(inventory, typesName, quantity);
const resp = await addItem(inventory, typesName, quantity);
await inventory.save();
return resp;
}
case "BoosterPacks": case "BoosterPacks":
return await handleBoosterPackPurchase(typesName, accountId, quantity); return handleBoosterPackPurchase(typesName, inventory, quantity);
case "SlotItems": case "SlotItems":
return await handleSlotPurchase(typesName, accountId, quantity); return handleSlotPurchase(typesName, inventory, quantity);
} }
}; };
@ -380,11 +362,11 @@ const boosterDuration: Record<TRarity, number> = {
LEGENDARY: 90 * 86400 LEGENDARY: 90 * 86400
}; };
const handleBoostersPurchase = async ( const handleBoostersPurchase = (
boosterStoreName: string, boosterStoreName: string,
accountId: string, inventory: TInventoryDatabaseDocument,
durability: TRarity durability: TRarity
): Promise<{ InventoryChanges: IInventoryChanges }> => { ): { InventoryChanges: IInventoryChanges } => {
const ItemType = boosterStoreName.replace("StoreItem", ""); const ItemType = boosterStoreName.replace("StoreItem", "");
if (!boosterCollection.find(x => x == ItemType)) { if (!boosterCollection.find(x => x == ItemType)) {
logger.error(`unknown booster type: ${ItemType}`); logger.error(`unknown booster type: ${ItemType}`);
@ -393,7 +375,7 @@ const handleBoostersPurchase = async (
const ExpiryDate = boosterDuration[durability]; const ExpiryDate = boosterDuration[durability];
await addBooster(ItemType, ExpiryDate, accountId); addBooster(ItemType, ExpiryDate, inventory);
return { return {
InventoryChanges: { InventoryChanges: {