diff --git a/Plugin/Extensions/ItemExtensions.cs b/Plugin/Extensions/ItemExtensions.cs
index 6efcba7..28f0f97 100644
--- a/Plugin/Extensions/ItemExtensions.cs
+++ b/Plugin/Extensions/ItemExtensions.cs
@@ -16,7 +16,8 @@ namespace LootValueEX.Extensions
/// The item to check.
/// True if the item has been examined, false otherwise.
internal static bool IsExamined(this Item? item) => item != null && ClientAppUtils.GetMainApp().GetClientBackEndSession().Profile.Examined(item);
-
+ internal static string PrehashTemplate(this Item? item) => string.Format("{0}|{1}|{2}", item?.TemplateId, item.GetDurability(), item.GetUses());
+
///
/// Retrieves the value of a specific attribute from an item.
///
@@ -39,27 +40,28 @@ namespace LootValueEX.Extensions
///
/// Generates a custom hash for the given item.
- ///
+ ///
/// This function takes an optional Item as a parameter and returns its custom hash.
/// If the item is null, it returns an empty string. The custom hash is determined by the item's template, durability, and uses.
///
/// The item to retrieve the custom hash for.
/// The custom hash of the item, or an empty string if the item is null.
- internal static string GetCustomHash(this Item? item)
+ internal static async Task GetCustomHashAsync(this Item? item)
{
if (item == null)
return string.Empty;
-
StringBuilder prehashString = new StringBuilder();
- item.GetAllItems().Where(prop => !prop.Equals(item)).ExecuteForEach(prop => prehashString.Append(prop.GetCustomHash()));
+
+ item.GetAllItems().Where(i => !i.Equals(item)).DoMap(i => prehashString.Append(i.PrehashTemplate()));
if (item.Template.Equals(typeof(MagazineTemplate)))
{
MagazineTemplate magTemplate = (MagazineTemplate)item.Template;
- magTemplate.Cartridges.ExecuteForEach(prop => prop.Items.ExecuteForEach(ammo => prehashString.Append(ammo.GetCustomHash())));
+ magTemplate.Cartridges.DoMap(s => s.Items.DoMap(i => prehashString.Append(i.PrehashTemplate())));
}
- string itemHashTemplate = string.Format("{0}|{1}|{2}|{3}", prehashString.ToString(), item.TemplateId, item.GetDurability(), item.GetUses());
- return Utils.HashingUtils.ConvertToSha256(itemHashTemplate);
+ prehashString.Append(item.PrehashTemplate());
+ return await Task.Run(() => Utils.HashingUtils.ConvertToSha256(prehashString.ToString()));
}
+ internal static string GetCustomHash(this Item? item) => Task.Run(() => item?.GetCustomHashAsync()).Result ?? string.Empty;
#if DEBUG
internal static string AttributesToString(this Item? item)
{
diff --git a/Plugin/Patches/Screens/InventoryScreenPatch.cs b/Plugin/Patches/Screens/InventoryScreenPatch.cs
index 03baf33..e25eea4 100644
--- a/Plugin/Patches/Screens/InventoryScreenPatch.cs
+++ b/Plugin/Patches/Screens/InventoryScreenPatch.cs
@@ -1,4 +1,5 @@
-using System.Reflection;
+using System.Diagnostics;
+using System.Reflection;
using EFT;
using EFT.HealthSystem;
using EFT.UI;
@@ -14,10 +15,40 @@ namespace LootValueEX.Patches.Screens
[PatchPostfix]
private static void PatchPostfix(ref Profile ___profile_0, ref LootItemClass ___lootItemClass)
{
- ___profile_0.Inventory.GetPlayerItems(EFT.InventoryLogic.EPlayerItems.Equipment).ExecuteForEach(item => Plugin.Log.LogDebug($"{item.LocalizedName()} ({item.TemplateId}): {item.GetCustomHash()}"));
-
+ Profile profile = ___profile_0;
+
+ TaskCompletionSource tcsInventory = new();
+ CancellationTokenSource ctsInventory = new CancellationTokenSource(5000);
+ Task taskInventory = tcsInventory.Task;
+ Task.Factory.StartNew(async () =>
+ {
+ Stopwatch sw = Stopwatch.StartNew();
+ foreach(EFT.InventoryLogic.Item item in profile.Inventory.GetPlayerItems(EFT.InventoryLogic.EPlayerItems.Equipment))
+ {
+ Plugin.Log.LogDebug($"Equip Process: {item.LocalizedName()} ({item.TemplateId}): {await item.GetCustomHashAsync()}");
+ }
+ sw.Stop();
+ Plugin.Log.LogDebug($"Equipment processing finished in {sw.ElapsedMilliseconds}ms");
+ tcsInventory.SetResult(true);
+ }, ctsInventory.Token);
+
if(___lootItemClass != null)
- ___lootItemClass.GetAllItems().ExecuteForEach(item => Plugin.Log.LogDebug($"{item.LocalizedName()} ({item.TemplateId}): {item.GetCustomHash()}"));
+ {
+ LootItemClass lootItemClass = ___lootItemClass;
+ TaskCompletionSource tcsLoot = new();
+ CancellationTokenSource ctsLoot = new CancellationTokenSource(5000);
+ Task taskLoot = tcsLoot.Task;
+ Task.Factory.StartNew(async () =>
+ {
+ Stopwatch sw = Stopwatch.StartNew();
+ foreach (EFT.InventoryLogic.Item item in lootItemClass.GetAllItems())
+ {
+ Plugin.Log.LogDebug($"LootItemClass process: {item.LocalizedName()} ({item.TemplateId}): {await item.GetCustomHashAsync()}");
+ }
+ Plugin.Log.LogDebug($"LootItemClass processing finished in {sw.ElapsedMilliseconds}ms");
+ tcsLoot.SetResult(true);
+ }, ctsLoot.Token);
+ }
}
}
}