From f562c634a75223c347a963d1bdc5b2d36a8e9692 Mon Sep 17 00:00:00 2001 From: Chomp Date: Thu, 24 Jul 2025 13:26:34 +0100 Subject: [PATCH] Converted lists to hashsets where appropriate Removed unnecessary uses of ToList() string to mongoId conversions --- .../Controllers/DialogueController.cs | 11 ++--------- .../Controllers/QuestController.cs | 6 ++++-- .../Extensions/ItemExtensions.cs | 4 ++-- .../Extensions/ProfileExtensions.cs | 4 ++-- .../Extensions/TraderAssortExtensions.cs | 4 ++-- .../Generators/BotEquipmentModGenerator.cs | 10 +++++++--- .../Generators/LocationLootGenerator.cs | 17 ++++++++--------- .../CompletionQuestGenerator.cs | 2 +- .../EliminationQuestGenerator.cs | 4 ++-- .../RepeatableQuestRewardGenerator.cs | 2 +- .../Implementations/ExternalInventoryMagGen.cs | 4 ++-- .../Helpers/AssortHelper.cs | 14 +++++++------- .../Helpers/BotGeneratorHelper.cs | 10 ++++------ .../SPTarkov.Server.Core/Helpers/BotHelper.cs | 15 --------------- .../Helpers/InRaidHelper.cs | 2 +- .../SPTarkov.Server.Core/Helpers/ItemHelper.cs | 4 ++-- .../Helpers/ProfileHelper.cs | 12 ++++++------ .../SPTarkov.Server.Core/Helpers/QuestHelper.cs | 8 ++++---- .../Helpers/RagfairOfferHelper.cs | 4 ++-- .../Helpers/TraderAssortHelper.cs | 10 +++++----- .../Models/Eft/Common/Tables/BotBase.cs | 2 +- .../Models/Eft/Common/Tables/ProfileTemplate.cs | 4 ++-- .../Models/Eft/Common/Tables/Quest.cs | 2 +- .../Eft/Common/Tables/RepeatableQuests.cs | 4 ++-- .../Models/Eft/Common/Tables/TemplateItem.cs | 2 +- .../Models/Eft/Profile/SptProfile.cs | 4 ++-- .../Spt/Bots/GenerateEquipmentProperties.cs | 2 +- .../Models/Spt/Bots/ModToSpawnRequest.cs | 2 +- .../Models/Spt/Config/AirdropConfig.cs | 2 +- .../Models/Spt/Config/BotConfig.cs | 8 ++++---- .../Models/Spt/Config/InRaidConfig.cs | 4 ++-- .../Models/Spt/Config/LocaleConfig.cs | 2 +- .../Models/Spt/Config/LocationConfig.cs | 2 +- .../Models/Spt/Config/QuestConfig.cs | 4 ++-- .../Models/Spt/Config/SeasonalEventConfig.cs | 2 +- .../Models/Spt/Services/LootRequest.cs | 2 +- .../Services/BotEquipmentFilterService.cs | 15 ++++++--------- .../Services/BtrDeliveryService.cs | 2 +- .../Services/CircleOfCultistService.cs | 3 ++- .../Services/LocaleService.cs | 2 +- .../Services/LocationLifecycleService.cs | 5 +++-- .../Services/OpenZoneService.cs | 2 +- .../Services/ServerLocalisationService.cs | 4 ++-- .../Utils/RagfairOfferHolder.cs | 4 ++-- 44 files changed, 106 insertions(+), 126 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/DialogueController.cs b/Libraries/SPTarkov.Server.Core/Controllers/DialogueController.cs index 2a4f8833..08e696d7 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/DialogueController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/DialogueController.cs @@ -638,10 +638,7 @@ public class DialogueController( // Only add the profile to the friends list if it doesn't already exist var profile = saveServer.GetProfile(sessionID); - if (!profile.FriendProfileIds.Contains(request.To.Value)) - { - profile.FriendProfileIds.Add(request.To.Value); - } + profile.FriendProfileIds.Add(request.To.Value); // We need to delay this so that the friend request gets properly added to the clientside list before we accept it _ = new Timer( @@ -677,11 +674,7 @@ public class DialogueController( public virtual void DeleteFriend(MongoId sessionID, DeleteFriendRequest request) { var profile = saveServer.GetProfile(sessionID); - var friendIndex = profile.FriendProfileIds.IndexOf(request.FriendId); - if (friendIndex != -1) - { - profile.FriendProfileIds.RemoveAt(friendIndex); - } + profile?.FriendProfileIds?.Remove(request.FriendId); } /// diff --git a/Libraries/SPTarkov.Server.Core/Controllers/QuestController.cs b/Libraries/SPTarkov.Server.Core/Controllers/QuestController.cs index 58273c80..06c24d3a 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/QuestController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/QuestController.cs @@ -226,7 +226,7 @@ public class QuestController( } handedInCount = int.Parse(condition.Value.ToString()); - isItemHandoverQuest = condition.ConditionType == handoverQuestTypes.FirstOrDefault(); + isItemHandoverQuest = condition.ConditionType == handoverQuestTypes.FirstOrDefault(); // TODO: there's 2 values, why does it only check for the first handoverRequirements = condition; if (pmcData.TaskConditionCounters.TryGetValue("ConditionId", out var counter)) @@ -312,7 +312,9 @@ public class QuestController( else { // Remove item with children - var toRemove = pmcData.Inventory.Items.GetItemWithChildrenTpls(itemHandover.Id); + var toRemove = pmcData + .Inventory.Items.GetItemWithChildrenTpls(itemHandover.Id) + .ToHashSet(); var index = pmcData.Inventory.Items.Count; // Important: don't tell the client to remove the attachments, it will handle it diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs index ec03e463..83e32c4e 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs @@ -365,7 +365,7 @@ namespace SPTarkov.Server.Core.Extensions /// /// Inventory items to look for secure container in /// List of ids - public static List GetSecureContainerItems(this IEnumerable items) + public static HashSet GetSecureContainerItems(this IEnumerable items) { var secureContainer = items.First(x => x.SlotId == "SecuredContainer"); @@ -378,7 +378,7 @@ namespace SPTarkov.Server.Core.Extensions var itemsInSecureContainer = items.GetItemWithChildrenTpls(secureContainer.Id); // Return all items returned and exclude the secure container item itself - return itemsInSecureContainer.Where(x => x != secureContainer.Id).ToList(); + return itemsInSecureContainer.Where(x => x != secureContainer.Id).ToHashSet(); } /// diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs index 80e5f40f..90200f6b 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs @@ -209,7 +209,7 @@ namespace SPTarkov.Server.Core.Extensions /// Item to check /// Root item id to check for /// True when item has rootId, false when not - public static bool DoesItemHaveRootId(this PmcData pmcData, Item item, string rootId) + public static bool DoesItemHaveRootId(this PmcData pmcData, Item item, MongoId rootId) { var currentItem = item; while (currentItem is not null) @@ -235,7 +235,7 @@ namespace SPTarkov.Server.Core.Extensions /// Profile to search /// Quest id to look up /// QuestStatus enum - public static QuestStatusEnum GetQuestStatus(this PmcData pmcData, string questId) + public static QuestStatusEnum GetQuestStatus(this PmcData pmcData, MongoId questId) { var quest = pmcData.Quests?.FirstOrDefault(q => q.QId == questId); diff --git a/Libraries/SPTarkov.Server.Core/Extensions/TraderAssortExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/TraderAssortExtensions.cs index 55a7bf1e..c62ca6fb 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/TraderAssortExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/TraderAssortExtensions.cs @@ -34,7 +34,7 @@ namespace SPTarkov.Server.Core.Extensions assort.LoyalLevelItems.Remove(itemId); // The item being removed may have children linked to it, find and remove them too - var idsToRemove = assort.Items.GetItemWithChildrenTpls(itemId); + var idsToRemove = assort.Items.GetItemWithChildrenTpls(itemId).ToHashSet(); assort.Items.RemoveAll(item => idsToRemove.Contains(item.Id)); return assort; @@ -47,7 +47,7 @@ namespace SPTarkov.Server.Core.Extensions /// Item TPLs the assort should not have public static void RemoveItemsFromAssort( this TraderAssort assortToFilter, - HashSet itemsTplsToRemove + HashSet itemsTplsToRemove ) { assortToFilter.Items = assortToFilter diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs index bdb10494..620d6a2f 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs @@ -197,7 +197,8 @@ public class BotEquipmentModGenerator( ); switch (plateSlotFilteringOutcome.Result) { - case Result.UNKNOWN_FAILURE or Result.NO_DEFAULT_FILTER: + case Result.UNKNOWN_FAILURE + or Result.NO_DEFAULT_FILTER: if (logger.IsLogEnabled(LogLevel.Debug)) { logger.Debug( @@ -1535,7 +1536,10 @@ public class BotEquipmentModGenerator( // Filtering mod pool to item that wasn't already there can have problems; // You'd have a mod being picked without any sub-mods in its chain, possibly resulting in missing required mods not being added // Mod is in existing mod pool - if (request.ItemModPool[request.ModSlot].Contains(matchingModFromPreset.Template)) + if ( + request.ItemModPool.TryGetValue(request.ModSlot, out var ids) + && ids.Contains(matchingModFromPreset.Template) + ) // Found mod on preset + it already exists in mod pool { return [matchingModFromPreset.Template]; @@ -2056,7 +2060,7 @@ public class BotEquipmentModGenerator( public HashSet FilterSightsByWeaponType( Item weapon, HashSet scopes, - Dictionary> botWeaponSightWhitelist + Dictionary> botWeaponSightWhitelist ) { var weaponDetails = itemHelper.GetItem(weapon.Template); diff --git a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs index 306cecfc..f11e8fde 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/LocationLootGenerator.cs @@ -154,11 +154,9 @@ public class LocationLootGenerator( // Remove christmas items from loot data if (!_seasonalEventService.ChristmasEventEnabled()) { - allStaticContainersOnMapClone = allStaticContainersOnMapClone - .Where(item => - !_seasonalEventConfig.ChristmasContainerIds.Contains(item.Template.Id) - ) - .ToList(); + allStaticContainersOnMapClone = allStaticContainersOnMapClone.Where(item => + !_seasonalEventConfig.ChristmasContainerIds.Contains(item.Template.Id) + ); } var staticRandomisableContainersOnMap = GetRandomisableContainersOnMap( @@ -561,7 +559,8 @@ public class LocationLootGenerator( // Some containers need to have items forced into it (quest keys etc.) var tplsForced = staticForced .Where(forcedStaticProp => forcedStaticProp.ContainerId == containerClone.Template.Id) - .Select(x => x.ItemTpl); + .Select(x => x.ItemTpl) + .ToHashSet(); // Draw random loot // Allow money to spawn more than once in container @@ -914,9 +913,9 @@ public class LocationLootGenerator( // Ensure no seasonal items are in pool if not in-season if (!seasonalEventActive) { - spawnPoint.Template.Items = spawnPoint - .Template.Items.Where(item => !seasonalItemTplBlacklist.Contains(item.Template)) - .ToList(); + spawnPoint.Template.Items = spawnPoint.Template.Items.Where(item => + !seasonalItemTplBlacklist.Contains(item.Template) + ); } // Spawn point has no items after filtering, skip diff --git a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/CompletionQuestGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/CompletionQuestGenerator.cs index 35ce1510..79309af1 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/CompletionQuestGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/CompletionQuestGenerator.cs @@ -119,7 +119,7 @@ public class CompletionQuestGenerator( traderId, repeatableConfig, completionConfig, - selectedItems + selectedItems.ToHashSet() ); return quest; diff --git a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs index 66128823..a87b6f75 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs @@ -636,7 +636,7 @@ public class EliminationQuestGenerator( // Filter out close range weapons from far distance requirement case > 50: { - List weaponTypeBlacklist = ["Shotgun", "Pistol"]; + HashSet weaponTypeBlacklist = ["Shotgun", "Pistol"]; // Filter out close range weapons from long distance requirement generationData.WeaponCategoryRequirementConfig.RemoveAll(category => @@ -647,7 +647,7 @@ public class EliminationQuestGenerator( // Filter out long range weapons from close distance requirement case < 20: { - List weaponTypeBlacklist = ["MarksmanRifle", "DMR"]; + HashSet weaponTypeBlacklist = ["MarksmanRifle", "DMR"]; // Filter out far range weapons from close distance requirement generationData.WeaponCategoryRequirementConfig.RemoveAll(category => diff --git a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs index 88f916ff..9616c775 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/RepeatableQuestRewardGenerator.cs @@ -64,7 +64,7 @@ public class RepeatableQuestRewardGenerator( MongoId traderId, RepeatableQuestConfig repeatableConfig, BaseQuestConfig eliminationConfig, - List? rewardTplBlacklist = null + HashSet? rewardTplBlacklist = null ) { // Get vars to configure rewards with diff --git a/Libraries/SPTarkov.Server.Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs b/Libraries/SPTarkov.Server.Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs index 99368c61..3eedc338 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/WeaponGen/Implementations/ExternalInventoryMagGen.cs @@ -40,7 +40,7 @@ public class ExternalInventoryMagGen( var magTemplate = inventoryMagGen.GetMagazineTemplate(); var magazineTpl = magTemplate.Id; var weapon = inventoryMagGen.GetWeaponTemplate(); - List attemptedMagBlacklist = []; + HashSet attemptedMagBlacklist = []; var defaultMagazineTpl = weapon.GetWeaponsDefaultMagazineTpl(); var isShotgun = itemHelper.IsOfBaseclass(weapon.Id, BaseClasses.SHOTGUN); @@ -176,7 +176,7 @@ public class ExternalInventoryMagGen( /// Item of chosen magazine public TemplateItem? GetRandomExternalMagazineForInternalMagazineGun( MongoId weaponTpl, - List magazineBlacklist + HashSet magazineBlacklist ) { // The mag Slot data for the weapon diff --git a/Libraries/SPTarkov.Server.Core/Helpers/AssortHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/AssortHelper.cs index 5ca8c838..8036f34a 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/AssortHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/AssortHelper.cs @@ -28,7 +28,7 @@ public class AssortHelper( PmcData pmcProfile, MongoId traderId, TraderAssort traderAssorts, - Dictionary> mergedQuestAssorts, + Dictionary> mergedQuestAssorts, bool isFlea = false ) { @@ -71,15 +71,15 @@ public class AssortHelper( /// quest assorts to search for assort id /// Assort to look for linked quest id /// quest id + array of quest status the assort should show for - protected KeyValuePair>? GetQuestIdAndStatusThatShowAssort( - Dictionary> mergedQuestAssorts, - string assortId + protected KeyValuePair>? GetQuestIdAndStatusThatShowAssort( + Dictionary> mergedQuestAssorts, + MongoId assortId ) { if (mergedQuestAssorts.TryGetValue("started", out var dict1) && dict1.ContainsKey(assortId)) // Assort unlocked by starting quest, assort is visible to player when : started or ready to hand in + handed in { - return new KeyValuePair>( + return new KeyValuePair>( mergedQuestAssorts["started"][assortId], [ QuestStatusEnum.Started, @@ -91,7 +91,7 @@ public class AssortHelper( if (mergedQuestAssorts.TryGetValue("success", out var dict2) && dict2.ContainsKey(assortId)) { - return new KeyValuePair>( + return new KeyValuePair>( mergedQuestAssorts["success"][assortId], [QuestStatusEnum.Success] ); @@ -99,7 +99,7 @@ public class AssortHelper( if (mergedQuestAssorts.TryGetValue("fail", out var dict3) && dict3.ContainsKey(assortId)) { - return new KeyValuePair>( + return new KeyValuePair>( mergedQuestAssorts["fail"][assortId], [QuestStatusEnum.Fail] ); diff --git a/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs index a765f2c5..f07b4f94 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/BotGeneratorHelper.cs @@ -37,7 +37,7 @@ public class BotGeneratorHelper( nameof(EquipmentSlots.ArmBand), ]; - private static readonly string[] _pmcTypes = + private static readonly FrozenSet _pmcTypes = [ Sides.PmcBear.ToLowerInvariant(), Sides.PmcUsec.ToLowerInvariant(), @@ -524,9 +524,7 @@ public class BotGeneratorHelper( /// Equipment role (e.g. pmc / assault / bossTagilla) public string GetBotEquipmentRole(string botRole) { - return _pmcTypes.Contains(botRole, StringComparer.OrdinalIgnoreCase) - ? Sides.PmcEquipmentRole - : botRole; + return _pmcTypes.Contains(botRole.ToLower()) ? Sides.PmcEquipmentRole : botRole; } /// @@ -775,13 +773,13 @@ public class BotGeneratorHelper( return false; } - // If Filter array only contains 1 filter and its for basetype 'item', allow it + // If Filter array only contains 1 filter and it is for basetype 'item', allow it if (filter.Count == 1 && filter.Contains(BaseClasses.ITEM)) { return true; } - // If allowed filter has something in it + filter doesnt have basetype 'item', not allowed + // If allowed filter has something in it + filter doesn't have basetype 'item', not allowed if (filter.Count > 0 && !filter.Contains(itemDetails?.Parent ?? string.Empty)) { return false; diff --git a/Libraries/SPTarkov.Server.Core/Helpers/BotHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/BotHelper.cs index c5cd8588..d28a08d9 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/BotHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/BotHelper.cs @@ -126,21 +126,6 @@ public class BotHelper( } } - /// - /// is the provided role a PMC, case-agnostic - /// - /// Role to check - /// True if role is PMC - public bool BotRoleIsPmc(string botRole) - { - HashSet listToCheck = - [ - _pmcConfig.UsecType.ToLowerInvariant(), - _pmcConfig.BearType.ToLowerInvariant(), - ]; - return listToCheck.Contains(botRole.ToLowerInvariant()); - } - /// /// Get randomization settings for bot from config/bot.json /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index 337d52ee..ff2427dc 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -250,7 +250,7 @@ public class InRaidHelper( // Ensure we don't pick up pocket items from mannequins if ( item.SlotId.StartsWith("pocket") - && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory.Equipment) + && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory.Equipment.Value) ) { return true; diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 2db00564..f1a2de5b 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -1152,7 +1152,7 @@ public class ItemHelper( /// Items tpl to check parents of /// Tpl values to check if parents of item match /// bool Match found - public bool DoesItemOrParentsIdMatch(MongoId tpl, List tplsToCheck) + public bool DoesItemOrParentsIdMatch(MongoId tpl, HashSet tplsToCheck) { var (itemExists, item) = GetItem(tpl); @@ -1631,7 +1631,7 @@ public class ItemHelper( string caliber, Dictionary> staticAmmoDist, MongoId? fallbackCartridgeTpl = null, - ICollection? cartridgeWhitelist = null + ISet? cartridgeWhitelist = null ) { var ammos = staticAmmoDist.GetValueOrDefault(caliber, []); diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs index 338e4b61..1009532c 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ProfileHelper.cs @@ -372,13 +372,13 @@ public class ProfileHelper( var secureContainer = items.FirstOrDefault(i => i.SlotId == "SecuredContainer"); if (secureContainer is not null) { - // Find and remove container + children - var childItemsInSecureContainer = items.GetItemWithChildrenTpls(secureContainer.Id); + // Find secure container + children + var secureContainerAndChildrenIds = items + .GetItemWithChildrenTpls(secureContainer.Id) + .ToHashSet(); - // Remove child items + secure container - profile.Inventory.Items = items - .Where(i => !childItemsInSecureContainer.Contains(i.Id)) - .ToList(); + // Remove secure container + its children + items.RemoveAll(x => secureContainerAndChildrenIds.Contains(x.Id)); } return profile; diff --git a/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs index a5e411f9..2756cf36 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs @@ -103,7 +103,7 @@ public class QuestHelper( /// List of quests #1 /// List of quests #2 /// quests not in before - public List GetDeltaQuests(List before, List after) + public IEnumerable GetDeltaQuests(List before, List after) { // Nothing to compare against, return after if (before.Count == 0) @@ -115,7 +115,7 @@ public class QuestHelper( var beforeQuests = before.Select(quest => quest.Id).ToHashSet(); // Return quests found in after but not before - return after.Where(quest => !beforeQuests.Contains(quest.Id)).ToList(); + return after.Where(quest => !beforeQuests.Contains(quest.Id)); } /// @@ -586,7 +586,7 @@ public class QuestHelper( var acceptedQuestCondition = q.Conditions.AvailableForStart.FirstOrDefault(c => c.ConditionType == "Quest" && (c.Target.IsList ? c.Target.List : [c.Target.Item]).Contains(failedQuestId) - && c.Status[0] == QuestStatusEnum.Fail + && c.Status.First() == QuestStatusEnum.Fail ); if (acceptedQuestCondition is null) @@ -1586,7 +1586,7 @@ public class QuestHelper( /// Quest just completed protected void AddTimeLockedQuestsToProfile( PmcData pmcData, - List quests, + IEnumerable quests, MongoId completedQuestId ) { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs index 864fd40b..d69e082c 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RagfairOfferHelper.cs @@ -612,9 +612,9 @@ public class RagfairOfferHelper( return false; } - protected HashSet GetLoyaltyLockedOffers(List offers, PmcData pmcProfile) + protected HashSet GetLoyaltyLockedOffers(List offers, PmcData pmcProfile) { - var loyaltyLockedOffers = new HashSet(); + var loyaltyLockedOffers = new HashSet(); foreach (var offer in offers.Where(x => x.IsTraderOffer())) { if ( diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TraderAssortHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TraderAssortHelper.cs index a6022730..d3086c61 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/TraderAssortHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/TraderAssortHelper.cs @@ -24,8 +24,8 @@ public class TraderAssortHelper( ICloner cloner ) { - private Dictionary>? _mergedQuestAssorts; - protected virtual Dictionary> MergedQuestAssorts + private Dictionary>? _mergedQuestAssorts; + protected virtual Dictionary> MergedQuestAssorts { get { return _mergedQuestAssorts ??= HydrateMergedQuestAssorts(); } } @@ -148,9 +148,9 @@ public class TraderAssortHelper( /// Create a dictionary keyed by quest status (started/success) with every assortId to QuestId from every trader /// /// Dictionary - protected Dictionary> HydrateMergedQuestAssorts() + protected Dictionary> HydrateMergedQuestAssorts() { - var result = new Dictionary>(); + var result = new Dictionary>(); // Loop every trader var traders = databaseService.GetTraders(); @@ -171,7 +171,7 @@ public class TraderAssortHelper( } // Null guard - ensure Started/Success/fail exists - result.TryAdd(unlockStatus, new Dictionary()); + result.TryAdd(unlockStatus, new Dictionary()); foreach (var (assortId, questId) in assortToQuestDict) { diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs index ad6e7f0c..9cb5a530 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/BotBase.cs @@ -606,7 +606,7 @@ public record CounterKeyValue [JsonExtensionData] public Dictionary? ExtensionData { get; set; } - public IEnumerable? Key { get; set; } + public HashSet? Key { get; set; } public double? Value { get; set; } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs index bb99af27..87f79f30 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/ProfileTemplate.cs @@ -79,11 +79,11 @@ public record ProfileTraderTemplate /// What traders default to being locked on profile creation /// [JsonPropertyName("lockedByDefaultOverride")] - public List? LockedByDefaultOverride { get; set; } + public HashSet? LockedByDefaultOverride { get; set; } /// /// What traders should have their clothing unlocked/purchased on creation /// [JsonPropertyName("purchaseAllClothingByDefaultForTrader")] - public List? PurchaseAllClothingByDefaultForTrader { get; set; } + public HashSet? PurchaseAllClothingByDefaultForTrader { get; set; } } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs index f0d7d1ec..20f42673 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Quest.cs @@ -213,7 +213,7 @@ public record QuestCondition public string? Type { get; set; } [JsonPropertyName("status")] - public List? Status { get; set; } + public HashSet? Status { get; set; } [JsonPropertyName("availableAfter")] public int? AvailableAfter { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/RepeatableQuests.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/RepeatableQuests.cs index 19972015..2e06d406 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/RepeatableQuests.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/RepeatableQuests.cs @@ -189,7 +189,7 @@ public record ItemsBlacklist public int? MinPlayerLevel { get; set; } [JsonPropertyName("itemIds")] - public List? ItemIds { get; set; } + public HashSet? ItemIds { get; set; } } public record ItemsWhitelist @@ -201,7 +201,7 @@ public record ItemsWhitelist public int? MinPlayerLevel { get; set; } [JsonPropertyName("itemIds")] - public List? ItemIds { get; set; } + public HashSet? ItemIds { get; set; } } public record SampleQuests diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/TemplateItem.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/TemplateItem.cs index 9557ed4b..4f327362 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/TemplateItem.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/TemplateItem.cs @@ -1725,7 +1725,7 @@ public record GridFilter public HashSet? Filter { get; set; } [JsonPropertyName("ExcludedFilter")] - public List? ExcludedFilter { get; set; } + public HashSet? ExcludedFilter { get; set; } [JsonPropertyName("locked")] public bool? Locked { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs index e5a11bd6..55606b89 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Profile/SptProfile.cs @@ -57,7 +57,7 @@ public record SptProfile /// List of friend profile IDs /// [JsonPropertyName("friends")] - public List? FriendProfileIds { get; set; } + public HashSet? FriendProfileIds { get; set; } /// /// Stores profile-related customisation, e.g. clothing / hideout walls / floors @@ -422,7 +422,7 @@ public record Spt /// item TPLs blacklisted from being sold on flea for this profile /// [JsonPropertyName("blacklistedItemTpls")] - public HashSet? BlacklistedItemTemplates { get; set; } + public HashSet? BlacklistedItemTemplates { get; set; } /// /// key: daily type diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/GenerateEquipmentProperties.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/GenerateEquipmentProperties.cs index b98065e2..de0e8b08 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/GenerateEquipmentProperties.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/GenerateEquipmentProperties.cs @@ -54,7 +54,7 @@ public record GenerateEquipmentProperties /// OPTIONAL - Do not generate mods for tpls in this array /// [JsonPropertyName("generateModsBlacklist")] - public HashSet? GenerateModsBlacklist { get; set; } + public HashSet? GenerateModsBlacklist { get; set; } [JsonPropertyName("generatingPlayerLevel")] public double? GeneratingPlayerLevel { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs index 9ade62a7..74aa919e 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Bots/ModToSpawnRequest.cs @@ -30,7 +30,7 @@ public record ModToSpawnRequest /// Parent slot the item will be a part of /// [JsonPropertyName("botWeaponSightWhitelist")] - public Dictionary>? BotWeaponSightWhitelist { get; set; } + public Dictionary>? BotWeaponSightWhitelist { get; set; } /// /// Blacklist to prevent mods from being picked diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/AirdropConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/AirdropConfig.cs index 683b3c39..52fcf68e 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/AirdropConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/AirdropConfig.cs @@ -86,7 +86,7 @@ public record AirdropLoot /// Armor levels to allow inside crate e.g. [4,5,6] /// [JsonPropertyName("armorLevelWhitelist")] - public List? ArmorLevelWhitelist { get; set; } + public HashSet? ArmorLevelWhitelist { get; set; } /// /// Should boss items be added to airdrop crate diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/BotConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/BotConfig.cs index 90cd9104..9f346544 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/BotConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/BotConfig.cs @@ -188,7 +188,7 @@ public record WalletLootSettings /// What wallets will have money in them /// [JsonPropertyName("walletTplPool")] - public required List WalletTplPool { get; set; } + public required HashSet WalletTplPool { get; set; } } public record EquipmentFilters @@ -206,7 +206,7 @@ public record EquipmentFilters /// Whitelist for weapon sight types allowed per gun /// [JsonPropertyName("weaponSightWhitelist")] - public Dictionary>? WeaponSightWhitelist { get; set; } + public Dictionary>? WeaponSightWhitelist { get; set; } [JsonPropertyName("forceOnlyArmoredRigWhenNoArmor")] public bool? ForceOnlyArmoredRigWhenNoArmor { get; set; } @@ -332,13 +332,13 @@ public record RandomisationDetails /// Mod slots that should be fully randomised -ignores mods from bottype.json and instead creates a pool using items.json /// [JsonPropertyName("randomisedWeaponModSlots")] - public List? RandomisedWeaponModSlots { get; set; } + public HashSet? RandomisedWeaponModSlots { get; set; } /// /// Armor slots that should be randomised e.g. 'Headwear, Armband' /// [JsonPropertyName("randomisedArmorSlots")] - public List? RandomisedArmorSlots { get; set; } + public HashSet? RandomisedArmorSlots { get; set; } /// /// Equipment chances diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InRaidConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InRaidConfig.cs index bb695cd0..0bee35de 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InRaidConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/InRaidConfig.cs @@ -17,13 +17,13 @@ public record InRaidConfig : BaseConfig /// Names of car extracts /// [JsonPropertyName("carExtracts")] - public required List CarExtracts { get; set; } + public required HashSet CarExtracts { get; set; } /// /// Names of coop extracts /// [JsonPropertyName("coopExtracts")] - public required List CoopExtracts { get; set; } + public required HashSet CoopExtracts { get; set; } /// /// Fence rep gain from a single car extract diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocaleConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocaleConfig.cs index 9a2cabf7..1b4aa481 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocaleConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocaleConfig.cs @@ -23,7 +23,7 @@ public record LocaleConfig : BaseConfig /// Languages server can be translated into /// [JsonPropertyName("serverSupportedLocales")] - public required List ServerSupportedLocales { get; set; } + public required HashSet ServerSupportedLocales { get; set; } [JsonPropertyName("fallbacks")] public required Dictionary Fallbacks { get; set; } diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocationConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocationConfig.cs index cb6e3ee2..4b6452f9 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocationConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/LocationConfig.cs @@ -106,7 +106,7 @@ public record LocationConfig : BaseConfig /// Key: map, value: loose loot ids to ignore /// [JsonPropertyName("looseLootBlacklist")] - public required Dictionary> LooseLootBlacklist { get; set; } + public required Dictionary> LooseLootBlacklist { get; set; } /// /// Key: map, value: settings to control how long scav raids are diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs index e51703e3..f2098c8a 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/QuestConfig.cs @@ -413,7 +413,7 @@ public record SpecificExits /// Whitelist of specific extract types /// [JsonPropertyName("passageRequirementWhitelist")] - public required List PassageRequirementWhitelist { get; set; } + public required HashSet PassageRequirementWhitelist { get; set; } } public record Completion : BaseQuestConfig @@ -541,7 +541,7 @@ public record EliminationConfig : BaseQuestConfig /// Locations that should be blacklisted as a requirement /// [JsonPropertyName("distLocationBlacklist")] - public required List DistLocationBlacklist { get; set; } + public required HashSet DistLocationBlacklist { get; set; } /// /// Probability that a distance requirement is chosen diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs index d399da1d..d432051a 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Config/SeasonalEventConfig.cs @@ -63,7 +63,7 @@ public record SeasonalEventConfig : BaseConfig /// Ids of containers on locations that only have Christmas loot /// [JsonPropertyName("christmasContainerIds")] - public required List ChristmasContainerIds { get; set; } + public required HashSet ChristmasContainerIds { get; set; } /// /// Season - botType - location (body/feet/hands/head) diff --git a/Libraries/SPTarkov.Server.Core/Models/Spt/Services/LootRequest.cs b/Libraries/SPTarkov.Server.Core/Models/Spt/Services/LootRequest.cs index e5864c65..ca707507 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Spt/Services/LootRequest.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Spt/Services/LootRequest.cs @@ -58,7 +58,7 @@ public record LootRequest /// Allowed armor plate levels 2/3/4/5/6 for armor generated /// [JsonPropertyName("armorLevelWhitelist")] - public List? ArmorLevelWhitelist { get; set; } + public HashSet? ArmorLevelWhitelist { get; set; } /// /// Should boss items be included in allowed items diff --git a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs index 66002719..bcf03405 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BotEquipmentFilterService.cs @@ -161,16 +161,13 @@ public class BotEquipmentFilterService( /// /// equipment role of bot to look up /// Dictionary of weapon type and their whitelisted scope types - public Dictionary> GetBotWeaponSightWhitelist(string botEquipmentRole) + public Dictionary>? GetBotWeaponSightWhitelist( + string botEquipmentRole + ) { - var botEquipmentSettings = _botConfig.Equipment[botEquipmentRole]; - - if (botEquipmentSettings is null) - { - return null; - } - - return botEquipmentSettings.WeaponSightWhitelist; + return _botConfig.Equipment.TryGetValue(botEquipmentRole, out var botEquipmentSettings) + ? botEquipmentSettings.WeaponSightWhitelist + : null; } /// diff --git a/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs b/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs index b661258d..3f81bee0 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs @@ -66,7 +66,7 @@ public class BtrDeliveryService( // Remove any items that were returned by the item delivery, but also insured, from the player's insurance list // This is to stop items being duplicated by being returned from both item delivery and insurance - var deliveredItemIds = items.Select(item => item.Id); + var deliveredItemIds = items.Select(item => item.Id).ToHashSet(); pmcData.InsuredItems = pmcData .InsuredItems.Where(insuredItem => !deliveredItemIds.Contains(insuredItem.ItemId.Value)) .ToList(); diff --git a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs index 8a1eaaef..6f502502 100644 --- a/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/CircleOfCultistService.cs @@ -468,6 +468,7 @@ public class CircleOfCultistService( // Handle special case of tagilla helmets - only one reward is allowed if (directReward.Reward.Contains(ItemTpl.FACECOVER_TAGILLAS_WELDING_MASK_GORILLA)) { + // TODO: this is likely redundant with direct reward system in config? directReward.Reward = [randomUtil.GetArrayValue(directReward.Reward)]; } @@ -598,7 +599,7 @@ public class CircleOfCultistService( /// /// Item being rewarded to get stack size of /// stack size of item - protected int GetDirectRewardBaseTypeStackSize(string rewardTpl) + protected int GetDirectRewardBaseTypeStackSize(MongoId rewardTpl) { var itemDetails = itemHelper.GetItem(rewardTpl); if (!itemDetails.Key) diff --git a/Libraries/SPTarkov.Server.Core/Services/LocaleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocaleService.cs index 893b2930..e4601833 100644 --- a/Libraries/SPTarkov.Server.Core/Services/LocaleService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/LocaleService.cs @@ -109,7 +109,7 @@ public class LocaleService( /// Get array of languages supported for localisation /// /// List of locales e.g. en/fr/cn - public List GetServerSupportedLocales() + public HashSet GetServerSupportedLocales() { return _localeConfig.ServerSupportedLocales; } diff --git a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs index cf0d9c5f..0198689d 100644 --- a/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/LocationLifecycleService.cs @@ -601,7 +601,7 @@ public class LocationLifecycleService( /// /// Name of extract player took /// True if coop extract - protected bool ExtractTakenWasCoop(string extractName) + protected bool ExtractTakenWasCoop(string? extractName) { // No extract name, not a coop extract if (extractName is null) @@ -990,7 +990,8 @@ public class LocationLifecycleService( is not QuestStatusEnum.AvailableForStart and not QuestStatusEnum.Success ) - .Select(status => status.QId); + .Select(status => status.QId) + .ToHashSet(); // Get db details of quests we found above var questDb = databaseService diff --git a/Libraries/SPTarkov.Server.Core/Services/OpenZoneService.cs b/Libraries/SPTarkov.Server.Core/Services/OpenZoneService.cs index 226dd676..3f4b785a 100644 --- a/Libraries/SPTarkov.Server.Core/Services/OpenZoneService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/OpenZoneService.cs @@ -53,7 +53,7 @@ public class OpenZoneService( var zonesToAdd = _locationConfig.OpenZones[mapKvP.Key]; // Convert openzones string into list, easier to work wih - var mapOpenZonesArray = dbLocations[mapKvP.Key].Base.OpenZones.Split(",").ToList(); + var mapOpenZonesArray = dbLocations[mapKvP.Key].Base.OpenZones.Split(",").ToHashSet(); foreach ( var zoneToAdd in zonesToAdd.Where(zoneToAdd => !mapOpenZonesArray.Contains(zoneToAdd) diff --git a/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs b/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs index f7935493..ad86823b 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs @@ -131,9 +131,9 @@ public class ServerLocalisationService( /// Locale text public string GetRandomTextThatMatchesPartialKey(string partialKey) { - var matchingKeys = GetLocaleKeys().Where(x => x.Contains(partialKey)).ToList(); + var matchingKeys = GetLocaleKeys().Where(x => x.Contains(partialKey)); - if (matchingKeys.Count == 0) + if (!matchingKeys.Any()) { logger.Warning($"No locale keys found for: {partialKey}"); diff --git a/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs b/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs index c1ce526e..3be76693 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/RagfairOfferHolder.cs @@ -21,7 +21,7 @@ public class RagfairOfferHolder( /// /// Expired offer Ids /// - private readonly HashSet _expiredOfferIds = []; + private readonly HashSet _expiredOfferIds = []; /// /// Ragfair offer cache, keyed by offer Id @@ -55,7 +55,7 @@ public class RagfairOfferHolder( /// Get a ragfair offer by its id /// /// RagfairOffer - public HashSet GetStaleOfferIds() + public HashSet GetStaleOfferIds() { lock (_expiredOfferIdsLock) {