diff --git a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs index da9f18c2..7a5250a8 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs @@ -1236,7 +1236,7 @@ public class HideoutController( // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndModsClone); + presetAndModsClone.RemapRootItemId(); // Store preset items in array return [presetAndModsClone]; diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs index f6212eb0..d108ab41 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs @@ -413,5 +413,40 @@ namespace SPTarkov.Server.Core.Extensions return items; } + + /// + /// Update a root items _id property value to be unique + /// + /// Item to update root items _id property + /// Optional: new id to use + /// New root id + public static string RemapRootItemId( + this List itemWithChildren, + MongoId? newId = null + ) + { + newId ??= new MongoId(); + + var rootItemExistingId = itemWithChildren.FirstOrDefault().Id; + + foreach (var item in itemWithChildren) + { + // Root, update id + if (item.Id.Equals(rootItemExistingId)) + { + item.Id = newId.Value; + + continue; + } + + // Child with parent of root, update + if (item.ParentId == rootItemExistingId) + { + item.ParentId = newId.Value; + } + } + + return newId; + } } } diff --git a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs index cc633db3..4fd2bb14 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs @@ -119,7 +119,7 @@ public class FenceBaseAssortGenerator( } // Ensure IDs are unique - itemHelper.RemapRootItemId(itemWithChildrenToAdd); + itemWithChildrenToAdd.RemapRootItemId(); if (itemWithChildrenToAdd.Count > 1) { itemHelper.ReparentItemAndChildren(itemWithChildrenToAdd[0], itemWithChildrenToAdd); diff --git a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs index bcffd5fb..be3cd1b4 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs @@ -1281,7 +1281,7 @@ public class LocationLootGenerator( if (defaultPreset is not null) { var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndModsClone); + presetAndModsClone.RemapRootItemId(); // Use original items parentId otherwise item doesn't get added to container correctly presetAndModsClone.FirstOrDefault().ParentId = rootItem.ParentId; diff --git a/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs index 39b81d22..685d5896 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs @@ -500,7 +500,7 @@ public class LootGenerator( } var presetAndModsClone = _cloner.Clone(chosenPreset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndModsClone); + presetAndModsClone.RemapRootItemId(); _itemHelper.SetFoundInRaid(presetAndModsClone); @@ -568,7 +568,7 @@ public class LootGenerator( // Clean up Ids to ensure they're all unique and prevent collisions var presetAndModsClone = _cloner.Clone(chosenWeaponPreset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndModsClone); + presetAndModsClone.RemapRootItemId(); // Add preset to return object itemsToReturn.Add(presetAndModsClone); @@ -767,7 +767,7 @@ public class LootGenerator( // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory var presetAndMods = preset.Items.ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndMods); + presetAndMods.RemapRootItemId(); itemsToReturn.Add(presetAndMods); continue; diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index e1a1fc58..377b1fce 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs @@ -67,7 +67,7 @@ public class RagfairAssortGenerator( { // Update Ids and clone var presetAndModsClone = cloner.Clone(preset.Items).ReplaceIDs().ToList(); - itemHelper.RemapRootItemId(presetAndModsClone); + presetAndModsClone.RemapRootItemId(); // Add presets base item tpl to the processed list so its skipped later on when processing items processedArmorItems.Add(preset.Items[0].Template); diff --git a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs index 107364be..9b95cf82 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs @@ -405,7 +405,7 @@ public class ScavCaseRewardGenerator( // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory var presetAndMods = _cloner.Clone(preset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndMods); + presetAndMods.RemapRootItemId(); resultItem = presetAndMods; } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 2e2f6618..afe19198 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -1916,39 +1916,6 @@ public class ItemHelper( return itemWithChildren; } - // Update a root items _id property value to be unique - // Item to update root items _id property - // Optional: new id to use - // Returns New root id - - public string RemapRootItemId(List itemWithChildren, MongoId? newId = null) - { - newId ??= new MongoId(); - - var rootItemExistingId = itemWithChildren[0].Id; - - foreach (var item in itemWithChildren) - { - // Root, update id - if (item.Id.Equals(rootItemExistingId)) - { - item.Id = newId.Value; - - continue; - } - - // Child with parent of root, update - if ( - string.Equals(item.ParentId, rootItemExistingId, StringComparison.OrdinalIgnoreCase) - ) - { - item.ParentId = newId; - } - } - - return newId; - } - // Add a blank upd object to passed in item if it does not exist already // item to add upd to // text to write to log when upd object was not found diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs index 23ac0f6d..8bf6d48d 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs @@ -384,7 +384,7 @@ public class RewardHelper( { // Found preset, use mods to hydrate reward item var presetAndMods = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); - var newRootId = _itemHelper.RemapRootItemId(presetAndMods); + var newRootId = presetAndMods.RemapRootItemId(); reward.Items = presetAndMods; diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs index ba5644e9..cf74533f 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs @@ -249,7 +249,7 @@ public class TradeHelper( offerClone.FirstOrDefault().Upd.StackObjectsCount = itemCountToSend; // Prevent any collisions - _itemHelper.RemapRootItemId(offerClone); + offerClone.RemapRootItemId(); if (offerClone.Count > 1) { _itemHelper.ReparentItemAndChildren(offerClone.FirstOrDefault(), offerClone); diff --git a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs index 95212670..5a3fd549 100644 --- a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs @@ -400,7 +400,7 @@ public class CircleOfCultistService( // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory var presetAndMods = defaultPreset.Items.ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndMods); + presetAndMods.RemapRootItemId(); // Set item as FiR _itemHelper.SetFoundInRaid(presetAndMods); @@ -495,7 +495,7 @@ public class CircleOfCultistService( // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory var presetAndMods = defaultPreset.Items.ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndMods); + presetAndMods.RemapRootItemId(); // Set item as FiR _itemHelper.SetFoundInRaid(presetAndMods); @@ -546,18 +546,18 @@ public class CircleOfCultistService( /// sessionId /// Items sacrificed /// Direct reward items to send to player - protected DirectRewardSettings CheckForDirectReward( + protected DirectRewardSettings? CheckForDirectReward( string sessionId, List sacrificedItems, Dictionary directRewardsCache ) { // Get sacrificed tpls - IEnumerable sacrificedItemTpls = sacrificedItems + var sacrificedItemTpls = sacrificedItems .Select(item => item.Template) .Where(item => item != null); // Create md5 key of the items player sacrificed so we can compare against the direct reward cache - string sacrificedItemsKey = CreateSacrificeCacheKey(sacrificedItemTpls); + var sacrificedItemsKey = CreateSacrificeCacheKey(sacrificedItemTpls); var matchingDirectReward = directRewardsCache.GetValueOrDefault(sacrificedItemsKey); if (matchingDirectReward is null) diff --git a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs index 6d2aecae..95711259 100644 --- a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs @@ -862,7 +862,7 @@ public class FenceService( .Clone(desiredAssortItemAndChildrenClone) .ReplaceIDs() .ToList(); - itemHelper.RemapRootItemId(desiredAssortItemAndChildrenClone); + desiredAssortItemAndChildrenClone.RemapRootItemId(); var rootItemBeingAdded = desiredAssortItemAndChildrenClone[0]; @@ -1153,7 +1153,7 @@ public class FenceService( presetWithChildrenClone[0], presetWithChildrenClone ); - itemHelper.RemapRootItemId(presetWithChildrenClone); + presetWithChildrenClone.RemapRootItemId(); // Remapping IDs causes parentId to be altered, fix presetWithChildrenClone[0].ParentId = "hideout"; @@ -1222,7 +1222,7 @@ public class FenceService( // MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client itemHelper.ReparentItemAndChildren(presetWithChildrenClone[0], presetWithChildrenClone); - itemHelper.RemapRootItemId(presetWithChildrenClone); + presetWithChildrenClone.RemapRootItemId(); // Remapping IDs causes parentId to be altered presetWithChildrenClone[0].ParentId = "hideout"; diff --git a/Libraries/SPTarkov.Server.Core/Services/InsuranceService.cs b/Libraries/SPTarkov.Server.Core/Services/InsuranceService.cs index e40b212a..9ab10538 100644 --- a/Libraries/SPTarkov.Server.Core/Services/InsuranceService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/InsuranceService.cs @@ -24,7 +24,6 @@ public class InsuranceService( TimeUtil _timeUtil, SaveServer _saveServer, TraderHelper _traderHelper, - ProfileHelper _profileHelper, ServerLocalisationService _serverLocalisationService, MailSendService _mailSendService, ConfigServer _configServer diff --git a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs index 453443b5..f631a7dc 100644 --- a/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/RagfairOfferService.cs @@ -1,5 +1,6 @@ using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; @@ -345,7 +346,7 @@ public class RagfairOfferService( itemAndChildrenClone.FirstOrDefault(), itemAndChildrenClone ); - itemHelper.RemapRootItemId(reparentedItemAndChildren); + reparentedItemAndChildren.RemapRootItemId(); result.AddRange(reparentedItemAndChildren); } diff --git a/Libraries/SPTarkov.Server.Core/Services/RagfairTaxService.cs b/Libraries/SPTarkov.Server.Core/Services/RagfairTaxService.cs index e7a847a2..de724171 100644 --- a/Libraries/SPTarkov.Server.Core/Services/RagfairTaxService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/RagfairTaxService.cs @@ -17,7 +17,6 @@ public class RagfairTaxService( DatabaseService _databaseService, RagfairPriceService _ragfairPriceService, ItemHelper _itemHelper, - ProfileHelper _profileHelper, ICloner _cloner ) {