From 5ef2271a2991b9cfa46c2b0226f095182ca1e8eb Mon Sep 17 00:00:00 2001 From: Chomp Date: Mon, 14 Jul 2025 19:56:20 +0100 Subject: [PATCH] Converted collections to their frozen counterparts for improved lookup speed --- .../Controllers/HideoutController.cs | 3 ++- .../Controllers/RepeatableQuestController.cs | 8 +++++++- .../Extensions/ItemExtensions.cs | 2 +- .../Generators/BotInventoryGenerator.cs | 6 +++--- .../Generators/RagfairAssortGenerator.cs | 7 ++++--- .../EliminationQuestGenerator.cs | 16 +++++++++------- .../Helpers/HttpServerHelper.cs | 7 ++++--- .../Helpers/InRaidHelper.cs | 5 +++-- .../Helpers/ItemHelper.cs | 2 +- .../Helpers/QuestHelper.cs | 3 ++- .../Services/BtrDeliveryService.cs | 4 ++-- .../Services/FenceService.cs | 3 ++- .../Services/MailSendService.cs | 5 +++-- .../Services/MatchBotDetailsCacheService.cs | 3 ++- .../Services/ProfileFixerService.cs | 3 ++- .../Services/SeasonalEventService.cs | 19 +++++++------------ .../Services/ServerLocalisationService.cs | 6 ++++-- 17 files changed, 58 insertions(+), 44 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs index 29f59712..3c8c7059 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/HideoutController.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Generators; @@ -45,7 +46,7 @@ public class HideoutController( { public const string NameTaskConditionCountersCraftingId = "673f5d6fdd6ed700c703afdc"; - protected readonly HashSet _areasWithResources = + protected readonly FrozenSet _areasWithResources = [ HideoutAreas.AirFilteringUnit, HideoutAreas.WaterCollector, diff --git a/Libraries/SPTarkov.Server.Core/Controllers/RepeatableQuestController.cs b/Libraries/SPTarkov.Server.Core/Controllers/RepeatableQuestController.cs index cf06c5cd..d4ac3353 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/RepeatableQuestController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/RepeatableQuestController.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Generators.RepeatableQuestGeneration; @@ -45,7 +46,12 @@ public class RepeatableQuestController( ICloner cloner ) { - protected static readonly List _questTypes = ["PickUp", "Exploration", "Elimination"]; + protected static readonly FrozenSet _questTypes = + [ + "PickUp", + "Exploration", + "Elimination", + ]; protected readonly QuestConfig QuestConfig = configServer.GetConfig(); /// diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs index efeb0532..ba614748 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs @@ -19,7 +19,7 @@ namespace SPTarkov.Server.Core.Extensions public static bool IsSameItem( this Item item1, Item item2, - HashSet? compareUpdProperties = null + ISet? compareUpdProperties = null ) { // Different tpl == different item diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs index 4a803154..b4a7f4ba 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotInventoryGenerator.cs @@ -51,10 +51,10 @@ public class BotInventoryGenerator( private readonly BotConfig _botConfig = configServer.GetConfig(); - private readonly HashSet _slotsToCheck = + private readonly FrozenSet _slotsToCheck = [ - EquipmentSlots.Pockets.ToString(), - EquipmentSlots.SecuredContainer.ToString(), + nameof(EquipmentSlots.Pockets), + nameof(EquipmentSlots.SecuredContainer), ]; /// diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairAssortGenerator.cs index 377b1fce..5161e009 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 System.Collections.Frozen; +using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Models.Common; @@ -23,7 +24,7 @@ public class RagfairAssortGenerator( { protected readonly RagfairConfig RagfairConfig = configServer.GetConfig(); - protected readonly List RagfairItemInvalidBaseTypes = + protected readonly FrozenSet RagfairItemInvalidBaseTypes = [ BaseClasses.LOOT_CONTAINER, // Safe, barrel cache etc BaseClasses.STASH, // Player inventory stash @@ -58,7 +59,7 @@ public class RagfairAssortGenerator( .Where(item => !string.Equals(item.Type, "Node", StringComparison.OrdinalIgnoreCase)); // Store processed preset tpls so we don't add them when processing non-preset items - HashSet processedArmorItems = []; + HashSet processedArmorItems = []; var seasonalEventActive = seasonalEventService.SeasonalEventEnabled(); var seasonalItemTplBlacklist = seasonalEventService.GetInactiveSeasonalEventItems(); diff --git a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs index 77540e58..66128823 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RepeatableQuestGeneration/EliminationQuestGenerator.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Helpers; using SPTarkov.Server.Core.Models.Common; @@ -34,13 +35,14 @@ public class EliminationQuestGenerator( /// /// Body parts to present to the client as opposed to the body part information in quest data. /// - private static readonly Dictionary> _bodyPartsToClient = new() - { - { BodyParts.Arms, [BodyParts.LeftArm, BodyParts.RightArm] }, - { BodyParts.Legs, [BodyParts.LeftLeg, BodyParts.RightLeg] }, - { BodyParts.Head, [BodyParts.Head] }, - { BodyParts.Chest, [BodyParts.Chest, BodyParts.Stomach] }, - }; + private static readonly FrozenDictionary> _bodyPartsToClient = + new Dictionary> + { + { BodyParts.Arms, [BodyParts.LeftArm, BodyParts.RightArm] }, + { BodyParts.Legs, [BodyParts.LeftLeg, BodyParts.RightLeg] }, + { BodyParts.Head, [BodyParts.Head] }, + { BodyParts.Chest, [BodyParts.Chest, BodyParts.Stomach] }, + }.ToFrozenDictionary(); /// /// MaxDistDifficulty is defined by 2, this could be a tuning parameter if we don't like the reward generation diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs index 2e29f1fa..480a5714 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs @@ -1,4 +1,5 @@ -using System.Net; +using System.Collections.Frozen; +using System.Net; using System.Net.Sockets; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Models.Spt.Config; @@ -11,7 +12,7 @@ public class HttpServerHelper(ConfigServer configServer) { protected readonly HttpConfig _httpConfig = configServer.GetConfig(); - protected readonly Dictionary mime = new() + protected readonly FrozenDictionary mime = new Dictionary { { "css", "text/css" }, { "bin", "application/octet-stream" }, @@ -22,7 +23,7 @@ public class HttpServerHelper(ConfigServer configServer) { "png", "image/png" }, { "svg", "image/svg+xml" }, { "txt", "text/plain" }, - }; + }.ToFrozenDictionary(); public string? GetMimeText(string key) { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index 7c5d542f..1ba40b24 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -1,4 +1,5 @@ -using SPTarkov.Common.Extensions; +using System.Collections.Frozen; +using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Models.Common; @@ -19,7 +20,7 @@ public class InRaidHelper( DatabaseService databaseService ) { - protected static readonly List _pocketSlots = + protected static readonly FrozenSet _pocketSlots = [ "pocket1", "pocket2", diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index e5ff2177..e11f07d7 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -157,7 +157,7 @@ public class ItemHelper( public bool IsSameItems( ICollection item1, ICollection item2, - HashSet? compareUpdProperties = null + ISet? compareUpdProperties = null ) { if (item1.Count != item2.Count) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs index 5564f238..bb4450cf 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/QuestHelper.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using System.Globalization; using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; @@ -38,7 +39,7 @@ public class QuestHelper( ICloner cloner ) { - protected readonly HashSet _startedOrAvailToFinish = + protected readonly FrozenSet _startedOrAvailToFinish = [ QuestStatusEnum.Started, QuestStatusEnum.AvailableForFinish, diff --git a/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs b/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs index 27f69abd..e96e9484 100644 --- a/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/BtrDeliveryService.cs @@ -28,7 +28,7 @@ public class BtrDeliveryService( configServer.GetConfig(); protected readonly TraderConfig _traderConfig = configServer.GetConfig(); - protected static readonly List _transferTypes = new() { "btr", "transit" }; + protected static readonly List _transferTypes = ["btr", "transit"]; /// /// Check if player used BTR or transit item sending service and send items to player via mail if found @@ -42,7 +42,7 @@ public class BtrDeliveryService( var rootId = $"{Traders.BTR}_{transferType}"; List? itemsToSend = null; - // if rootId doesnt exist in TransferItems, skip + // if rootId doesn't exist in TransferItems, skip if (!request?.TransferItems?.TryGetValue(rootId, out itemsToSend) ?? false) { continue; diff --git a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs index a378037d..b0d50922 100644 --- a/Libraries/SPTarkov.Server.Core/Services/FenceService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/FenceService.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; @@ -44,7 +45,7 @@ public class FenceService( /// protected TraderAssort? fenceDiscountAssort; - protected readonly HashSet fenceItemUpdCompareProperties = + protected readonly FrozenSet fenceItemUpdCompareProperties = [ "Buff", "Repairable", diff --git a/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs b/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs index ecac8aea..10d61968 100644 --- a/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/MailSendService.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Helpers; @@ -29,12 +30,12 @@ public class MailSendService( ) { private const string _systemSenderId = "59e7125688a45068a6249071"; - protected readonly HashSet _messageTypes = + protected readonly FrozenSet _messageTypes = [ MessageType.NpcTraderMessage, MessageType.FleamarketMessage, ]; - protected readonly HashSet _slotNames = ["hideout", "main"]; + protected readonly FrozenSet _slotNames = ["hideout", "main"]; /// /// Send a message from an NPC (e.g. prapor) to the player with or without items using direct message text, do not look up any locale diff --git a/Libraries/SPTarkov.Server.Core/Services/MatchBotDetailsCacheService.cs b/Libraries/SPTarkov.Server.Core/Services/MatchBotDetailsCacheService.cs index 413253e9..6bc824e3 100644 --- a/Libraries/SPTarkov.Server.Core/Services/MatchBotDetailsCacheService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/MatchBotDetailsCacheService.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Collections.Frozen; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Constants; using SPTarkov.Server.Core.Models.Eft.Common.Tables; @@ -14,7 +15,7 @@ namespace SPTarkov.Server.Core.Services; [Injectable(InjectionType.Singleton)] public class MatchBotDetailsCacheService(ISptLogger logger) { - private static readonly HashSet _sidesToCache = [Sides.PmcUsec, Sides.PmcBear]; + private static readonly FrozenSet _sidesToCache = [Sides.PmcUsec, Sides.PmcBear]; protected readonly ConcurrentDictionary BotDetailsCache = new(); diff --git a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs index 0a175736..0513ed26 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ProfileFixerService.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using System.Text.RegularExpressions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; @@ -29,7 +30,7 @@ public class ProfileFixerService( InventoryHelper inventoryHelper ) { - protected readonly List _areas = ["hideout", "main"]; + protected readonly FrozenSet _areas = ["hideout", "main"]; protected readonly CoreConfig _coreConfig = configServer.GetConfig(); /// diff --git a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs index f16ed05a..23839f45 100644 --- a/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/SeasonalEventService.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Extensions; @@ -28,7 +29,7 @@ public class SeasonalEventService( { private bool _christmasEventActive; - protected readonly HashSet _christmasEventItems = + protected readonly FrozenSet _christmasEventItems = [ ItemTpl.ARMOR_6B13_M_ASSAULT_ARMOR_CHRISTMAS_EDITION, ItemTpl.BACKPACK_SANTAS_BAG, @@ -61,7 +62,7 @@ public class SeasonalEventService( private List _currentlyActiveEvents = []; - protected readonly HashSet _equipmentSlotsToFilter = + protected readonly FrozenSet _equipmentSlotsToFilter = [ EquipmentSlots.FaceCover, EquipmentSlots.Headwear, @@ -71,7 +72,7 @@ public class SeasonalEventService( private bool _halloweenEventActive; - protected readonly HashSet _halloweenEventItems = + protected readonly FrozenSet _halloweenEventItems = [ ItemTpl.HEADWEAR_JACKOLANTERN_TACTICAL_PUMPKIN_HELMET, ItemTpl.FACECOVER_FACELESS_MASK, @@ -88,12 +89,6 @@ public class SeasonalEventService( protected readonly HttpConfig _httpConfig = configServer.GetConfig(); protected readonly LocationConfig _locationConfig = configServer.GetConfig(); - protected readonly HashSet _lootContainersToFilter = - [ - "Backpack", - "Pockets", - "TacticalVest", - ]; protected readonly QuestConfig _questConfig = configServer.GetConfig(); protected readonly SeasonalEventConfig _seasonalEventConfig = configServer.GetConfig(); @@ -103,7 +98,7 @@ public class SeasonalEventService( /// Get an array of christmas items found in bots inventories as loot /// /// array - public HashSet GetChristmasEventItems() + public FrozenSet GetChristmasEventItems() { return _christmasEventItems; } @@ -112,7 +107,7 @@ public class SeasonalEventService( /// Get an array of halloween items found in bots inventories as loot /// /// array - public HashSet GetHalloweenEventItems() + public FrozenSet GetHalloweenEventItems() { return _halloweenEventItems; } @@ -207,7 +202,7 @@ public class SeasonalEventService( /// /// Get a dictionary of gear changes to apply to bots for a specific event e.g. Christmas/Halloween /// - /// Name of event to get gear changes for + /// Name of event to get gear changes for /// bots with equipment changes protected Dictionary>>? GetEventBotGear( SeasonalEventType eventType diff --git a/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs b/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs index 9ea43701..f7935493 100644 --- a/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/ServerLocalisationService.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Models.Utils; @@ -20,8 +21,9 @@ public class ServerLocalisationService( { private readonly Dictionary>> _loadedLocales = []; private string _serverLocale = localeService.GetDesiredServerLocale(); - private readonly Dictionary _localeFallbacks = - localeService.GetLocaleFallbacks(); + private readonly FrozenDictionary _localeFallbacks = localeService + .GetLocaleFallbacks() + .ToFrozenDictionary(); private const string DefaultLocale = "en"; private const string LocaleDirectory = "./SPT_Data/database/locales/server";