preliminary foundry
This commit is contained in:
		
							parent
							
								
									7aaa51b3eb
								
							
						
					
					
						commit
						be2a87d326
					
				@ -3,11 +3,13 @@ const secondsPerMinute = 60;
 | 
			
		||||
const minutesPerHour = 60;
 | 
			
		||||
const hoursPerDay = 24;
 | 
			
		||||
 | 
			
		||||
const unixSecond = millisecondsPerSecond;
 | 
			
		||||
const unixMinute = secondsPerMinute * millisecondsPerSecond;
 | 
			
		||||
const unixHour = unixMinute * minutesPerHour;
 | 
			
		||||
const unixDay = hoursPerDay * unixHour;
 | 
			
		||||
 | 
			
		||||
export const unixTimesInMs = {
 | 
			
		||||
    second: unixSecond,
 | 
			
		||||
    minute: unixMinute,
 | 
			
		||||
    hour: unixHour,
 | 
			
		||||
    day: unixDay
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,62 @@
 | 
			
		||||
 | 
			
		||||
import { Request, RequestHandler, Response } from "express";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService";
 | 
			
		||||
import { IOid } from "@/src/types/commonTypes";
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { IInventoryDatabase } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
 | 
			
		||||
export const claimCompletedRecipeController: RequestHandler = async (_req: Request, res: Response) => {
 | 
			
		||||
    logger.debug("Claiming Completed Recipe");
 | 
			
		||||
    res.json({ status: "success" });
 | 
			
		||||
export interface IClaimCompletedRecipeRequest {
 | 
			
		||||
    RecipeIds: IOid[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
 | 
			
		||||
export const claimCompletedRecipeController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const claimCompletedRecipeRequest = getJSONfromString(req.body.toString()) as IClaimCompletedRecipeRequest;
 | 
			
		||||
    const accountId = req.query.accountId as string;
 | 
			
		||||
    if (!accountId) throw new Error("no account id");
 | 
			
		||||
 | 
			
		||||
    console.log(claimCompletedRecipeRequest);
 | 
			
		||||
    const inventory = await getInventory(accountId);
 | 
			
		||||
    const pendingRecipe = inventory.PendingRecipes.find(
 | 
			
		||||
        recipe => recipe._id?.toString() === claimCompletedRecipeRequest.RecipeIds[0].$oid
 | 
			
		||||
    );
 | 
			
		||||
    console.log(pendingRecipe);
 | 
			
		||||
    if (!pendingRecipe) {
 | 
			
		||||
        logger.error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
 | 
			
		||||
        throw new Error(`no pending recipe found with id ${claimCompletedRecipeRequest.RecipeIds[0].$oid}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //check recipe is indeed ready to be completed
 | 
			
		||||
    // if (pendingRecipe.CompletionDate > new Date()) {
 | 
			
		||||
    //     logger.error(`recipe ${pendingRecipe._id} is not ready to be completed`);
 | 
			
		||||
    //     throw new Error(`recipe ${pendingRecipe._id} is not ready to be completed`);
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    //get completed Items
 | 
			
		||||
    const completedItemName = getItemByBlueprint(pendingRecipe.ItemType)?.uniqueName;
 | 
			
		||||
 | 
			
		||||
    if (!completedItemName) {
 | 
			
		||||
        logger.error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
			
		||||
        throw new Error(`no completed item found for recipe ${pendingRecipe._id}`);
 | 
			
		||||
    }
 | 
			
		||||
    const itemCategory = getItemCategoryByUniqueName(completedItemName) as keyof typeof inventory;
 | 
			
		||||
    console.log(itemCategory);
 | 
			
		||||
    //TODO: remove all Schema.Mixed for inventory[itemCategory] not to be any
 | 
			
		||||
    //add item
 | 
			
		||||
    //inventory[itemCategory].
 | 
			
		||||
 | 
			
		||||
    //add additional item components like mods or weapons for a sentinel.
 | 
			
		||||
    //const additionalItemComponents = itemComponents[uniqueName]
 | 
			
		||||
    //add these items to inventory
 | 
			
		||||
    //return changes as InventoryChanges
 | 
			
		||||
 | 
			
		||||
    //remove pending recipe
 | 
			
		||||
    inventory.PendingRecipes.pull(pendingRecipe._id);
 | 
			
		||||
    // await inventory.save();
 | 
			
		||||
 | 
			
		||||
    logger.debug("Claiming Completed Recipe", { completedItemName });
 | 
			
		||||
 | 
			
		||||
    res.json({ InventoryChanges: {} });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -23,20 +23,20 @@ interface IAddItemRequest {
 | 
			
		||||
    InternalName: string;
 | 
			
		||||
    accountId: string;
 | 
			
		||||
}
 | 
			
		||||
export const isInternalName = (internalName: string): boolean => {
 | 
			
		||||
export const isInternalItemName = (internalName: string): boolean => {
 | 
			
		||||
    const item = items.find(i => i.uniqueName === internalName);
 | 
			
		||||
    return Boolean(item);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const parseInternalName = (internalName: unknown): string => {
 | 
			
		||||
    if (!isString(internalName) || !isInternalName(internalName)) {
 | 
			
		||||
const parseInternalItemName = (internalName: unknown): string => {
 | 
			
		||||
    if (!isString(internalName) || !isInternalItemName(internalName)) {
 | 
			
		||||
        throw new Error("incorrect internal name");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return internalName;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const toAddItemRequest = (body: unknown): IAddItemRequest => {
 | 
			
		||||
export const toAddItemRequest = (body: unknown): IAddItemRequest => {
 | 
			
		||||
    if (!body || typeof body !== "object") {
 | 
			
		||||
        throw new Error("incorrect or missing add item request data");
 | 
			
		||||
    }
 | 
			
		||||
@ -44,12 +44,10 @@ const toAddItemRequest = (body: unknown): IAddItemRequest => {
 | 
			
		||||
    if ("type" in body && "internalName" in body && "accountId" in body) {
 | 
			
		||||
        return {
 | 
			
		||||
            type: parseItemType(body.type),
 | 
			
		||||
            InternalName: parseInternalName(body.internalName),
 | 
			
		||||
            InternalName: parseInternalItemName(body.internalName),
 | 
			
		||||
            accountId: parseString(body.accountId)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    throw new Error("malformed add item request");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { toAddItemRequest };
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import Items, { Buildable, Category, Item, Warframe, Weapon } from "warframe-items";
 | 
			
		||||
import { log } from "winston";
 | 
			
		||||
 | 
			
		||||
type MinWeapon = Omit<Weapon, "patchlogs">;
 | 
			
		||||
type MinItem = Omit<Item, "patchlogs">;
 | 
			
		||||
@ -80,14 +79,46 @@ export const blueprintNames = Object.fromEntries(
 | 
			
		||||
        .map(name => [name, craftNames[name]])
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const items2 = new Items({
 | 
			
		||||
    category: ["Warframes", "Gear", "Melee", "Primary", "Secondary", "Sentinels", "Misc", "Arch-Gun", "Arch-Melee"]
 | 
			
		||||
});
 | 
			
		||||
const buildables = items.filter(item => !!(item as Buildable).components);
 | 
			
		||||
 | 
			
		||||
items2.flatMap(item => item.components || []);
 | 
			
		||||
// for (const item of items2) {
 | 
			
		||||
//     console.log(item.category === "Warframes");
 | 
			
		||||
//     if (item.category === "Warframes") {
 | 
			
		||||
//         console.log(item);
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
export const getItemByBlueprint = (uniqueName: string): (MinItem & Buildable) | undefined => {
 | 
			
		||||
    const item = buildables.find(
 | 
			
		||||
        item => (item as Buildable).components?.find(component => component.uniqueName === uniqueName)
 | 
			
		||||
    );
 | 
			
		||||
    return item;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getItemCategoryByUniqueName = (uniqueName: string) => {
 | 
			
		||||
    //Lotus/Types/Items/MiscItems/PolymerBundle
 | 
			
		||||
 | 
			
		||||
    let splitWord = "Items/";
 | 
			
		||||
    if (!uniqueName.includes("/Items/")) {
 | 
			
		||||
        splitWord = "/Types/";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const index = getIndexAfter(uniqueName, splitWord);
 | 
			
		||||
    if (index === -1) {
 | 
			
		||||
        logger.error(`error parsing item category ${uniqueName}`);
 | 
			
		||||
        throw new Error(`error parsing item category ${uniqueName}`);
 | 
			
		||||
    }
 | 
			
		||||
    const category = uniqueName.substring(index).split("/")[0];
 | 
			
		||||
    return category;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getIndexAfter = (str: string, searchWord: string) => {
 | 
			
		||||
    const index = str.indexOf(searchWord);
 | 
			
		||||
    if (index === -1) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    return index + searchWord.length;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getItemByUniqueName = (uniqueName: string) => {
 | 
			
		||||
    const item = items.find(item => item.uniqueName === uniqueName);
 | 
			
		||||
    return item;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getItemByName = (name: string) => {
 | 
			
		||||
    const item = items.find(item => item.name === name);
 | 
			
		||||
    return item;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,68 @@
 | 
			
		||||
import { unixTimesInMs } from "@/src/constants/timeConstants";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getItemByBlueprint, getItemCategoryByUniqueName } from "@/src/services/itemDataService";
 | 
			
		||||
import { logger } from "@/src/utils/logger";
 | 
			
		||||
import { Types } from "mongoose";
 | 
			
		||||
 | 
			
		||||
export const startRecipe = async (recipeName: string, accountId: string) => {
 | 
			
		||||
    //get recipe data
 | 
			
		||||
export interface IResource {
 | 
			
		||||
    uniqueName: string;
 | 
			
		||||
    count: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export const updateResources = async (accountId: string, components: IResource[]) => {
 | 
			
		||||
//     const inventory = await getInventory(accountId);
 | 
			
		||||
 | 
			
		||||
//     for (const component of components) {
 | 
			
		||||
//         const category = getItemCategoryByUniqueName(component.uniqueName) as keyof typeof inventory;
 | 
			
		||||
//         //validate category
 | 
			
		||||
 | 
			
		||||
//         console.log(component.uniqueName);
 | 
			
		||||
//         console.log("cate", category);
 | 
			
		||||
 | 
			
		||||
//         const invItem = inventory[category];
 | 
			
		||||
//         console.log("invItem", invItem);
 | 
			
		||||
 | 
			
		||||
//         inventory["MiscItems"];
 | 
			
		||||
//     }
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
export const startRecipe = async (recipeName: string, accountId: string) => {
 | 
			
		||||
    const recipe = getItemByBlueprint(recipeName);
 | 
			
		||||
 | 
			
		||||
    if (!recipe) {
 | 
			
		||||
        logger.error(`unknown recipe ${recipeName}`);
 | 
			
		||||
        throw new Error(`unknown recipe ${recipeName}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const componentsNeeded = recipe.components?.map(component => ({
 | 
			
		||||
        uniqueName: component.uniqueName,
 | 
			
		||||
        count: component.itemCount
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    if (!componentsNeeded) {
 | 
			
		||||
        logger.error(`recipe ${recipeName} has no components`);
 | 
			
		||||
        throw new Error(`recipe ${recipeName} has no components`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //TODO: consume components used
 | 
			
		||||
    //await updateResources(accountId, componentsNeeded);
 | 
			
		||||
 | 
			
		||||
    //might be redundant
 | 
			
		||||
    if (recipe.consumeOnBuild) {
 | 
			
		||||
        //consume
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!recipe.buildTime) {
 | 
			
		||||
        logger.error(`recipe ${recipeName} has no build time`);
 | 
			
		||||
        throw new Error(`recipe ${recipeName} has no build time`);
 | 
			
		||||
    }
 | 
			
		||||
    //buildtime is in seconds
 | 
			
		||||
    const completionDate = new Date(Date.now() + recipe.buildTime * unixTimesInMs.second);
 | 
			
		||||
 | 
			
		||||
    //consume resources
 | 
			
		||||
    const inventory = await getInventory(accountId);
 | 
			
		||||
    inventory.PendingRecipes.push({
 | 
			
		||||
        ItemType: recipeName,
 | 
			
		||||
        CompletionDate: new Date(),
 | 
			
		||||
        CompletionDate: completionDate,
 | 
			
		||||
        _id: new Types.ObjectId()
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user