chore: fix controllers exporting non-RequestHandler things (#1468)
I'm surprised JavaScript allows circular includes, but they still don't feel good. Reviewed-on: #1468 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									62263efde3
								
							
						
					
					
						commit
						49edebc1eb
					
				@ -19,7 +19,7 @@ import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			|||||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
					import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
				
			||||||
import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IClaimCompletedRecipeRequest {
 | 
					interface IClaimCompletedRecipeRequest {
 | 
				
			||||||
    RecipeIds: IOid[];
 | 
					    RecipeIds: IOid[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
 | 
					import { Inventory } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
 | 
					import { generateRewardSeed } from "@/src/services/inventoryService";
 | 
				
			||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
@ -18,9 +19,3 @@ export const getNewRewardSeedController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
    res.json({ rewardSeed: rewardSeed });
 | 
					    res.json({ rewardSeed: rewardSeed });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
export function generateRewardSeed(): number {
 | 
					 | 
				
			||||||
    const min = -Number.MAX_SAFE_INTEGER;
 | 
					 | 
				
			||||||
    const max = Number.MAX_SAFE_INTEGER;
 | 
					 | 
				
			||||||
    return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,8 @@ import { RequestHandler } from "express";
 | 
				
			|||||||
import { parseString } from "@/src/helpers/general";
 | 
					import { parseString } from "@/src/helpers/general";
 | 
				
			||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { getInventory } from "@/src/services/inventoryService";
 | 
					import { getInventory } from "@/src/services/inventoryService";
 | 
				
			||||||
import { IGroup } from "@/src/types/loginTypes";
 | 
					 | 
				
			||||||
import { giveKeyChainItem } from "@/src/services/questService";
 | 
					import { giveKeyChainItem } from "@/src/services/questService";
 | 
				
			||||||
 | 
					import { IKeyChainRequest } from "@/src/types/requestTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => {
 | 
					export const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const accountId = parseString(req.query.accountId);
 | 
					    const accountId = parseString(req.query.accountId);
 | 
				
			||||||
@ -15,9 +15,3 @@ export const giveKeyChainTriggeredItemsController: RequestHandler = async (req,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    res.send(inventoryChanges);
 | 
					    res.send(inventoryChanges);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface IKeyChainRequest {
 | 
					 | 
				
			||||||
    KeyChain: string;
 | 
					 | 
				
			||||||
    ChainStage: number;
 | 
					 | 
				
			||||||
    Groups?: IGroup[];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
					 | 
				
			||||||
import { getInventory } from "@/src/services/inventoryService";
 | 
					import { getInventory } from "@/src/services/inventoryService";
 | 
				
			||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { giveKeyChainMessage } from "@/src/services/questService";
 | 
					import { giveKeyChainMessage } from "@/src/services/questService";
 | 
				
			||||||
 | 
					import { IKeyChainRequest } from "@/src/types/requestTypes";
 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const giveKeyChainTriggeredMessageController: RequestHandler = async (req, res) => {
 | 
					export const giveKeyChainTriggeredMessageController: RequestHandler = async (req, res) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -20,11 +20,11 @@ export const giveQuestKeyRewardController: RequestHandler = async (req, res) =>
 | 
				
			|||||||
    //TODO: consider whishlist changes
 | 
					    //TODO: consider whishlist changes
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IQuestKeyRewardRequest {
 | 
					interface IQuestKeyRewardRequest {
 | 
				
			||||||
    reward: IQuestKeyReward;
 | 
					    reward: IQuestKeyReward;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IQuestKeyReward {
 | 
					interface IQuestKeyReward {
 | 
				
			||||||
    RewardType: string;
 | 
					    RewardType: string;
 | 
				
			||||||
    CouponType: string;
 | 
					    CouponType: string;
 | 
				
			||||||
    Icon: string;
 | 
					    Icon: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,8 @@
 | 
				
			|||||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
					import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { InventoryDocumentProps } from "@/src/models/inventoryModels/inventoryModel";
 | 
					import { addStartingGear, getInventory } from "@/src/services/inventoryService";
 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
    addEquipment,
 | 
					 | 
				
			||||||
    addItem,
 | 
					 | 
				
			||||||
    addPowerSuit,
 | 
					 | 
				
			||||||
    combineInventoryChanges,
 | 
					 | 
				
			||||||
    getInventory,
 | 
					 | 
				
			||||||
    updateSlots
 | 
					 | 
				
			||||||
} from "@/src/services/inventoryService";
 | 
					 | 
				
			||||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
					import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			||||||
import { IInventoryClient, IInventoryDatabase, InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { TPartialStartingGear } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
					 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
import { HydratedDocument } from "mongoose";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type TPartialStartingGear = Pick<IInventoryClient, "LongGuns" | "Suits" | "Pistols" | "Melee">;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const giveStartingGearController: RequestHandler = async (req, res) => {
 | 
					export const giveStartingGearController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
@ -26,72 +14,3 @@ export const giveStartingGearController: RequestHandler = async (req, res) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    res.send(inventoryChanges);
 | 
					    res.send(inventoryChanges);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
//TODO: RawUpgrades might need to return a LastAdded
 | 
					 | 
				
			||||||
const awakeningRewards = [
 | 
					 | 
				
			||||||
    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1",
 | 
					 | 
				
			||||||
    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2",
 | 
					 | 
				
			||||||
    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3",
 | 
					 | 
				
			||||||
    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4",
 | 
					 | 
				
			||||||
    "/Lotus/Types/Restoratives/LisetAutoHack",
 | 
					 | 
				
			||||||
    "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod"
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const addStartingGear = async (
 | 
					 | 
				
			||||||
    inventory: HydratedDocument<IInventoryDatabase, InventoryDocumentProps>,
 | 
					 | 
				
			||||||
    startingGear: TPartialStartingGear | undefined = undefined
 | 
					 | 
				
			||||||
): Promise<IInventoryChanges> => {
 | 
					 | 
				
			||||||
    const { LongGuns, Pistols, Suits, Melee } = startingGear || {
 | 
					 | 
				
			||||||
        LongGuns: [{ ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }],
 | 
					 | 
				
			||||||
        Pistols: [{ ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }],
 | 
					 | 
				
			||||||
        Suits: [{ ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }],
 | 
					 | 
				
			||||||
        Melee: [{ ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }]
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //TODO: properly merge weapon bin changes it is currently static here
 | 
					 | 
				
			||||||
    const inventoryChanges: IInventoryChanges = {};
 | 
					 | 
				
			||||||
    addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, undefined, inventoryChanges);
 | 
					 | 
				
			||||||
    addEquipment(inventory, "Pistols", Pistols[0].ItemType, undefined, inventoryChanges);
 | 
					 | 
				
			||||||
    addEquipment(inventory, "Melee", Melee[0].ItemType, undefined, inventoryChanges);
 | 
					 | 
				
			||||||
    await addPowerSuit(inventory, Suits[0].ItemType, inventoryChanges);
 | 
					 | 
				
			||||||
    addEquipment(
 | 
					 | 
				
			||||||
        inventory,
 | 
					 | 
				
			||||||
        "DataKnives",
 | 
					 | 
				
			||||||
        "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
 | 
					 | 
				
			||||||
        undefined,
 | 
					 | 
				
			||||||
        inventoryChanges,
 | 
					 | 
				
			||||||
        { XP: 450_000 }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    addEquipment(
 | 
					 | 
				
			||||||
        inventory,
 | 
					 | 
				
			||||||
        "Scoops",
 | 
					 | 
				
			||||||
        "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest",
 | 
					 | 
				
			||||||
        undefined,
 | 
					 | 
				
			||||||
        inventoryChanges
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    updateSlots(inventory, InventorySlot.SUITS, 0, 1);
 | 
					 | 
				
			||||||
    updateSlots(inventory, InventorySlot.WEAPONS, 0, 3);
 | 
					 | 
				
			||||||
    inventoryChanges.SuitBin = { count: 1, platinum: 0, Slots: -1 };
 | 
					 | 
				
			||||||
    inventoryChanges.WeaponBin = { count: 3, platinum: 0, Slots: -3 };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await addItem(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
 | 
					 | 
				
			||||||
    inventory.ActiveQuest = "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inventory.PremiumCredits = 50;
 | 
					 | 
				
			||||||
    inventory.PremiumCreditsFree = 50;
 | 
					 | 
				
			||||||
    inventoryChanges.PremiumCredits = 50;
 | 
					 | 
				
			||||||
    inventoryChanges.PremiumCreditsFree = 50;
 | 
					 | 
				
			||||||
    inventory.RegularCredits = 3000;
 | 
					 | 
				
			||||||
    inventoryChanges.RegularCredits = 3000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (const item of awakeningRewards) {
 | 
					 | 
				
			||||||
        const inventoryDelta = await addItem(inventory, item);
 | 
					 | 
				
			||||||
        combineInventoryChanges(inventoryChanges, inventoryDelta);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inventory.PlayedParkourTutorial = true;
 | 
					 | 
				
			||||||
    inventory.ReceivedStartingGear = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return inventoryChanges;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -6,20 +6,21 @@ import { IOid } from "@/src/types/commonTypes";
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
    IConsumedSuit,
 | 
					    IConsumedSuit,
 | 
				
			||||||
    IHelminthFoodRecord,
 | 
					    IHelminthFoodRecord,
 | 
				
			||||||
    IInfestedFoundryClient,
 | 
					 | 
				
			||||||
    IInfestedFoundryDatabase,
 | 
					 | 
				
			||||||
    IInventoryClient,
 | 
					    IInventoryClient,
 | 
				
			||||||
    IMiscItem,
 | 
					    IMiscItem,
 | 
				
			||||||
    InventorySlot,
 | 
					    InventorySlot
 | 
				
			||||||
    ITypeCount
 | 
					 | 
				
			||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { ExportMisc, ExportRecipes } from "warframe-public-export-plus";
 | 
					import { ExportMisc } from "warframe-public-export-plus";
 | 
				
			||||||
import { getRecipe } from "@/src/services/itemDataService";
 | 
					import { getRecipe } from "@/src/services/itemDataService";
 | 
				
			||||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
					 | 
				
			||||||
import { toMongoDate } from "@/src/helpers/inventoryHelpers";
 | 
					import { toMongoDate } from "@/src/helpers/inventoryHelpers";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { colorToShard } from "@/src/helpers/shardHelper";
 | 
					import { colorToShard } from "@/src/helpers/shardHelper";
 | 
				
			||||||
import { config } from "@/src/services/configService";
 | 
					import { config } from "@/src/services/configService";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    addInfestedFoundryXP,
 | 
				
			||||||
 | 
					    applyCheatsToInfestedFoundry,
 | 
				
			||||||
 | 
					    handleSubsumeCompletion
 | 
				
			||||||
 | 
					} from "@/src/services/infestedFoundryService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const infestedFoundryController: RequestHandler = async (req, res) => {
 | 
					export const infestedFoundryController: RequestHandler = async (req, res) => {
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(req);
 | 
					    const accountId = await getAccountIdForRequest(req);
 | 
				
			||||||
@ -383,116 +384,11 @@ interface IHelminthFeedRequest {
 | 
				
			|||||||
    }[];
 | 
					    }[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => {
 | 
					 | 
				
			||||||
    const recipeChanges: ITypeCount[] = [];
 | 
					 | 
				
			||||||
    infestedFoundry.XP ??= 0;
 | 
					 | 
				
			||||||
    const prevXP = infestedFoundry.XP;
 | 
					 | 
				
			||||||
    infestedFoundry.XP += delta;
 | 
					 | 
				
			||||||
    if (prevXP < 2250_00 && infestedFoundry.XP >= 2250_00) {
 | 
					 | 
				
			||||||
        infestedFoundry.Slots ??= 0;
 | 
					 | 
				
			||||||
        infestedFoundry.Slots += 3;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 5625_00 && infestedFoundry.XP >= 5625_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldsBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 10125_00 && infestedFoundry.XP >= 10125_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthHackBlueprint", ItemCount: 1 });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 15750_00 && infestedFoundry.XP >= 15750_00) {
 | 
					 | 
				
			||||||
        infestedFoundry.Slots ??= 0;
 | 
					 | 
				
			||||||
        infestedFoundry.Slots += 10;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 22500_00 && infestedFoundry.XP >= 22500_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthAmmoEfficiencyBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 30375_00 && infestedFoundry.XP >= 30375_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStunBlueprint", ItemCount: 1 });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 39375_00 && infestedFoundry.XP >= 39375_00) {
 | 
					 | 
				
			||||||
        infestedFoundry.Slots ??= 0;
 | 
					 | 
				
			||||||
        infestedFoundry.Slots += 20;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 60750_00 && infestedFoundry.XP >= 60750_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStatusBlueprint", ItemCount: 1 });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 73125_00 && infestedFoundry.XP >= 73125_00) {
 | 
					 | 
				
			||||||
        infestedFoundry.Slots = 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 86625_00 && infestedFoundry.XP >= 86625_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldArmorBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 101250_00 && infestedFoundry.XP >= 101250_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthProcBlockBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 117000_00 && infestedFoundry.XP >= 117000_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthEnergyShareBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 133875_00 && infestedFoundry.XP >= 133875_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthMaxStatusBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (prevXP < 151875_00 && infestedFoundry.XP >= 151875_00) {
 | 
					 | 
				
			||||||
        recipeChanges.push({
 | 
					 | 
				
			||||||
            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthTreasureBlueprint",
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return recipeChanges;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface IHelminthSubsumeRequest {
 | 
					interface IHelminthSubsumeRequest {
 | 
				
			||||||
    SuitId: IOid;
 | 
					    SuitId: IOid;
 | 
				
			||||||
    Recipe: string;
 | 
					    Recipe: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const handleSubsumeCompletion = (inventory: TInventoryDatabaseDocument): ITypeCount[] => {
 | 
					 | 
				
			||||||
    const [recipeType] = Object.entries(ExportRecipes).find(
 | 
					 | 
				
			||||||
        ([_recipeType, recipe]) =>
 | 
					 | 
				
			||||||
            recipe.secretIngredientAction == "SIA_WARFRAME_ABILITY" &&
 | 
					 | 
				
			||||||
            recipe.secretIngredients![0].ItemType == inventory.InfestedFoundry!.LastConsumedSuit!.ItemType
 | 
					 | 
				
			||||||
    )!;
 | 
					 | 
				
			||||||
    inventory.InfestedFoundry!.LastConsumedSuit = undefined;
 | 
					 | 
				
			||||||
    inventory.InfestedFoundry!.AbilityOverrideUnlockCooldown = undefined;
 | 
					 | 
				
			||||||
    const recipeChanges: ITypeCount[] = [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            ItemType: recipeType,
 | 
					 | 
				
			||||||
            ItemCount: 1
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
    addRecipes(inventory, recipeChanges);
 | 
					 | 
				
			||||||
    return recipeChanges;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const applyCheatsToInfestedFoundry = (infestedFoundry: IInfestedFoundryClient): void => {
 | 
					 | 
				
			||||||
    if (config.infiniteHelminthMaterials) {
 | 
					 | 
				
			||||||
        infestedFoundry.Resources = [
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthCalx", Count: 1000 },
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBiotics", Count: 1000 },
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthSynthetics", Count: 1000 },
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthPheromones", Count: 1000 },
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBile", Count: 1000 },
 | 
					 | 
				
			||||||
            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthOxides", Count: 1000 }
 | 
					 | 
				
			||||||
        ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
interface IHelminthOfferingsUpdate {
 | 
					interface IHelminthOfferingsUpdate {
 | 
				
			||||||
    OfferingsIndex: number;
 | 
					    OfferingsIndex: number;
 | 
				
			||||||
    SuitTypes: string[];
 | 
					    SuitTypes: string[];
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,10 @@ import {
 | 
				
			|||||||
    ExportResources,
 | 
					    ExportResources,
 | 
				
			||||||
    ExportVirtuals
 | 
					    ExportVirtuals
 | 
				
			||||||
} from "warframe-public-export-plus";
 | 
					} from "warframe-public-export-plus";
 | 
				
			||||||
import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "./infestedFoundryController";
 | 
					import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService";
 | 
				
			||||||
import { addMiscItems, allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
 | 
					import { addMiscItems, allDailyAffiliationKeys, createLibraryDailyTask } from "@/src/services/inventoryService";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
 | 
					import { catBreadHash } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const inventoryController: RequestHandler = async (request, response) => {
 | 
					export const inventoryController: RequestHandler = async (request, response) => {
 | 
				
			||||||
    const accountId = await getAccountIdForRequest(request);
 | 
					    const accountId = await getAccountIdForRequest(request);
 | 
				
			||||||
@ -269,7 +270,7 @@ export const getInventoryResponse = async (
 | 
				
			|||||||
    return inventoryResponse;
 | 
					    return inventoryResponse;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const addString = (arr: string[], str: string): void => {
 | 
					const addString = (arr: string[], str: string): void => {
 | 
				
			||||||
    if (!arr.find(x => x == str)) {
 | 
					    if (!arr.find(x => x == str)) {
 | 
				
			||||||
        arr.push(str);
 | 
					        arr.push(str);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -299,13 +300,3 @@ const resourceGetParent = (resourceName: string): string | undefined => {
 | 
				
			|||||||
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
 | 
					    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
 | 
				
			||||||
    return ExportVirtuals[resourceName]?.parentName;
 | 
					    return ExportVirtuals[resourceName]?.parentName;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
// This is FNV1a-32 except operating under modulus 2^31 because JavaScript is stinky and likes producing negative integers out of nowhere.
 | 
					 | 
				
			||||||
export const catBreadHash = (name: string): number => {
 | 
					 | 
				
			||||||
    let hash = 2166136261;
 | 
					 | 
				
			||||||
    for (let i = 0; i != name.length; ++i) {
 | 
					 | 
				
			||||||
        hash = (hash ^ name.charCodeAt(i)) & 0x7fffffff;
 | 
					 | 
				
			||||||
        hash = (hash * 16777619) & 0x7fffffff;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return hash;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
				
			|||||||
import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
					import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService";
 | 
				
			||||||
import { getRecipeByResult } from "@/src/services/itemDataService";
 | 
					import { getRecipeByResult } from "@/src/services/itemDataService";
 | 
				
			||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
					import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "./infestedFoundryController";
 | 
					import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService";
 | 
				
			||||||
import { config } from "@/src/services/configService";
 | 
					import { config } from "@/src/services/configService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const upgradesController: RequestHandler = async (req, res) => {
 | 
					export const upgradesController: RequestHandler = async (req, res) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ import {
 | 
				
			|||||||
    ITypeXPItem
 | 
					    ITypeXPItem
 | 
				
			||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { RequestHandler } from "express";
 | 
					import { RequestHandler } from "express";
 | 
				
			||||||
import { catBreadHash } from "../api/inventoryController";
 | 
					import { catBreadHash } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { ExportCustoms, ExportDojoRecipes } from "warframe-public-export-plus";
 | 
					import { ExportCustoms, ExportDojoRecipes } from "warframe-public-export-plus";
 | 
				
			||||||
import { IStatsClient } from "@/src/types/statTypes";
 | 
					import { IStatsClient } from "@/src/types/statTypes";
 | 
				
			||||||
import { toStoreItem } from "@/src/services/itemDataService";
 | 
					import { toStoreItem } from "@/src/services/itemDataService";
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,16 @@ export const getIndexAfter = (str: string, searchWord: string): number => {
 | 
				
			|||||||
    return index + searchWord.length;
 | 
					    return index + searchWord.length;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is FNV1a-32 except operating under modulus 2^31 because JavaScript is stinky and likes producing negative integers out of nowhere.
 | 
				
			||||||
 | 
					export const catBreadHash = (name: string): number => {
 | 
				
			||||||
 | 
					    let hash = 2166136261;
 | 
				
			||||||
 | 
					    for (let i = 0; i != name.length; ++i) {
 | 
				
			||||||
 | 
					        hash = (hash ^ name.charCodeAt(i)) & 0x7fffffff;
 | 
				
			||||||
 | 
					        hash = (hash * 16777619) & 0x7fffffff;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return hash;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const regexEscape = (str: string): string => {
 | 
					export const regexEscape = (str: string): string => {
 | 
				
			||||||
    str = str.split(".").join("\\.");
 | 
					    str = str.split(".").join("\\.");
 | 
				
			||||||
    str = str.split("\\").join("\\\\");
 | 
					    str = str.split("\\").join("\\\\");
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										110
									
								
								src/services/infestedFoundryService.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/services/infestedFoundryService.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					import { ExportRecipes } from "warframe-public-export-plus";
 | 
				
			||||||
 | 
					import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel";
 | 
				
			||||||
 | 
					import { IInfestedFoundryClient, IInfestedFoundryDatabase, ITypeCount } from "../types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
 | 
					import { addRecipes } from "./inventoryService";
 | 
				
			||||||
 | 
					import { config } from "./configService";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => {
 | 
				
			||||||
 | 
					    const recipeChanges: ITypeCount[] = [];
 | 
				
			||||||
 | 
					    infestedFoundry.XP ??= 0;
 | 
				
			||||||
 | 
					    const prevXP = infestedFoundry.XP;
 | 
				
			||||||
 | 
					    infestedFoundry.XP += delta;
 | 
				
			||||||
 | 
					    if (prevXP < 2250_00 && infestedFoundry.XP >= 2250_00) {
 | 
				
			||||||
 | 
					        infestedFoundry.Slots ??= 0;
 | 
				
			||||||
 | 
					        infestedFoundry.Slots += 3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 5625_00 && infestedFoundry.XP >= 5625_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldsBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 10125_00 && infestedFoundry.XP >= 10125_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthHackBlueprint", ItemCount: 1 });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 15750_00 && infestedFoundry.XP >= 15750_00) {
 | 
				
			||||||
 | 
					        infestedFoundry.Slots ??= 0;
 | 
				
			||||||
 | 
					        infestedFoundry.Slots += 10;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 22500_00 && infestedFoundry.XP >= 22500_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthAmmoEfficiencyBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 30375_00 && infestedFoundry.XP >= 30375_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStunBlueprint", ItemCount: 1 });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 39375_00 && infestedFoundry.XP >= 39375_00) {
 | 
				
			||||||
 | 
					        infestedFoundry.Slots ??= 0;
 | 
				
			||||||
 | 
					        infestedFoundry.Slots += 20;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 60750_00 && infestedFoundry.XP >= 60750_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({ ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthStatusBlueprint", ItemCount: 1 });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 73125_00 && infestedFoundry.XP >= 73125_00) {
 | 
				
			||||||
 | 
					        infestedFoundry.Slots = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 86625_00 && infestedFoundry.XP >= 86625_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthShieldArmorBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 101250_00 && infestedFoundry.XP >= 101250_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthProcBlockBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 117000_00 && infestedFoundry.XP >= 117000_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthEnergyShareBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 133875_00 && infestedFoundry.XP >= 133875_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthMaxStatusBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (prevXP < 151875_00 && infestedFoundry.XP >= 151875_00) {
 | 
				
			||||||
 | 
					        recipeChanges.push({
 | 
				
			||||||
 | 
					            ItemType: "/Lotus/Types/Recipes/AbilityOverrides/HelminthTreasureBlueprint",
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return recipeChanges;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const handleSubsumeCompletion = (inventory: TInventoryDatabaseDocument): ITypeCount[] => {
 | 
				
			||||||
 | 
					    const [recipeType] = Object.entries(ExportRecipes).find(
 | 
				
			||||||
 | 
					        ([_recipeType, recipe]) =>
 | 
				
			||||||
 | 
					            recipe.secretIngredientAction == "SIA_WARFRAME_ABILITY" &&
 | 
				
			||||||
 | 
					            recipe.secretIngredients![0].ItemType == inventory.InfestedFoundry!.LastConsumedSuit!.ItemType
 | 
				
			||||||
 | 
					    )!;
 | 
				
			||||||
 | 
					    inventory.InfestedFoundry!.LastConsumedSuit = undefined;
 | 
				
			||||||
 | 
					    inventory.InfestedFoundry!.AbilityOverrideUnlockCooldown = undefined;
 | 
				
			||||||
 | 
					    const recipeChanges: ITypeCount[] = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ItemType: recipeType,
 | 
				
			||||||
 | 
					            ItemCount: 1
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    addRecipes(inventory, recipeChanges);
 | 
				
			||||||
 | 
					    return recipeChanges;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const applyCheatsToInfestedFoundry = (infestedFoundry: IInfestedFoundryClient): void => {
 | 
				
			||||||
 | 
					    if (config.infiniteHelminthMaterials) {
 | 
				
			||||||
 | 
					        infestedFoundry.Resources = [
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthCalx", Count: 1000 },
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBiotics", Count: 1000 },
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthSynthetics", Count: 1000 },
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthPheromones", Count: 1000 },
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthBile", Count: 1000 },
 | 
				
			||||||
 | 
					            { ItemType: "/Lotus/Types/Items/InfestedFoundry/HelminthOxides", Count: 1000 }
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,10 +1,6 @@
 | 
				
			|||||||
import {
 | 
					import { Inventory, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
    Inventory,
 | 
					 | 
				
			||||||
    InventoryDocumentProps,
 | 
					 | 
				
			||||||
    TInventoryDatabaseDocument
 | 
					 | 
				
			||||||
} from "@/src/models/inventoryModels/inventoryModel";
 | 
					 | 
				
			||||||
import { config } from "@/src/services/configService";
 | 
					import { config } from "@/src/services/configService";
 | 
				
			||||||
import { HydratedDocument, Types } from "mongoose";
 | 
					import { Types } from "mongoose";
 | 
				
			||||||
import { SlotNames, IInventoryChanges, IBinChanges, slotNames } from "@/src/types/purchaseTypes";
 | 
					import { SlotNames, IInventoryChanges, IBinChanges, slotNames } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    IChallengeProgress,
 | 
					    IChallengeProgress,
 | 
				
			||||||
@ -19,16 +15,16 @@ import {
 | 
				
			|||||||
    TEquipmentKey,
 | 
					    TEquipmentKey,
 | 
				
			||||||
    IFusionTreasure,
 | 
					    IFusionTreasure,
 | 
				
			||||||
    IDailyAffiliations,
 | 
					    IDailyAffiliations,
 | 
				
			||||||
    IInventoryDatabase,
 | 
					 | 
				
			||||||
    IKubrowPetEggDatabase,
 | 
					    IKubrowPetEggDatabase,
 | 
				
			||||||
    IKubrowPetEggClient,
 | 
					    IKubrowPetEggClient,
 | 
				
			||||||
    ILibraryDailyTaskInfo,
 | 
					    ILibraryDailyTaskInfo,
 | 
				
			||||||
    ICalendarProgress,
 | 
					    ICalendarProgress,
 | 
				
			||||||
    IDroneClient,
 | 
					    IDroneClient,
 | 
				
			||||||
    IUpgradeClient
 | 
					    IUpgradeClient,
 | 
				
			||||||
 | 
					    TPartialStartingGear
 | 
				
			||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
 | 
					import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate";
 | 
				
			||||||
import { IMissionInventoryUpdateRequest } from "../types/requestTypes";
 | 
					import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { convertInboxMessage, fromStoreItem, getKeyChainItems } from "@/src/services/itemDataService";
 | 
					import { convertInboxMessage, fromStoreItem, getKeyChainItems } from "@/src/services/itemDataService";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -62,10 +58,7 @@ import {
 | 
				
			|||||||
    TStandingLimitBin
 | 
					    TStandingLimitBin
 | 
				
			||||||
} from "warframe-public-export-plus";
 | 
					} from "warframe-public-export-plus";
 | 
				
			||||||
import { createShip } from "./shipService";
 | 
					import { createShip } from "./shipService";
 | 
				
			||||||
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
					 | 
				
			||||||
import { toOid } from "../helpers/inventoryHelpers";
 | 
					import { toOid } from "../helpers/inventoryHelpers";
 | 
				
			||||||
import { generateRewardSeed } from "@/src/controllers/api/getNewRewardSeedController";
 | 
					 | 
				
			||||||
import { addStartingGear } from "@/src/controllers/api/giveStartingGearController";
 | 
					 | 
				
			||||||
import { addQuestKey, completeQuest } from "@/src/services/questService";
 | 
					import { addQuestKey, completeQuest } from "@/src/services/questService";
 | 
				
			||||||
import { handleBundleAcqusition } from "./purchaseService";
 | 
					import { handleBundleAcqusition } from "./purchaseService";
 | 
				
			||||||
import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
					import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json";
 | 
				
			||||||
@ -114,6 +107,81 @@ export const createInventory = async (
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const generateRewardSeed = (): number => {
 | 
				
			||||||
 | 
					    const min = -Number.MAX_SAFE_INTEGER;
 | 
				
			||||||
 | 
					    const max = Number.MAX_SAFE_INTEGER;
 | 
				
			||||||
 | 
					    return Math.floor(Math.random() * (max - min + 1)) + min;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//TODO: RawUpgrades might need to return a LastAdded
 | 
				
			||||||
 | 
					const awakeningRewards = [
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3",
 | 
				
			||||||
 | 
					    "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4",
 | 
				
			||||||
 | 
					    "/Lotus/Types/Restoratives/LisetAutoHack",
 | 
				
			||||||
 | 
					    "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod"
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const addStartingGear = async (
 | 
				
			||||||
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
 | 
					    startingGear: TPartialStartingGear | undefined = undefined
 | 
				
			||||||
 | 
					): Promise<IInventoryChanges> => {
 | 
				
			||||||
 | 
					    const { LongGuns, Pistols, Suits, Melee } = startingGear || {
 | 
				
			||||||
 | 
					        LongGuns: [{ ItemType: "/Lotus/Weapons/Tenno/Rifle/Rifle" }],
 | 
				
			||||||
 | 
					        Pistols: [{ ItemType: "/Lotus/Weapons/Tenno/Pistol/Pistol" }],
 | 
				
			||||||
 | 
					        Suits: [{ ItemType: "/Lotus/Powersuits/Excalibur/Excalibur" }],
 | 
				
			||||||
 | 
					        Melee: [{ ItemType: "/Lotus/Weapons/Tenno/Melee/LongSword/LongSword" }]
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //TODO: properly merge weapon bin changes it is currently static here
 | 
				
			||||||
 | 
					    const inventoryChanges: IInventoryChanges = {};
 | 
				
			||||||
 | 
					    addEquipment(inventory, "LongGuns", LongGuns[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(inventory, "Pistols", Pistols[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(inventory, "Melee", Melee[0].ItemType, undefined, inventoryChanges);
 | 
				
			||||||
 | 
					    await addPowerSuit(inventory, Suits[0].ItemType, inventoryChanges);
 | 
				
			||||||
 | 
					    addEquipment(
 | 
				
			||||||
 | 
					        inventory,
 | 
				
			||||||
 | 
					        "DataKnives",
 | 
				
			||||||
 | 
					        "/Lotus/Weapons/Tenno/HackingDevices/TnHackingDevice/TnHackingDeviceWeapon",
 | 
				
			||||||
 | 
					        undefined,
 | 
				
			||||||
 | 
					        inventoryChanges,
 | 
				
			||||||
 | 
					        { XP: 450_000 }
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    addEquipment(
 | 
				
			||||||
 | 
					        inventory,
 | 
				
			||||||
 | 
					        "Scoops",
 | 
				
			||||||
 | 
					        "/Lotus/Weapons/Tenno/Speedball/SpeedballWeaponTest",
 | 
				
			||||||
 | 
					        undefined,
 | 
				
			||||||
 | 
					        inventoryChanges
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    updateSlots(inventory, InventorySlot.SUITS, 0, 1);
 | 
				
			||||||
 | 
					    updateSlots(inventory, InventorySlot.WEAPONS, 0, 3);
 | 
				
			||||||
 | 
					    inventoryChanges.SuitBin = { count: 1, platinum: 0, Slots: -1 };
 | 
				
			||||||
 | 
					    inventoryChanges.WeaponBin = { count: 3, platinum: 0, Slots: -3 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await addItem(inventory, "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain");
 | 
				
			||||||
 | 
					    inventory.ActiveQuest = "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inventory.PremiumCredits = 50;
 | 
				
			||||||
 | 
					    inventory.PremiumCreditsFree = 50;
 | 
				
			||||||
 | 
					    inventoryChanges.PremiumCredits = 50;
 | 
				
			||||||
 | 
					    inventoryChanges.PremiumCreditsFree = 50;
 | 
				
			||||||
 | 
					    inventory.RegularCredits = 3000;
 | 
				
			||||||
 | 
					    inventoryChanges.RegularCredits = 3000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (const item of awakeningRewards) {
 | 
				
			||||||
 | 
					        const inventoryDelta = await addItem(inventory, item);
 | 
				
			||||||
 | 
					        combineInventoryChanges(inventoryChanges, inventoryDelta);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inventory.PlayedParkourTutorial = true;
 | 
				
			||||||
 | 
					    inventory.ReceivedStartingGear = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return inventoryChanges;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Combines two inventory changes objects into one.
 | 
					 * Combines two inventory changes objects into one.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -1302,7 +1370,7 @@ export const addBooster = (ItemType: string, time: number, inventory: TInventory
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const updateSyndicate = (
 | 
					export const updateSyndicate = (
 | 
				
			||||||
    inventory: HydratedDocument<IInventoryDatabase, InventoryDocumentProps>,
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
    syndicateUpdate: IMissionInventoryUpdateRequest["AffiliationChanges"]
 | 
					    syndicateUpdate: IMissionInventoryUpdateRequest["AffiliationChanges"]
 | 
				
			||||||
): void => {
 | 
					): void => {
 | 
				
			||||||
    syndicateUpdate?.forEach(affiliation => {
 | 
					    syndicateUpdate?.forEach(affiliation => {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
					import { IKeyChainRequest } from "@/src/types/requestTypes";
 | 
				
			||||||
import { getIndexAfter } from "@/src/helpers/stringHelpers";
 | 
					import { getIndexAfter } from "@/src/helpers/stringHelpers";
 | 
				
			||||||
import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ import {
 | 
				
			|||||||
import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
 | 
					import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes";
 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { IRngResult, getRandomElement, getRandomReward } from "@/src/services/rngService";
 | 
					import { IRngResult, getRandomElement, getRandomReward } from "@/src/services/rngService";
 | 
				
			||||||
import { equipmentKeys, IInventoryDatabase, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    addBooster,
 | 
					    addBooster,
 | 
				
			||||||
    addChallenges,
 | 
					    addChallenges,
 | 
				
			||||||
@ -32,10 +32,10 @@ import {
 | 
				
			|||||||
    updateSyndicate
 | 
					    updateSyndicate
 | 
				
			||||||
} from "@/src/services/inventoryService";
 | 
					} from "@/src/services/inventoryService";
 | 
				
			||||||
import { updateQuestKey } from "@/src/services/questService";
 | 
					import { updateQuestKey } from "@/src/services/questService";
 | 
				
			||||||
import { HydratedDocument, Types } from "mongoose";
 | 
					import { Types } from "mongoose";
 | 
				
			||||||
import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
					import { IInventoryChanges } from "@/src/types/purchaseTypes";
 | 
				
			||||||
import { getLevelKeyRewards, toStoreItem } from "@/src/services/itemDataService";
 | 
					import { getLevelKeyRewards, toStoreItem } from "@/src/services/itemDataService";
 | 
				
			||||||
import { InventoryDocumentProps, TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
					import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
import { getEntriesUnsafe } from "@/src/utils/ts-utils";
 | 
					import { getEntriesUnsafe } from "@/src/utils/ts-utils";
 | 
				
			||||||
import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
					import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes";
 | 
				
			||||||
import { handleStoreItemAcquisition } from "./purchaseService";
 | 
					import { handleStoreItemAcquisition } from "./purchaseService";
 | 
				
			||||||
@ -73,7 +73,7 @@ const getRandomRewardByChance = (pool: IReward[]): IRngResult | undefined => {
 | 
				
			|||||||
//const knownUnhandledKeys: readonly string[] = ["test"] as const; // for unimplemented but important keys
 | 
					//const knownUnhandledKeys: readonly string[] = ["test"] as const; // for unimplemented but important keys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const addMissionInventoryUpdates = async (
 | 
					export const addMissionInventoryUpdates = async (
 | 
				
			||||||
    inventory: HydratedDocument<IInventoryDatabase, InventoryDocumentProps>,
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
    inventoryUpdates: IMissionInventoryUpdateRequest
 | 
					    inventoryUpdates: IMissionInventoryUpdateRequest
 | 
				
			||||||
): Promise<IInventoryChanges> => {
 | 
					): Promise<IInventoryChanges> => {
 | 
				
			||||||
    const inventoryChanges: IInventoryChanges = {};
 | 
					    const inventoryChanges: IInventoryChanges = {};
 | 
				
			||||||
@ -661,7 +661,7 @@ interface IMissionCredits {
 | 
				
			|||||||
//creditBonus is not entirely accurate.
 | 
					//creditBonus is not entirely accurate.
 | 
				
			||||||
//TODO: consider ActiveBoosters
 | 
					//TODO: consider ActiveBoosters
 | 
				
			||||||
export const addCredits = (
 | 
					export const addCredits = (
 | 
				
			||||||
    inventory: HydratedDocument<IInventoryDatabase>,
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        missionDropCredits,
 | 
					        missionDropCredits,
 | 
				
			||||||
        missionCompletionCredits,
 | 
					        missionCompletionCredits,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController";
 | 
					import { IKeyChainRequest } from "@/src/types/requestTypes";
 | 
				
			||||||
import { isEmptyObject } from "@/src/helpers/general";
 | 
					import { isEmptyObject } from "@/src/helpers/general";
 | 
				
			||||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
					import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
				
			||||||
import { createMessage } from "@/src/services/inboxService";
 | 
					import { createMessage } from "@/src/services/inboxService";
 | 
				
			||||||
@ -9,14 +9,9 @@ import {
 | 
				
			|||||||
    getLevelKeyRewards,
 | 
					    getLevelKeyRewards,
 | 
				
			||||||
    getQuestCompletionItems
 | 
					    getQuestCompletionItems
 | 
				
			||||||
} from "@/src/services/itemDataService";
 | 
					} from "@/src/services/itemDataService";
 | 
				
			||||||
import {
 | 
					import { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
				
			||||||
    IInventoryDatabase,
 | 
					 | 
				
			||||||
    IQuestKeyClient,
 | 
					 | 
				
			||||||
    IQuestKeyDatabase,
 | 
					 | 
				
			||||||
    IQuestStage
 | 
					 | 
				
			||||||
} from "@/src/types/inventoryTypes/inventoryTypes";
 | 
					 | 
				
			||||||
import { logger } from "@/src/utils/logger";
 | 
					import { logger } from "@/src/utils/logger";
 | 
				
			||||||
import { HydratedDocument, Types } from "mongoose";
 | 
					import { Types } from "mongoose";
 | 
				
			||||||
import { ExportKeys } from "warframe-public-export-plus";
 | 
					import { ExportKeys } from "warframe-public-export-plus";
 | 
				
			||||||
import { addFixedLevelRewards } from "./missionInventoryUpdateService";
 | 
					import { addFixedLevelRewards } from "./missionInventoryUpdateService";
 | 
				
			||||||
import { IInventoryChanges } from "../types/purchaseTypes";
 | 
					import { IInventoryChanges } from "../types/purchaseTypes";
 | 
				
			||||||
@ -31,7 +26,7 @@ export interface IUpdateQuestRequest {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const updateQuestKey = async (
 | 
					export const updateQuestKey = async (
 | 
				
			||||||
    inventory: HydratedDocument<IInventoryDatabase>,
 | 
					    inventory: TInventoryDatabaseDocument,
 | 
				
			||||||
    questKeyUpdate: IUpdateQuestRequest["QuestKeys"]
 | 
					    questKeyUpdate: IUpdateQuestRequest["QuestKeys"]
 | 
				
			||||||
): Promise<IInventoryChanges> => {
 | 
					): Promise<IInventoryChanges> => {
 | 
				
			||||||
    if (questKeyUpdate.length > 1) {
 | 
					    if (questKeyUpdate.length > 1) {
 | 
				
			||||||
@ -45,7 +40,7 @@ export const updateQuestKey = async (
 | 
				
			|||||||
        throw new Error(`quest key ${questKeyUpdate[0].ItemType} not found`);
 | 
					        throw new Error(`quest key ${questKeyUpdate[0].ItemType} not found`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inventory.QuestKeys[questKeyIndex] = questKeyUpdate[0];
 | 
					    inventory.QuestKeys[questKeyIndex].overwrite(questKeyUpdate[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let inventoryChanges: IInventoryChanges = {};
 | 
					    let inventoryChanges: IInventoryChanges = {};
 | 
				
			||||||
    if (questKeyUpdate[0].Completed) {
 | 
					    if (questKeyUpdate[0].Completed) {
 | 
				
			||||||
@ -57,12 +52,12 @@ export const updateQuestKey = async (
 | 
				
			|||||||
        logger.debug(`quest completion items`, questCompletionItems);
 | 
					        logger.debug(`quest completion items`, questCompletionItems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (questCompletionItems) {
 | 
					        if (questCompletionItems) {
 | 
				
			||||||
            inventoryChanges = await addItems(inventory as TInventoryDatabaseDocument, questCompletionItems);
 | 
					            inventoryChanges = await addItems(inventory, questCompletionItems);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        inventory.ActiveQuest = "";
 | 
					        inventory.ActiveQuest = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (questKeyUpdate[0].ItemType == "/Lotus/Types/Keys/NewWarQuest/NewWarQuestKeyChain") {
 | 
					        if (questKeyUpdate[0].ItemType == "/Lotus/Types/Keys/NewWarQuest/NewWarQuestKeyChain") {
 | 
				
			||||||
            setupKahlSyndicate(inventory as TInventoryDatabaseDocument);
 | 
					            setupKahlSyndicate(inventory);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return inventoryChanges;
 | 
					    return inventoryChanges;
 | 
				
			||||||
 | 
				
			|||||||
@ -1168,3 +1168,5 @@ export interface ILockedWeaponGroupDatabase {
 | 
				
			|||||||
    m?: Types.ObjectId;
 | 
					    m?: Types.ObjectId;
 | 
				
			||||||
    sn?: Types.ObjectId;
 | 
					    sn?: Types.ObjectId;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type TPartialStartingGear = Pick<IInventoryClient, "LongGuns" | "Suits" | "Pistols" | "Melee">;
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ import {
 | 
				
			|||||||
    ILockedWeaponGroupClient,
 | 
					    ILockedWeaponGroupClient,
 | 
				
			||||||
    ILoadOutPresets
 | 
					    ILoadOutPresets
 | 
				
			||||||
} from "./inventoryTypes/inventoryTypes";
 | 
					} from "./inventoryTypes/inventoryTypes";
 | 
				
			||||||
 | 
					import { IGroup } from "./loginTypes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IAffiliationChange {
 | 
					export interface IAffiliationChange {
 | 
				
			||||||
    Tag: string;
 | 
					    Tag: string;
 | 
				
			||||||
@ -175,3 +176,9 @@ export interface IVoidTearParticipantInfo {
 | 
				
			|||||||
    RewardProjection: string;
 | 
					    RewardProjection: string;
 | 
				
			||||||
    HardModeReward: ITypeCount;
 | 
					    HardModeReward: ITypeCount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface IKeyChainRequest {
 | 
				
			||||||
 | 
					    KeyChain: string;
 | 
				
			||||||
 | 
					    ChainStage: number;
 | 
				
			||||||
 | 
					    Groups?: IGroup[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user