From f140e1e106ae5b45de13931c1e6df650257f1d55 Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 5 Jul 2025 17:25:59 +0100 Subject: [PATCH 1/2] Converted `ReplaceIDs` into extension method --- .../Controllers/HideoutController.cs | 17 ++++++---- .../Extensions/ItemExtensions.cs | 31 +++++++++++++++++ .../Generators/FenceBaseAssortGenerator.cs | 3 +- .../Generators/LocationLootGenerator.cs | 10 +++--- .../Generators/LootGenerator.cs | 28 ++++++++-------- .../Generators/RagfairAssortGenerator.cs | 13 ++++---- .../Generators/ScavCaseRewardGenerator.cs | 3 +- .../SptCommands/GiveCommand/GiveSptCommand.cs | 2 +- .../Helpers/ItemHelper.cs | 33 +------------------ .../Helpers/RewardHelper.cs | 2 +- .../Models/Spt/Config/InventoryConfig.cs | 2 +- .../Services/CircleOfCultistService.cs | 4 +-- .../Services/FenceService.cs | 7 ++-- .../Services/MailSendService.cs | 2 +- 14 files changed, 83 insertions(+), 74 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs index cf15c816..da9f18c2 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs @@ -1,4 +1,5 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Generators; using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Models.Common; @@ -1215,10 +1216,12 @@ public class HideoutController( var countOfItemsToReward = recipe.Count; for (var index = 1; index < countOfItemsToReward; index++) { - var itemAndMods = _itemHelper.ReplaceIDs( - _cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault()) - ); - itemAndChildrenToSendToPlayer.AddRange([itemAndMods]); + var firstItemWithChildrenClone = _cloner + .Clone(itemAndChildrenToSendToPlayer.FirstOrDefault()) + .ReplaceIDs() + .ToList(); + + itemAndChildrenToSendToPlayer.AddRange([firstItemWithChildrenClone]); } } @@ -1231,12 +1234,12 @@ public class HideoutController( var defaultPreset = _presetHelper.GetDefaultPreset(recipe.EndProduct); // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); + var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); - _itemHelper.RemapRootItemId(presetAndMods); + _itemHelper.RemapRootItemId(presetAndModsClone); // Store preset items in array - return [presetAndMods]; + return [presetAndModsClone]; } /// diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs index 6f1074c7..f6212eb0 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs @@ -382,5 +382,36 @@ namespace SPTarkov.Server.Core.Extensions // Return all items returned and exclude the secure container item itself return itemsInSecureContainer.Where(x => x != secureContainer.Id).ToList(); } + + /// + /// Regenerate all GUIDs with new IDs, except special item types (e.g. quest, sorting table, etc.) + /// + /// + /// + public static IEnumerable ReplaceIDs(this IEnumerable items) + { + foreach (var item in items) + { + // Generate new id + var newId = new MongoId(); + + // Keep copy of original id + var originalId = item.Id; + + // Update items id to new one we generated + item.Id = newId; + + // Find all children of item and update their parent ids to match + var childItems = items.Where(x => + string.Equals(x.ParentId, originalId, StringComparison.OrdinalIgnoreCase) + ); + foreach (var childItem in childItems) + { + childItem.ParentId = newId; + } + } + + return items; + } } } diff --git a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs index 7a497cac..cc633db3 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/FenceBaseAssortGenerator.cs @@ -1,4 +1,5 @@ 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; @@ -162,7 +163,7 @@ public class FenceBaseAssortGenerator( } // Construct preset + mods - var itemAndChildren = itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); + var itemAndChildren = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); // Find root item and add some properties to it for (var i = 0; i < itemAndChildren.Count; i++) diff --git a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs index 06d00e1f..bcffd5fb 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs @@ -1171,7 +1171,7 @@ public class LocationLootGenerator( var itemWithChildren = lootItems.FindAndReturnChildrenAsItems(chosenItem.Id); // Ensure all IDs are unique - itemWithChildren = _itemHelper.ReplaceIDs(_cloner.Clone(itemWithChildren)); + itemWithChildren = _cloner.Clone(itemWithChildren).ReplaceIDs().ToList(); if (_locationConfig.TplsToStripChildItemsFrom.Contains(chosenItem.Template)) // Strip children from parent before adding @@ -1280,12 +1280,12 @@ public class LocationLootGenerator( var defaultPreset = _presetHelper.GetDefaultPreset(chosenTpl); if (defaultPreset is not null) { - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); - _itemHelper.RemapRootItemId(presetAndMods); + var presetAndModsClone = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); + _itemHelper.RemapRootItemId(presetAndModsClone); // Use original items parentId otherwise item doesn't get added to container correctly - presetAndMods.FirstOrDefault().ParentId = rootItem.ParentId; - items = presetAndMods; + presetAndModsClone.FirstOrDefault().ParentId = rootItem.ParentId; + items = presetAndModsClone; } else { diff --git a/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs index d795b9f2..39b81d22 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LootGenerator.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; 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; @@ -200,12 +201,13 @@ public class LootGenerator( for (var i = 0; i < randomisedItemCount; i++) { // Clone preset and alter Ids to be unique - var presetWithUniqueIds = _itemHelper.ReplaceIDs( - _cloner.Clone(preset.Items) - ); + var presetWithUniqueIdsClone = _cloner + .Clone(preset.Items) + .ReplaceIDs() + .ToList(); // Add to results - result.Add(presetWithUniqueIds); + result.Add(presetWithUniqueIdsClone); } } @@ -497,13 +499,13 @@ public class LootGenerator( return false; } - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(chosenPreset.Items)); - _itemHelper.RemapRootItemId(presetAndMods); + var presetAndModsClone = _cloner.Clone(chosenPreset.Items).ReplaceIDs().ToList(); + _itemHelper.RemapRootItemId(presetAndModsClone); - _itemHelper.SetFoundInRaid(presetAndMods); + _itemHelper.SetFoundInRaid(presetAndModsClone); // Add chosen preset tpl to result array - result.Add(presetAndMods); + result.Add(presetAndModsClone); if (itemLimitCount is not null) // Increment item count as item has been chosen and its inside itemLimitCount dictionary @@ -565,13 +567,13 @@ public class LootGenerator( } // Clean up Ids to ensure they're all unique and prevent collisions - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(chosenWeaponPreset.Items)); - _itemHelper.RemapRootItemId(presetAndMods); + var presetAndModsClone = _cloner.Clone(chosenWeaponPreset.Items).ReplaceIDs().ToList(); + _itemHelper.RemapRootItemId(presetAndModsClone); // Add preset to return object - itemsToReturn.Add(presetAndMods); + itemsToReturn.Add(presetAndModsClone); - // Get a random collection of weapon mods related to chosen weawpon and add them to result array + // Get a random collection of weapon mods related to chosen weapon and add them to result array var linkedItemsToWeapon = _ragfairLinkedItemService.GetLinkedDbItems(chosenWeaponTpl); itemsToReturn.AddRange( GetSealedContainerWeaponModRewards( @@ -763,7 +765,7 @@ public class LootGenerator( var preset = _presetHelper.GetDefaultPreset(chosenRewardItemTpl); // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory - var presetAndMods = _itemHelper.ReplaceIDs(preset.Items); + var presetAndMods = preset.Items.ReplaceIDs().ToList(); _itemHelper.RemapRootItemId(presetAndMods); itemsToReturn.Add(presetAndMods); diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index 9ecfef97..e1a1fc58 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs @@ -1,4 +1,5 @@ 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; @@ -65,22 +66,22 @@ public class RagfairAssortGenerator( foreach (var preset in presets) { // Update Ids and clone - var presetAndMods = itemHelper.ReplaceIDs(cloner.Clone(preset.Items)); - itemHelper.RemapRootItemId(presetAndMods); + var presetAndModsClone = cloner.Clone(preset.Items).ReplaceIDs().ToList(); + itemHelper.RemapRootItemId(presetAndModsClone); // Add presets base item tpl to the processed list so its skipped later on when processing items processedArmorItems.Add(preset.Items[0].Template); - presetAndMods[0].ParentId = "hideout"; - presetAndMods[0].SlotId = "hideout"; - presetAndMods[0].Upd = new Upd + presetAndModsClone[0].ParentId = "hideout"; + presetAndModsClone[0].SlotId = "hideout"; + presetAndModsClone[0].Upd = new Upd { StackObjectsCount = 99999999, UnlimitedCount = true, SptPresetId = preset.Id, }; - results.Add(presetAndMods); + results.Add(presetAndModsClone); } foreach (var item in dbItemsClone) diff --git a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs index acb57e46..107364be 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/ScavCaseRewardGenerator.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; @@ -403,7 +404,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 = _itemHelper.ReplaceIDs(_cloner.Clone(preset.Items)); + var presetAndMods = _cloner.Clone(preset.Items).ReplaceIDs().ToList(); _itemHelper.RemapRootItemId(presetAndMods); resultItem = presetAndMods; diff --git a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs index 2a86244d..a2c169e6 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs @@ -234,7 +234,7 @@ public class GiveSptCommand( for (var i = 0; i < quantity; i++) { var items = _cloner.Clone(preset.Items); - items = _itemHelper.ReplaceIDs(items); + items = items.ReplaceIDs().ToList(); itemsToSend.AddRange(items); } } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 1c0a97d0..2e2f6618 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -837,7 +837,7 @@ public class ItemHelper( while (remainingCount.Value != 0) { // Clone item and make IDs unique - var itemWithChildrenClone = ReplaceIDs(_cloner.Clone(itemWithChildren)); + var itemWithChildrenClone = _cloner.Clone(itemWithChildren).ReplaceIDs().ToList(); // Set stack count to new value var amount = Math.Min(remainingCount ?? 0, maxStackSize ?? 0); @@ -1017,37 +1017,6 @@ public class ItemHelper( } } - /// - /// Regenerate all GUIDs with new IDs, except special item types (e.g. quest, sorting table, etc.) - /// - /// - /// - public List ReplaceIDs(List items) - { - foreach (var item in items) - { - // Generate new id - var newId = new MongoId(); - - // Keep copy of original id - var originalId = item.Id; - - // Update items id to new one we generated - item.Id = newId; - - // Find all children of item and update their parent ids to match - var childItems = items.Where(x => - string.Equals(x.ParentId, originalId, StringComparison.OrdinalIgnoreCase) - ); - foreach (var childItem in childItems) - { - childItem.ParentId = newId; - } - } - - return items; - } - /// /// Regenerate all GUIDs with new IDs, except special item types (e.g. quest, sorting table, etc.) This /// function will not mutate the original items list, but will return a new list with new GUIDs. diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs index ce617594..23ac0f6d 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs @@ -383,7 +383,7 @@ public class RewardHelper( if (defaultPreset is not null) { // Found preset, use mods to hydrate reward item - var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); + var presetAndMods = _cloner.Clone(defaultPreset.Items).ReplaceIDs().ToList(); var newRootId = _itemHelper.RemapRootItemId(presetAndMods); reward.Items = presetAndMods; diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InventoryConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InventoryConfig.cs index 96d7291e..64af64a8 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InventoryConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InventoryConfig.cs @@ -66,7 +66,7 @@ public record SealedAirdropContainerSettings public Dictionary? ExtensionData { get; set; } [JsonPropertyName("weaponRewardWeight")] - public required Dictionary WeaponRewardWeight { get; set; } + public required Dictionary WeaponRewardWeight { get; set; } [JsonPropertyName("defaultPresetsOnly")] public bool DefaultPresetsOnly { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs index fbd46713..95212670 100644 --- a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs @@ -399,7 +399,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 = _itemHelper.ReplaceIDs(defaultPreset.Items); + var presetAndMods = defaultPreset.Items.ReplaceIDs().ToList(); _itemHelper.RemapRootItemId(presetAndMods); // Set item as FiR @@ -494,7 +494,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 = _itemHelper.ReplaceIDs(defaultPreset.Items); + var presetAndMods = defaultPreset.Items.ReplaceIDs().ToList(); _itemHelper.RemapRootItemId(presetAndMods); // Set item as FiR diff --git a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs index 242e6809..6d2aecae 100644 --- a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs @@ -858,9 +858,10 @@ public class FenceService( } // MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client - desiredAssortItemAndChildrenClone = itemHelper.ReplaceIDs( - _cloner.Clone(desiredAssortItemAndChildrenClone) - ); + desiredAssortItemAndChildrenClone = _cloner + .Clone(desiredAssortItemAndChildrenClone) + .ReplaceIDs() + .ToList(); itemHelper.RemapRootItemId(desiredAssortItemAndChildrenClone); var rootItemBeingAdded = desiredAssortItemAndChildrenClone[0]; diff --git a/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs b/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs index 1d776eee..98534efd 100644 --- a/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs @@ -516,7 +516,7 @@ public class MailSendService( }; // Ensure Ids are unique and cont collide with items in player inventory later - messageDetails.Items = _itemHelper.ReplaceIDs(_cloner.Clone(messageDetails.Items)); + messageDetails.Items = _cloner.Clone(messageDetails.Items).ReplaceIDs().ToList(); // Ensure item exits in items db foreach (var reward in messageDetails.Items) From fa674d6add94e4a5d31eb6bc96a4a710281c942e Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 5 Jul 2025 17:46:58 +0100 Subject: [PATCH 2/2] Converted `RemapRootItemId` into extension method --- .../Controllers/HideoutController.cs | 2 +- .../Extensions/ItemExtensions.cs | 35 +++++++++++++++++++ .../Generators/FenceBaseAssortGenerator.cs | 2 +- .../Generators/LocationLootGenerator.cs | 2 +- .../Generators/LootGenerator.cs | 6 ++-- .../Generators/RagfairAssortGenerator.cs | 2 +- .../Generators/ScavCaseRewardGenerator.cs | 2 +- .../Helpers/ItemHelper.cs | 33 ----------------- .../Helpers/RewardHelper.cs | 2 +- .../Helpers/TradeHelper.cs | 2 +- .../Services/CircleOfCultistService.cs | 10 +++--- .../Services/FenceService.cs | 6 ++-- .../Services/InsuranceService.cs | 1 - .../Services/RagfairOfferService.cs | 3 +- .../Services/RagfairTaxService.cs | 1 - 15 files changed, 55 insertions(+), 54 deletions(-) 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 ) {