From 4b9baa89d5728347301bd328e3778b876287b4d1 Mon Sep 17 00:00:00 2001 From: Cj <161484149+CJ-SPT@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:04:46 -0400 Subject: [PATCH 1/2] Helper warning fixes --- .../Helpers/InRaidHelperException.cs | 10 ++ .../Helpers/InventoryHelperException.cs | 10 ++ .../Helpers/HttpServerHelper.cs | 10 +- .../Helpers/InRaidHelper.cs | 108 ++++++++++++------ 4 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InRaidHelperException.cs create mode 100644 Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InventoryHelperException.cs diff --git a/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InRaidHelperException.cs b/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InRaidHelperException.cs new file mode 100644 index 000000000..64ba38486 --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InRaidHelperException.cs @@ -0,0 +1,10 @@ +namespace SPTarkov.Server.Core.Exceptions.Helpers; + +public class InRaidHelperException : Exception +{ + public InRaidHelperException(string message) + : base(message) { } + + public InRaidHelperException(string message, Exception innerException) + : base(message, innerException) { } +} diff --git a/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InventoryHelperException.cs b/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InventoryHelperException.cs new file mode 100644 index 000000000..7f807767a --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Exceptions/Helpers/InventoryHelperException.cs @@ -0,0 +1,10 @@ +namespace SPTarkov.Server.Core.Exceptions.Helpers; + +public class InventoryHelperException : Exception +{ + public InventoryHelperException(string message) + : base(message) { } + + public InventoryHelperException(string message, Exception innerException) + : base(message, innerException) { } +} diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs index 37fbdb1b3..6648dce54 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HttpServerHelper.cs @@ -9,9 +9,9 @@ namespace SPTarkov.Server.Core.Helpers; [Injectable(InjectionType.Singleton)] public class HttpServerHelper(ConfigServer configServer) { - protected readonly HttpConfig _httpConfig = configServer.GetConfig(); + protected readonly HttpConfig HttpConfig = configServer.GetConfig(); - protected readonly FrozenDictionary mime = new Dictionary + protected readonly FrozenDictionary Mime = new Dictionary { { "css", "text/css" }, { "bin", "application/octet-stream" }, @@ -26,7 +26,7 @@ public class HttpServerHelper(ConfigServer configServer) public string? GetMimeText(string key) { - return mime.GetValueOrDefault(key); + return Mime.GetValueOrDefault(key); } /// @@ -35,7 +35,7 @@ public class HttpServerHelper(ConfigServer configServer) /// URI public string BuildUrl() { - return $"{_httpConfig.BackendIp}:{_httpConfig.BackendPort}"; + return $"{HttpConfig.BackendIp}:{HttpConfig.BackendPort}"; } /// @@ -58,7 +58,7 @@ public string GetWebsocketUrl() public void SendTextJson(HttpResponse resp, object output) { - resp.Headers.Append("Content-Type", mime["json"]); + resp.Headers.Append("Content-Type", Mime["json"]); resp.StatusCode = 200; // TODO: figure this one out // resp.writeHead(200, "OK", { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index e9de0b4a8..b454c9817 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -1,11 +1,13 @@ using System.Collections.Frozen; using SPTarkov.Common.Extensions; using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Exceptions.Helpers; using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Spt.Config; +using SPTarkov.Server.Core.Models.Utils; using SPTarkov.Server.Core.Servers; using SPTarkov.Server.Core.Services; using SPTarkov.Server.Core.Utils.Cloners; @@ -13,23 +15,17 @@ namespace SPTarkov.Server.Core.Helpers; [Injectable] -public class InRaidHelper(InventoryHelper inventoryHelper, ConfigServer configServer, ICloner cloner, DatabaseService databaseService) +public class InRaidHelper( + ISptLogger logger, + InventoryHelper inventoryHelper, + ConfigServer configServer, + ICloner cloner, + DatabaseService databaseService +) { - protected static readonly FrozenSet _pocketSlots = ["pocket1", "pocket2", "pocket3", "pocket4"]; - protected readonly InRaidConfig _inRaidConfig = configServer.GetConfig(); - protected readonly LostOnDeathConfig _lostOnDeathConfig = configServer.GetConfig(); - - /// - /// Deprecated. Reset the skill points earned in a raid to 0, ready for next raid. - /// - /// Profile to update - protected void ResetSkillPointsEarnedDuringRaid(PmcData profile) - { - foreach (var skill in profile.Skills.Common) - { - skill.PointsEarnedDuringSession = 0.0; - } - } + protected static readonly FrozenSet PocketSlots = ["pocket1", "pocket2", "pocket3", "pocket4"]; + protected readonly InRaidConfig InRaidConfig = configServer.GetConfig(); + protected readonly LostOnDeathConfig LostOnDeathConfig = configServer.GetConfig(); /// /// Update a player's inventory post-raid. @@ -37,21 +33,53 @@ protected void ResetSkillPointsEarnedDuringRaid(PmcData profile) /// Add new items found in raid to profile. /// Store insurance items in profile. /// - /// Session id + /// Session id /// Profile to update /// Profile returned by client after a raid /// Indicates if the player survived the raid /// Indicates if it is a transfer operation - public void SetInventory(MongoId sessionID, PmcData serverProfile, PmcData postRaidProfile, bool isSurvived, bool isTransfer) + public void SetInventory(MongoId sessionId, PmcData serverProfile, PmcData postRaidProfile, bool isSurvived, bool isTransfer) { + if (serverProfile.InsuredItems is null) + { + throw new InRaidHelperException("Insured items are null when trying to set inventory post raid"); + } + + if ( + serverProfile.Inventory?.Items is null + || serverProfile.Inventory.QuestRaidItems is null + || serverProfile.Inventory?.Equipment is null + ) + { + throw new InRaidHelperException( + "Server profile inventory items, quest raid items, or equipment are null when trying to set inventory post raid" + ); + } + + if ( + postRaidProfile.Inventory?.Items is null + || postRaidProfile.Inventory.QuestRaidItems is null + || postRaidProfile.Inventory.Equipment is null + ) + { + throw new InRaidHelperException( + "Post raid profile inventory items, quest raid items, or equipment are null when trying to set inventory post raid" + ); + } + // Store insurance (as removeItem() removes insured items) var insured = cloner.Clone(serverProfile.InsuredItems); + if (insured is null) + { + logger.Error("Cloned insured items are null when trying to set inventory post raid"); + return; + } // Remove equipment and loot items stored on player from server profile in preparation for data from client being added - inventoryHelper.RemoveItem(serverProfile, serverProfile.Inventory.Equipment.Value, sessionID); + inventoryHelper.RemoveItem(serverProfile, serverProfile.Inventory.Equipment.Value, sessionId); // Remove quest items stored on player from server profile in preparation for data from client being added - inventoryHelper.RemoveItem(serverProfile, serverProfile.Inventory.QuestRaidItems.Value, sessionID); + inventoryHelper.RemoveItem(serverProfile, serverProfile.Inventory.QuestRaidItems.Value, sessionId); // Get all items that have a parent of `serverProfile.Inventory.equipment` (All items player had on them at end of raid) var postRaidInventoryItems = postRaidProfile.Inventory.Items.GetItemWithChildren(postRaidProfile.Inventory.Equipment.Value); @@ -61,7 +89,7 @@ public void SetInventory(MongoId sessionID, PmcData serverProfile, PmcData postR // Handle Removing of FIR status if player did not survive + not transferring // Do after above filtering code to reduce work done - if (!isSurvived && !isTransfer && !_inRaidConfig.AlwaysKeepFoundInRaidOnRaidEnd) + if (!isSurvived && !isTransfer && !InRaidConfig.AlwaysKeepFoundInRaidOnRaidEnd) { RemoveFiRStatusFromItems(postRaidProfile.Inventory.Items); } @@ -85,12 +113,10 @@ protected void RemoveFiRStatusFromItems(IEnumerable items) var dbItems = databaseService.GetItems(); var itemsToRemovePropertyFrom = items.Where(item => - { - // Has upd object + upd.SpawnedInSession property + not a quest item - return (item.Upd?.SpawnedInSession ?? false) - && !(dbItems[item.Template].Properties.QuestItem ?? false) - && !(_inRaidConfig.KeepFiRSecureContainerOnDeath && item.ItemIsInsideContainer("SecuredContainer", items)); - }); + (item.Upd?.SpawnedInSession ?? false) + && !(dbItems[item.Template].Properties?.QuestItem ?? false) + && !(InRaidConfig.KeepFiRSecureContainerOnDeath && item.ItemIsInsideContainer("SecuredContainer", items)) + ); foreach (var item in itemsToRemovePropertyFrom) { @@ -131,6 +157,11 @@ protected void AddItemsToInventory(IEnumerable itemsToAdd, List serv /// Player/Session id public void DeleteInventory(PmcData pmcData, MongoId sessionId) { + if (pmcData.Inventory is null) + { + throw new InRaidHelperException("Pmc profile inventory is null when trying to delete inventory"); + } + // Get inventory items to remove from players profile var itemsToDeleteFromProfile = GetInventoryItemsLostOnDeath(pmcData).ToList(); @@ -141,7 +172,7 @@ public void DeleteInventory(PmcData pmcData, MongoId sessionId) } // Remove contents of fast panel - pmcData.Inventory.FastPanel = new(); + pmcData.Inventory.FastPanel = new Dictionary(); } /// @@ -151,9 +182,9 @@ public void DeleteInventory(PmcData pmcData, MongoId sessionId) /// List of items lost on death protected IEnumerable GetInventoryItemsLostOnDeath(PmcData pmcProfile) { - var inventoryItems = pmcProfile.Inventory.Items ?? []; - var equipmentRootId = pmcProfile?.Inventory?.Equipment; - var questRaidItemContainerId = pmcProfile?.Inventory?.QuestRaidItems; + var inventoryItems = pmcProfile.Inventory?.Items ?? []; + var equipmentRootId = pmcProfile.Inventory?.Equipment; + var questRaidItemContainerId = pmcProfile.Inventory?.QuestRaidItems; return inventoryItems.Where(item => { @@ -171,7 +202,7 @@ protected IEnumerable GetInventoryItemsLostOnDeath(PmcData pmcProfile) // Pocket items are lost on death // Ensure we don't pick up pocket items from mannequins - if (item.SlotId.StartsWith("pocket") && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory.Equipment.Value)) + if ((item.SlotId?.StartsWith("pocket") ?? false) && pmcProfile.DoesItemHaveRootId(item, pmcProfile.Inventory!.Equipment!.Value)) { return true; } @@ -188,6 +219,11 @@ protected IEnumerable GetInventoryItemsLostOnDeath(PmcData pmcProfile) /// true if item is kept after death protected bool IsItemKeptAfterDeath(PmcData pmcData, Item itemToCheck) { + if (pmcData.Inventory is null) + { + throw new InRaidHelperException("Pmc profile inventory is null when checking if an item is kept on death"); + } + // Base inventory items are always kept if (itemToCheck.ParentId is null) { @@ -198,7 +234,7 @@ protected bool IsItemKeptAfterDeath(PmcData pmcData, Item itemToCheck) if (itemToCheck.ParentId == pmcData.Inventory.Equipment) { // Check slot id against config, true = delete, false = keep, undefined = delete - var discard = _lostOnDeathConfig.Equipment.GetByJsonProp(itemToCheck.SlotId); + var discard = LostOnDeathConfig.Equipment.GetByJsonProp(itemToCheck.SlotId); if (discard) // Lost on death { @@ -209,19 +245,19 @@ protected bool IsItemKeptAfterDeath(PmcData pmcData, Item itemToCheck) } // Should we keep items in pockets on death - if (!_lostOnDeathConfig.Equipment.PocketItems && _pocketSlots.Contains(itemToCheck.SlotId)) + if (!LostOnDeathConfig.Equipment.PocketItems && PocketSlots.Contains(itemToCheck.SlotId ?? string.Empty)) { return true; } // Is quest item + quest item not lost on death - if (itemToCheck.ParentId == pmcData.Inventory.QuestRaidItems && !_lostOnDeathConfig.QuestItems) + if (itemToCheck.ParentId == pmcData.Inventory.QuestRaidItems && !LostOnDeathConfig.QuestItems) { return true; } // special slots are always kept after death - if ((itemToCheck.SlotId?.Contains("SpecialSlot") ?? false) && _lostOnDeathConfig.SpecialSlotItems) + if ((itemToCheck.SlotId?.Contains("SpecialSlot") ?? false) && LostOnDeathConfig.SpecialSlotItems) { return true; } From 6e1a4b5805c81a00efd425b6bfcdff1c4bae9448 Mon Sep 17 00:00:00 2001 From: Cj <161484149+CJ-SPT@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:10:02 -0400 Subject: [PATCH 2/2] Make AI happy --- Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs index b454c9817..acf035e45 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InRaidHelper.cs @@ -71,8 +71,9 @@ public void SetInventory(MongoId sessionId, PmcData serverProfile, PmcData postR var insured = cloner.Clone(serverProfile.InsuredItems); if (insured is null) { - logger.Error("Cloned insured items are null when trying to set inventory post raid"); - return; + const string message = "Cloned insured items are null when trying to set inventory post raid"; + logger.Error(message); + throw new InRaidHelperException(message); } // Remove equipment and loot items stored on player from server profile in preparation for data from client being added