using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EconomyInfo.money_vendor;
using EconomyInfo.tools;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("EconomyInfo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EconomyInfo")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("aae89eab-0761-4012-a8ed-ceadc086e98c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EconomyInfo
{
[BepInPlugin("Turbero.EconomyInfo", "Economy Info", "1.1.1")]
public class EconomyInfo : BaseUnityPlugin
{
public const string GUID = "Turbero.EconomyInfo";
public const string NAME = "Economy Info";
public const string VERSION = "1.1.1";
private readonly Harmony harmony = new Harmony("Turbero.EconomyInfo");
private void Awake()
{
ConfigurationFile.LoadConfig((BaseUnityPlugin)(object)this);
harmony.PatchAll();
}
private void onDestroy()
{
harmony.UnpatchSelf();
}
}
}
namespace EconomyInfo.tools
{
internal class ConfigurationFile
{
public static ConfigEntry<bool> debug;
public static ConfigEntry<bool> advancedVendorMoneyPanel;
private static ConfigFile configFile;
private static string ConfigFileName = "Turbero.EconomyInfo.cfg";
private static string ConfigFileFullPath;
internal static void LoadConfig(BaseUnityPlugin plugin)
{
configFile = plugin.Config;
debug = configFile.Bind<bool>("1 - General", "DebugMode", false, "Enabling/Disabling the debugging in the console (default = false)");
advancedVendorMoneyPanel = configFile.Bind<bool>("2 - Features", "AdvancedVendorMoneyPanel", true, "Enabling/Disabling the advanced panel with all valuables at the vendor window (default = true)");
SetupWatcher();
}
private static void SetupWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
fileSystemWatcher.Changed += ReadConfigValues;
fileSystemWatcher.Created += ReadConfigValues;
fileSystemWatcher.Renamed += ReadConfigValues;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private static void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
Logger.Log("Attempting to reload configuration...");
configFile.Reload();
MoneyStoreGuiShowPatch.enable(advancedVendorMoneyPanel.Value);
}
catch
{
Logger.LogError("There was an issue loading " + ConfigFileName);
}
}
static ConfigurationFile()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
}
}
public static class Logger
{
public static ManualLogSource logger = Logger.CreateLogSource("Economy Info");
internal static void Log(object s)
{
if (ConfigurationFile.debug.Value)
{
logger.LogInfo((object)s?.ToString());
}
}
internal static void LogInfo(object s)
{
logger.LogInfo((object)s?.ToString());
}
internal static void LogWarning(object s)
{
string text = "Economy Info 1.1.1: " + ((s != null) ? s.ToString() : "null");
Debug.LogWarning((object)text);
}
internal static void LogError(object s)
{
string text = "Economy Info 1.1.1: " + ((s != null) ? s.ToString() : "null");
Debug.LogError((object)text);
}
}
public class ModUtils
{
private static Dictionary<string, Sprite> cachedSprites = new Dictionary<string, Sprite>();
public static Sprite getSprite(string name)
{
if (!cachedSprites.ContainsKey(name))
{
Logger.Log("Finding " + name + " sprite...");
Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>();
foreach (Sprite val in array)
{
if (((Object)val).name == name)
{
Logger.Log(name + " sprite found.");
cachedSprites.Add(name, val);
return val;
}
}
Logger.Log(name + " sprite NOT found.");
return null;
}
return GeneralExtensions.GetValueSafe<string, Sprite>(cachedSprites, name);
}
}
}
namespace EconomyInfo.money_vendor
{
[HarmonyPatch(typeof(StoreGui), "Show")]
public class MoneyStoreGuiShowPatch
{
private static VendorPanelValuable rubyPanel;
private static VendorPanelValuable amberPanel;
private static VendorPanelValuable pearlPanel;
private static VendorPanelValuable silverNecklacePanel;
private static bool panelsCreated;
public static void enable(bool enable)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
if (enable)
{
resize();
updateValuables();
}
else
{
Transform transform = GameObject.Find("Store").transform;
((Component)transform.Find("border (1)")).GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, 0f);
((Component)transform.Find("border (1)")).GetComponent<RectTransform>().sizeDelta = new Vector2(40f, 40f);
enableValuablePanels(enable: false);
}
updateCoinsColor();
}
public static void Postfix(StoreGui __instance, Trader trader)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
bool value = ConfigurationFile.advancedVendorMoneyPanel.Value;
if (!panelsCreated)
{
Transform transform = GameObject.Find("Store").transform;
amberPanel = new VendorPanelValuable(transform, "amberPanel", "amber", value, new Vector2(0f, -15f), (Vector2?)new Vector2(20f, 20f), (Vector2?)new Vector2(42f, 42f));
pearlPanel = new VendorPanelValuable(transform, "amberpearlPanel", "AmberPearl", value, new Vector2(0f, -60f), (Vector2?)new Vector2(8f, 32f), (Vector2?)null);
rubyPanel = new VendorPanelValuable(transform, "rubyPanel", "ruby", value, new Vector2(0f, -105f), (Vector2?)new Vector2(20f, 20f), (Vector2?)new Vector2(42f, 42f));
silverNecklacePanel = new VendorPanelValuable(transform, "silverNecklacePanel", "silvernecklace", value, new Vector2(0f, -150f), (Vector2?)new Vector2(18f, 20f), (Vector2?)new Vector2(46f, 46f));
panelsCreated = true;
}
if (value)
{
resize();
updateValuables();
updateCoinsColor();
}
}
private static void resize()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
Transform transform = GameObject.Find("Store").transform;
((Component)transform.Find("border (1)")).GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, -90f);
((Component)transform.Find("border (1)")).GetComponent<RectTransform>().sizeDelta = new Vector2(40f, 220f);
enableValuablePanels(enable: true);
}
private static void enableValuablePanels(bool enable)
{
amberPanel.getMainPanel().SetActive(enable);
pearlPanel.getMainPanel().SetActive(enable);
rubyPanel.getMainPanel().SetActive(enable);
silverNecklacePanel.getMainPanel().SetActive(enable);
}
public static void updateValuables()
{
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
int num5 = 0;
int num6 = 0;
int num7 = 0;
int num8 = 0;
if ((Object)(object)Player.m_localPlayer != (Object)null)
{
foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
{
if (allItem.m_shared.m_value > 0)
{
Logger.Log("Found in player inventory: " + allItem.m_shared.m_name + " = " + allItem.m_shared.m_value);
if (allItem.m_shared.m_name.ToLower().Contains("amberpearl"))
{
num2 += allItem.m_stack * allItem.m_shared.m_value;
num6 += allItem.m_stack;
}
else if (allItem.m_shared.m_name.ToLower().Contains("amber"))
{
num += allItem.m_stack * allItem.m_shared.m_value;
num5 += allItem.m_stack;
}
else if (allItem.m_shared.m_name.ToLower().Contains("ruby"))
{
num3 += allItem.m_stack * allItem.m_shared.m_value;
num7 += allItem.m_stack;
}
else if (allItem.m_shared.m_name.ToLower().Contains("silvernecklace"))
{
num4 += allItem.m_stack * allItem.m_shared.m_value;
num8 += allItem.m_stack;
}
}
}
}
amberPanel.updateValue(num5, num);
pearlPanel.updateValue(num6, num2);
rubyPanel.updateValue(num7, num3);
silverNecklacePanel.updateValue(num8, num4);
updateCoinsColor();
}
public static void updateCoinsColor()
{
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
Transform val = ((Component)GameObject.Find("Store").transform.Find("coins")).transform.Find("coins");
TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>();
int num = ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(StoreGui.instance.m_coinPrefab.m_itemData.m_shared.m_name, -1, true);
Logger.Log("Value to calculate color: " + num);
if (num == 0 && ConfigurationFile.advancedVendorMoneyPanel.Value)
{
((TMP_Text)component).faceColor = Color32.op_Implicit(new Color(255f, 0f, 0f, 255f));
}
else
{
((TMP_Text)component).faceColor = Color32.op_Implicit(new Color(255f, 255f, 255f, 255f));
}
}
}
[HarmonyPatch(typeof(StoreGui), "OnSellItem")]
public class MoneyStoreGuiOnSellItemPatch
{
public static void Postfix(StoreGui __instance)
{
Logger.Log("Item sold. Recalculating...");
MoneyStoreGuiShowPatch.updateValuables();
}
}
[HarmonyPatch(typeof(StoreGui), "OnBuyItem")]
public class MoneyStoreGuiOnBuyItemPatch
{
public static void Postfix(StoreGui __instance)
{
Logger.Log("Item bought. Recalculating...");
MoneyStoreGuiShowPatch.updateCoinsColor();
}
}
[HarmonyPatch(typeof(Inventory), "Changed")]
internal class Inventory_Changed_StoreGui_Patch
{
public static void Postfix(Inventory __instance)
{
Player localPlayer = Player.m_localPlayer;
if (__instance == ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null) && (Object)(object)GameObject.Find("Store") != (Object)null)
{
Logger.Log("Inventory changed while trader opened. Recalculating...");
MoneyStoreGuiShowPatch.updateValuables();
MoneyStoreGuiShowPatch.updateCoinsColor();
}
}
}
public class VendorPanelValuable
{
private readonly GameObject vendorPanelValuableGameObject;
public VendorPanelValuable(Transform storeTransform, string valuableName, string spriteName, bool configActive, Vector2 anchoredPosition, Vector2? anchoredPositionIcon = null, Vector2? sizeDeltaIcon = null)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
GameObject gameObject = ((Component)storeTransform.Find("coins")).gameObject;
vendorPanelValuableGameObject = Object.Instantiate<GameObject>(gameObject, storeTransform);
((Object)vendorPanelValuableGameObject).name = valuableName;
vendorPanelValuableGameObject.SetActive(configActive);
vendorPanelValuableGameObject.GetComponent<RectTransform>().anchoredPosition = anchoredPosition;
((Object)vendorPanelValuableGameObject.transform.GetChild(0)).name = "icon";
((Object)vendorPanelValuableGameObject.transform.GetChild(1)).name = "amount";
Sprite sprite = ModUtils.getSprite(spriteName);
((Component)vendorPanelValuableGameObject.transform.GetChild(0)).GetComponent<Image>().sprite = sprite;
if (anchoredPositionIcon.HasValue)
{
((Component)vendorPanelValuableGameObject.transform.GetChild(0)).GetComponent<RectTransform>().anchoredPosition = anchoredPositionIcon.Value;
}
if (sizeDeltaIcon.HasValue)
{
((Component)vendorPanelValuableGameObject.transform.GetChild(0)).GetComponent<RectTransform>().sizeDelta = sizeDeltaIcon.Value;
}
((TMP_Text)((Component)vendorPanelValuableGameObject.transform.GetChild(1)).GetComponent<TextMeshProUGUI>()).text = "0 (0)";
}
public void updateValue(int amount, int value)
{
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
((TMP_Text)((Component)vendorPanelValuableGameObject.transform.GetChild(1)).GetComponent<TextMeshProUGUI>()).text = amount + " (" + value + ")";
if (amount == 0)
{
((TMP_Text)((Component)vendorPanelValuableGameObject.transform.GetChild(1)).GetComponent<TextMeshProUGUI>()).faceColor = Color32.op_Implicit(new Color(255f, 0f, 0f, 255f));
}
else
{
((TMP_Text)((Component)vendorPanelValuableGameObject.transform.GetChild(1)).GetComponent<TextMeshProUGUI>()).faceColor = Color32.op_Implicit(new Color(255f, 255f, 255f, 255f));
}
}
public GameObject getMainPanel()
{
return vendorPanelValuableGameObject;
}
}
}
namespace EconomyInfo.money_inventory
{
[HarmonyPatch(typeof(InventoryGui), "Awake")]
public class MoneyInventoryGuiPatch
{
public static MoneyPanel moneyPanelInventory;
public static MoneyPanel moneyPanelContainer;
public static void Postfix(InventoryGui __instance)
{
Transform parentTransform = ((Component)InventoryGui.instance.m_inventoryRoot).transform.Find("Player");
Transform parentTransform2 = ((Component)InventoryGui.instance.m_inventoryRoot).transform.Find("Container");
moneyPanelInventory = new MoneyPanel(MoneyPanel.MoneyPanelType.Inventory, parentTransform);
moneyPanelInventory.getGameObject().SetActive(true);
moneyPanelContainer = new MoneyPanel(MoneyPanel.MoneyPanelType.Container, parentTransform2);
moneyPanelContainer.getGameObject().SetActive(true);
}
}
[HarmonyPatch(typeof(InventoryGui), "Show")]
public class InventoryGui_Show_Patch
{
public static void Postfix(InventoryGui __instance)
{
Logger.Log("Inventory opened!");
MoneyInventoryRecalculation.RecalculateMoneyInventoryValue();
}
}
[HarmonyPatch(typeof(Inventory), "Changed")]
internal class Inventory_Changed_Patch
{
public static void Postfix(Inventory __instance)
{
Player localPlayer = Player.m_localPlayer;
if (__instance == ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null))
{
MoneyInventoryRecalculation.RecalculateMoneyInventoryValue();
}
}
}
[HarmonyPatch(typeof(Container), "Interact")]
public class Container_Interact_Patch
{
public static void Postfix(Container __instance, Humanoid character, bool hold, bool alt, bool __result)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance != (Object)null)
{
Logger.Log($"Chest opened in {((Component)__instance).transform.position}!");
MoneyInventoryRecalculation.RecalculateCalculateChestValue(__instance);
}
}
}
[HarmonyPatch]
public class Container_Changed_patch
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(Container), "OnContainerChanged", (Type[])null, (Type[])null);
}
public static void Postfix(ref Container __instance)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance != (Object)null)
{
Logger.Log($"Chest opened in {((Component)__instance).transform.position}!");
MoneyInventoryRecalculation.RecalculateCalculateChestValue(__instance);
}
}
}
public class MoneyInventoryRecalculation
{
public static void RecalculateMoneyInventoryValue()
{
int num = 0;
if ((Object)(object)Player.m_localPlayer != (Object)null)
{
foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
{
if (allItem.m_shared.m_value > 0)
{
Logger.Log("Found in player inventory: " + allItem.m_shared.m_name + " = " + allItem.m_shared.m_value);
num += allItem.m_stack * allItem.m_shared.m_value;
}
}
}
MoneyInventoryGuiPatch.moneyPanelInventory.updateMoneyValue(num.ToString());
}
public static void RecalculateCalculateChestValue(Container chest)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
if ((Object)(object)chest == (Object)null)
{
return;
}
int num = 0;
FieldInfo field = typeof(Container).GetField("m_inventory", BindingFlags.Instance | BindingFlags.NonPublic);
Inventory val = (Inventory)field.GetValue(chest);
foreach (ItemData allItem in val.GetAllItems())
{
if (allItem.m_shared.m_value > 0)
{
Logger.Log("Found in container inventory: " + allItem.m_shared.m_name + " = " + allItem.m_shared.m_value);
num += allItem.m_stack * allItem.m_shared.m_value;
}
}
MoneyInventoryGuiPatch.moneyPanelContainer.updateMoneyValue(num.ToString());
}
}
public class MoneyPanel
{
public enum MoneyPanelType
{
Inventory,
Container
}
private readonly GameObject moneyPanelGameObject;
private readonly Transform weightTransform;
private TextMeshProUGUI moneyPanelValueComponentText;
public MoneyPanel(MoneyPanelType moneyPanelType, Transform parentTransform)
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
if (moneyPanelType == MoneyPanelType.Inventory)
{
weightTransform = ((Component)((Component)InventoryGui.instance.m_inventoryRoot).transform.Find("Player")).transform.Find("Weight");
}
else
{
weightTransform = ((Component)((Component)InventoryGui.instance.m_inventoryRoot).transform.Find("Container")).transform.Find("Weight");
}
moneyPanelGameObject = new GameObject("MoneyPanel", new Type[1] { typeof(RectTransform) });
moneyPanelGameObject.SetActive(true);
moneyPanelGameObject.transform.SetParent(parentTransform);
RectTransform component = moneyPanelGameObject.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(80f, 64f);
switch (moneyPanelType)
{
case MoneyPanelType.Inventory:
component.anchoredPosition = new Vector2(317f, -7f);
break;
case MoneyPanelType.Container:
component.anchoredPosition = new Vector2(319f, -30f);
break;
}
moneyPanelGameObject.transform.SetSiblingIndex(weightTransform.GetSiblingIndex() + 1);
moneyPanelBackground();
moneyPanelIcon();
moneyPanelValue();
((TMP_Text)moneyPanelValueComponentText).text = "0";
}
private void moneyPanelBackground()
{
GameObject gameObject = ((Component)weightTransform.Find("bkg")).gameObject;
GameObject val = Object.Instantiate<GameObject>(gameObject, moneyPanelGameObject.transform);
((Object)val).name = "moneypanel_bkg";
}
private void moneyPanelIcon()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("moneypanel_icon");
val.transform.SetParent(moneyPanelGameObject.transform);
Image val2 = val.AddComponent<Image>();
val2.sprite = ModUtils.getSprite("coins");
val2.type = (Type)1;
RectTransform component = val.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(32f, 32f);
component.anchoredPosition = new Vector2(2f, 25f);
}
private void moneyPanelValue()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
GameObject gameObject = ((Component)weightTransform.Find("weight_text")).gameObject;
GameObject val = Object.Instantiate<GameObject>(gameObject, moneyPanelGameObject.transform);
((Object)val).name = "moneypanel_value";
RectTransform component = val.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(80f, 64f);
component.anchoredPosition = new Vector2(0f, 0f);
moneyPanelValueComponentText = val.GetComponent<TextMeshProUGUI>();
}
public void updateMoneyValue(string value)
{
((TMP_Text)moneyPanelValueComponentText).text = value;
}
public GameObject getGameObject()
{
return moneyPanelGameObject;
}
}
}