Foundry 1 - Preliminary #127
@ -3,11 +3,13 @@ const secondsPerMinute = 60;
|
|||||||
const minutesPerHour = 60;
|
const minutesPerHour = 60;
|
||||||
const hoursPerDay = 24;
|
const hoursPerDay = 24;
|
||||||
|
|
||||||
|
const unixSecond = millisecondsPerSecond;
|
||||||
const unixMinute = secondsPerMinute * millisecondsPerSecond;
|
const unixMinute = secondsPerMinute * millisecondsPerSecond;
|
||||||
const unixHour = unixMinute * minutesPerHour;
|
const unixHour = unixMinute * minutesPerHour;
|
||||||
const unixDay = hoursPerDay * unixHour;
|
const unixDay = hoursPerDay * unixHour;
|
||||||
|
|
||||||
export const unixTimesInMs = {
|
export const unixTimesInMs = {
|
||||||
|
second: unixSecond,
|
||||||
minute: unixMinute,
|
minute: unixMinute,
|
||||||
hour: unixHour,
|
hour: unixHour,
|
||||||
day: unixDay
|
day: unixDay
|
||||||
|
64
src/controllers/api/claimCompletedRecipeController.ts
Normal file
64
src/controllers/api/claimCompletedRecipeController.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//this is a controller for the claimCompletedRecipe route
|
||||||
|
//it will claim a recipe for the user
|
||||||
|
|
||||||
|
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 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: {} });
|
||||||
|
};
|
@ -24,6 +24,7 @@ const inventoryController: RequestHandler = async (request: Request, response: R
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: make a function that converts from database representation to client
|
||||||
const inventoryJSON = inventory.toJSON();
|
const inventoryJSON = inventory.toJSON();
|
||||||
|
|
||||||
const inventoryResponse = toInventoryResponse(inventoryJSON);
|
const inventoryResponse = toInventoryResponse(inventoryJSON);
|
||||||
|
21
src/controllers/api/startRecipeController.ts
Normal file
21
src/controllers/api/startRecipeController.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { parseString } from "@/src/helpers/general";
|
||||||
|
import { getJSONfromString } from "@/src/helpers/stringHelpers";
|
||||||
|
import { startRecipe } from "@/src/services/recipeService";
|
||||||
|
import { logger } from "@/src/utils/logger";
|
||||||
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
|
interface IStartRecipeRequest {
|
||||||
|
RecipeName: string;
|
||||||
|
Ids: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
export const startRecipeController: RequestHandler = async (req, res) => {
|
||||||
|
const startRecipeRequest = getJSONfromString(req.body.toString()) as IStartRecipeRequest;
|
||||||
|
logger.debug("StartRecipe Request", { startRecipeRequest });
|
||||||
|
|
||||||
|
const accountId = parseString(req.query.accountId);
|
||||||
|
|
||||||
|
const newRecipeId = await startRecipe(startRecipeRequest.RecipeName, accountId);
|
||||||
|
res.json(newRecipeId);
|
||||||
|
};
|
@ -1,5 +1,5 @@
|
|||||||
import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers";
|
import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers";
|
||||||
import { getWeaponType } from "@/src/helpers/purchaseHelpers";
|
import { getWeaponType } from "@/src/services/itemDataService";
|
||||||
import { addPowerSuit, addWeapon } from "@/src/services/inventoryService";
|
import { addPowerSuit, addWeapon } from "@/src/services/inventoryService";
|
||||||
import { RequestHandler } from "express";
|
import { RequestHandler } from "express";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { isString, parseString } from "@/src/helpers/general";
|
import { isString, parseString } from "@/src/helpers/general";
|
||||||
import { items } from "@/static/data/items";
|
import { items } from "@/src/services/itemDataService";
|
||||||
|
|
||||||
export enum ItemType {
|
export enum ItemType {
|
||||||
Powersuit = "Powersuit",
|
Powersuit = "Powersuit",
|
||||||
@ -23,20 +23,20 @@ interface IAddItemRequest {
|
|||||||
InternalName: string;
|
InternalName: string;
|
||||||
accountId: string;
|
accountId: string;
|
||||||
}
|
}
|
||||||
export const isInternalName = (internalName: string): boolean => {
|
export const isInternalItemName = (internalName: string): boolean => {
|
||||||
const item = items.find(i => i.uniqueName === internalName);
|
const item = items.find(i => i.uniqueName === internalName);
|
||||||
return Boolean(item);
|
return Boolean(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseInternalName = (internalName: unknown): string => {
|
const parseInternalItemName = (internalName: unknown): string => {
|
||||||
if (!isString(internalName) || !isInternalName(internalName)) {
|
if (!isString(internalName) || !isInternalItemName(internalName)) {
|
||||||
throw new Error("incorrect internal name");
|
throw new Error("incorrect internal name");
|
||||||
}
|
}
|
||||||
|
|
||||||
return internalName;
|
return internalName;
|
||||||
};
|
};
|
||||||
|
|
||||||
const toAddItemRequest = (body: unknown): IAddItemRequest => {
|
export const toAddItemRequest = (body: unknown): IAddItemRequest => {
|
||||||
if (!body || typeof body !== "object") {
|
if (!body || typeof body !== "object") {
|
||||||
throw new Error("incorrect or missing add item request data");
|
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) {
|
if ("type" in body && "internalName" in body && "accountId" in body) {
|
||||||
return {
|
return {
|
||||||
type: parseItemType(body.type),
|
type: parseItemType(body.type),
|
||||||
InternalName: parseInternalName(body.internalName),
|
InternalName: parseInternalItemName(body.internalName),
|
||||||
accountId: parseString(body.accountId)
|
accountId: parseString(body.accountId)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error("malformed add item request");
|
throw new Error("malformed add item request");
|
||||||
};
|
};
|
||||||
|
|
||||||
export { toAddItemRequest };
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { parseBoolean, parseNumber, parseString } from "@/src/helpers/general";
|
import { parseBoolean, parseNumber, parseString } from "@/src/helpers/general";
|
||||||
import { WeaponTypeInternal } from "@/src/services/inventoryService";
|
import { weapons } from "@/src/services/itemDataService";
|
||||||
import { slotPurchaseNameToSlotName } from "@/src/services/purchaseService";
|
import { slotPurchaseNameToSlotName } from "@/src/services/purchaseService";
|
||||||
import { IPurchaseRequest, SlotPurchaseName } from "@/src/types/purchaseTypes";
|
import { IPurchaseRequest, SlotPurchaseName } from "@/src/types/purchaseTypes";
|
||||||
import { weapons } from "@/static/data/items";
|
|
||||||
|
|
||||||
export const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
|
export const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest => {
|
||||||
if (!purchaseRequest || typeof purchaseRequest !== "object") {
|
if (!purchaseRequest || typeof purchaseRequest !== "object") {
|
||||||
@ -41,22 +40,6 @@ export const toPurchaseRequest = (purchaseRequest: unknown): IPurchaseRequest =>
|
|||||||
throw new Error("invalid purchaseRequest");
|
throw new Error("invalid purchaseRequest");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWeaponType = (weaponName: string) => {
|
|
||||||
const weaponInfo = weapons.find(i => i.uniqueName === weaponName);
|
|
||||||
|
|
||||||
if (!weaponInfo) {
|
|
||||||
throw new Error(`unknown weapon ${weaponName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const weaponType = weaponInfo.productCategory as WeaponTypeInternal;
|
|
||||||
|
|
||||||
if (!weaponType) {
|
|
||||||
throw new Error(`unknown weapon category for item ${weaponName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return weaponType;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isSlotPurchaseName = (slotPurchaseName: string): slotPurchaseName is SlotPurchaseName => {
|
export const isSlotPurchaseName = (slotPurchaseName: string): slotPurchaseName is SlotPurchaseName => {
|
||||||
return slotPurchaseName in slotPurchaseNameToSlotName;
|
return slotPurchaseName in slotPurchaseNameToSlotName;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export const getJSONfromString = (str: string): any => {
|
export const getJSONfromString = (str: string) => {
|
||||||
const jsonSubstring = str.substring(0, str.lastIndexOf("}") + 1);
|
const jsonSubstring = str.substring(0, str.lastIndexOf("}") + 1);
|
||||||
return JSON.parse(jsonSubstring);
|
return JSON.parse(jsonSubstring);
|
||||||
};
|
};
|
||||||
@ -16,3 +16,11 @@ export const getSubstringFromKeywordToKeyword = (str: string, keywordBegin: stri
|
|||||||
const endIndex = str.indexOf(keywordEnd);
|
const endIndex = str.indexOf(keywordEnd);
|
||||||
return str.substring(beginIndex, endIndex + 1);
|
return str.substring(beginIndex, endIndex + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getIndexAfter = (str: string, searchWord: string) => {
|
||||||
|
const index = str.indexOf(searchWord);
|
||||||
|
if (index === -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return index + searchWord.length;
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Model, Schema, Types, model } from "mongoose";
|
import { HydratedDocument, Model, Schema, Types, model } from "mongoose";
|
||||||
import {
|
import {
|
||||||
IFlavourItem,
|
IFlavourItem,
|
||||||
IRawUpgrade,
|
IRawUpgrade,
|
||||||
@ -10,7 +10,9 @@ import {
|
|||||||
ISlots,
|
ISlots,
|
||||||
IGenericItem,
|
IGenericItem,
|
||||||
IMailbox,
|
IMailbox,
|
||||||
IDuviriInfo
|
IDuviriInfo,
|
||||||
|
IPendingRecipe as IPendingRecipeDatabase,
|
||||||
|
IPendingRecipeResponse
|
||||||
} from "../../types/inventoryTypes/inventoryTypes";
|
} from "../../types/inventoryTypes/inventoryTypes";
|
||||||
import { IMongoDate, IOid } from "../../types/commonTypes";
|
import { IMongoDate, IOid } from "../../types/commonTypes";
|
||||||
import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes";
|
import { ISuitDatabase } from "@/src/types/inventoryTypes/SuitTypes";
|
||||||
@ -25,6 +27,29 @@ import {
|
|||||||
} from "@/src/types/inventoryTypes/commonInventoryTypes";
|
} from "@/src/types/inventoryTypes/commonInventoryTypes";
|
||||||
import { toOid } from "@/src/helpers/inventoryHelpers";
|
import { toOid } from "@/src/helpers/inventoryHelpers";
|
||||||
|
|
||||||
|
const pendingRecipeSchema = new Schema<IPendingRecipeDatabase>(
|
||||||
|
{
|
||||||
|
ItemType: String,
|
||||||
|
CompletionDate: Date
|
||||||
|
},
|
||||||
|
{ id: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
pendingRecipeSchema.virtual("ItemId").get(function () {
|
||||||
|
return { $oid: this._id.toString() };
|
||||||
|
});
|
||||||
|
|
||||||
|
pendingRecipeSchema.set("toJSON", {
|
||||||
|
virtuals: true,
|
||||||
|
transform(_document, returnedObject) {
|
||||||
|
delete returnedObject._id;
|
||||||
|
delete returnedObject.__v;
|
||||||
|
(returnedObject as IPendingRecipeResponse).CompletionDate = {
|
||||||
|
$date: { $numberLong: (returnedObject as IPendingRecipeDatabase).CompletionDate.getTime().toString() }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const polaritySchema = new Schema<IPolarity>({
|
const polaritySchema = new Schema<IPolarity>({
|
||||||
Slot: Number,
|
Slot: Number,
|
||||||
Value: String
|
Value: String
|
||||||
@ -296,7 +321,6 @@ DuviriInfoSchema.set("toJSON", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
||||||
|
|
||||||
accountOwnerId: Schema.Types.ObjectId,
|
accountOwnerId: Schema.Types.ObjectId,
|
||||||
SubscribedToEmails: Number,
|
SubscribedToEmails: Number,
|
||||||
Created: Schema.Types.Mixed,
|
Created: Schema.Types.Mixed,
|
||||||
@ -325,7 +349,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
MechBin: slotsBinSchema,
|
MechBin: slotsBinSchema,
|
||||||
CrewMemberBin: slotsBinSchema,
|
CrewMemberBin: slotsBinSchema,
|
||||||
|
|
||||||
|
|
||||||
//How many trades do you have left
|
//How many trades do you have left
|
||||||
TradesRemaining: Number,
|
TradesRemaining: Number,
|
||||||
//How many Gift do you have left*(gift spends the trade)
|
//How many Gift do you have left*(gift spends the trade)
|
||||||
@ -351,10 +374,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
DailyAffiliationZariman: Number,
|
DailyAffiliationZariman: Number,
|
||||||
DailyAffiliationKahl: Number,
|
DailyAffiliationKahl: Number,
|
||||||
|
|
||||||
|
|
||||||
//Daily Focus limit
|
//Daily Focus limit
|
||||||
DailyFocus: Number,
|
DailyFocus: Number,
|
||||||
//you not used Focus
|
//you not used Focus
|
||||||
FocusXP: Schema.Types.Mixed,
|
FocusXP: Schema.Types.Mixed,
|
||||||
//Curent active like Active school focuses is = "Zenurik"
|
//Curent active like Active school focuses is = "Zenurik"
|
||||||
FocusAbility: String,
|
FocusAbility: String,
|
||||||
@ -441,24 +463,21 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components)
|
//Railjack/Components(https://warframe.fandom.com/wiki/Railjack/Components)
|
||||||
CrewShipRawSalvage: [Schema.Types.Mixed],
|
CrewShipRawSalvage: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Default RailJack
|
//Default RailJack
|
||||||
CrewShips: [Schema.Types.Mixed],
|
CrewShips: [Schema.Types.Mixed],
|
||||||
CrewShipAmmo: [Schema.Types.Mixed],
|
CrewShipAmmo: [Schema.Types.Mixed],
|
||||||
CrewShipWeapons: [Schema.Types.Mixed],
|
CrewShipWeapons: [Schema.Types.Mixed],
|
||||||
CrewShipWeaponSkins: [Schema.Types.Mixed],
|
CrewShipWeaponSkins: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//NPC Crew and weapon
|
//NPC Crew and weapon
|
||||||
CrewMembers: [Schema.Types.Mixed],
|
CrewMembers: [Schema.Types.Mixed],
|
||||||
CrewShipSalvagedWeaponSkins: [Schema.Types.Mixed],
|
CrewShipSalvagedWeaponSkins: [Schema.Types.Mixed],
|
||||||
CrewShipSalvagedWeapons: [Schema.Types.Mixed],
|
CrewShipSalvagedWeapons: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Complete Mission\Quests
|
//Complete Mission\Quests
|
||||||
Missions: [Schema.Types.Mixed],
|
Missions: [Schema.Types.Mixed],
|
||||||
QuestKeys: [Schema.Types.Mixed],
|
QuestKeys: [Schema.Types.Mixed],
|
||||||
//item like DojoKey or Boss missions key
|
//item like DojoKey or Boss missions key
|
||||||
LevelKeys: [Schema.Types.Mixed],
|
LevelKeys: [Schema.Types.Mixed],
|
||||||
//Active quests
|
//Active quests
|
||||||
Quests: [Schema.Types.Mixed],
|
Quests: [Schema.Types.Mixed],
|
||||||
@ -478,25 +497,22 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//Retries rank up(3 time)
|
//Retries rank up(3 time)
|
||||||
TrainingRetriesLeft: Number,
|
TrainingRetriesLeft: Number,
|
||||||
|
|
||||||
|
|
||||||
//you saw last played Region when you opened the star map
|
//you saw last played Region when you opened the star map
|
||||||
LastRegionPlayed: String,
|
LastRegionPlayed: String,
|
||||||
|
|
||||||
//Blueprint
|
//Blueprint
|
||||||
Recipes: [Schema.Types.Mixed],
|
Recipes: [Schema.Types.Mixed],
|
||||||
//Crafting Blueprint(Item Name + CompletionDate)
|
//Crafting Blueprint(Item Name + CompletionDate)
|
||||||
PendingRecipes: [Schema.Types.Mixed],
|
PendingRecipes: [pendingRecipeSchema],
|
||||||
|
|
||||||
//warframe\Weapon skins
|
//warframe\Weapon skins
|
||||||
WeaponSkins: [Schema.Types.Mixed],
|
WeaponSkins: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Ayatan Item
|
//Ayatan Item
|
||||||
FusionTreasures: [Schema.Types.Mixed],
|
FusionTreasures: [Schema.Types.Mixed],
|
||||||
//"node": "TreasureTutorial", "state": "TS_COMPLETED"
|
//"node": "TreasureTutorial", "state": "TS_COMPLETED"
|
||||||
TauntHistory: [Schema.Types.Mixed],
|
TauntHistory: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//noShow2FA,VisitPrimeVault etc
|
//noShow2FA,VisitPrimeVault etc
|
||||||
WebFlags: Schema.Types.Mixed,
|
WebFlags: Schema.Types.Mixed,
|
||||||
//Id CompletedAlerts
|
//Id CompletedAlerts
|
||||||
@ -508,7 +524,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//Alert->Kuva Siphon
|
//Alert->Kuva Siphon
|
||||||
PeriodicMissionCompletions: [Schema.Types.Mixed],
|
PeriodicMissionCompletions: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Codex->LoreFragment
|
//Codex->LoreFragment
|
||||||
LoreFragmentScans: [Schema.Types.Mixed],
|
LoreFragmentScans: [Schema.Types.Mixed],
|
||||||
|
|
||||||
@ -520,7 +535,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
ActiveDojoColorResearch: String,
|
ActiveDojoColorResearch: String,
|
||||||
|
|
||||||
SentientSpawnChanceBoosters: Schema.Types.Mixed,
|
SentientSpawnChanceBoosters: Schema.Types.Mixed,
|
||||||
|
|
||||||
QualifyingInvasions: [Schema.Types.Mixed],
|
QualifyingInvasions: [Schema.Types.Mixed],
|
||||||
FactionScores: [Number],
|
FactionScores: [Number],
|
||||||
|
|
||||||
@ -530,11 +545,9 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//If you want change Spectre Gear id
|
//If you want change Spectre Gear id
|
||||||
PendingSpectreLoadouts: [Schema.Types.Mixed],
|
PendingSpectreLoadouts: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//New quest Email spam
|
//New quest Email spam
|
||||||
//example:"ItemType": "/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestEmailItem",
|
//example:"ItemType": "/Lotus/Types/Keys/RailJackBuildQuest/RailjackBuildQuestEmailItem",
|
||||||
EmailItems: [Schema.Types.Mixed],
|
EmailItems: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Profile->Wishlist
|
//Profile->Wishlist
|
||||||
Wishlist: [String],
|
Wishlist: [String],
|
||||||
@ -561,7 +574,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
|
|
||||||
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
//Game mission\ivent score example "Tag": "WaterFight", "Best": 170, "Count": 1258,
|
||||||
PersonalGoalProgress: [Schema.Types.Mixed],
|
PersonalGoalProgress: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Setting interface Style
|
//Setting interface Style
|
||||||
ThemeStyle: String,
|
ThemeStyle: String,
|
||||||
ThemeBackground: String,
|
ThemeBackground: String,
|
||||||
@ -579,7 +592,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//Night Wave Challenge
|
//Night Wave Challenge
|
||||||
SeasonChallengeHistory: [Schema.Types.Mixed],
|
SeasonChallengeHistory: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
|
//Cephalon Simaris Entries Example:"TargetType"+"Scans"(1-10)+"Completed": true|false
|
||||||
LibraryPersonalProgress: [Schema.Types.Mixed],
|
LibraryPersonalProgress: [Schema.Types.Mixed],
|
||||||
//Cephalon Simaris Daily Task
|
//Cephalon Simaris Daily Task
|
||||||
@ -587,23 +599,23 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
|
|
||||||
//https://warframe.fandom.com/wiki/Invasion
|
//https://warframe.fandom.com/wiki/Invasion
|
||||||
InvasionChainProgress: [Schema.Types.Mixed],
|
InvasionChainProgress: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//https://warframe.fandom.com/wiki/Parazon
|
//https://warframe.fandom.com/wiki/Parazon
|
||||||
DataKnives: [GenericItemSchema],
|
DataKnives: [GenericItemSchema],
|
||||||
|
|
||||||
//CorpusLich or GrineerLich
|
//CorpusLich or GrineerLich
|
||||||
NemesisAbandonedRewards: [String],
|
NemesisAbandonedRewards: [String],
|
||||||
//CorpusLich\KuvaLich
|
//CorpusLich\KuvaLich
|
||||||
NemesisHistory: [Schema.Types.Mixed],
|
NemesisHistory: [Schema.Types.Mixed],
|
||||||
LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
LastNemesisAllySpawnTime: Schema.Types.Mixed,
|
||||||
|
|
||||||
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
//TradingRulesConfirmed,ShowFriendInvNotifications(Option->Social)
|
||||||
Settings: Schema.Types.Mixed,
|
Settings: Schema.Types.Mixed,
|
||||||
|
|
||||||
//Railjack craft
|
//Railjack craft
|
||||||
//https://warframe.fandom.com/wiki/Rising_Tide
|
//https://warframe.fandom.com/wiki/Rising_Tide
|
||||||
PersonalTechProjects: [Schema.Types.Mixed],
|
PersonalTechProjects: [Schema.Types.Mixed],
|
||||||
|
|
||||||
//Modulars lvl and exp(Railjack|Duviri)
|
//Modulars lvl and exp(Railjack|Duviri)
|
||||||
//https://warframe.fandom.com/wiki/Intrinsics
|
//https://warframe.fandom.com/wiki/Intrinsics
|
||||||
PlayerSkills: Schema.Types.Mixed,
|
PlayerSkills: Schema.Types.Mixed,
|
||||||
@ -611,7 +623,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//TradeBannedUntil data
|
//TradeBannedUntil data
|
||||||
TradeBannedUntil: Schema.Types.Mixed,
|
TradeBannedUntil: Schema.Types.Mixed,
|
||||||
|
|
||||||
|
|
||||||
//https://warframe.fandom.com/wiki/Helminth
|
//https://warframe.fandom.com/wiki/Helminth
|
||||||
InfestedFoundry: Schema.Types.Mixed,
|
InfestedFoundry: Schema.Types.Mixed,
|
||||||
NextRefill: Schema.Types.Mixed,
|
NextRefill: Schema.Types.Mixed,
|
||||||
@ -624,7 +635,6 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
//https://warframe.fandom.com/wiki/Incarnon
|
//https://warframe.fandom.com/wiki/Incarnon
|
||||||
EvolutionProgress: [Schema.Types.Mixed],
|
EvolutionProgress: [Schema.Types.Mixed],
|
||||||
|
|
||||||
|
|
||||||
//Unknown and system
|
//Unknown and system
|
||||||
DuviriInfo: DuviriInfoSchema,
|
DuviriInfo: DuviriInfoSchema,
|
||||||
Mailbox: MailboxSchema,
|
Mailbox: MailboxSchema,
|
||||||
@ -650,7 +660,7 @@ const inventorySchema = new Schema<IInventoryDatabase, InventoryDocumentProps>({
|
|||||||
CollectibleSeries: [Schema.Types.Mixed],
|
CollectibleSeries: [Schema.Types.Mixed],
|
||||||
HasResetAccount: Boolean,
|
HasResetAccount: Boolean,
|
||||||
|
|
||||||
//Discount Coupon
|
//Discount Coupon
|
||||||
PendingCoupon: Schema.Types.Mixed,
|
PendingCoupon: Schema.Types.Mixed,
|
||||||
//Like BossAladV,BossCaptainVor come for you on missions % chance
|
//Like BossAladV,BossCaptainVor come for you on missions % chance
|
||||||
DeathMarks: [String],
|
DeathMarks: [String],
|
||||||
@ -685,13 +695,14 @@ type InventoryDocumentProps = {
|
|||||||
MiscItems: Types.DocumentArray<IMiscItem>;
|
MiscItems: Types.DocumentArray<IMiscItem>;
|
||||||
Boosters: Types.DocumentArray<IBooster>;
|
Boosters: Types.DocumentArray<IBooster>;
|
||||||
OperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
|
OperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
|
||||||
AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>;
|
AdultOperatorLoadOuts: Types.DocumentArray<IOperatorConfigClient>; //TODO: this should still contain _id
|
||||||
MechSuits: Types.DocumentArray<ISuitDatabase>;
|
MechSuits: Types.DocumentArray<ISuitDatabase>;
|
||||||
Scoops: Types.DocumentArray<IGenericItem>;
|
Scoops: Types.DocumentArray<IGenericItem>;
|
||||||
DataKnives: Types.DocumentArray<IGenericItem>;
|
DataKnives: Types.DocumentArray<IGenericItem>;
|
||||||
DrifterMelee: Types.DocumentArray<IGenericItem>;
|
DrifterMelee: Types.DocumentArray<IGenericItem>;
|
||||||
Sentinels: Types.DocumentArray<IWeaponDatabase>;
|
Sentinels: Types.DocumentArray<IWeaponDatabase>;
|
||||||
Horses: Types.DocumentArray<IGenericItem>;
|
Horses: Types.DocumentArray<IGenericItem>;
|
||||||
|
PendingRecipes: Types.DocumentArray<IPendingRecipeDatabase>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
|
type InventoryModelType = Model<IInventoryDatabase, {}, InventoryDocumentProps>;
|
||||||
|
@ -35,6 +35,8 @@ import express from "express";
|
|||||||
import { setBootLocationController } from "@/src/controllers/api/setBootLocationController";
|
import { setBootLocationController } from "@/src/controllers/api/setBootLocationController";
|
||||||
import { focusController } from "@/src/controllers/api/focusController";
|
import { focusController } from "@/src/controllers/api/focusController";
|
||||||
import { inventorySlotsController } from "@/src/controllers/api/inventorySlotsController";
|
import { inventorySlotsController } from "@/src/controllers/api/inventorySlotsController";
|
||||||
|
import { startRecipeController } from "@/src/controllers/api/startRecipeController";
|
||||||
|
import { claimCompletedRecipeController } from "@/src/controllers/api/claimCompletedRecipeController";
|
||||||
|
|
||||||
const apiRouter = express.Router();
|
const apiRouter = express.Router();
|
||||||
|
|
||||||
@ -62,6 +64,9 @@ apiRouter.get("/logout.php", logoutController);
|
|||||||
apiRouter.get("/setBootLocation.php", setBootLocationController);
|
apiRouter.get("/setBootLocation.php", setBootLocationController);
|
||||||
|
|
||||||
// post
|
// post
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
|
apiRouter.post("/claimCompletedRecipe.php", claimCompletedRecipeController);
|
||||||
|
apiRouter.post("/startRecipe.php", startRecipeController);
|
||||||
apiRouter.post("/inventorySlots.php", inventorySlotsController);
|
apiRouter.post("/inventorySlots.php", inventorySlotsController);
|
||||||
apiRouter.post("/focus.php", focusController);
|
apiRouter.post("/focus.php", focusController);
|
||||||
apiRouter.post("/artifacts.php", artifactsController);
|
apiRouter.post("/artifacts.php", artifactsController);
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
import { IGenericUpdate } from "../types/genericUpdate";
|
import { IGenericUpdate } from "../types/genericUpdate";
|
||||||
import { IArtifactsRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
import { IArtifactsRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
|
import { WeaponTypeInternal } from "@/src/services/itemDataService";
|
||||||
|
|
||||||
export const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => {
|
export const createInventory = async (accountOwnerId: Types.ObjectId, loadOutPresetId: Types.ObjectId) => {
|
||||||
try {
|
try {
|
||||||
@ -145,8 +146,6 @@ export const updateGeneric = async (data: IGenericUpdate, accountId: string) =>
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WeaponTypeInternal = "LongGuns" | "Pistols" | "Melee";
|
|
||||||
|
|
||||||
export const addWeapon = async (
|
export const addWeapon = async (
|
||||||
weaponType: WeaponTypeInternal,
|
weaponType: WeaponTypeInternal,
|
||||||
weaponName: string,
|
weaponName: string,
|
||||||
|
117
src/services/itemDataService.ts
Normal file
117
src/services/itemDataService.ts
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import { getIndexAfter } from "@/src/helpers/stringHelpers";
|
||||||
|
import { logger } from "@/src/utils/logger";
|
||||||
|
import Items, { Buildable, Category, Item, Warframe, Weapon } from "warframe-items";
|
||||||
|
|
||||||
|
type MinWeapon = Omit<Weapon, "patchlogs">;
|
||||||
|
type MinItem = Omit<Item, "patchlogs">;
|
||||||
|
|
||||||
|
export const weapons: MinWeapon[] = (new Items({ category: ["Primary", "Secondary", "Melee"] }) as Weapon[]).map(
|
||||||
|
item => {
|
||||||
|
const next = { ...item };
|
||||||
|
delete next.patchlogs;
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export type WeaponTypeInternal = "LongGuns" | "Pistols" | "Melee";
|
||||||
|
|
||||||
|
export const items: MinItem[] = new Items({ category: ["All"] }).map(item => {
|
||||||
|
const next = { ...item };
|
||||||
|
delete next.patchlogs;
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getWeaponType = (weaponName: string) => {
|
||||||
|
const weaponInfo = weapons.find(i => i.uniqueName === weaponName);
|
||||||
|
|
||||||
|
if (!weaponInfo) {
|
||||||
|
throw new Error(`unknown weapon ${weaponName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const weaponType = weaponInfo.productCategory as WeaponTypeInternal;
|
||||||
|
|
||||||
|
if (!weaponType) {
|
||||||
|
logger.error(`unknown weapon category for item ${weaponName}`);
|
||||||
|
throw new Error(`unknown weapon category for item ${weaponName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return weaponType;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNamesObj = (category: Category) =>
|
||||||
|
new Items({ category: [category] }).reduce<{ [index: string]: string }>((acc, item) => {
|
||||||
|
acc[item.name!.replace("'S", "'s")] = item.uniqueName!;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
export const modNames = getNamesObj("Mods");
|
||||||
|
export const resourceNames = getNamesObj("Resources");
|
||||||
|
export const miscNames = getNamesObj("Misc");
|
||||||
|
export const relicNames = getNamesObj("Relics");
|
||||||
|
export const skinNames = getNamesObj("Skins");
|
||||||
|
export const arcaneNames = getNamesObj("Arcanes");
|
||||||
|
export const gearNames = getNamesObj("Gear");
|
||||||
|
//logger.debug(`gear names`, { gearNames });
|
||||||
|
|
||||||
|
export const craftNames = Object.fromEntries(
|
||||||
|
(
|
||||||
|
new Items({
|
||||||
|
category: [
|
||||||
|
"Warframes",
|
||||||
|
"Gear",
|
||||||
|
"Melee",
|
||||||
|
"Primary",
|
||||||
|
"Secondary",
|
||||||
|
"Sentinels",
|
||||||
|
"Misc",
|
||||||
|
"Arch-Gun",
|
||||||
|
"Arch-Melee"
|
||||||
|
]
|
||||||
|
}) as Warframe[]
|
||||||
|
)
|
||||||
|
.flatMap(item => item.components || [])
|
||||||
|
.filter(item => item.drops && item.drops[0])
|
||||||
|
.map(item => [item.drops![0].type, item.uniqueName])
|
||||||
|
);
|
||||||
|
|
||||||
|
export const blueprintNames = Object.fromEntries(
|
||||||
|
Object.keys(craftNames)
|
||||||
|
.filter(name => name.includes("Blueprint"))
|
||||||
|
.map(name => [name, craftNames[name]])
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildables = items.filter(item => !!(item as Buildable).components);
|
||||||
|
|
||||||
|
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 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,7 +1,14 @@
|
|||||||
import { IMissionRewardResponse, IReward, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
|
import { IMissionRewardResponse, IReward, IInventoryFieldType, inventoryFields } from "@/src/types/missionTypes";
|
||||||
|
|
||||||
import missionsDropTable from "@/static/json/missions-drop-table.json";
|
import missionsDropTable from "@/static/json/missions-drop-table.json";
|
||||||
import { modNames, relicNames, miscNames, resourceNames, gearNames, blueprintNames } from "@/static/data/items";
|
import {
|
||||||
|
modNames,
|
||||||
|
relicNames,
|
||||||
|
miscNames,
|
||||||
|
resourceNames,
|
||||||
|
gearNames,
|
||||||
|
blueprintNames
|
||||||
|
} from "@/src/services/itemDataService";
|
||||||
import { IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
import { IMissionInventoryUpdateRequest } from "../types/requestTypes";
|
||||||
import { logger } from "@/src/utils/logger";
|
import { logger } from "@/src/utils/logger";
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { getWeaponType, parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
|
import { parseSlotPurchaseName } from "@/src/helpers/purchaseHelpers";
|
||||||
|
import { getWeaponType } from "@/src/services/itemDataService";
|
||||||
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
|
import { getSubstringFromKeyword } from "@/src/helpers/stringHelpers";
|
||||||
import {
|
import {
|
||||||
addBooster,
|
addBooster,
|
||||||
|
74
src/services/recipeService.ts
Normal file
74
src/services/recipeService.ts
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
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 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);
|
||||||
|
|
||||||
|
const inventory = await getInventory(accountId);
|
||||||
|
inventory.PendingRecipes.push({
|
||||||
|
ItemType: recipeName,
|
||||||
|
CompletionDate: completionDate,
|
||||||
|
_id: new Types.ObjectId()
|
||||||
|
});
|
||||||
|
|
||||||
|
const newInventory = await inventory.save();
|
||||||
|
|
||||||
|
return {
|
||||||
|
RecipeId: { $oid: newInventory.PendingRecipes[newInventory.PendingRecipes.length - 1]._id?.toString() }
|
||||||
|
};
|
||||||
|
};
|
@ -14,11 +14,13 @@ import { IOperatorLoadOutSigcol, IWeaponDatabase } from "@/src/types/inventoryTy
|
|||||||
|
|
||||||
//Document extends will be deleted soon. TODO: delete and migrate uses to ...
|
//Document extends will be deleted soon. TODO: delete and migrate uses to ...
|
||||||
export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {}
|
export interface IInventoryDatabaseDocument extends IInventoryDatabase, Document {}
|
||||||
export interface IInventoryDatabase extends Omit<IInventoryResponse, "TrainingDate" | "LoadOutPresets" | "Mailbox"> {
|
export interface IInventoryDatabase
|
||||||
|
extends Omit<IInventoryResponse, "TrainingDate" | "LoadOutPresets" | "Mailbox" | "PendingRecipes"> {
|
||||||
accountOwnerId: Types.ObjectId;
|
accountOwnerId: Types.ObjectId;
|
||||||
TrainingDate: Date; // TrainingDate changed from IMongoDate to Date
|
TrainingDate: Date; // TrainingDate changed from IMongoDate to Date
|
||||||
LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population
|
LoadOutPresets: Types.ObjectId; // LoadOutPresets changed from ILoadOutPresets to Types.ObjectId for population
|
||||||
Mailbox: Types.ObjectId; // Mailbox changed from IMailbox to Types.ObjectId
|
Mailbox: Types.ObjectId; // Mailbox changed from IMailbox to Types.ObjectId
|
||||||
|
PendingRecipes: IPendingRecipe[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInventoryResponseDocument extends IInventoryResponse, Document {}
|
export interface IInventoryResponseDocument extends IInventoryResponse, Document {}
|
||||||
@ -41,6 +43,11 @@ export interface IMailbox {
|
|||||||
LastInboxId: IOid;
|
LastInboxId: IOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: perhaps split response and database into their own files
|
||||||
|
|
||||||
|
export interface IPendingRecipeResponse extends Omit<IPendingRecipe, "CompletionDate"> {
|
||||||
|
CompletionDate: IMongoDate;
|
||||||
|
}
|
||||||
export interface IInventoryResponse {
|
export interface IInventoryResponse {
|
||||||
Horses: IGenericItem[];
|
Horses: IGenericItem[];
|
||||||
DrifterMelee: IGenericItem[];
|
DrifterMelee: IGenericItem[];
|
||||||
@ -96,7 +103,7 @@ export interface IInventoryResponse {
|
|||||||
XPInfo: IEmailItem[];
|
XPInfo: IEmailItem[];
|
||||||
Recipes: IConsumable[];
|
Recipes: IConsumable[];
|
||||||
WeaponSkins: IWeaponSkin[];
|
WeaponSkins: IWeaponSkin[];
|
||||||
PendingRecipes: IPendingRecipe[];
|
PendingRecipes: IPendingRecipeResponse[];
|
||||||
TrainingDate: IMongoDate;
|
TrainingDate: IMongoDate;
|
||||||
PlayerLevel: number;
|
PlayerLevel: number;
|
||||||
Upgrades: ICrewShipSalvagedWeaponSkin[];
|
Upgrades: ICrewShipSalvagedWeaponSkin[];
|
||||||
@ -816,7 +823,7 @@ export interface IPendingCoupon {
|
|||||||
|
|
||||||
export interface IPendingRecipe {
|
export interface IPendingRecipe {
|
||||||
ItemType: string;
|
ItemType: string;
|
||||||
CompletionDate: IMongoDate;
|
CompletionDate: Date;
|
||||||
ItemId: IOid;
|
ItemId: IOid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import Items, { Category, Item, Warframe, Weapon } from "warframe-items";
|
|
||||||
|
|
||||||
type MinWeapon = Omit<Weapon, "patchlogs">;
|
|
||||||
type MinItem = Omit<Item, "patchlogs">;
|
|
||||||
|
|
||||||
export const weapons: MinWeapon[] = (new Items({ category: ["Primary", "Secondary", "Melee"] }) as Weapon[]).map(
|
|
||||||
item => {
|
|
||||||
const next = { ...item };
|
|
||||||
delete next.patchlogs;
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const items: MinItem[] = new Items({ category: ["All"] }).map(item => {
|
|
||||||
const next = { ...item };
|
|
||||||
delete next.patchlogs;
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getNamesObj = (category: Category) =>
|
|
||||||
new Items({ category: [category] }).reduce((acc, item) => {
|
|
||||||
acc[item.name!.replace("'S", "'s")] = item.uniqueName!;
|
|
||||||
return acc;
|
|
||||||
}, {} as ImportAssertions);
|
|
||||||
|
|
||||||
export const modNames = getNamesObj("Mods");
|
|
||||||
export const resourceNames = getNamesObj("Resources");
|
|
||||||
export const miscNames = getNamesObj("Misc");
|
|
||||||
export const relicNames = getNamesObj("Relics");
|
|
||||||
export const skinNames = getNamesObj("Skins");
|
|
||||||
export const arcaneNames = getNamesObj("Arcanes");
|
|
||||||
export const gearNames = getNamesObj("Gear");
|
|
||||||
|
|
||||||
export const craftNames: ImportAssertions = Object.fromEntries(
|
|
||||||
(
|
|
||||||
new Items({
|
|
||||||
category: [
|
|
||||||
"Warframes",
|
|
||||||
"Gear",
|
|
||||||
"Melee",
|
|
||||||
"Primary",
|
|
||||||
"Secondary",
|
|
||||||
"Sentinels",
|
|
||||||
"Misc",
|
|
||||||
"Arch-Gun",
|
|
||||||
"Arch-Melee"
|
|
||||||
]
|
|
||||||
}) as Warframe[]
|
|
||||||
)
|
|
||||||
.flatMap(item => item.components || [])
|
|
||||||
.filter(item => item.drops && item.drops[0])
|
|
||||||
.map(item => [item.drops![0].type, item.uniqueName])
|
|
||||||
);
|
|
||||||
craftNames["Forma Blueprint"] = "/Lotus/Types/Recipes/Components/FormaBlueprint";
|
|
||||||
|
|
||||||
export const blueprintNames: ImportAssertions = Object.fromEntries(
|
|
||||||
Object.keys(craftNames)
|
|
||||||
.filter(name => name.includes("Blueprint"))
|
|
||||||
.map(name => [name, craftNames[name]])
|
|
||||||
);
|
|
Loading…
x
Reference in New Issue
Block a user