using Aki.Reflection.Utils; using Comfort.Common; using EFT; using EFT.InventoryLogic; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using CurrencyUtil = GClass2333; namespace IcyClawz.ItemSellPrice { internal static class TraderClassExtensions { private static ISession Session => ClientAppUtils.GetMainApp().GetClientBackEndSession(); private static readonly FieldInfo SupplyDataField = typeof(TraderClass).GetField("supplyData_0", BindingFlags.NonPublic | BindingFlags.Instance); public static SupplyData GetSupplyData(this TraderClass trader) => SupplyDataField.GetValue(trader) as SupplyData; public static void SetSupplyData(this TraderClass trader, SupplyData supplyData) => SupplyDataField.SetValue(trader, supplyData); public static async void UpdateSupplyData(this TraderClass trader) { Result result = await Session.GetSupplyData(trader.Id); if (result.Failed) { Debug.LogError("Failed to download supply data"); return; } trader.SetSupplyData(result.Value); } } internal static class ItemExtensions { private static readonly Dictionary DisplayNames = new Dictionary() { { "ch", new[] { "售价({0})", "无法出售给商人" } }, { "cz", new[] { "Prodejní cena ({0})", "Nemůže být prodán obchodníkům" } }, { "en", new[] { "Selling price ({0})", "Cannot be sold to traders" } }, { "es", new[] { "Precio de venta ({0})", "No puede ser vendido a los vendedores" } }, { "es-mx", new[] { "Precio de venta ({0})", "No puede ser vendido a comerciantes" } }, { "fr", new[] { "Prix de vente ({0})", "Ne peut pas être vendu aux marchands" } }, { "ge", new[] { "Verkaufspreis ({0})", "Kann nicht an Händler verkauft werden" } }, { "hu", new[] { "Eladási ár ({0})", "Kereskedőknek nem adható el" } }, { "it", new[] { "Prezzo di vendita ({0})", "Non vendibile ai mercanti" } }, { "jp", new[] { "販売価格({0})", "トレーダーには販売できません" } }, { "kr", new[] { "판매 가격 ({0})", "상인에게 판매 불가" } }, { "pl", new[] { "Cena sprzedaży ({0})", "Nie można sprzedawać handlarzom" } }, { "po", new[] { "Preço de venda ({0})", "Não pode ser vendido a comerciantes" } }, { "ru", new[] { "Цена продажи ({0})", "Невозможно продать торговцам" } }, { "sk", new[] { "Predajná cena ({0})", "Nedá sa predať obchodníkom" } }, { "tu", new[] { "Satış fiyatı ({0})", "Tüccarlara satılamaz" } } }; private static ISession Session => ClientAppUtils.GetMainApp().GetClientBackEndSession(); public static void AddTraderOfferAttribute(this Item item) { ItemAttributeClass attribute = new ItemAttributeClass(EItemAttributeId.MoneySum) { Name = EItemAttributeId.MoneySum.GetName(), DisplayNameFunc = () => { string language = Singleton.Instance?.Game?.Settings?.Language?.GetValue(); if (language == null || !DisplayNames.ContainsKey(language)) { language = "en"; } if (GetBestTraderOffer(item) is TraderOffer offer) { return string.Format(DisplayNames[language][0], offer.Name); } else { return DisplayNames[language][1]; } }, Base = () => { if (GetBestTraderOffer(item) is TraderOffer offer) { return offer.Price; } else { return 0.01f; } }, StringValue = () => { if (GetBestTraderOffer(item) is TraderOffer offer) { string value = $"{offer.Currency} {offer.Price}"; if (offer.Count > 1) { value += $" ({offer.Count})"; } return value; } else { return string.Empty; } }, FullStringValue = () => { if (GetAllTraderOffers(item) is List offers) { string[] lines = new string[offers.Count]; for (int i = 0; i < offers.Count; i++) { TraderOffer offer = offers[i]; lines[i] = $"{offer.Name}: {offer.Currency} {offer.Price}"; } return string.Join(Environment.NewLine, lines); } else { return string.Empty; } }, DisplayType = () => EItemAttributeDisplayType.Compact }; List attributes = new List { attribute }; attributes.AddRange(item.Attributes); item.Attributes = attributes; } private sealed class TraderOffer { public string Name; public int Price; public string Currency; public double Course; public int Count; public TraderOffer(string name, int price, string currency, double course, int count) { Name = name; Price = price; Currency = currency; Course = course; Count = count; } } private static TraderOffer GetTraderOffer(Item item, TraderClass trader) { var result = trader.GetUserItemPrice(item); if (result == null) { return null; } return new TraderOffer( trader.LocalizedName, result.Value.Amount, CurrencyUtil.GetCurrencyCharById(result.Value.CurrencyId), trader.GetSupplyData().CurrencyCourses[result.Value.CurrencyId], item.StackObjectsCount ); } private static List GetAllTraderOffers(Item item) { if (!Session.Profile.Examined(item)) { return null; } switch (item.Owner?.OwnerType) { case EOwnerType.RagFair: case EOwnerType.Trader: if (item.StackObjectsCount > 1 || item.UnlimitedCount) { item = item.CloneItem(); item.StackObjectsCount = 1; item.UnlimitedCount = false; } break; } List offers = new List(); foreach (TraderClass trader in Session.Traders) { if (GetTraderOffer(item, trader) is TraderOffer offer) { offers.Add(offer); } } offers.Sort((x, y) => (y.Price * y.Course).CompareTo(x.Price * x.Course)); return offers; } private static TraderOffer GetBestTraderOffer(Item item) { if (GetAllTraderOffers(item) is List offers) { return offers.FirstOrDefault(); } else { return null; } } } }