From e7bf9733fbfb213ca5a119bb95489c6aac848e9d Mon Sep 17 00:00:00 2001 From: nrbdev Date: Thu, 20 Feb 2025 05:50:00 -0500 Subject: [PATCH 1/5] chore: send messages after completing quest --- src/services/inventoryService.ts | 40 ++++++++++++++++++++++++++++ static/fixed_responses/messages.json | 37 ------------------------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 8780e82f..cd793afd 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -47,6 +47,7 @@ import { ExportWeapons, TStandingLimitBin } from "warframe-public-export-plus"; +import { createMessage } from "./inboxService"; import { createShip } from "./shipService"; import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService"; import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; @@ -79,6 +80,45 @@ export const createInventory = async ( { ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" } ]; + // Give Darvo items that would be given after completing vors prize + await createMessage(String(accountOwnerId), [ + { + sub: "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", + sndr: "/Lotus/Language/Menu/Mailbox_WarframeSender", + msg: "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc", + icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png", + transmission: "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus", + highPriority: true, + r: false + }, + { + sub: "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", + sndr: "/Lotus/Language/Bosses/Darvo", + msg: "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc", + icon: "/Lotus/Interface/Icons/Npcs/Darvo.png", + countedAtt: [ + { + ItemCount: 1, + ItemType: "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" + }, + { + ItemCount: 1, + ItemType: "/Lotus/Types/Items/MiscItems/Morphic" + }, + { + ItemCount: 400, + ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle" + }, + { + ItemCount: 150, + ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate" + } + ], + highPriority: true, + r: false + } + ]); + // const vorsPrizeRewards = [ // // Vor's Prize rewards // { ItemCount: 1, ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarHealthMaxMod" }, diff --git a/static/fixed_responses/messages.json b/static/fixed_responses/messages.json index a67069c7..6ecf6d44 100644 --- a/static/fixed_responses/messages.json +++ b/static/fixed_responses/messages.json @@ -7,43 +7,6 @@ "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", "eventMessageDate": "2025-01-30T13:00:00.000Z", "r": false - }, - { - "sub": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", - "sndr": "/Lotus/Language/Bosses/Darvo", - "msg": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc", - "icon": "/Lotus/Interface/Icons/Npcs/Darvo.png", - "countedAtt": [ - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" - }, - { - "ItemCount": 1, - "ItemType": "/Lotus/Types/Items/MiscItems/Morphic" - }, - { - "ItemCount": 400, - "ItemType": "/Lotus/Types/Items/MiscItems/PolymerBundle" - }, - { - "ItemCount": 150, - "ItemType": "/Lotus/Types/Items/MiscItems/AlloyPlate" - } - ], - "highPriority": true, - "eventMessageDate": "2023-10-01T17:00:00.000Z", - "r": false - }, - { - "sub": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", - "sndr": "/Lotus/Language/Menu/Mailbox_WarframeSender", - "msg": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc", - "icon": "/Lotus/Interface/Icons/Npcs/Lotus_d.png", - "transmission": "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus", - "highPriority": true, - "eventMessageDate": "2023-09-01T17:00:00.000Z", - "r": false } ] } -- 2.47.2 From be9dec010796987c9444552c331735e94f28e133 Mon Sep 17 00:00:00 2001 From: nrbdev Date: Thu, 20 Feb 2025 05:45:33 -0500 Subject: [PATCH 2/5] feat: implement giveStartingGear --- src/controllers/api/giveStartingGear.ts | 207 ++++++++++++++++++++++++ src/routes/api.ts | 2 + 2 files changed, 209 insertions(+) create mode 100644 src/controllers/api/giveStartingGear.ts diff --git a/src/controllers/api/giveStartingGear.ts b/src/controllers/api/giveStartingGear.ts new file mode 100644 index 00000000..cbc7ebae --- /dev/null +++ b/src/controllers/api/giveStartingGear.ts @@ -0,0 +1,207 @@ +import { config } from "@/src/services/configService"; +import { toOid } from "@/src/helpers/inventoryHelpers"; +import { IOid } from "@/src/types/commonTypes"; +import { Types } from "mongoose"; +import { RequestHandler } from "express"; +import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { + IDailyAffiliations, + IInventoryClient, + IPlayerSkills, + ITypeCount +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { addConsumables, addKeyChainItems, addMods, getInventory } from "@/src/services/inventoryService"; +import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { getAccountIdForRequest } from "@/src/services/loginService"; + +export const giveStartingGearController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId); + + const dataJSON = getJSONfromString(String(req.body)); + + await addKeyChainItems(inventory, { + KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", + ChainStage: 0 + }); + + for (const key of Object.keys(dataJSON) as Array) { + switch (key) { + // This is the only gear we receive as the rest will come from future quests + case "LongGuns": + case "Pistols": + case "Melee": + case "Suits": + // Filter out already owned items (shouldnt happen but this was mostly for testing) + const existingItems = new Set(inventory[key].map(item => item.ItemType)); + + // Adding items to inventory + inventory[key].push( + ...dataJSON[key] + .filter(item => !existingItems.has(item.ItemType)) + .map(x => ({ + _id: new Types.ObjectId(), + ItemType: x.ItemType, + XP: x.XP, + Configs: [{}, {}, {}] + })) + ); + } + } + + addConsumables(inventory, [{ ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" }]); + if (!config.unlockAllFlavourItems) { + inventory.FlavourItems.push([ + { ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1" }, + { ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem2" }, + { ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem3" }, + { ItemType: "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem4" } + ]); + } + addMods(inventory, [ + { + ItemCount: 1, + ItemType: "/Lotus/Upgrades/Mods/Warframe/AvatarShieldMaxMod", + LastAdded: toOid(new Types.ObjectId()) + } + ]); + + inventory.DrifterMelee.push({ + ItemType: "/Lotus/Types/Friendly/PlayerControllable/Weapons/DuviriDualSwords", + _id: new Types.ObjectId() + }); + inventory.PlayedParkourTutorial = true; + inventory.ReceivedStartingGear = true; + inventory.TrainingDate = new Date(); + inventory.QuestKeys.push({ + Progress: [{ i: true }], + unlock: false, + ItemType: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain" + }); + await inventory.save(); + + res.json({}); +}; + +// Alot of stuff is not received in the request, instead of being redundant I will just omit an already created type (pain) +interface IStartingGearClient + extends Omit< + IInventoryClient, + | keyof IDailyAffiliations + | "Missions" + | "RandomUpgradesIdentified" + | "LastRegionPlayed" + | "TradesRemaining" + | "DailyFocus" + | "GiftsRemaining" + | "HasOwnedVoidProjectionsPreviously" + | "ChallengesFixVersion" + | "ChallengeProgress" + | "ReceivedStartingGear" + | "PendingRecipes" + | "PendingTrades" + | "DeathMarks" + | "WebFlags" + | "CompletedAlerts" + | "TauntHistory" + | "StoryModeChoice" + | "PeriodicMissionCompletions" + | "ActiveDojoColorResearch" + | "SentientSpawnChanceBoosters" + | "SupportedSyndicate" + | "Affiliations" + | "QualifyingInvasions" + | "FactionScores" + | "ArchwingEnabled" + | "PendingSpectreLoadouts" + | "SpectreLoadouts" + | "CompletedSyndicates" + | "FocusXP" + | "Alignment" + | "CompletedSorties" + | "LastSortieReward" + | "ActiveAvatarImageType" + | "DiscoveredMarkers" + | "CompletedJobs" + | "FocusAbility" + | "HasContributedToDojo" + | "HWIDProtectEnabled" + | "AlignmentReplay" + | "PersonalGoalProgress" + | "ThemeStyle" + | "ThemeBackground" + | "ThemeSounds" + | "BountyScore" + | "ChallengeInstanceStates" + | "LoginMilestoneRewards" + | "NodeIntrosCompleted" + | "GuildId" + | "CompletedJobChains" + | "SeasonChallengeHistory" + | "EquippedInstrument" + | "InvasionChainProgress" + | "NemesisHistory" + | "LastNemesisAllySpawnTime" + | "Settings" + | "PersonalTechProjects" + | "PlayerSkills" + | "TradeBannedUntil" + | "PlayedParkourTutorial" + | "SubscribedToEmailsPersonalized" + | "BlessingCooldown" + | "NemesisAbandonedRewards" + | "LastInventorySync" + | "NextRefill" + | "CustomMarkers" + | "ActiveLandscapeTraps" + | "EvolutionProgress" + | "RepVotes" + | "UsedDailyDeals" + | "LibraryPersonalTarget" + | "LibraryPersonalProgress" + | "CollectibleSeries" + | "LibraryAvailableDailyTaskInfo" + | "HasResetAccount" + | "PendingCoupon" + | "Harvestable" + | "DeathSquadable" + | "EndlessXP" + | "DialogueHistory" + > { + LongGuns: IStartingGearItem[]; + Melee: IStartingGearItem[]; + Pistols: IStartingGearItem[]; + Suits: IStartingGearItem[]; + XPLost?: unknown[]; + CrewShipFusionPoints?: number; + PlayerSkillGains?: IPlayerSkills[]; + // Lot's of unknown but these never receive data (at least not in this request) + StrippedItems?: unknown[]; + BonusMiscItems?: unknown[]; + EmailItems: ITypeCount[]; + OneTimePurchases?: unknown[]; + Rating?: number; + WishlistChanges?: unknown[]; + RecentVendorPurchases: (string | number)[]; + RemovedIdItems?: { ItemId: number }[]; + SongChallenges?: unknown[]; +} + +interface IStartingGearItem + extends Omit< + IEquipmentClient, + | "_id" + | "InfestationDate" + | "InfestationDays" + | "InfestationType" + | "UnlockLevel" + | "Weapon" + | "Customization" + | "RailjackImage" + | "CrewMembers" + | "Details" + > { + // Warframe sends an ItemId instead _id, it will be converted to _id before being pushed to the inventory + ItemId: IOid; + Favorite?: boolean; +} diff --git a/src/routes/api.ts b/src/routes/api.ts index 7ad9e5a6..ef353ebf 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -35,6 +35,7 @@ import { gildWeaponController } from "@/src/controllers/api/gildWeaponController import { giveKeyChainTriggeredItemsController } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { giveKeyChainTriggeredMessageController } from "@/src/controllers/api/giveKeyChainTriggeredMessageController"; import { giveQuestKeyRewardController } from "@/src/controllers/api/giveQuestKey"; +import { giveStartingGearController } from "../controllers/api/giveStartingGear"; import { guildTechController } from "../controllers/api/guildTechController"; import { hostSessionController } from "@/src/controllers/api/hostSessionController"; import { hubController } from "@/src/controllers/api/hubController"; @@ -146,6 +147,7 @@ apiRouter.post("/gildWeapon.php", gildWeaponController); apiRouter.post("/giveKeyChainTriggeredItems.php", giveKeyChainTriggeredItemsController); apiRouter.post("/giveKeyChainTriggeredMessage.php", giveKeyChainTriggeredMessageController); apiRouter.post("/giveQuestKeyReward.php", giveQuestKeyRewardController); +apiRouter.post("/giveStartingGear.php", giveStartingGearController); apiRouter.post("/guildTech.php", guildTechController); apiRouter.post("/hostSession.php", hostSessionController); apiRouter.post("/infestedFoundry.php", infestedFoundryController); -- 2.47.2 From 31ed3540f56a7ac1ae4c20e512b41724351b6292 Mon Sep 17 00:00:00 2001 From: nrbdev Date: Thu, 20 Feb 2025 05:58:14 -0500 Subject: [PATCH 3/5] moved --- src/controllers/api/giveStartingGear.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/controllers/api/giveStartingGear.ts b/src/controllers/api/giveStartingGear.ts index cbc7ebae..14aff5f3 100644 --- a/src/controllers/api/giveStartingGear.ts +++ b/src/controllers/api/giveStartingGear.ts @@ -20,11 +20,6 @@ export const giveStartingGearController: RequestHandler = async (req, res) => { const dataJSON = getJSONfromString(String(req.body)); - await addKeyChainItems(inventory, { - KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", - ChainStage: 0 - }); - for (const key of Object.keys(dataJSON) as Array) { switch (key) { // This is the only gear we receive as the rest will come from future quests @@ -49,6 +44,11 @@ export const giveStartingGearController: RequestHandler = async (req, res) => { } } + await addKeyChainItems(inventory, { + KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", + ChainStage: 0 + }); + addConsumables(inventory, [{ ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" }]); if (!config.unlockAllFlavourItems) { inventory.FlavourItems.push([ -- 2.47.2 From 4ccf8de801dc7c4db36384df9db39c85766a0c17 Mon Sep 17 00:00:00 2001 From: nrbdev Date: Thu, 20 Feb 2025 11:43:07 -0500 Subject: [PATCH 4/5] add comments --- src/controllers/api/giveStartingGear.ts | 3 ++- src/types/inventoryTypes/inventoryTypes.ts | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/controllers/api/giveStartingGear.ts b/src/controllers/api/giveStartingGear.ts index 14aff5f3..03e44dbb 100644 --- a/src/controllers/api/giveStartingGear.ts +++ b/src/controllers/api/giveStartingGear.ts @@ -44,9 +44,10 @@ export const giveStartingGearController: RequestHandler = async (req, res) => { } } + // Give the Arsenal Segment which is given after the Awakening. (MissionInventoryUpdate doesnt get called so we can't do it there) await addKeyChainItems(inventory, { KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", - ChainStage: 0 + ChainStage: 0 // /Lotus/Types/Keys/VorsPrize/MissionOne }); addConsumables(inventory, [{ ItemCount: 1, ItemType: "/Lotus/Types/Restoratives/LisetAutoHack" }]); diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index e27df725..ef2e826a 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -914,10 +914,10 @@ export interface IQuestKeyClient extends Omit Date: Thu, 20 Feb 2025 12:18:32 -0500 Subject: [PATCH 5/5] chore: use giveKeyChainMessage to send messages --- src/services/inventoryService.ts | 48 +++++++------------------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index cd793afd..6b26641c 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -47,11 +47,11 @@ import { ExportWeapons, TStandingLimitBin } from "warframe-public-export-plus"; -import { createMessage } from "./inboxService"; import { createShip } from "./shipService"; import { creditBundles, fusionBundles } from "@/src/services/missionInventoryUpdateService"; import { IKeyChainRequest } from "@/src/controllers/api/giveKeyChainTriggeredItemsController"; import { toOid } from "../helpers/inventoryHelpers"; +import { giveKeyChainMessage } from "./questService"; export const createInventory = async ( accountOwnerId: Types.ObjectId, @@ -81,43 +81,15 @@ export const createInventory = async ( ]; // Give Darvo items that would be given after completing vors prize - await createMessage(String(accountOwnerId), [ - { - sub: "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", - sndr: "/Lotus/Language/Menu/Mailbox_WarframeSender", - msg: "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc", - icon: "/Lotus/Interface/Icons/Npcs/Lotus_d.png", - transmission: "/Lotus/Sounds/Dialog/VorsPrize/DLisetPostAssassinate110Lotus", - highPriority: true, - r: false - }, - { - sub: "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", - sndr: "/Lotus/Language/Bosses/Darvo", - msg: "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc", - icon: "/Lotus/Interface/Icons/Npcs/Darvo.png", - countedAtt: [ - { - ItemCount: 1, - ItemType: "/Lotus/Types/Recipes/Weapons/BurstonRifleBlueprint" - }, - { - ItemCount: 1, - ItemType: "/Lotus/Types/Items/MiscItems/Morphic" - }, - { - ItemCount: 400, - ItemType: "/Lotus/Types/Items/MiscItems/PolymerBundle" - }, - { - ItemCount: 150, - ItemType: "/Lotus/Types/Items/MiscItems/AlloyPlate" - } - ], - highPriority: true, - r: false - } - ]); + await giveKeyChainMessage(inventory, String(accountOwnerId), { + KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", + ChainStage: 7 /* a.k.a { "title": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Title", "body": "/Lotus/Language/G1Quests/Beginner_Growth_Inbox_Desc" } */ + }); + + await giveKeyChainMessage(inventory, String(accountOwnerId), { + KeyChain: "/Lotus/Types/Keys/VorsPrize/VorsPrizeQuestKeyChain", + ChainStage: 6 /* a.k.a { "title": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBTitle", "body": "/Lotus/Language/Inbox/DarvoWeaponCraftingMessageBDesc" } */ + }); // const vorsPrizeRewards = [ // // Vor's Prize rewards -- 2.47.2