diff --git a/package-lock.json b/package-lock.json index d2ca4c16..8bceb7d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "copyfiles": "^2.4.1", "express": "^5.0.0-beta.3", "mongoose": "^8.1.1", - "warframe-public-export-plus": "^0.3.3", + "warframe-public-export-plus": "^0.4.0", "warframe-riven-info": "^0.1.0", "winston": "^3.11.0", "winston-daily-rotate-file": "^4.7.1" @@ -3669,9 +3669,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.3.3.tgz", - "integrity": "sha512-35pSMqXxe9vG4kdA+SnCyZyWO8zRGuPQbNeOPgZm5886kiujR+Qd6iY7TH0fdQYgKCk1M+q8lXonATT9VB9bbQ==" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.4.0.tgz", + "integrity": "sha512-8wOkh9dET4IHmHDSZ8g8RW0GlfEevHnBwEETAqy3jRhwssyF0TgQsOOpJVuhcPKedCYeudR92HJ3JoXoiTCr6A==" }, "node_modules/warframe-riven-info": { "version": "0.1.0", diff --git a/package.json b/package.json index f5b472df..522d03c4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "copyfiles": "^2.4.1", "express": "^5.0.0-beta.3", "mongoose": "^8.1.1", - "warframe-public-export-plus": "^0.3.3", + "warframe-public-export-plus": "^0.4.0", "warframe-riven-info": "^0.1.0", "winston": "^3.11.0", "winston-daily-rotate-file": "^4.7.1" diff --git a/src/controllers/api/focusController.ts b/src/controllers/api/focusController.ts index 2558e3c2..0d48f3c0 100644 --- a/src/controllers/api/focusController.ts +++ b/src/controllers/api/focusController.ts @@ -1,6 +1,6 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { getInventory, addMiscItems } from "@/src/services/inventoryService"; +import { getInventory, addMiscItems, addEquipment } from "@/src/services/inventoryService"; import { IMiscItem, TFocusPolarity } from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; import { ExportFocusUpgrades } from "warframe-public-export-plus"; @@ -74,6 +74,17 @@ export const focusController: RequestHandler = async (req, res) => { }); break; } + case FocusOperation.SentTrainingAmplifier: { + const request = JSON.parse(String(req.body)) as ISentTrainingAmplifierRequest; + const parts: string[] = [ + "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingGrip", + "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingChassis", + "/Lotus/Weapons/Sentients/OperatorAmplifiers/SentTrainingAmplifier/SentAmpTrainingBarrel" + ]; + const result = await addEquipment("OperatorAmps", request.StartingWeaponType, accountId, parts); + res.json(result); + break; + } case FocusOperation.UnbindUpgrade: { const request = JSON.parse(String(req.body)) as IUnbindUpgradeRequest; const focusPolarity = focusTypeToPolarity(request.FocusTypes[0]); @@ -137,6 +148,7 @@ enum FocusOperation { UnlockUpgrade = "3", LevelUpUpgrade = "4", ActivateWay = "5", + SentTrainingAmplifier = "7", UnbindUpgrade = "8", ConvertShard = "9" } @@ -170,6 +182,10 @@ interface IConvertShardRequest { Polarity: TFocusPolarity; } +interface ISentTrainingAmplifierRequest { + StartingWeaponType: string; +} + // Works for ways & upgrades const focusTypeToPolarity = (type: string): TFocusPolarity => { return ("AP_" + type.substr(1).split("/")[3].toUpperCase()) as TFocusPolarity; diff --git a/src/controllers/api/modularWeaponCraftingController.ts b/src/controllers/api/modularWeaponCraftingController.ts index 00a776d8..f9d6198e 100644 --- a/src/controllers/api/modularWeaponCraftingController.ts +++ b/src/controllers/api/modularWeaponCraftingController.ts @@ -1,17 +1,18 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { WeaponTypeInternal } from "@/src/services/itemDataService"; -import { getInventory, updateCurrency, addWeapon, addMiscItems } from "@/src/services/inventoryService"; +import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { getInventory, updateCurrency, addEquipment, addMiscItems } from "@/src/services/inventoryService"; -const modularWeaponTypes: Record = { +const modularWeaponTypes: Record = { "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimaryBeam": "LongGuns", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondary": "Pistols", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryBeam": "Pistols", "/Lotus/Weapons/SolarisUnited/Secondary/LotusModularSecondaryShotgun": "Pistols", "/Lotus/Weapons/Ostron/Melee/LotusModularWeapon": "Melee", "/Lotus/Weapons/Sentients/OperatorAmplifiers/OperatorAmpWeapon": "OperatorAmps", - "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": "Hoverboards" + "/Lotus/Types/Vehicles/Hoverboard/HoverboardSuit": "Hoverboards", + "/Lotus/Types/Friendly/Pets/MoaPets/MoaPetPowerSuit": "MoaPets" }; interface IModularCraftRequest { @@ -29,10 +30,14 @@ export const modularWeaponCraftingController: RequestHandler = async (req, res) const category = modularWeaponTypes[data.WeaponType]; // Give weapon - const weapon = await addWeapon(category, data.WeaponType, accountId, data.Parts); + const weapon = await addEquipment(category, data.WeaponType, accountId, data.Parts); // Remove credits - const currencyChanges = await updateCurrency(category == "Hoverboards" ? 5000 : 4000, false, accountId); + const currencyChanges = await updateCurrency( + category == "Hoverboards" || category == "MoaPets" ? 5000 : 4000, + false, + accountId + ); // Remove parts const miscItemChanges = []; diff --git a/src/controllers/custom/addItemController.ts b/src/controllers/custom/addItemController.ts index 4f01df94..7488710f 100644 --- a/src/controllers/custom/addItemController.ts +++ b/src/controllers/custom/addItemController.ts @@ -1,7 +1,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { ItemType, toAddItemRequest } from "@/src/helpers/customHelpers/addItemHelpers"; import { getWeaponType } from "@/src/services/itemDataService"; -import { addPowerSuit, addWeapon } from "@/src/services/inventoryService"; +import { addPowerSuit, addEquipment } from "@/src/services/inventoryService"; import { RequestHandler } from "express"; // eslint-disable-next-line @typescript-eslint/no-misused-promises @@ -16,7 +16,7 @@ const addItemController: RequestHandler = async (req, res) => { return; case ItemType.Weapon: const weaponType = getWeaponType(request.InternalName); - const weapon = await addWeapon(weaponType, request.InternalName, accountId); + const weapon = await addEquipment(weaponType, request.InternalName, accountId); res.json(weapon); break; default: diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 085238d3..487600de 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -985,6 +985,7 @@ type InventoryDocumentProps = { SpaceMelee: Types.DocumentArray; SentinelWeapons: Types.DocumentArray; Hoverboards: Types.DocumentArray; + MoaPets: Types.DocumentArray; WeaponSkins: Types.DocumentArray; }; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 5d422f03..81a35dae 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -17,7 +17,9 @@ import { IWeaponSkinClient, IDefaultUpgrade, KubrowPetEggItemType, - IKubrowPetEgg + IKubrowPetEgg, + TEquipmentKey, + equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; import { IGenericUpdate } from "../types/genericUpdate"; import { @@ -27,7 +29,7 @@ import { IUpdateChallengeProgressRequest } from "../types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { WeaponTypeInternal, getWeaponType, getExalted } from "@/src/services/itemDataService"; +import { getWeaponType, getExalted } from "@/src/services/itemDataService"; import { ISyndicateSacrifice, ISyndicateSacrificeResponse } from "../types/syndicateTypes"; import { IEquipmentClient, IEquipmentDatabase } from "../types/inventoryTypes/commonInventoryTypes"; import { @@ -277,7 +279,7 @@ export const addItem = async ( break; case "Weapons": const weaponType = getWeaponType(typeName); - const weapon = await addWeapon(weaponType, typeName, accountId); + const weapon = await addEquipment(weaponType, typeName, accountId); await updateSlots(accountId, InventorySlot.WEAPONS, 0, 1); return { InventoryChanges: { @@ -285,6 +287,22 @@ export const addItem = async ( [weaponType]: [weapon] } }; + case "Upgrades": { + const inventory = await getInventory(accountId); + const changes = [ + { + ItemType: typeName, + ItemCount: quantity + } + ]; + addMods(inventory, changes); + await inventory.save(); + return { + InventoryChanges: { + ShipDecorations: changes + } + }; + } case "Objects": { // /Lotus/Objects/Tenno/Props/TnoLisetTextProjector (Note Beacon) const inventory = await getInventory(accountId); @@ -558,23 +576,23 @@ export const syndicateSacrifice = async ( return res; }; -export const addWeapon = async ( - weaponType: WeaponTypeInternal | "Hoverboards", - weaponName: string, +export const addEquipment = async ( + category: TEquipmentKey, + type: string, accountId: string, modularParts: string[] | undefined = undefined ): Promise => { const inventory = await getInventory(accountId); - const weaponIndex = inventory[weaponType].push({ - ItemType: weaponName, + const index = inventory[category].push({ + ItemType: type, Configs: [], XP: 0, ModularParts: modularParts }); const changedInventory = await inventory.save(); - return changedInventory[weaponType][weaponIndex - 1].toJSON(); + return changedInventory[category][index - 1].toJSON(); }; export const addCustomization = async (customizatonName: string, accountId: string): Promise => { @@ -594,7 +612,7 @@ export const addSkin = async (typeName: string, accountId: string): Promise { const category = inventory[categoryName]; @@ -751,8 +769,6 @@ const addMissionComplete = (inventory: IInventoryDatabaseDocument, { Tag, Comple } }; -const gearKeys = ["Suits", "Pistols", "LongGuns", "Melee"] as const; - export const missionInventoryUpdate = async (data: IMissionInventoryUpdateRequest, accountId: string) => { const { RawUpgrades, @@ -792,7 +808,7 @@ export const missionInventoryUpdate = async (data: IMissionInventoryUpdateReques }); // Gear XP - gearKeys.forEach(key => addGearExpByCategory(inventory, data[key], key)); + equipmentKeys.forEach(key => addGearExpByCategory(inventory, data[key], key)); // Incarnon Challenges if (data.EvolutionProgress) { @@ -810,6 +826,11 @@ export const missionInventoryUpdate = async (data: IMissionInventoryUpdateReques } } + // LastRegionPlayed + if (data.LastRegionPlayed) { + inventory.LastRegionPlayed = data.LastRegionPlayed; + } + // other addMods(inventory, RawUpgrades); addMiscItems(inventory, MiscItems); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index cf7b935d..3c049fa9 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -72,7 +72,9 @@ export const equipmentKeys = [ "SpaceSuits", "SpaceGuns", "SpaceMelee", - "Hoverboards" + "Hoverboards", + "OperatorAmps", + "MoaPets" ] as const; export type TEquipmentKey = (typeof equipmentKeys)[number]; @@ -86,6 +88,24 @@ export interface IMailbox { LastInboxId: IOid; } +export type TSolarMapRegion = + | "Earth" + | "Ceres" + | "Eris" + | "Europa" + | "Jupiter" + | "Mars" + | "Mercury" + | "Neptune" + | "Phobos" + | "Pluto" + | "Saturn" + | "Sedna" + | "Uranus" + | "Venus" + | "Void" + | "SolarMapDeimosName"; + //TODO: perhaps split response and database into their own files export interface IPendingRecipeResponse extends Omit { @@ -142,7 +162,7 @@ export interface IInventoryResponse { CurrentLoadOutIds: Array; Missions: IMission[]; RandomUpgradesIdentified?: number; - LastRegionPlayed: string; + LastRegionPlayed: TSolarMapRegion; XPInfo: ITypeXPItem[]; Recipes: ITypeCount[]; WeaponSkins: IWeaponSkinClient[]; diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index 120283ce..0dd0d414 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -12,7 +12,8 @@ import { IRawUpgrade, ISeasonChallenge, TEquipmentKey, - IQuestKeyDatabase + IQuestKeyDatabase, + TSolarMapRegion } from "./inventoryTypes/inventoryTypes"; export interface IArtifactsRequest { @@ -44,10 +45,19 @@ export interface IMissionInventoryUpdateRequest { rewardsMultiplier?: number; ActiveBoosters?: IBooster[]; AffiliationChanges?: IAffiliationChange[]; + Suits?: IEquipmentClient[]; LongGuns?: IEquipmentClient[]; Pistols?: IEquipmentClient[]; - Suits?: IEquipmentClient[]; Melee?: IEquipmentClient[]; + SpecialItems?: IEquipmentClient[]; + Sentinels?: IEquipmentClient[]; + SentinelWeapons?: IEquipmentClient[]; + SpaceSuits?: IEquipmentClient[]; + SpaceGuns?: IEquipmentClient[]; + SpaceMelee?: IEquipmentClient[]; + Hoverboards?: IEquipmentClient[]; + OperatorAmps?: IEquipmentClient[]; + MoaPets?: IEquipmentClient[]; FusionBundles?: ITypeCount[]; RawUpgrades?: IRawUpgrade[]; MiscItems?: IMiscItem[]; @@ -59,6 +69,7 @@ export interface IMissionInventoryUpdateRequest { Missions?: IMission; EvolutionProgress?: IEvolutionProgress[]; QuestKeys?: IQuestKeyDatabase[]; + LastRegionPlayed?: TSolarMapRegion; FusionPoints?: number; // Not a part of the request, but we put it in this struct as an intermediate storage. } diff --git a/static/webui/script.js b/static/webui/script.js index e6eaa7c9..ffabd833 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -676,12 +676,29 @@ function fetchSettings() { ); } +const uiConfigs = [ + "autoCreateAccount", + "skipStoryModeChoice", + "skipTutorial", + "unlockAllScans", + "unlockAllMissions", + "unlockAllQuests", + "completeAllQuests", + "infiniteResources", + "unlockAllShipFeatures", + "unlockAllShipDecorations", + "unlockAllFlavourItems", + "unlockAllSkins", + "universalPolarityEverywhere", + "spoofMasteryRank" +]; + function doChangeSettings() { fetch("/custom/config") .then(response => response.json()) .then(json => { - for (var i in json) { - var x = document.getElementById(`${i}`); + for (const i of uiConfigs) { + var x = document.getElementById(i); if (x != null) { if (x.type == "checkbox") { if (x.checked === true) { diff --git a/static/webui/style.css b/static/webui/style.css index 341588cd..a78037e0 100644 --- a/static/webui/style.css +++ b/static/webui/style.css @@ -27,3 +27,8 @@ td.text-end > a > svg { margin-left: 0.5em; margin-bottom: 4px; /* to centre the icon */ } + +/* if an item name is super long, ensure it doesn't prevent the user from using actions */ +.card-body { + overflow: auto; +}