fix: not being able to buy incarnon bundles (#337)
This commit is contained in:
		
							parent
							
								
									7c47c9f1e4
								
							
						
					
					
						commit
						5597db6761
					
				@ -2,7 +2,7 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			|||||||
import new_inventory from "@/static/fixed_responses/postTutorialInventory.json";
 | 
					import new_inventory from "@/static/fixed_responses/postTutorialInventory.json";
 | 
				
			||||||
import { config } from "@/src/services/configService";
 | 
					import { config } from "@/src/services/configService";
 | 
				
			||||||
import { Types } from "mongoose";
 | 
					import { Types } from "mongoose";
 | 
				
			||||||
import { SlotNames } from "@/src/types/purchaseTypes";
 | 
					import { SlotNames, IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    IChallengeProgress,
 | 
					    IChallengeProgress,
 | 
				
			||||||
    IConsumable,
 | 
					    IConsumable,
 | 
				
			||||||
@ -26,7 +26,7 @@ import { logger } from "@/src/utils/logger";
 | 
				
			|||||||
import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService";
 | 
					import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService";
 | 
				
			||||||
import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
 | 
					import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes";
 | 
				
			||||||
import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
 | 
					import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes";
 | 
				
			||||||
import { ExportRecipes } from "warframe-public-export-plus";
 | 
					import { ExportRecipes, ExportResources } from "warframe-public-export-plus";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const createInventory = async (
 | 
					export const createInventory = async (
 | 
				
			||||||
    accountOwnerId: Types.ObjectId,
 | 
					    accountOwnerId: Types.ObjectId,
 | 
				
			||||||
@ -70,7 +70,7 @@ export const addItem = async (
 | 
				
			|||||||
    accountId: string,
 | 
					    accountId: string,
 | 
				
			||||||
    typeName: string,
 | 
					    typeName: string,
 | 
				
			||||||
    quantity: number = 1
 | 
					    quantity: number = 1
 | 
				
			||||||
): Promise<{ InventoryChanges: object }> => {
 | 
					): Promise<{ InventoryChanges: IInventoryChanges }> => {
 | 
				
			||||||
    // Strict typing
 | 
					    // Strict typing
 | 
				
			||||||
    if (typeName in ExportRecipes) {
 | 
					    if (typeName in ExportRecipes) {
 | 
				
			||||||
        const inventory = await getInventory(accountId);
 | 
					        const inventory = await getInventory(accountId);
 | 
				
			||||||
@ -88,6 +88,22 @@ export const addItem = async (
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (typeName in ExportResources) {
 | 
				
			||||||
 | 
					        const inventory = await getInventory(accountId);
 | 
				
			||||||
 | 
					        const miscItemChanges = [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ItemType: typeName,
 | 
				
			||||||
 | 
					                ItemCount: quantity
 | 
				
			||||||
 | 
					            } satisfies IMiscItem
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        addMiscItems(inventory, miscItemChanges);
 | 
				
			||||||
 | 
					        await inventory.save();
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            InventoryChanges: {
 | 
				
			||||||
 | 
					                MiscItems: miscItemChanges
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Path-based duck typing
 | 
					    // Path-based duck typing
 | 
				
			||||||
    switch (typeName.substr(1).split("/")[1]) {
 | 
					    switch (typeName.substr(1).split("/")[1]) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
 | 
					import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
 | 
				
			||||||
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
 | 
					import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { addItem, addBooster, updateCurrency, updateSlots } from "@/src/services/inventoryService";
 | 
					import { addItem, addBooster, updateCurrency, updateSlots } from "@/src/services/inventoryService";
 | 
				
			||||||
import { IPurchaseRequest, SlotPurchase } from "@/src/types/purchaseTypes";
 | 
					import { IPurchaseRequest, SlotPurchase, IInventoryChanges, IBinChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { ExportBundles, TRarity } from "warframe-public-export-plus";
 | 
					import { ExportBundles, TRarity } from "warframe-public-export-plus";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,12 +46,37 @@ export const handlePurchase = async (purchaseRequest: IPurchaseRequest, accountI
 | 
				
			|||||||
    return purchaseResponse;
 | 
					    return purchaseResponse;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const addInventoryChanges = (InventoryChanges: IInventoryChanges, delta: IInventoryChanges): void => {
 | 
				
			||||||
 | 
					    for (const key in delta) {
 | 
				
			||||||
 | 
					        if (!(key in InventoryChanges)) {
 | 
				
			||||||
 | 
					            InventoryChanges[key] = delta[key];
 | 
				
			||||||
 | 
					        } else if (Array.isArray(delta[key])) {
 | 
				
			||||||
 | 
					            const left = InventoryChanges[key] as object[];
 | 
				
			||||||
 | 
					            const right = delta[key] as object[];
 | 
				
			||||||
 | 
					            for (const item of right) {
 | 
				
			||||||
 | 
					                left.push(item);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            console.assert(key.substring(-3) == "Bin");
 | 
				
			||||||
 | 
					            const left = InventoryChanges[key] as IBinChanges;
 | 
				
			||||||
 | 
					            const right = delta[key] as IBinChanges;
 | 
				
			||||||
 | 
					            left.count += right.count;
 | 
				
			||||||
 | 
					            left.platinum += right.platinum;
 | 
				
			||||||
 | 
					            left.Slots += right.Slots;
 | 
				
			||||||
 | 
					            if (right.Extra) {
 | 
				
			||||||
 | 
					                left.Extra ??= 0;
 | 
				
			||||||
 | 
					                left.Extra += right.Extra;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleStoreItemAcquisition = async (
 | 
					const handleStoreItemAcquisition = async (
 | 
				
			||||||
    storeItemName: string,
 | 
					    storeItemName: string,
 | 
				
			||||||
    accountId: string,
 | 
					    accountId: string,
 | 
				
			||||||
    quantity: number,
 | 
					    quantity: number,
 | 
				
			||||||
    durability: TRarity
 | 
					    durability: TRarity
 | 
				
			||||||
): Promise<{ InventoryChanges: object }> => {
 | 
					): Promise<{ InventoryChanges: IInventoryChanges }> => {
 | 
				
			||||||
    let purchaseResponse = {
 | 
					    let purchaseResponse = {
 | 
				
			||||||
        InventoryChanges: {}
 | 
					        InventoryChanges: {}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@ -60,15 +85,17 @@ const handleStoreItemAcquisition = async (
 | 
				
			|||||||
        const bundle = ExportBundles[storeItemName];
 | 
					        const bundle = ExportBundles[storeItemName];
 | 
				
			||||||
        logger.debug("acquiring bundle", bundle);
 | 
					        logger.debug("acquiring bundle", bundle);
 | 
				
			||||||
        for (const component of bundle.components) {
 | 
					        for (const component of bundle.components) {
 | 
				
			||||||
            purchaseResponse = {
 | 
					            addInventoryChanges(
 | 
				
			||||||
                ...purchaseResponse,
 | 
					                purchaseResponse.InventoryChanges,
 | 
				
			||||||
                ...(await handleStoreItemAcquisition(
 | 
					                (
 | 
				
			||||||
 | 
					                    await handleStoreItemAcquisition(
 | 
				
			||||||
                        component.typeName,
 | 
					                        component.typeName,
 | 
				
			||||||
                        accountId,
 | 
					                        accountId,
 | 
				
			||||||
                        component.purchaseQuantity,
 | 
					                        component.purchaseQuantity,
 | 
				
			||||||
                        component.durability
 | 
					                        component.durability
 | 
				
			||||||
                ))
 | 
					                    )
 | 
				
			||||||
            };
 | 
					                ).InventoryChanges
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        const storeCategory = getStoreItemCategory(storeItemName);
 | 
					        const storeCategory = getStoreItemCategory(storeItemName);
 | 
				
			||||||
@ -106,7 +133,10 @@ 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 (slotPurchaseNameFull: string, accountId: string) => {
 | 
					const handleSlotPurchase = async (
 | 
				
			||||||
 | 
					    slotPurchaseNameFull: string,
 | 
				
			||||||
 | 
					    accountId: string
 | 
				
			||||||
 | 
					): Promise<{ InventoryChanges: IInventoryChanges }> => {
 | 
				
			||||||
    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)
 | 
				
			||||||
@ -133,7 +163,11 @@ const handleSlotPurchase = async (slotPurchaseNameFull: string, accountId: strin
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//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 (typesName: string, accountId: string, quantity: number) => {
 | 
					const handleTypesPurchase = async (
 | 
				
			||||||
 | 
					    typesName: string,
 | 
				
			||||||
 | 
					    accountId: string,
 | 
				
			||||||
 | 
					    quantity: number
 | 
				
			||||||
 | 
					): Promise<{ InventoryChanges: IInventoryChanges }> => {
 | 
				
			||||||
    const typeCategory = getStoreItemTypesCategory(typesName);
 | 
					    const typeCategory = getStoreItemTypesCategory(typesName);
 | 
				
			||||||
    logger.debug(`type category ${typeCategory}`);
 | 
					    logger.debug(`type category ${typeCategory}`);
 | 
				
			||||||
    switch (typeCategory) {
 | 
					    switch (typeCategory) {
 | 
				
			||||||
@ -158,7 +192,11 @@ const boosterDuration: Record<TRarity, number> = {
 | 
				
			|||||||
    LEGENDARY: 90 * 86400
 | 
					    LEGENDARY: 90 * 86400
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleBoostersPurchase = async (boosterStoreName: string, accountId: string, durability: TRarity) => {
 | 
					const handleBoostersPurchase = async (
 | 
				
			||||||
 | 
					    boosterStoreName: string,
 | 
				
			||||||
 | 
					    accountId: string,
 | 
				
			||||||
 | 
					    durability: TRarity
 | 
				
			||||||
 | 
					): Promise<{ 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}`);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,3 @@
 | 
				
			|||||||
import { IFlavourItem } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					 | 
				
			||||||
import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface IPurchaseRequest {
 | 
					export interface IPurchaseRequest {
 | 
				
			||||||
    PurchaseParams: IPurchaseParams;
 | 
					    PurchaseParams: IPurchaseParams;
 | 
				
			||||||
    buildLabel: string;
 | 
					    buildLabel: string;
 | 
				
			||||||
@ -17,22 +14,7 @@ export interface IPurchaseParams {
 | 
				
			|||||||
    ExpectedPrice: number;
 | 
					    ExpectedPrice: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IPurchaseResponse {
 | 
					export type IInventoryChanges = Record<string, IBinChanges | object[]>;
 | 
				
			||||||
    InventoryChanges: {
 | 
					 | 
				
			||||||
        SuitBin?: IBinChanges;
 | 
					 | 
				
			||||||
        WeaponBin?: IBinChanges;
 | 
					 | 
				
			||||||
        MechBin?: IBinChanges;
 | 
					 | 
				
			||||||
        MechSuits?: IEquipmentClient[];
 | 
					 | 
				
			||||||
        Suits?: IEquipmentClient[];
 | 
					 | 
				
			||||||
        LongGuns?: IEquipmentClient[];
 | 
					 | 
				
			||||||
        Pistols?: IEquipmentClient[];
 | 
					 | 
				
			||||||
        Melee?: IEquipmentClient[];
 | 
					 | 
				
			||||||
        PremiumCredits?: number;
 | 
					 | 
				
			||||||
        PremiumCreditsFree?: number;
 | 
					 | 
				
			||||||
        RegularCredits?: number;
 | 
					 | 
				
			||||||
        FlavourItems?: IFlavourItem[];
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type IBinChanges = {
 | 
					export type IBinChanges = {
 | 
				
			||||||
    count: number;
 | 
					    count: number;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user