feat: get best trader offer for items
TODO: Make a better conversion for USD/EUR to RUB
This commit is contained in:
parent
a86213d3a6
commit
db4003caa7
|
@ -16,8 +16,23 @@ namespace LootValueEX.Extensions
|
||||||
/// <param name="item">The item to check.</param>
|
/// <param name="item">The item to check.</param>
|
||||||
/// <returns>True if the item has been examined, false otherwise.</returns>
|
/// <returns>True if the item has been examined, false otherwise.</returns>
|
||||||
internal static bool IsExamined(this Item? item) => item != null && ClientAppUtils.GetMainApp().GetClientBackEndSession().Profile.Examined(item);
|
internal static bool IsExamined(this Item? item) => item != null && ClientAppUtils.GetMainApp().GetClientBackEndSession().Profile.Examined(item);
|
||||||
|
internal static bool IsStacked(this Item? item) => item != null && (item.StackObjectsCount > 1 || item.UnlimitedCount);
|
||||||
internal static string PrehashTemplate(this Item? item) => string.Format("{0}|{1}|{2}", item?.TemplateId, item.GetDurability(), item.GetUses());
|
internal static string PrehashTemplate(this Item? item) => string.Format("{0}|{1}|{2}", item?.TemplateId, item.GetDurability(), item.GetUses());
|
||||||
|
|
||||||
|
internal static Item? UnstackItem(this Item? item)
|
||||||
|
{
|
||||||
|
if (item == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!item.IsStacked())
|
||||||
|
return item;
|
||||||
|
|
||||||
|
Item? itemClone = item.CloneItem();
|
||||||
|
itemClone.StackObjectsCount = 1;
|
||||||
|
itemClone.UnlimitedCount = false;
|
||||||
|
return itemClone;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the value of a specific attribute from an item.
|
/// Retrieves the value of a specific attribute from an item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -25,7 +25,8 @@ namespace LootValueEX.Patches.Screens
|
||||||
Stopwatch sw = Stopwatch.StartNew();
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
foreach(EFT.InventoryLogic.Item item in profile.Inventory.GetPlayerItems(EFT.InventoryLogic.EPlayerItems.Equipment))
|
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()}");
|
//Plugin.Log.LogDebug($"Equip Process: {item.LocalizedName()} ({item.TemplateId}): {await item.GetCustomHashAsync()}");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
Plugin.Log.LogDebug($"Equipment processing finished in {sw.ElapsedMilliseconds}ms");
|
Plugin.Log.LogDebug($"Equipment processing finished in {sw.ElapsedMilliseconds}ms");
|
||||||
|
@ -43,7 +44,8 @@ namespace LootValueEX.Patches.Screens
|
||||||
Stopwatch sw = Stopwatch.StartNew();
|
Stopwatch sw = Stopwatch.StartNew();
|
||||||
foreach (EFT.InventoryLogic.Item item in lootItemClass.GetAllItems())
|
foreach (EFT.InventoryLogic.Item item in lootItemClass.GetAllItems())
|
||||||
{
|
{
|
||||||
Plugin.Log.LogDebug($"LootItemClass process: {item.LocalizedName()} ({item.TemplateId}): {await item.GetCustomHashAsync()}");
|
//Plugin.Log.LogDebug($"LootItemClass process: {item.LocalizedName()} ({item.TemplateId}): {await item.GetCustomHashAsync()}");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
Plugin.Log.LogDebug($"LootItemClass processing finished in {sw.ElapsedMilliseconds}ms");
|
Plugin.Log.LogDebug($"LootItemClass processing finished in {sw.ElapsedMilliseconds}ms");
|
||||||
tcsLoot.SetResult(true);
|
tcsLoot.SetResult(true);
|
||||||
|
|
|
@ -19,12 +19,10 @@ namespace LootValueEX.Patches.Tooltips
|
||||||
[PatchPostfix]
|
[PatchPostfix]
|
||||||
public static void AlterText(SimpleTooltip __instance, string text)
|
public static void AlterText(SimpleTooltip __instance, string text)
|
||||||
{
|
{
|
||||||
StackTrace stackTrace = new StackTrace();
|
|
||||||
Plugin.Log.LogDebug("Stacktrace of tooltip call: \n" + stackTrace.ToString());
|
|
||||||
if (GridItemTooltipPatch.PatchTooltip)
|
if (GridItemTooltipPatch.PatchTooltip)
|
||||||
{
|
{
|
||||||
text += $"<br>TemplateID: {GridItemTooltipPatch.HoveredItem?.TemplateId}<br>Template: {GridItemTooltipPatch.HoveredItem?.Template}<br>Item hashsum: {GridItemTooltipPatch.HoveredItem?.GetHashSum()}<br>Custom hash: {GridItemTooltipPatch.HoveredItem?.GetCustomHash()}<br>Item durability: {GridItemTooltipPatch.HoveredItem?.GetDurability()}<br>Item uses: {GridItemTooltipPatch.HoveredItem?.GetUses()}<br><color=#ff0fff><b>GridItemView</b></color>";
|
Structs.TradeOfferStruct tradeOffer = Utils.ItemUtils.GetBestTraderValue(GridItemTooltipPatch.HoveredItem);
|
||||||
Plugin.Log.LogDebug(GridItemTooltipPatch.HoveredItem?.AttributesToString());
|
text += $"<br>Hash: {GridItemTooltipPatch.HoveredItem?.GetCustomHash()}<br>Trader: {tradeOffer.TraderID}<br>Value: {tradeOffer.Price}<br>Currency: {tradeOffer.CurrencyID}<br>Price in rubles: {tradeOffer.PriceInRouble}<br><color=#ff0fff><b>GridItemView</b></color>";
|
||||||
}
|
}
|
||||||
if (InsuranceSlotPatch.PatchTooltip)
|
if (InsuranceSlotPatch.PatchTooltip)
|
||||||
{
|
{
|
||||||
|
|
22
Plugin/Patches/TraderClassPatch.cs
Normal file
22
Plugin/Patches/TraderClassPatch.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SPT.Reflection.Patching;
|
||||||
|
|
||||||
|
namespace LootValueEX.Patches
|
||||||
|
{
|
||||||
|
internal class TraderClassPatch : ModulePatch
|
||||||
|
{
|
||||||
|
protected override MethodBase GetTargetMethod() => typeof(TraderClass).GetConstructors().First();
|
||||||
|
|
||||||
|
[PatchPostfix]
|
||||||
|
private static void GenerateSupplyData(ref TraderClass __instance)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug($"Generating Assortment Data for trader {__instance.Id}");
|
||||||
|
__instance.RefreshAssortment(true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ namespace LootValueEX
|
||||||
{
|
{
|
||||||
Log = base.Logger;
|
Log = base.Logger;
|
||||||
|
|
||||||
|
new Patches.TraderClassPatch().Enable();
|
||||||
|
|
||||||
new Patches.Tooltips.GridItemTooltipPatch().Enable();
|
new Patches.Tooltips.GridItemTooltipPatch().Enable();
|
||||||
new Patches.Tooltips.TooltipPatch().Enable();
|
new Patches.Tooltips.TooltipPatch().Enable();
|
||||||
new Patches.Tooltips.InsuranceGridPatch().Enable();
|
new Patches.Tooltips.InsuranceGridPatch().Enable();
|
||||||
|
|
23
Plugin/Structs/TradeOfferStruct.cs
Normal file
23
Plugin/Structs/TradeOfferStruct.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LootValueEX.Structs
|
||||||
|
{
|
||||||
|
internal readonly struct TradeOfferStruct
|
||||||
|
{
|
||||||
|
internal readonly string TraderID;
|
||||||
|
internal readonly string CurrencyID;
|
||||||
|
internal readonly int Price;
|
||||||
|
internal readonly float PriceInRouble;
|
||||||
|
internal TradeOfferStruct(string traderId, string currencyId, int price, float priceInRouble)
|
||||||
|
{
|
||||||
|
TraderID = traderId;
|
||||||
|
CurrencyID = currencyId;
|
||||||
|
Price = price;
|
||||||
|
PriceInRouble = priceInRouble;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
Plugin/Utils/EconomyUtils.cs
Normal file
44
Plugin/Utils/EconomyUtils.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Comfort.Common;
|
||||||
|
using EFT.InventoryLogic;
|
||||||
|
using SPT.Reflection.Utils;
|
||||||
|
using EFTCurrencyUtils = GClass2531;
|
||||||
|
|
||||||
|
namespace LootValueEX.Utils
|
||||||
|
{
|
||||||
|
internal class EconomyUtils
|
||||||
|
{
|
||||||
|
|
||||||
|
public static float ConvertToRuble(string id, float amount)
|
||||||
|
{
|
||||||
|
if (!EFTCurrencyUtils.TryGetCurrencyType(id, out ECurrencyType currencyType))
|
||||||
|
return 0f;
|
||||||
|
if (currencyType.Equals(ECurrencyType.RUB))
|
||||||
|
return amount;
|
||||||
|
return amount * (float)Singleton<HandbookClass>.Instance.GetBasePrice(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Structs.TradeOfferStruct GetTraderItemOffer(TraderClass trader, Item item)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug($"GetTraderItemOffer: {item.LocalizedName()} - {trader.LocalizedName}");
|
||||||
|
TraderClass.GStruct244? tradeOffer = trader.GetUserItemPrice(item);
|
||||||
|
|
||||||
|
if (tradeOffer == null)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug("GetTraderItemOffer: tradeOffer == null");
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
if(tradeOffer.Value.Amount > 0)
|
||||||
|
{
|
||||||
|
Plugin.Log.LogDebug($"{trader.LocalizedName}\n\tCurrencyID: {tradeOffer.Value.CurrencyId}\n\tValue: {tradeOffer.Value.Amount}\n\tPrice in RB: {EconomyUtils.ConvertToRuble(tradeOffer.Value.CurrencyId, tradeOffer.Value.Amount)}");
|
||||||
|
return new Structs.TradeOfferStruct(trader.Id, tradeOffer.Value.CurrencyId, tradeOffer.Value.Amount, EconomyUtils.ConvertToRuble(tradeOffer.Value.CurrencyId, tradeOffer.Value.Amount));
|
||||||
|
}
|
||||||
|
Plugin.Log.LogDebug("GetTraderItemOffer: no value");
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using EFT.InventoryLogic;
|
using EFT.InventoryLogic;
|
||||||
|
using LootValueEX.Extensions;
|
||||||
|
using SPT.Reflection.Utils;
|
||||||
|
|
||||||
namespace LootValueEX.Utils
|
namespace LootValueEX.Utils
|
||||||
{
|
{
|
||||||
|
@ -13,5 +15,23 @@ namespace LootValueEX.Utils
|
||||||
}
|
}
|
||||||
return totalDurability;
|
return totalDurability;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task<Structs.TradeOfferStruct> GetBestTraderValueAsync(Item item)
|
||||||
|
{
|
||||||
|
Structs.TradeOfferStruct bestOffer = new();
|
||||||
|
item = item.UnstackItem();
|
||||||
|
foreach (TraderClass trader in ClientAppUtils.GetMainApp().GetClientBackEndSession().DisplayableTraders)
|
||||||
|
{
|
||||||
|
Structs.TradeOfferStruct currentOffer = EconomyUtils.GetTraderItemOffer(trader, item);
|
||||||
|
|
||||||
|
if (currentOffer.Equals(default) || currentOffer.Price <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (currentOffer.PriceInRouble > bestOffer.PriceInRouble)
|
||||||
|
bestOffer = currentOffer;
|
||||||
|
}
|
||||||
|
return Task.FromResult(bestOffer);
|
||||||
|
}
|
||||||
|
public static Structs.TradeOfferStruct GetBestTraderValue(Item item) => Task.Run(() => GetBestTraderValueAsync(item)).Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user