From f7f4b2042234da94ca65788afe06b2b88c3374ee Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:20:04 +0200 Subject: [PATCH 1/4] add updateEntratiVault --- .../api/entratiLabConquestModeController.ts | 25 +++---------------- src/services/inventoryService.ts | 23 +++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/controllers/api/entratiLabConquestModeController.ts b/src/controllers/api/entratiLabConquestModeController.ts index e5b6c818..c16595ee 100644 --- a/src/controllers/api/entratiLabConquestModeController.ts +++ b/src/controllers/api/entratiLabConquestModeController.ts @@ -1,6 +1,6 @@ import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; -import { getInventory } from "@/src/services/inventoryService"; +import { getInventory, updateEntratiVault } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { RequestHandler } from "express"; @@ -11,26 +11,7 @@ export const entratiLabConquestModeController: RequestHandler = async (req, res) "EntratiVaultCountResetDate EntratiVaultCountLastPeriod EntratiLabConquestUnlocked EchoesHexConquestUnlocked EchoesHexConquestActiveFrameVariants EchoesHexConquestActiveStickers EntratiLabConquestActiveFrameVariants EntratiLabConquestCacheScoreMission EchoesHexConquestCacheScoreMission" ); const body = getJSONfromString(String(req.body)); - if (!inventory.EntratiVaultCountResetDate || Date.now() >= inventory.EntratiVaultCountResetDate.getTime()) { - const EPOCH = 1734307200 * 1000; // Mondays, amirite? - const day = Math.trunc((Date.now() - EPOCH) / 86400000); - const week = Math.trunc(day / 7); - const weekStart = EPOCH + week * 604800000; - const weekEnd = weekStart + 604800000; - inventory.EntratiVaultCountLastPeriod = 0; - inventory.EntratiVaultCountResetDate = new Date(weekEnd); - if (inventory.EntratiLabConquestUnlocked) { - inventory.EntratiLabConquestUnlocked = 0; - inventory.EntratiLabConquestCacheScoreMission = 0; - inventory.EntratiLabConquestActiveFrameVariants = []; - } - if (inventory.EchoesHexConquestUnlocked) { - inventory.EchoesHexConquestUnlocked = 0; - inventory.EchoesHexConquestCacheScoreMission = 0; - inventory.EchoesHexConquestActiveFrameVariants = []; - inventory.EchoesHexConquestActiveStickers = []; - } - } + updateEntratiVault(inventory); if (body.BuyMode) { inventory.EntratiVaultCountLastPeriod! += 2; if (body.IsEchoesDeepArchemedea) { @@ -51,7 +32,7 @@ export const entratiLabConquestModeController: RequestHandler = async (req, res) } await inventory.save(); res.json({ - EntratiVaultCountResetDate: toMongoDate(inventory.EntratiVaultCountResetDate), + EntratiVaultCountResetDate: toMongoDate(inventory.EntratiVaultCountResetDate!), EntratiVaultCountLastPeriod: inventory.EntratiVaultCountLastPeriod, EntratiLabConquestUnlocked: inventory.EntratiLabConquestUnlocked, EntratiLabConquestCacheScoreMission: inventory.EntratiLabConquestCacheScoreMission, diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index c6f16b08..acf7374d 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -2449,3 +2449,26 @@ export const giveNemesisPetRecipe = ( export const getEffectiveAvatarImageType = (inventory: TInventoryDatabaseDocument): string => { return inventory.ActiveAvatarImageType ?? "/Lotus/Types/StoreItems/AvatarImages/AvatarImageDefault"; }; + +export const updateEntratiVault = (inventory: TInventoryDatabaseDocument): void => { + if (!inventory.EntratiVaultCountResetDate || Date.now() >= inventory.EntratiVaultCountResetDate.getTime()) { + const EPOCH = 1734307200 * 1000; // Mondays, amirite? + const day = Math.trunc((Date.now() - EPOCH) / 86400000); + const week = Math.trunc(day / 7); + const weekStart = EPOCH + week * 604800000; + const weekEnd = weekStart + 604800000; + inventory.EntratiVaultCountLastPeriod = 0; + inventory.EntratiVaultCountResetDate = new Date(weekEnd); + if (inventory.EntratiLabConquestUnlocked) { + inventory.EntratiLabConquestUnlocked = 0; + inventory.EntratiLabConquestCacheScoreMission = 0; + inventory.EntratiLabConquestActiveFrameVariants = []; + } + if (inventory.EchoesHexConquestUnlocked) { + inventory.EchoesHexConquestUnlocked = 0; + inventory.EchoesHexConquestCacheScoreMission = 0; + inventory.EchoesHexConquestActiveFrameVariants = []; + inventory.EchoesHexConquestActiveStickers = []; + } + } +}; -- 2.47.2 From 9eefe5db84b052eed84da28bdc5aae7f90a146d2 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:20:46 +0200 Subject: [PATCH 2/4] feat: consume search pulse for doing netracells --- src/services/missionInventoryUpdateService.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index 7ae15e01..01da1c22 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -39,6 +39,7 @@ import { giveNemesisPetRecipe, giveNemesisWeaponRecipe, updateCurrency, + updateEntratiVault, updateSyndicate } from "@/src/services/inventoryService"; import { updateQuestKey } from "@/src/services/questService"; @@ -169,6 +170,12 @@ export const addMissionInventoryUpdates = async ( } ]); } + + // Consume netracells search pulse + if (inventoryUpdates.Missions.Tag == "SolNode720") { + updateEntratiVault(inventory); + inventory.EntratiVaultCountLastPeriod! += 1; + } } if (inventoryUpdates.KeyToRemove) { if (!inventoryUpdates.KeyOwner || inventory.accountOwnerId.equals(inventoryUpdates.KeyOwner)) { -- 2.47.2 From 2fe9843429d4ff76333eb12cc0f9d87b47385295 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:29:42 +0200 Subject: [PATCH 3/4] only consume search pulse on successful completion --- src/services/missionInventoryUpdateService.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index 01da1c22..70b45b9a 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -170,12 +170,6 @@ export const addMissionInventoryUpdates = async ( } ]); } - - // Consume netracells search pulse - if (inventoryUpdates.Missions.Tag == "SolNode720") { - updateEntratiVault(inventory); - inventory.EntratiVaultCountLastPeriod! += 1; - } } if (inventoryUpdates.KeyToRemove) { if (!inventoryUpdates.KeyOwner || inventory.accountOwnerId.equals(inventoryUpdates.KeyOwner)) { @@ -1221,6 +1215,12 @@ export const addMissionRewards = async ( } ]); } + + // Consume netracells search pulse. Moved here to only cover successful completions. Discussed in https://onlyg.it/OpenWF/SpaceNinjaServer/issues/2673 + if (missions.Tag == "SolNode720") { + updateEntratiVault(inventory); + inventory.EntratiVaultCountLastPeriod! += 1; + } } if (rewardInfo.useVaultManifest) { -- 2.47.2 From d0fa88edbbc34e6447e91b8902c6d10eb8d1ef25 Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Thu, 21 Aug 2025 21:34:38 +0200 Subject: [PATCH 4/4] ensure netracells completion is eligible for credits --- src/services/missionInventoryUpdateService.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index 70b45b9a..bccbed42 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -1085,6 +1085,22 @@ const droptableAliases: Record = { "/Lotus/Types/DropTables/WF1999DropTables/LasrianTankHardModeDropTable" }; +const isEligibleForCreditReward = (rewardInfo: IRewardInfo, missions: IMission, node: IRegion): boolean => { + // (E)SO should not give credits for only completing zone 1, in which case it has no rewardQualifications (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823) + if (getRotations(rewardInfo).length == 0) { + return missions.Tag == "SolNode720"; // Netracells don't use rewardQualifications but probably should give credits anyway + } + // The rest here might not be needed anymore, but just to be sure we don't give undue credits... + return ( + node.missionIndex != 23 && // junction + node.missionIndex != 28 && // open world + missions.Tag != "SolNode761" && // the index + missions.Tag != "SolNode762" && // the index + missions.Tag != "SolNode763" && // the index + missions.Tag != "CrewBattleNode556" // free flight + ); +}; + //TODO: return type of partial missioninventoryupdate response export const addMissionRewards = async ( account: TAccountDocument, @@ -1177,15 +1193,7 @@ export const addMissionRewards = async ( const node = ExportRegions[missions.Tag]; //node based credit rewards for mission completion - if ( - node.missionIndex != 23 && // junction - node.missionIndex != 28 && // open world - missions.Tag != "SolNode761" && // the index - missions.Tag != "SolNode762" && // the index - missions.Tag != "SolNode763" && // the index - missions.Tag != "CrewBattleNode556" && // free flight - getRotations(rewardInfo).length > 0 // (E)SO should not give credits for only completing zone 1, in which case it has no rewardQualifications (https://onlyg.it/OpenWF/SpaceNinjaServer/issues/1823) - ) { + if (isEligibleForCreditReward(rewardInfo, missions, node)) { const levelCreditReward = getLevelCreditRewards(node); missionCompletionCredits += levelCreditReward; logger.debug(`levelCreditReward ${levelCreditReward}`); -- 2.47.2