From 1979b20f8cc00b79f305478f1da3d69f90a3d43e Mon Sep 17 00:00:00 2001 From: Sainan <63328889+Sainan@users.noreply.github.com> Date: Tue, 10 Jun 2025 05:49:43 -0700 Subject: [PATCH] fix: handle multiple syndicate title increases at once (#2139) Only really possible with nightwave afaik. Bug reported via #2138. Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2139 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com> --- .../api/syndicateSacrificeController.ts | 125 +++++++++--------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/src/controllers/api/syndicateSacrificeController.ts b/src/controllers/api/syndicateSacrificeController.ts index 8b1a9c7a..021608b3 100644 --- a/src/controllers/api/syndicateSacrificeController.ts +++ b/src/controllers/api/syndicateSacrificeController.ts @@ -3,7 +3,7 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { ExportSyndicates, ISyndicateSacrifice } from "warframe-public-export-plus"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; -import { addMiscItems, combineInventoryChanges, getInventory, updateCurrency } from "@/src/services/inventoryService"; +import { addMiscItem, combineInventoryChanges, getInventory, updateCurrency } from "@/src/services/inventoryService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { toStoreItem } from "@/src/services/itemDataService"; import { logger } from "@/src/utils/logger"; @@ -18,80 +18,83 @@ export const syndicateSacrificeController: RequestHandler = async (request, resp syndicate = inventory.Affiliations[inventory.Affiliations.push({ Tag: data.AffiliationTag, Standing: 0 }) - 1]; } - const level = data.SacrificeLevel - (syndicate.Title ?? 0); + const oldLevel = syndicate.Title ?? 0; + const levelIncrease = data.SacrificeLevel - oldLevel; + if (levelIncrease < 1) { + throw new Error(`syndicate sacrifice needs an increase of at least 1`); + } + if (levelIncrease > 1 && !data.AllowMultiple) { + throw new Error(`desired syndicate level is an increase of ${levelIncrease}, max. allowed increase is 1`); + } + const res: ISyndicateSacrificeResponse = { AffiliationTag: data.AffiliationTag, InventoryChanges: {}, Level: data.SacrificeLevel, - LevelIncrease: level <= 0 ? 1 : level, + LevelIncrease: levelIncrease, NewEpisodeReward: false }; + // Process sacrifices and rewards for every level we're reaching const manifest = ExportSyndicates[data.AffiliationTag]; - let sacrifice: ISyndicateSacrifice | undefined; - let reward: string | undefined; - if (data.SacrificeLevel == 0) { - sacrifice = manifest.initiationSacrifice; - reward = manifest.initiationReward; - syndicate.Initiated = true; - } else { - sacrifice = manifest.titles?.find(x => x.level == data.SacrificeLevel)?.sacrifice; - } - - if (sacrifice) { - res.InventoryChanges = { ...updateCurrency(inventory, sacrifice.credits, false) }; - - const miscItemChanges = sacrifice.items.map(x => ({ - ItemType: x.ItemType, - ItemCount: x.ItemCount * -1 - })); - addMiscItems(inventory, miscItemChanges); - res.InventoryChanges.MiscItems = miscItemChanges; - } - - syndicate.Title ??= 0; - syndicate.Title += 1; - - if (reward) { - combineInventoryChanges( - res.InventoryChanges, - (await handleStoreItemAcquisition(reward, inventory)).InventoryChanges - ); - } - - // Quacks like a nightwave syndicate? - if (manifest.dailyChallenges) { - const title = manifest.titles!.find(x => x.level == syndicate.Title); - if (title) { - res.NewEpisodeReward = true; - let rewardType: string; - let rewardCount: number; - if (title.storeItemReward) { - rewardType = title.storeItemReward; - rewardCount = 1; - } else { - rewardType = toStoreItem(title.reward!.ItemType); - rewardCount = title.reward!.ItemCount; + for (let level = oldLevel + 1; level <= data.SacrificeLevel; ++level) { + let sacrifice: ISyndicateSacrifice | undefined; + if (level == 0) { + sacrifice = manifest.initiationSacrifice; + if (manifest.initiationReward) { + combineInventoryChanges( + res.InventoryChanges, + (await handleStoreItemAcquisition(manifest.initiationReward, inventory)).InventoryChanges + ); } - const rewardInventoryChanges = (await handleStoreItemAcquisition(rewardType, inventory, rewardCount)) - .InventoryChanges; - if (Object.keys(rewardInventoryChanges).length == 0) { - logger.debug(`nightwave rank up reward did not seem to get added, giving 50 creds instead`); - const nightwaveCredsItemType = manifest.titles![0].reward!.ItemType; - rewardInventoryChanges.MiscItems = [{ ItemType: nightwaveCredsItemType, ItemCount: 50 }]; - addMiscItems(inventory, rewardInventoryChanges.MiscItems); - } - combineInventoryChanges(res.InventoryChanges, rewardInventoryChanges); + syndicate.Initiated = true; + } else { + sacrifice = manifest.titles?.find(x => x.level == level)?.sacrifice; } - } else { - if (syndicate.Title > 0 && manifest.favours.find(x => x.rankUpReward && x.requiredLevel == syndicate.Title)) { - syndicate.FreeFavorsEarned ??= []; - if (!syndicate.FreeFavorsEarned.includes(syndicate.Title)) { - syndicate.FreeFavorsEarned.push(syndicate.Title); + + if (sacrifice) { + updateCurrency(inventory, sacrifice.credits, false, res.InventoryChanges); + + for (const item of sacrifice.items) { + addMiscItem(inventory, item.ItemType, item.ItemCount * -1, res.InventoryChanges); + } + } + + // Quacks like a nightwave syndicate? + if (manifest.dailyChallenges) { + const title = manifest.titles!.find(x => x.level == level); + if (title) { + res.NewEpisodeReward = true; + let rewardType: string; + let rewardCount: number; + if (title.storeItemReward) { + rewardType = title.storeItemReward; + rewardCount = 1; + } else { + rewardType = toStoreItem(title.reward!.ItemType); + rewardCount = title.reward!.ItemCount; + } + const rewardInventoryChanges = (await handleStoreItemAcquisition(rewardType, inventory, rewardCount)) + .InventoryChanges; + if (Object.keys(rewardInventoryChanges).length == 0) { + logger.debug(`nightwave rank up reward did not seem to get added, giving 50 creds instead`); + const nightwaveCredsItemType = manifest.titles![0].reward!.ItemType; + addMiscItem(inventory, nightwaveCredsItemType, 50, rewardInventoryChanges); + } + combineInventoryChanges(res.InventoryChanges, rewardInventoryChanges); + } + } else { + if (level > 0 && manifest.favours.find(x => x.rankUpReward && x.requiredLevel == level)) { + syndicate.FreeFavorsEarned ??= []; + if (!syndicate.FreeFavorsEarned.includes(level)) { + syndicate.FreeFavorsEarned.push(level); + } } } } + // Commit + syndicate.Title = data.SacrificeLevel; await inventory.save(); response.json(res);