Decompiled source of InventorySelectionHighlight v1.0.0

BepInEx/plugins/InventorySelectionHighlight.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 HarmonyLib;
using InventorySelectionHighlight.Configuration;
using InventorySelectionHighlight.Localization;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InventorySelectionHighlight")]
[assembly: AssemblyDescription("InventorySelectionHighlight mod for Old Market Simulator by Ice Box Studio")]
[assembly: AssemblyCompany("Ice Box Studio")]
[assembly: AssemblyProduct("InventorySelectionHighlight")]
[assembly: AssemblyCopyright("Copyright © 2025 Ice Box Studio")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E6B2A3B5-2D6B-4D9A-9B03-6B45F92C8B10")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace InventorySelectionHighlight
{
	[BepInPlugin("IceBoxStudio.InventorySelectionHighlight", "InventorySelectionHighlight", "1.0.0")]
	public class InventorySelectionHighlight : BaseUnityPlugin
	{
		private static InventorySelectionHighlight _instance;

		private Harmony _harmony;

		private bool patchesApplied;

		public static InventorySelectionHighlight Instance => _instance;

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			_instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Logger.LogInfo((object)"=============================================");
				Logger.LogInfo((object)("InventorySelectionHighlight " + LocalizationManager.Instance.GetLocalizedText("plugin.initializing")));
				Logger.LogInfo((object)(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix") + "Ice Box Studio(https://steamcommunity.com/id/ibox666/)"));
				ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
				ApplyPatches();
				Logger.LogInfo((object)("InventorySelectionHighlight " + LocalizationManager.Instance.GetLocalizedText("plugin.initialized")));
				Logger.LogInfo((object)"=============================================");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("InventorySelectionHighlight 初始化错误: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void ApplyPatches()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (!patchesApplied)
			{
				try
				{
					_harmony = new Harmony("IceBoxStudio.InventorySelectionHighlight");
					_harmony.PatchAll();
					patchesApplied = true;
					return;
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("InventorySelectionHighlight 应用补丁错误: " + ex.Message + "\n" + ex.StackTrace));
					return;
				}
			}
			Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped"));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IceBoxStudio.InventorySelectionHighlight";

		public const string PLUGIN_NAME = "InventorySelectionHighlight";

		public const string PLUGIN_VERSION = "1.0.0";

		public const string PLUGIN_AUTHOR = "Ice Box Studio";

		public const string PLUGIN_DESCRIPTION = "自定义物品栏选中高亮颜色和粗细。";
	}
}
namespace InventorySelectionHighlight.Patches
{
	[HarmonyPatch(typeof(PlayerInventory))]
	public static class PlayerInventoryPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("OnCurrentSlotChanged")]
		public static void OnCurrentSlotChanged_Postfix(PlayerInventory __instance, int previous, int current)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!ConfigManager.EnableMod.Value)
			{
				return;
			}
			try
			{
				Transform transform = __instance.itemSlots.transform;
				if (current >= 0 && current < transform.childCount)
				{
					Outline component = ((Component)transform.GetChild(current)).GetComponent<Outline>();
					if ((Object)(object)component != (Object)null)
					{
						((Shadow)component).effectColor = ConfigManager.GetHighlightColor();
						((Shadow)component).effectDistance = ConfigManager.GetEffectDistance();
					}
				}
			}
			catch
			{
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnNetworkSpawn")]
		public static void OnNetworkSpawn_Postfix(PlayerInventory __instance)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!ConfigManager.EnableMod.Value)
			{
				return;
			}
			try
			{
				Transform transform = __instance.itemSlots.transform;
				for (int i = 0; i < transform.childCount; i++)
				{
					Outline component = ((Component)transform.GetChild(i)).GetComponent<Outline>();
					if ((Object)(object)component != (Object)null)
					{
						((Shadow)component).effectColor = ConfigManager.GetHighlightColor();
						((Shadow)component).effectDistance = ConfigManager.GetEffectDistance();
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(ItemSlot), "UpdateSlot")]
	public static class ItemSlotPatches
	{
		[HarmonyPostfix]
		public static void ItemSlot_UpdateSlot_Postfix(ItemSlot __instance)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigManager.EnableMod.Value)
			{
				Outline outline = __instance.outline;
				if ((Object)(object)outline != (Object)null)
				{
					((Shadow)outline).effectColor = ConfigManager.GetHighlightColor();
					((Shadow)outline).effectDistance = ConfigManager.GetEffectDistance();
				}
			}
		}
	}
}
namespace InventorySelectionHighlight.Localization
{
	public static class LocalizationHelper
	{
		private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };

		public static void InitializeLanguageFiles()
		{
			string text = Path.Combine(Paths.ConfigPath, "InventorySelectionHighlight", "Localization");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string[] defaultTranslationLanguages = DefaultTranslationLanguages;
			foreach (string text2 in defaultTranslationLanguages)
			{
				string filePath = Path.Combine(text, text2 + ".json");
				EnsureLanguageFile(text2, filePath);
			}
		}

		private static void EnsureLanguageFile(string language, string filePath)
		{
			Dictionary<string, string> defaultTranslations = GetDefaultTranslations(language);
			if (File.Exists(filePath))
			{
				try
				{
					Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath)) ?? new Dictionary<string, string>();
					bool flag = false;
					foreach (KeyValuePair<string, string> item in defaultTranslations)
					{
						if (!dictionary.ContainsKey(item.Key))
						{
							dictionary[item.Key] = item.Value;
							flag = true;
						}
						else if (dictionary[item.Key] != item.Value)
						{
							dictionary[item.Key] = item.Value;
							flag = true;
						}
					}
					foreach (string item2 in new List<string>(dictionary.Keys))
					{
						if (!defaultTranslations.ContainsKey(item2))
						{
							dictionary.Remove(item2);
							flag = true;
						}
					}
					if (flag)
					{
						string contents = JsonConvert.SerializeObject((object)dictionary, (Formatting)1);
						File.WriteAllText(filePath, contents);
					}
					return;
				}
				catch
				{
					CreateLanguageFile(filePath, defaultTranslations);
					return;
				}
			}
			CreateLanguageFile(filePath, defaultTranslations);
		}

		private static void CreateLanguageFile(string filePath, Dictionary<string, string> translations)
		{
			string contents = JsonConvert.SerializeObject((object)translations, (Formatting)1);
			File.WriteAllText(filePath, contents);
		}

		public static Dictionary<string, string> GetDefaultTranslations(string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			switch (language)
			{
			case "zh":
				dictionary.Add("plugin.initializing", "开始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "补丁已应用,跳过...");
				dictionary.Add("plugin.language_fallback", "不支持的语言 {0},使用英语作为备用。");
				dictionary.Add("config.enable_mod_desc", "是否启用本模组");
				dictionary.Add("config.highlight_color_desc", "选中高亮颜色(Hex,支持RGBA)");
				dictionary.Add("config.highlight_thickness_desc", "选中高亮粗细(像素)");
				break;
			case "zh-Hant":
				dictionary.Add("plugin.initializing", "開始初始化...");
				dictionary.Add("plugin.author_prefix", "作者:");
				dictionary.Add("plugin.initialized", "初始化成功!");
				dictionary.Add("plugin.patches_skipped", "補丁已應用,跳過...");
				dictionary.Add("plugin.language_fallback", "不支持的語言 {0},使用英語作為備用。");
				dictionary.Add("config.enable_mod_desc", "是否啟用本模組");
				dictionary.Add("config.highlight_color_desc", "選中高亮顏色(Hex,支援RGBA)");
				dictionary.Add("config.highlight_thickness_desc", "選中高亮粗細(像素)");
				break;
			case "en":
				dictionary.Add("plugin.initializing", "is initializing...");
				dictionary.Add("plugin.author_prefix", "Author: ");
				dictionary.Add("plugin.initialized", "initialized successfully!");
				dictionary.Add("plugin.patches_skipped", "Patches already applied, skipping...");
				dictionary.Add("plugin.language_fallback", "Unsupported language {0}, using English as fallback.");
				dictionary.Add("config.enable_mod_desc", "Whether to enable mod functionality");
				dictionary.Add("config.highlight_color_desc", "Selected slot outline color (Hex, RGBA supported)");
				dictionary.Add("config.highlight_thickness_desc", "Selected slot outline thickness (pixels)");
				break;
			}
			return dictionary;
		}
	}
	public class LocalizationManager
	{
		private static LocalizationManager _instance;

		private Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>();

		private string _currentLocale = "zh";

		public static readonly string[] SupportedLanguages = new string[12]
		{
			"zh", "zh-Hant", "en", "fr", "de", "ja", "ko", "pt", "ru", "es",
			"tr", "uk"
		};

		private static readonly string[] DefaultTranslationLanguages = new string[3] { "zh", "zh-Hant", "en" };

		public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager());

		private LocalizationManager()
		{
			Initialize();
		}

		public void Initialize()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LocalizationSettings.SelectedLocale != (Object)null)
			{
				LocaleIdentifier identifier = LocalizationSettings.SelectedLocale.Identifier;
				_currentLocale = ((LocaleIdentifier)(ref identifier)).Code;
			}
			LocalizationHelper.InitializeLanguageFiles();
			string path = Path.Combine(Paths.ConfigPath, "InventorySelectionHighlight", "Localization");
			string[] supportedLanguages = SupportedLanguages;
			foreach (string text in supportedLanguages)
			{
				string filePath = Path.Combine(path, text + ".json");
				LoadLanguageFile(text, filePath);
			}
			LocalizationSettings.SelectedLocaleChanged += OnGameLanguageChanged;
		}

		private void OnGameLanguageChanged(Locale locale)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)locale != (Object)null)
			{
				LocaleIdentifier identifier = locale.Identifier;
				string code = ((LocaleIdentifier)(ref identifier)).Code;
				if (_localizations.ContainsKey(code))
				{
					_currentLocale = code;
					return;
				}
				_currentLocale = "en";
				InventorySelectionHighlight.Logger.LogInfo((object)GetLocalizedText("plugin.language_fallback", code));
			}
		}

		private void LoadLanguageFile(string language, string filePath)
		{
			if (File.Exists(filePath))
			{
				try
				{
					Dictionary<string, string> value = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(filePath));
					_localizations[language] = value;
					return;
				}
				catch
				{
					if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
					{
						_localizations[language] = GetDefaultTranslations(language);
					}
					return;
				}
			}
			if (Array.IndexOf(DefaultTranslationLanguages, language) >= 0)
			{
				_localizations[language] = GetDefaultTranslations(language);
			}
		}

		private Dictionary<string, string> GetDefaultTranslations(string language)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(LocalizationHelper), "GetDefaultTranslations", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				return methodInfo.Invoke(null, new object[1] { language }) as Dictionary<string, string>;
			}
			return new Dictionary<string, string>();
		}

		public string GetLocalizedText(string key, params object[] args)
		{
			if (string.IsNullOrEmpty(_currentLocale) || !_localizations.ContainsKey(_currentLocale))
			{
				_currentLocale = "en";
			}
			if (_localizations.ContainsKey(_currentLocale) && _localizations[_currentLocale].TryGetValue(key, out var value))
			{
				if (args.Length == 0)
				{
					return value;
				}
				return string.Format(value, args);
			}
			if (_currentLocale != "en" && _localizations.ContainsKey("en") && _localizations["en"].TryGetValue(key, out var value2))
			{
				if (args.Length == 0)
				{
					return value2;
				}
				return string.Format(value2, args);
			}
			if (_localizations.ContainsKey("zh") && _localizations["zh"].TryGetValue(key, out var value3))
			{
				if (args.Length == 0)
				{
					return value3;
				}
				return string.Format(value3, args);
			}
			return key;
		}
	}
}
namespace InventorySelectionHighlight.Configuration
{
	public static class ConfigManager
	{
		public static ConfigEntry<bool> EnableMod { get; private set; }

		public static ConfigEntry<string> HighlightColorHex { get; private set; }

		public static ConfigEntry<float> HighlightThickness { get; private set; }

		public static void Initialize(ConfigFile config)
		{
			EnableMod = config.Bind<bool>("General", "EnableMod", true, LocalizationManager.Instance.GetLocalizedText("config.enable_mod_desc"));
			HighlightColorHex = config.Bind<string>("General", "HighlightColorHex", "#00FFFFFF", LocalizationManager.Instance.GetLocalizedText("config.highlight_color_desc"));
			HighlightThickness = config.Bind<float>("General", "HighlightThickness", 3f, LocalizationManager.Instance.GetLocalizedText("config.highlight_thickness_desc"));
		}

		public static Color GetHighlightColor()
		{
			//IL_0027: 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)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			string text = HighlightColorHex.Value;
			if (string.IsNullOrWhiteSpace(text))
			{
				return new Color(1f, 1f, 0f, 1f);
			}
			if (text.StartsWith("#"))
			{
				text = text.Substring(1);
			}
			if (!uint.TryParse(text, NumberStyles.HexNumber, null, out var result))
			{
				return new Color(1f, 1f, 0f, 1f);
			}
			if (text.Length == 8)
			{
				float num = (float)((result >> 24) & 0xFFu) / 255f;
				float num2 = (float)((result >> 16) & 0xFFu) / 255f;
				float num3 = (float)((result >> 8) & 0xFFu) / 255f;
				float num4 = (float)(result & 0xFFu) / 255f;
				return new Color(num, num2, num3, num4);
			}
			if (text.Length == 6)
			{
				float num5 = (float)((result >> 16) & 0xFFu) / 255f;
				float num6 = (float)((result >> 8) & 0xFFu) / 255f;
				float num7 = (float)(result & 0xFFu) / 255f;
				return new Color(num5, num6, num7, 1f);
			}
			return new Color(1f, 1f, 0f, 1f);
		}

		public static Vector2 GetEffectDistance()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(HighlightThickness.Value, 0f, 20f);
			return new Vector2(num, num);
		}
	}
}