From 7ed081d305bebe6c542de224d4d50d1f649ee4e8 Mon Sep 17 00:00:00 2001 From: Chris Adamson Date: Mon, 28 Apr 2025 12:07:46 -0500 Subject: [PATCH] fixed error where itemlocation can be either a string or int --- .../Helpers/InventoryHelper.cs | 11 +-- .../Helpers/ItemHelper.cs | 69 +++++++++++++++++-- .../Models/Eft/Common/Tables/Item.cs | 42 ++++++++--- 3 files changed, 101 insertions(+), 21 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs index 3b6ab782..bf187523 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs @@ -842,15 +842,8 @@ public class InventoryHelper( // Check each item in container foreach (var item in containerItemHash) { - ItemLocation? itemLocation; - if (item.Location is JsonElement) - { - itemLocation = ((JsonElement) item.Location).ToObject(); - } - else - { - itemLocation = (ItemLocation) item.Location; - } + + var (itemLocation, _) = ItemHelper.TryParseItemLocation(item); if (itemLocation is null) { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 97ceb6a4..e92233da 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -1,6 +1,8 @@ using System.Collections.Frozen; +using System.Text.Json; using System.Text.Json.Serialization; using SPTarkov.Common.Annotations; +using SPTarkov.Common.Extensions; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Enums; @@ -857,6 +859,65 @@ public class ItemHelper( return _dogTagTpls.Contains(tpl); } + /// + /// Given that the R field of item location can be string enum or int, provide a method to get the exact type + /// + /// + /// + + public static (ItemLocation? itemLocation, LocationInGrid? locationInGrid) TryParseItemLocation(Item item) + { + if (item.Location is not JsonElement jsonLocation) + { + return ((ItemLocation?) item.Location, null); + } + + var itemLocation = TryParseItemLocation(jsonLocation); + if (itemLocation != null) + { + return (itemLocation, null); + } + + var locationInGrid = TryParseLocationInGrid(jsonLocation); + if (locationInGrid == null) + { + return (null, null); + } + + itemLocation = new ItemLocation + { + X = locationInGrid.X, + Y = locationInGrid.Y, + IsSearched = locationInGrid.IsSearched, + R = locationInGrid.R == ItemRotation.Vertical ? 1 : 0 + }; + return (itemLocation, locationInGrid); + + ItemLocation? TryParseItemLocation(JsonElement element) + { + try + { + return element.ToObject(); + } + catch + { + return null; + } + } + + LocationInGrid? TryParseLocationInGrid(JsonElement element) + { + try + { + return element.ToObject(); + } + catch + { + return null; + } + } + } + /// /// Gets the identifier for a child using slotId, locationX and locationY. /// @@ -1356,7 +1417,7 @@ public class ItemHelper( /** * Determines if an item is an attachment that is currently attached to its parent item. - * + * * @param item The item to check. * @returns true if the item is attached attachment, otherwise false. */ @@ -1369,15 +1430,15 @@ public class ItemHelper( /** * Retrieves the equipment parent item for a given item. - * + * * This method traverses up the hierarchy of items starting from a given `itemId`, until it finds the equipment * parent item. In other words, if you pass it an item id of a suppressor, it will traverse up the muzzle brake, * barrel, upper receiver, gun, nested backpack, and finally return the backpack Item that is equipped. - * + * * It's important to note that traversal is expensive, so this method requires that you pass it a Dictionary of the items * to traverse, where the keys are the item IDs and the values are the corresponding Item objects. This alleviates * some of the performance concerns, as it allows for quick lookups of items by ID. - * + * * @param itemId - The unique identifier of the item for which to find the equipment parent. * @param itemsMap - A Dictionary containing item IDs mapped to their corresponding Item objects for quick lookup. * @returns The Item object representing the equipment parent of the given item, or `null` if no such parent exists. diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs index b0c8ec80..b50a6629 100644 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs +++ b/Libraries/SPTarkov.Server.Core/Models/Eft/Common/Tables/Item.cs @@ -152,7 +152,7 @@ public record HideoutItem } } -public record ItemLocation +public record ItemLocationBase { [JsonPropertyName("x")] public int? X @@ -168,13 +168,6 @@ public record ItemLocation set; } - [JsonPropertyName("r")] - public int R - { - get; - set; - } - [JsonPropertyName("isSearched")] public bool? IsSearched { @@ -193,6 +186,39 @@ public record ItemLocation } } +public record ItemLocation : ItemLocationBase +{ + + + [JsonPropertyName("r")] + public int R + { + get; + set; + } +} + +public enum ItemRotation +{ + // Token: 0x0400259F RID: 9631 + Horizontal, + // Token: 0x040025A0 RID: 9632 + Vertical +} + + +public record LocationInGrid : ItemLocationBase +{ + + [JsonPropertyName("r")] + [JsonConverter(typeof(JsonStringEnumConverter))] + public ItemRotation R + { + get; + set; + } +} + public record Upd { public UpdBuff? Buff