diff --git a/.prettierignore b/.prettierignore index 7b977582..ab38eac9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ static/webui/libs/ +*.html diff --git a/src/controllers/api/gildWeaponController.ts b/src/controllers/api/gildWeaponController.ts new file mode 100644 index 00000000..0b77513f --- /dev/null +++ b/src/controllers/api/gildWeaponController.ts @@ -0,0 +1,66 @@ +import { RequestHandler } from "express"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { getInventory } from "@/src/services/inventoryService"; +import { WeaponTypeInternal } from "@/src/services/itemDataService"; +import { ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; + +const modularWeaponCategory: (WeaponTypeInternal | "Hoverboards")[] = [ + "LongGuns", + "Pistols", + "Melee", + "OperatorAmps", + "Hoverboards" // Not sure about hoverboards just coppied from modual crafting +]; + +interface IGildWeaponRequest { + ItemName: string; + Recipe: string; // /Lotus/Weapons/SolarisUnited/LotusGildKitgunBlueprint + PolarizeSlot?: number; + PolarizeValue?: ArtifactPolarity; + ItemId: string; + Category: WeaponTypeInternal | "Hoverboards"; +} + +// In export there no recipes for gild action, so reputation and ressources only consumed visually + +// eslint-disable-next-line @typescript-eslint/no-misused-promises +export const gildWeaponController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const data: IGildWeaponRequest = getJSONfromString(String(req.body)); + data.ItemId = String(req.query.ItemId); + if (!modularWeaponCategory.includes(req.query.Category as WeaponTypeInternal | "Hoverboards")) { + throw new Error(`Unknown modular weapon Category: ${req.query.Category}`); + } + data.Category = req.query.Category as WeaponTypeInternal | "Hoverboards"; + + const inventory = await getInventory(accountId); + if (!inventory[data.Category]) { + throw new Error(`Category ${req.query.Category} not found in inventory`); + } + const weaponIndex = inventory[data.Category].findIndex(x => String(x._id) === data.ItemId); + if (weaponIndex === -1) { + throw new Error(`Weapon with ${data.ItemId} not found in category ${req.query.Category}`); + } + + const weapon = inventory[data.Category][weaponIndex]; + weapon.Features = EquipmentFeatures.GILDED; // maybe 9 idk if DOUBLE_CAPACITY is also given + weapon.ItemName = data.ItemName; + weapon.XP = 0; + if (data.Category != "OperatorAmps" && data.PolarizeSlot && data.PolarizeValue) { + weapon.Polarity = [ + { + Slot: data.PolarizeSlot, + Value: data.PolarizeValue + } + ]; + } + inventory[data.Category][weaponIndex] = weapon; + await inventory.save(); + + res.json({ + InventoryChanges: { + [data.Category]: [weapon] + } + }); +}; diff --git a/src/controllers/api/giveKeyChainTriggeredItemsController.ts b/src/controllers/api/giveKeyChainTriggeredItemsController.ts index 7189775c..a04f9bd2 100644 --- a/src/controllers/api/giveKeyChainTriggeredItemsController.ts +++ b/src/controllers/api/giveKeyChainTriggeredItemsController.ts @@ -7,7 +7,7 @@ import { IGiveKeyChainTriggeredItemsRequest } from "@/src/types/questTypes"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const giveKeyChainTriggeredItemsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const payload = getJSONfromString(req.body as string) as IGiveKeyChainTriggeredItemsRequest; + const payload = getJSONfromString(String(req.body)) as IGiveKeyChainTriggeredItemsRequest; const result = await giveKeyChainTriggeredItems(accountId, payload.KeyChain, payload.ChainStage); if (result) res.json(result); else res.json({}); diff --git a/src/controllers/api/giveKeyChainTriggeredMessageController.ts b/src/controllers/api/giveKeyChainTriggeredMessageController.ts index 3e4b6334..04cd715b 100644 --- a/src/controllers/api/giveKeyChainTriggeredMessageController.ts +++ b/src/controllers/api/giveKeyChainTriggeredMessageController.ts @@ -7,7 +7,7 @@ import { IGiveKeyChainTriggeredMessageRequest } from "@/src/types/questTypes"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const giveKeyChainTriggeredMessageController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const payload = getJSONfromString(req.body as string) as IGiveKeyChainTriggeredMessageRequest; + const payload = getJSONfromString(String(req.body)) as IGiveKeyChainTriggeredMessageRequest; const result = giveKeyChainTriggeredMessage(accountId, payload.KeyChain, payload.ChainStage); if (result != null) res.json(result); else res.status(200).end(); diff --git a/src/controllers/api/hostSessionController.ts b/src/controllers/api/hostSessionController.ts index 94ca633a..b8e65780 100644 --- a/src/controllers/api/hostSessionController.ts +++ b/src/controllers/api/hostSessionController.ts @@ -7,7 +7,7 @@ import { ISession } from "@/src/types/session"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const hostSessionController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const hostSessionRequest = JSON.parse(req.body as string) as ISession; + const hostSessionRequest = JSON.parse(String(req.body)) as ISession; logger.debug("HostSession Request", { hostSessionRequest }); const session = createNewSession(hostSessionRequest, accountId); logger.debug(`New Session Created`, { session }); diff --git a/src/controllers/api/inventorySlotsController.ts b/src/controllers/api/inventorySlotsController.ts index b026077b..c4701dce 100644 --- a/src/controllers/api/inventorySlotsController.ts +++ b/src/controllers/api/inventorySlotsController.ts @@ -21,7 +21,7 @@ import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; // eslint-disable-next-line @typescript-eslint/no-misused-promises export const inventorySlotsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - //const body = JSON.parse(req.body as string) as IInventorySlotsRequest; + //const body = JSON.parse(String(req.body)) as IInventorySlotsRequest; //console.log(body); diff --git a/src/controllers/api/saveLoadout.ts b/src/controllers/api/saveLoadout.ts index e5c180ed..64570329 100644 --- a/src/controllers/api/saveLoadout.ts +++ b/src/controllers/api/saveLoadout.ts @@ -10,7 +10,7 @@ export const saveLoadoutController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); try { - const body: ISaveLoadoutRequest = JSON.parse(req.body as string) as ISaveLoadoutRequest; + const body: ISaveLoadoutRequest = JSON.parse(String(req.body)) as ISaveLoadoutRequest; // console.log(util.inspect(body, { showHidden: false, depth: null, colors: true })); // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/controllers/api/setShipCustomizationsController.ts b/src/controllers/api/setShipCustomizationsController.ts index 8e78b1c3..5cc00ec3 100644 --- a/src/controllers/api/setShipCustomizationsController.ts +++ b/src/controllers/api/setShipCustomizationsController.ts @@ -6,7 +6,7 @@ import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises export const setShipCustomizationsController: RequestHandler = async (req, res) => { try { - const setShipCustomizationsRequest = JSON.parse(req.body as string) as ISetShipCustomizationsRequest; + const setShipCustomizationsRequest = JSON.parse(String(req.body)) as ISetShipCustomizationsRequest; const setShipCustomizationsResponse = await setShipCustomizations(setShipCustomizationsRequest); res.json(setShipCustomizationsResponse); diff --git a/src/controllers/api/shipDecorationsController.ts b/src/controllers/api/shipDecorationsController.ts index 414bd5a2..f3234ba2 100644 --- a/src/controllers/api/shipDecorationsController.ts +++ b/src/controllers/api/shipDecorationsController.ts @@ -7,7 +7,7 @@ import { handleSetShipDecorations } from "@/src/services/shipCustomizationsServi // eslint-disable-next-line @typescript-eslint/no-misused-promises export const shipDecorationsController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const shipDecorationsRequest = JSON.parse(req.body as string) as IShipDecorationsRequest; + const shipDecorationsRequest = JSON.parse(String(req.body)) as IShipDecorationsRequest; try { const placedDecoration = await handleSetShipDecorations(accountId, shipDecorationsRequest); diff --git a/src/controllers/api/unlockShipFeatureController.ts b/src/controllers/api/unlockShipFeatureController.ts index 430e3a85..822cb3a9 100644 --- a/src/controllers/api/unlockShipFeatureController.ts +++ b/src/controllers/api/unlockShipFeatureController.ts @@ -12,7 +12,7 @@ export interface IUnlockShipFeatureRequest { export const unlockShipFeatureController: RequestHandler = async (req, res) => { const accountId = parseString(req.query.accountId); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call - const shipFeatureRequest = JSON.parse(req.body as string) as IUnlockShipFeatureRequest; + const shipFeatureRequest = JSON.parse(String(req.body)) as IUnlockShipFeatureRequest; await unlockShipFeature(accountId, shipFeatureRequest.Feature); res.send([]); }; diff --git a/src/controllers/api/updateQuestController.ts b/src/controllers/api/updateQuestController.ts index 31b410fb..c43a3716 100644 --- a/src/controllers/api/updateQuestController.ts +++ b/src/controllers/api/updateQuestController.ts @@ -7,7 +7,7 @@ import { updateQuest } from "@/src/services/questService"; // eslint-disable-next-line @typescript-eslint/no-misused-promises const updateQuestController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const payload = getJSONfromString(req.body as string) as IUpdateQuestRequest; + const payload = getJSONfromString(String(req.body)) as IUpdateQuestRequest; const result = await updateQuest(accountId, payload); res.json(result); }; diff --git a/src/controllers/stats/viewController.ts b/src/controllers/stats/viewController.ts index 3d6b9e20..cae180ce 100644 --- a/src/controllers/stats/viewController.ts +++ b/src/controllers/stats/viewController.ts @@ -3,7 +3,6 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; import { IStatsView } from "@/src/types/statTypes"; import { config } from "@/src/services/configService"; -import view from "@/static/fixed_responses/view.json"; import allScans from "@/static/fixed_responses/allScans.json"; // eslint-disable-next-line @typescript-eslint/no-misused-promises @@ -15,7 +14,7 @@ const viewController: RequestHandler = async (req, res) => { return; } - const responseJson: IStatsView = view; + const responseJson: IStatsView = {}; responseJson.Weapons = []; for (const item of inventory.XPInfo) { responseJson.Weapons.push({ diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index bcd02868..3a6c2b1c 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -36,9 +36,10 @@ import { IPeriodicMissionCompletionDatabase, IPeriodicMissionCompletionResponse, ILoreFragmentScan, - IEvolutionProgress -} from "../../types/inventoryTypes/inventoryTypes"; -import { IOid } from "../../types/commonTypes"; + IEvolutionProgress, + IDefaultUpgrade +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { IOid } from "@/src/types/commonTypes"; import { IAbilityOverride, IColor, @@ -634,6 +635,7 @@ const inventorySchema = new Schema( DailyAffiliationNecraloid: Number, DailyAffiliationZariman: Number, DailyAffiliationKahl: Number, + DailyAffiliationCavia: Number, //Daily Focus limit DailyFocus: Number, @@ -966,7 +968,7 @@ type InventoryDocumentProps = { OperatorAmps: Types.DocumentArray; FlavourItems: Types.DocumentArray; RawUpgrades: Types.DocumentArray; - Upgrades: Types.DocumentArray; + Upgrades: Types.DocumentArray; MiscItems: Types.DocumentArray; Boosters: Types.DocumentArray; OperatorLoadOuts: Types.DocumentArray; diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index a0cd68e1..30a22c90 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -27,13 +27,16 @@ const EquipmentSelectionSchema = new Schema( const loadoutConfigSchema = new Schema( { + FocusSchool: String, PresetIcon: String, Favorite: Boolean, - n: String, - s: EquipmentSelectionSchema, - p: EquipmentSelectionSchema, - l: EquipmentSelectionSchema, - m: EquipmentSelectionSchema + n: String, // Loadout name + s: EquipmentSelectionSchema, // Suit + l: EquipmentSelectionSchema, // Primary weapon + p: EquipmentSelectionSchema, // Secondary weapon + m: EquipmentSelectionSchema, // Melee weapon + h: EquipmentSelectionSchema, // Gravimag weapon + a: EquipmentSelectionSchema // Necromech exalted weapon }, { id: false diff --git a/src/routes/api.ts b/src/routes/api.ts index ef23f221..5196042c 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -64,6 +64,7 @@ import { updateQuestController } from "@/src/controllers/api/updateQuestControll import { updateSessionGetController, updateSessionPostController } from "@/src/controllers/api/updateSessionController"; import { updateThemeController } from "@/src/controllers/api/updateThemeController"; import { upgradesController } from "@/src/controllers/api/upgradesController"; +import { gildWeaponController } from "../controllers/api/gildWeaponController"; const apiRouter = express.Router(); @@ -111,6 +112,7 @@ apiRouter.post("/genericUpdate.php", genericUpdateController); apiRouter.post("/getAlliance.php", getAllianceController); apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController); apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController); +apiRouter.post("/gildWeapon.php", gildWeaponController); apiRouter.post("/guildTech.php", guildTechController); apiRouter.post("/hostSession.php", hostSessionController); apiRouter.post("/infestedFoundry.php", infestedFoundryController); diff --git a/src/routes/webui.ts b/src/routes/webui.ts index 93005f34..27ac95e5 100644 --- a/src/routes/webui.ts +++ b/src/routes/webui.ts @@ -19,15 +19,18 @@ webuiRouter.use("/webui", (req, res, next) => { }); // Serve virtual routes -webuiRouter.get("/webui/settings", (_req, res) => { - res.sendFile(path.join(rootDir, "static/webui/index.html")); -}); webuiRouter.get("/webui/inventory", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); webuiRouter.get("/webui/mods", (_req, res) => { res.sendFile(path.join(rootDir, "static/webui/index.html")); }); +webuiRouter.get("/webui/settings", (_req, res) => { + res.sendFile(path.join(rootDir, "static/webui/index.html")); +}); +webuiRouter.get("/webui/cheats", (_req, res) => { + res.sendFile(path.join(rootDir, "static/webui/index.html")); +}); // Serve static files webuiRouter.use("/webui", express.static(path.join(rootDir, "static/webui"))); diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 76d0656c..b1ab7d27 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -14,7 +14,10 @@ import { ISeasonChallenge, ITypeCount, InventorySlot, - IWeaponSkinClient + IWeaponSkinClient, + IDefaultUpgrade, + KubrowPetEggItemType, + IKubrowPetEgg } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -26,9 +29,10 @@ import { import { logger } from "@/src/utils/logger"; import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService"; import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes"; -import { IEquipmentClient } from "../types/inventoryTypes/commonInventoryTypes"; -import { ExportCustoms, ExportFlavour, ExportRecipes, ExportResources } from "warframe-public-export-plus"; +import { IEquipmentClient, IEquipmentDatabase } from "../types/inventoryTypes/commonInventoryTypes"; +import { ExportArcanes, ExportCustoms, ExportFlavour, ExportFusionBundles, ExportRecipes, ExportResources, ExportSentinels, ExportUpgrades } from "warframe-public-export-plus"; import { updateQuestKeys } from "./questService"; +import { toOid } from "../helpers/inventoryHelpers"; export const createInventory = async ( accountOwnerId: Types.ObjectId, @@ -75,6 +79,7 @@ export const addItem = async ( ): Promise<{ InventoryChanges: IInventoryChanges }> => { // Strict typing if (typeName in ExportRecipes) { + const recipe = ExportRecipes[typeName]; const inventory = await getInventory(accountId); const recipeChanges = [ { @@ -82,6 +87,13 @@ export const addItem = async ( ItemCount: quantity } satisfies ITypeCount ]; + recipe.ingredients.forEach(ingredient => { + const itemType = ingredient.ItemType.replace("Component", "Blueprint"); + recipeChanges.push({ + ItemType: itemType, + ItemCount: ingredient.ItemCount + } satisfies ITypeCount); + }); addRecipes(inventory, recipeChanges); await inventory.save(); return { @@ -92,19 +104,55 @@ export const addItem = async ( } if (typeName in ExportResources) { const inventory = await getInventory(accountId); - const miscItemChanges = [ - { - ItemType: typeName, - ItemCount: quantity - } satisfies IMiscItem - ]; - addMiscItems(inventory, miscItemChanges); - await inventory.save(); - return { - InventoryChanges: { - MiscItems: miscItemChanges + const resource = ExportResources[typeName]; + switch (resource.productCategory) { + case "MiscItems": { + const miscItemChanges = [ + { + ItemType: typeName, + ItemCount: quantity + } satisfies IMiscItem + ]; + addMiscItems(inventory, miscItemChanges); + await inventory.save(); + return { + InventoryChanges: { + MiscItems: miscItemChanges + } + }; } - }; + case "ShipDecorations": { + const changes = [ + { + ItemType: typeName, + ItemCount: quantity + } satisfies IMiscItem + ]; + addShipDecorations(inventory, changes); + await inventory.save(); + return { + InventoryChanges: { + ShipDecorations: changes + } + }; + } + case "KubrowPetEggs": { + const changes = [ + { + ItemId: toOid(new Types.ObjectId()), + ItemType: KubrowPetEggItemType.LotusTypesGameKubrowPetEggsKubrowEgg, + ExpirationDate: { $date: { $numberLong: "9999999999999" } } + } satisfies IKubrowPetEgg + ]; + inventory.KubrowPetEggs.push(...changes); + await inventory.save(); + return { + InventoryChanges: { + KubrowPetEggs: changes + } + }; + } + } } if (typeName in ExportCustoms) { return { @@ -120,6 +168,53 @@ export const addItem = async ( } }; } + if (typeName in ExportUpgrades) { + return { + InventoryChanges: { + Upgrades: [await addUpgrade(typeName, accountId)] + } + }; + } + + if (typeName in ExportFusionBundles) { + const inventory = await getInventory(accountId); + inventory.FusionPoints += ExportFusionBundles[typeName].fusionPoints; + await inventory.save(); + return { + InventoryChanges: { + FusionPoints: inventory.FusionPoints + } + }; + } + if (typeName in ExportArcanes) { + return { + InventoryChanges: { + Upgrades: [await addUpgrade(typeName, accountId)] + } + }; + } + if (typeName in ExportSentinels) { + const inventory = await getInventory(accountId); + const sentinelData = ExportSentinels[typeName]; + const sentinel = await addSentinel(typeName, accountId); + await updateSlots(accountId, InventorySlot.SENTINELS, 0, 1); + if (!inventory.SentinelWeapons.find(i => i.ItemType == (sentinelData.defaultWeapon as string))) { + const sentinelWeapon = await addSentinelWeapon(sentinelData.defaultWeapon as string, accountId); + return { + InventoryChanges: { + SentinelBin: { count: 1, platinum: 0, Slots: -1 }, + Sentinels: [sentinel], + SentinelWeapons: [sentinelWeapon] + } + }; + } + return { + InventoryChanges: { + SentinelBin: { count: 1, platinum: 0, Slots: -1 }, + Sentinels: [sentinel] + } + }; + } // Path-based duck typing switch (typeName.substring(1).split("/")[1]) { @@ -268,13 +363,20 @@ export const addItem = async ( }; //TODO: maybe genericMethod for all the add methods, they share a lot of logic -export const addSentinel = async (sentinelName: string, accountId: string) => { +export const addSentinel = async (sentinelName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const sentinelIndex = inventory.Sentinels.push({ ItemType: sentinelName, Configs: [], XP: 0 }); const changedInventory = await inventory.save(); return changedInventory.Sentinels[sentinelIndex - 1].toJSON(); }; +export const addSentinelWeapon = async (weaponName: string, accountId: string): Promise => { + const inventory = await getInventory(accountId); + const sentinelWeaponIndex = inventory.SentinelWeapons.push({ ItemType: weaponName, Configs: [], XP: 0 }); + const changedInventory = await inventory.save(); + return changedInventory.SentinelWeapons[sentinelWeaponIndex - 1].toJSON(); +}; + export const addPowerSuit = async (powersuitName: string, accountId: string): Promise => { const specialItems = getExalted(powersuitName); if (specialItems != false) { @@ -288,7 +390,7 @@ export const addPowerSuit = async (powersuitName: string, accountId: string): Pr return changedInventory.Suits[suitIndex - 1].toJSON(); }; -export const addMechSuit = async (mechsuitName: string, accountId: string) => { +export const addMechSuit = async (mechsuitName: string, accountId: string): Promise => { const specialItems = getExalted(mechsuitName); if (specialItems != false) { for await (const specialItem of specialItems) { @@ -301,7 +403,7 @@ export const addMechSuit = async (mechsuitName: string, accountId: string) => { return changedInventory.MechSuits[suitIndex - 1].toJSON(); }; -export const addSpecialItem = async (itemName: string, accountId: string) => { +export const addSpecialItem = async (itemName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const specialItemIndex = inventory.SpecialItems.push({ ItemType: itemName, @@ -314,7 +416,7 @@ export const addSpecialItem = async (itemName: string, accountId: string) => { return changedInventory.SpecialItems[specialItemIndex - 1].toJSON(); }; -export const addSpaceSuit = async (spacesuitName: string, accountId: string) => { +export const addSpaceSuit = async (spacesuitName: string, accountId: string): Promise => { const inventory = await getInventory(accountId); const suitIndex = inventory.SpaceSuits.push({ ItemType: spacesuitName, Configs: [], UpgradeVer: 101, XP: 0 }); const changedInventory = await inventory.save(); @@ -756,3 +858,17 @@ export const upgradeMod = async (artifactsData: IArtifactsRequest, accountId: st throw error; } }; + +export const addHerse = async (ItemType: string, accountId: string): Promise => { + const inventory = await getInventory(accountId); + const herseIndex = inventory.Horses.push({ ItemType: ItemType, Configs: [], UpgradeVer: 101 }); + const changedInventory = await inventory.save(); + return changedInventory.Horses[herseIndex - 1].toJSON(); +}; + +export const addUpgrade = async (ItemType: string, accountId: string): Promise => { + const inventory = await getInventory(accountId); + const upgradeIndex = inventory.Upgrades.push({ ItemType: ItemType, UpgradeFingerprint: "{}" }); + const changedInventory = await inventory.save(); + return changedInventory.Upgrades[upgradeIndex - 1].toJSON(); +}; diff --git a/src/types/inventoryTypes/commonInventoryTypes.ts b/src/types/inventoryTypes/commonInventoryTypes.ts index b1debf7a..f7026c0c 100644 --- a/src/types/inventoryTypes/commonInventoryTypes.ts +++ b/src/types/inventoryTypes/commonInventoryTypes.ts @@ -86,6 +86,7 @@ export enum EquipmentFeatures { DOUBLE_CAPACITY = 1, UTILITY_SLOT = 2, GRAVIMAG_INSTALLED = 4, + GILDED = 8, ARCANE_SLOT = 32, INCARNON_GENESIS = 512 } diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index c4b4ddfd..81952487 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -252,6 +252,7 @@ export interface IInventoryResponse { DailyAffiliationZariman: number; NemesisAbandonedRewards: string[]; DailyAffiliationKahl: number; + DailyAffiliationCavia: number; LastInventorySync: IOid; NextRefill: IMongoDate; // Next time argon crystals will have a decay tick FoundToday?: IMiscItem[]; // for Argon Crystals @@ -621,11 +622,11 @@ export interface ILoadoutConfigClient { Favorite?: boolean; n?: string; // Loadout name s?: IEquipmentSelection; // Suit - p?: IEquipmentSelection; + p?: IEquipmentSelection; // Secondary weapon l?: IEquipmentSelection; // Primary weapon m?: IEquipmentSelection; // Melee weapon h?: IEquipmentSelection; // Gravimag weapon - a?: IEquipmentSelection; + a?: IEquipmentSelection; // Necromech exalted weapon ItemId: IOid; Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove. } @@ -807,6 +808,13 @@ export interface IQuestProgress { b?: any[]; } +export interface IDefaultUpgrade { + ItemType: string; + UpgradeFingerprint?: string; + ItemId?: IOid; + _id?: Types.ObjectId; +} + export interface IRawUpgrade { ItemType: string; ItemCount: number; diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index 0d04114e..435b5c86 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -14,7 +14,7 @@ export interface IPurchaseParams { ExpectedPrice: number; } -export type IInventoryChanges = Record; +export type IInventoryChanges = Record; export type IBinChanges = { count: number; diff --git a/static/fixed_responses/login.json b/static/fixed_responses/login.json deleted file mode 100644 index 0967ef42..00000000 --- a/static/fixed_responses/login.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/static/fixed_responses/new_inventory.json b/static/fixed_responses/new_inventory.json index 8c112a7a..fb2e616e 100644 --- a/static/fixed_responses/new_inventory.json +++ b/static/fixed_responses/new_inventory.json @@ -101,6 +101,7 @@ "DailyAffiliationNecraloid": 16000, "DailyAffiliationZariman": 16000, "DailyAffiliationKahl": 16000, + "DailyAffiliationCavia": 16000, "DailyFocus": 250000, "GiftsRemaining": 8, "LibraryAvailableDailyTaskInfo": { diff --git a/static/fixed_responses/postTutorialInventory.json b/static/fixed_responses/postTutorialInventory.json index 53af6393..31160132 100644 --- a/static/fixed_responses/postTutorialInventory.json +++ b/static/fixed_responses/postTutorialInventory.json @@ -29,6 +29,7 @@ "DailyAffiliationVentkids": 16000, "DailyAffiliationVox": 16000, "DailyAffiliationZariman": 16000, + "DailyAffiliationCavia": 16000, "DailyFocus": 250000, "DuviriInfo": { "Seed": 5898912197983600352, "NumCompletions": 0 }, "GiftsRemaining": 8, diff --git a/static/fixed_responses/purchase.json b/static/fixed_responses/purchase.json deleted file mode 100644 index e9c27715..00000000 --- a/static/fixed_responses/purchase.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "InventoryChanges": { - "WeaponBin": { "count": 1, "platinum": 0, "Slots": -1 }, - "Suits": [ - { - "ItemType": "/Lotus/Powersuits/Ninja/Ninja", - "Configs": [], - "ItemId": { "$oid": "123123123123" } - } - ], - "RegularCredits": -25000 - } -} diff --git a/static/fixed_responses/upload.json b/static/fixed_responses/upload.json deleted file mode 100644 index 0967ef42..00000000 --- a/static/fixed_responses/upload.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/static/fixed_responses/view.json b/static/fixed_responses/view.json deleted file mode 100644 index 0967ef42..00000000 --- a/static/fixed_responses/view.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/static/json/scripts/missions-drop-table-get-script.js b/static/json/scripts/missions-drop-table-get-script.js deleted file mode 100644 index e80d6020..00000000 --- a/static/json/scripts/missions-drop-table-get-script.js +++ /dev/null @@ -1,273 +0,0 @@ -// for https://www.warframe.com/ru/droptables -/* eslint-disable */ -(() => { - const missionNames = { - "Mercury/Larunda Relay": "MercuryHUB", - "Venus/Vesper Relay": "VenusHUB", - "Earth/Strata Relay": "EarthHUB", - "Mars/Maroo's Bazaar": "TradeHUB1", - "Saturn/Kronia Relay": "SaturnHUB", - "Eris/Kuiper Relay": "ErisHUB", - "Europa/Leonov Relay": "EuropaHUB", - "Pluto/Orcus Relay": "PlutoHUB", - "Venus/Romula": "ClanNode0", - "Venus/Malva": "ClanNode1", - "Earth/Coba": "ClanNode2", - "Earth/Tikal": "ClanNode3", - "Jupiter/Sinai": "ClanNode4", - "Jupiter/Cameria": "ClanNode5", - "Europa/Larzac": "ClanNode6", - "Europa/Cholistan": "ClanNode7", - "Mars/Kadesh": "ClanNode8", - "Mars/Wahiba": "ClanNode9", - "Phobos/Memphis": "ClanNode10", - "Phobos/Zeugma": "ClanNode11", - "Saturn/Caracol": "ClanNode12", - "Saturn/Piscinas": "ClanNode13", - "Sedna/Amarna": "ClanNode14", - "Sedna/Sangeru": "ClanNode15", - "Uranus/Ur": "ClanNode16", - "Uranus/Assur": "ClanNode17", - "Eris/Akkad": "ClanNode18", - "Eris/Zabala": "ClanNode19", - "Neptune/Yursa": "ClanNode20", - "Neptune/Kelashin": "ClanNode21", - "Ceres/Seimeni": "ClanNode22", - "Ceres/Gabii": "ClanNode23", - "Pluto/Sechura": "ClanNode24", - "Pluto/Hieracon": "ClanNode25", - "Phobos/Roche": "SettlementNode1", - "Phobos/Skyresh": "SettlementNode2", - "Phobos/Stickney": "SettlementNode3", - "Phobos/Kepler": "SettlementNode10", - "Phobos/Gulliver": "SettlementNode11", - "Phobos/Monolith": "SettlementNode12", - "Phobos/Shklovsky": "SettlementNode14", - "Phobos/Sharpless": "SettlementNode15", - "Phobos/Iliad": "SettlementNode20", - "Neptune/Galatea": "SolNode1", - "Venus/Aphrodite": "SolNode2", - "Pluto/Acheron": "SolNode4", - "Neptune/Despina": "SolNode6", - "Uranus/Rosalind": "SolNode9", - "Jupiter/Thebe": "SolNode10", - "Mars/Tharsis": "SolNode11", - "Mercury/Elion": "SolNode12", - "Mars/Ultor": "SolNode14", - "Earth/Pacific": "SolNode15", - "Mars/Augustus": "SolNode16", - "Neptune/Proteus": "SolNode17", - "Saturn/Rhea": "SolNode18", - "Saturn/Enceladus": "SolNode19", - "Saturn/Telesto": "SolNode20", - "Pluto/Narcissus": "SolNode21", - "Venus/Tessera": "SolNode22", - "Venus/Cytherean": "SolNode23", - "Earth/Oro": "SolNode24", - "Jupiter/Callisto": "SolNode25", - "Earth/Lith": "SolNode26", - "Earth/E Prime": "SolNode27", - "Mercury/Terminus": "SolNode28", - "Mars/Olympus": "SolNode30", - "Saturn/Anthe": "SolNode31", - "Saturn/Tethys": "SolNode32", - "Uranus/Ariel": "SolNode33", - "Uranus/Sycorax": "SolNode34", - "Mars/Martialis": "SolNode36", - "Pluto/Minthe": "SolNode38", - "Earth/Everest": "SolNode39", - "Mars/Arval": "SolNode41", - "Saturn/Helene": "SolNode42", - "Pluto/Cerberus": "SolNode43", - "Mars/Ara": "SolNode45", - "Mars/Spear": "SolNode46", - "Pluto/Regna": "SolNode48", - "Neptune/Larissa": "SolNode49", - "Saturn/Numa": "SolNode50", - "Pluto/Hades": "SolNode51", - "Jupiter/Themisto": "SolNode53", - "Pluto/Cypress": "SolNode56", - "Neptune/Sao": "SolNode57", - "Mars/Hellas": "SolNode58", - "Earth/Eurasia": "SolNode59", - "Uranus/Caliban": "SolNode60", - "Venus/Ishtar": "SolNode61", - "Neptune/Neso": "SolNode62", - "Earth/Mantle": "SolNode63", - "Uranus/Umbriel": "SolNode64", - "Mars/Gradivus": "SolNode65", - "Venus/Unda": "SolNode66", - "Saturn/Dione": "SolNode67", - "Mars/Vallis": "SolNode68", - "Uranus/Ophelia": "SolNode69", - "Saturn/Cassini": "SolNode70", - "Pluto/Outer Terminus": "SolNode72", - "Jupiter/Ananke": "SolNode73", - "Jupiter/Carme": "SolNode74", - "Earth/Cervantes": "SolNode75", - "Pluto/Hydra": "SolNode76", - "Neptune/Triton": "SolNode78", - "Earth/Cambria": "SolNode79", - "Pluto/Palus": "SolNode81", - "Saturn/Calypso": "SolNode82", - "Uranus/Cressida": "SolNode83", - "Neptune/Nereid": "SolNode84", - "Earth/Gaia": "SolNode85", - "Jupiter/Ganymede": "SolNode87", - "Jupiter/Adrastea": "SolNode88", - "Earth/Mariana": "SolNode89", - "Saturn/Keeler": "SolNode93", - "Mercury/Apollodorus": "SolNode94", - "Saturn/Titan": "SolNode96", - "Jupiter/Amalthea": "SolNode97", - "Uranus/Desdemona": "SolNode98", - "Mars/War": "SolNode99", - "Jupiter/Elara": "SolNode100", - "Venus/Kiliken": "SolNode101", - "Pluto/Oceanum": "SolNode102", - "Mercury/M Prime": "SolNode103", - "Venus/Fossa": "SolNode104", - "Uranus/Titania": "SolNode105", - "Mars/Alator": "SolNode106", - "Venus/Venera": "SolNode107", - "Mercury/Tolstoj": "SolNode108", - "Venus/Linea": "SolNode109", - "Mars/Ares": "SolNode113", - "Uranus/Puck": "SolNode114", - "Neptune/Laomedeia": "SolNode118", - "Mercury/Caloris": "SolNode119", - "Jupiter/Carpo": "SolNode121", - "Uranus/Stephano": "SolNode122", - "Venus/V Prime": "SolNode123", - "Jupiter/Io": "SolNode125", - "Jupiter/Metis": "SolNode126", - "Neptune/Psamathe": "SolNode127", - "Venus/E Gate": "SolNode128", - "Venus/Orb Vallis": "SolNode129", - "Mercury/Lares": "SolNode130", - "Ceres/Pallas": "SolNode131", - "Ceres/Bode": "SolNode132", - "Ceres/Thon": "SolNode135", - "Ceres/Nuovo": "SolNode137", - "Ceres/Ludi": "SolNode138", - "Ceres/Lex": "SolNode139", - "Ceres/Kiste": "SolNode140", - "Ceres/Ker": "SolNode141", - "Ceres/Exta": "SolNode144", - "Ceres/Draco": "SolNode146", - "Ceres/Cinxia": "SolNode147", - "Ceres/Casta": "SolNode149", - "Eris/Brugia": "SolNode153", - "Eris/Isos": "SolNode162", - "Eris/Kala-azar": "SolNode164", - "Eris/Nimus": "SolNode166", - "Eris/Oestrus": "SolNode167", - "Eris/Saxis": "SolNode171", - "Eris/Xini": "SolNode172", - "Eris/Solium": "SolNode173", - "Eris/Naeglar": "SolNode175", - "Sedna/Kappa": "SolNode177", - "Sedna/Adaro": "SolNode181", - "Sedna/Vodyanoi": "SolNode183", - "Sedna/Rusalka": "SolNode184", - "Sedna/Berehynia": "SolNode185", - "Sedna/Selkie": "SolNode187", - "Sedna/Kelpie": "SolNode188", - "Sedna/Naga": "SolNode189", - "Sedna/Nakki": "SolNode190", - "Sedna/Marid": "SolNode191", - "Sedna/Merrow": "SolNode193", - "Sedna/Hydron": "SolNode195", - "Sedna/Charybdis": "SolNode196", - "Sedna/Yam": "SolNode199", - "Europa/Abaddon": "SolNode203", - "Europa/Armaros": "SolNode204", - "Europa/Baal": "SolNode205", - "Europa/Morax": "SolNode209", - "Europa/Naamah": "SolNode210", - "Europa/Ose": "SolNode211", - "Europa/Paimon": "SolNode212", - "Europa/Sorath": "SolNode214", - "Europa/Valac": "SolNode215", - "Europa/Valefor": "SolNode216", - "Europa/Orias": "SolNode217", - "Europa/Kokabiel": "SolNode220", - "Mercury/Boethius": "SolNode223", - "Mercury/Odin": "SolNode224", - "Mercury/Suisei": "SolNode225", - "Mercury/Pantheon": "SolNode226", - "Earth/Plains of Eidolon": "SolNode228", - "Deimos/Cambion Drift": "SolNode229", - "Lua/Plato": "SolNode300", - "Lua/Grimaldi": "SolNode301", - "Lua/Tycho": "SolNode302", - "Lua/Copernicus": "SolNode304", - "Lua/Stöfler": "SolNode305", - "Lua/Pavlov": "SolNode306", - "Lua/Zeipel": "SolNode307", - "Lua/Apollo": "SolNode308", - "Void/Teshub": "SolNode400", - "Void/Hepit": "SolNode401", - "Void/Taranis": "SolNode402", - "Void/Tiwaz": "SolNode403", - "Void/Stribog": "SolNode404", - "Void/Ani": "SolNode405", - "Void/Ukko": "SolNode406", - "Void/Oxomoco": "SolNode407", - "Void/Belenus": "SolNode408", - "Void/Mot": "SolNode409", - "Void/Aten": "SolNode410", - "Void/Marduk": "SolNode411", - "Void/Mithra": "SolNode412", - "undefined/Jordas Golem Assassinate": "SolNode701", - "undefined/Mutalist Alad V Assassinate": "SolNode705", - "Deimos/Horend": "SolNode706", - "Deimos/Hyf": "SolNode707", - "Deimos/Phlegyas": "SolNode708", - "Deimos/Dirus": "SolNode709", - "Deimos/Formido": "SolNode710", - "Deimos/Terrorem": "SolNode711", - "Deimos/Magnacidium": "SolNode712", - "Deimos/Exequias": "SolNode713", - "Jupiter/The Ropalolyst": "SolNode740", - "Kuva Fortress/Koro": "SolNode741", - "Kuva Fortress/Nabuk": "SolNode742", - "Kuva Fortress/Rotuma": "SolNode743", - "Kuva Fortress/Taveuni": "SolNode744", - "Kuva Fortress/Tamu": "SolNode745", - "Kuva Fortress/Dakata": "SolNode746", - "Kuva Fortress/Pago": "SolNode747", - "Kuva Fortress/Garus": "SolNode748", - "Venus/Montes": "SolNode902", - "Earth/Erpo": "SolNode903", - "Mars/Syrtis": "SolNode904", - "Jupiter/Galilea": "SolNode905", - "Saturn/Pandora": "SolNode906", - "Uranus/Caelus": "SolNode907" - }; - const result = {}; - let lastItem = []; - let lastItemIndex; - let rotation; - Array.from(document.querySelectorAll("table")[0].children[0].children).forEach(element => { - if (element.classList.contains("blank-row")) { - if (lastItemIndex) result[lastItemIndex] = lastItem; - lastItem = []; - lastItemIndex = undefined; - rotation = undefined; - } else if (element.children[0].getAttribute("colspan") == 2) { - if (!lastItemIndex) { - const mission = element.children[0].textContent; - const formatedMission = mission.substring(0, mission.indexOf(" (")); - lastItemIndex = missionNames[formatedMission]; - } else { - rotation = element.children[0].textContent.replace("Rotation ", ""); - } - } else { - const name = element.children[0].textContent; - const chance = parseFloat(element.children[1].textContent.match(/(\d+\.\d+)/)[0]); - lastItem.push({ chance, name, ...(rotation !== undefined && { rotation }) }); - } - }); - return JSON.stringify(result); -})(); diff --git a/static/webui/index.html b/static/webui/index.html index 037c5280..423c51a1 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -1,286 +1,269 @@ - - OpenWF WebUI - - - - - - -
-