Decompiled source of IMSBetterMarket v1.0.2
BepInEx/plugins/BetterMarket.dll
Decompiled 9 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BetterMarket.Configuration; using BetterMarket.Features; using BetterMarket.Localization; using BetterMarket.Patches; using BetterMarket.UI; using BetterMarket.Utils; using DistantLands.Cozy; using GinjaGaming.FinalCharacterController; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Mirror; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Localization; using UnityEngine.Localization.Components; using UnityEngine.Localization.Settings; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("BetterMarket")] [assembly: AssemblyDescription("Better Market mod for Island Market Simulator by Ice Box Studio")] [assembly: AssemblyCompany("Ice Box Studio")] [assembly: AssemblyProduct("BetterMarket")] [assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("79ED620B-2738-4F23-8683-3854FB41A8D4")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.0.1.0")] namespace BetterMarket { [BepInPlugin("IceBoxStudio.IslandMarketSimulator.BetterMarket", "BetterMarket", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class BetterMarket : BasePlugin { public static BetterMarket _Instance; private Harmony _harmony; private bool patchesApplied; private static bool _timeDisplayControllerRegistered; private static bool _bankRatePanelControllerRegistered; private static bool _orderGuideControllerRegistered; private const string ModConfigManagerApiTypeName = "ModConfigManager.Api.ModConfigManagerAPI"; private const string ModConfigManagerRegisterMethodName = "RegisterPluginInfo"; public static BetterMarket Instance => _Instance; internal static ManualLogSource Logger { get; private set; } public override void Load() { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown _Instance = this; Logger = ((BasePlugin)this).Log; bool flag = default(bool); try { Logger.LogInfo((object)"============================================="); ManualLogSource logger = Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(1, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(LocalizationManager.Instance.GetLocalizedText("plugin.initializing")); } logger.LogInfo(val); ManualLogSource logger2 = Logger; val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(LocalizationManager.Instance.GetLocalizedText("plugin.author_prefix")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Ice Box Studio(https://steamcommunity.com/id/ibox666/)"); } logger2.LogInfo(val); ConfigManager.Initialize(((BasePlugin)this).Config); EnsureInjectedTypesRegistered(); RegisterToModConfigManager(); ApplyPatches(); ManualLogSource logger3 = Logger; val = new BepInExInfoLogInterpolatedStringHandler(1, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(LocalizationManager.Instance.GetLocalizedText("plugin.initialized")); } logger3.LogInfo(val); Logger.LogInfo((object)"============================================="); } catch (Exception ex) { ManualLogSource logger4 = Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(9, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" 初始化错误: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\n"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.StackTrace); } logger4.LogError(val2); } } private static void EnsureInjectedTypesRegistered() { if (!_timeDisplayControllerRegistered) { ClassInjector.RegisterTypeInIl2Cpp<TimeDisplayController>(); _timeDisplayControllerRegistered = true; } if (!_bankRatePanelControllerRegistered) { ClassInjector.RegisterTypeInIl2Cpp<BankRatePanelController>(); _bankRatePanelControllerRegistered = true; } if (!_orderGuideControllerRegistered) { ClassInjector.RegisterTypeInIl2Cpp<OrderGuideController>(); _orderGuideControllerRegistered = true; } } private void ApplyPatches() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //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.IslandMarketSimulator.BetterMarket"); _harmony.PatchAll(); patchesApplied = true; return; } catch (Exception ex) { ManualLogSource logger = Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(10, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" 应用补丁错误: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\n"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.StackTrace); } logger.LogError(val); return; } } Logger.LogInfo((object)LocalizationManager.Instance.GetLocalizedText("plugin.patches_skipped")); } private void RegisterToModConfigManager() { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => assembly.GetType("ModConfigManager.Api.ModConfigManagerAPI") != null)?.GetType("ModConfigManager.Api.ModConfigManagerAPI"); if (!(type == null)) { MethodInfo method = type.GetMethod("RegisterPluginInfo", BindingFlags.Static | BindingFlags.Public); if (!(method == null)) { method.Invoke(null, new object[5] { "IceBoxStudio.IslandMarketSimulator.BetterMarket", LocalizationManager.Instance.GetLocalizedText("plugin.name"), "1.0.1", "Ice Box Studio", LocalizationManager.Instance.GetLocalizedText("plugin.description") }); } } } } public static class PluginInfo { public const string PLUGIN_GUID = "IceBoxStudio.IslandMarketSimulator.BetterMarket"; public const string PLUGIN_NAME = "BetterMarket"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace BetterMarket.Utils { public static class KeyboardInputHelper { private static readonly Dictionary<KeyCode, string> KeyPropertyOverrides = new Dictionary<KeyCode, string> { { (KeyCode)96, "backquoteKey" }, { (KeyCode)8, "backspaceKey" }, { (KeyCode)92, "backslashKey" }, { (KeyCode)301, "capsLockKey" }, { (KeyCode)44, "commaKey" }, { (KeyCode)127, "deleteKey" }, { (KeyCode)274, "downArrowKey" }, { (KeyCode)279, "endKey" }, { (KeyCode)61, "equalsKey" }, { (KeyCode)27, "escapeKey" }, { (KeyCode)278, "homeKey" }, { (KeyCode)277, "insertKey" }, { (KeyCode)271, "numpadEnterKey" }, { (KeyCode)308, "leftAltKey" }, { (KeyCode)276, "leftArrowKey" }, { (KeyCode)91, "leftBracketKey" }, { (KeyCode)306, "leftCtrlKey" }, { (KeyCode)304, "leftShiftKey" }, { (KeyCode)319, "contextMenuKey" }, { (KeyCode)45, "minusKey" }, { (KeyCode)300, "numLockKey" }, { (KeyCode)281, "pageDownKey" }, { (KeyCode)280, "pageUpKey" }, { (KeyCode)46, "periodKey" }, { (KeyCode)39, "quoteKey" }, { (KeyCode)13, "enterKey" }, { (KeyCode)307, "rightAltKey" }, { (KeyCode)275, "rightArrowKey" }, { (KeyCode)93, "rightBracketKey" }, { (KeyCode)305, "rightCtrlKey" }, { (KeyCode)303, "rightShiftKey" }, { (KeyCode)302, "scrollLockKey" }, { (KeyCode)59, "semicolonKey" }, { (KeyCode)47, "slashKey" }, { (KeyCode)32, "spaceKey" }, { (KeyCode)9, "tabKey" }, { (KeyCode)273, "upArrowKey" } }; private static readonly Dictionary<string, PropertyInfo> KeyboardPropertyCache = new Dictionary<string, PropertyInfo>(); private static readonly Dictionary<string, InputAction> ActionCache = new Dictionary<string, InputAction>(); private static bool _legacyInputUnavailable; private static Type _keyboardType; private static PropertyInfo _keyboardCurrentProperty; public static bool WasKeyPressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!TryGetLegacyKeyDown(key)) { return TryGetNewInputSystemKeyDown(key); } return true; } public static bool WasActionPressed(string actionName, KeyCode fallbackKey = (KeyCode)0) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (TryGetAction(actionName, out var action)) { try { if (!action.enabled) { action.Enable(); } if (action.WasPressedThisFrame()) { return true; } } catch { } } if ((int)fallbackKey != 0) { return WasKeyPressed(fallbackKey); } return false; } public static bool WasControlPressed(string controlPath, KeyCode fallbackKey = (KeyCode)0) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) try { if (!string.IsNullOrWhiteSpace(controlPath)) { InputControl obj = InputSystem.FindControl(controlPath); ButtonControl val = (ButtonControl)(object)((obj is ButtonControl) ? obj : null); if (val != null && val.wasPressedThisFrame) { return true; } } } catch { } if ((int)fallbackKey != 0) { return WasKeyPressed(fallbackKey); } return false; } private static bool TryGetLegacyKeyDown(KeyCode key) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (_legacyInputUnavailable) { return false; } try { return Input.GetKeyDown(key); } catch (InvalidOperationException) { _legacyInputUnavailable = true; return false; } } private static bool TryGetNewInputSystemKeyDown(KeyCode key) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) try { if (!TryResolveKeyboard(out var keyboard)) { return false; } string keyboardPropertyName = GetKeyboardPropertyName(key); if (string.IsNullOrEmpty(keyboardPropertyName)) { return false; } if (!KeyboardPropertyCache.TryGetValue(keyboardPropertyName, out var value)) { value = _keyboardType.GetProperty(keyboardPropertyName); KeyboardPropertyCache[keyboardPropertyName] = value; } if (value == null) { return false; } object value2 = value.GetValue(keyboard); if (value2 == null) { return false; } PropertyInfo property = value2.GetType().GetProperty("wasPressedThisFrame"); return property != null && (bool)property.GetValue(value2); } catch { return false; } } private static bool TryResolveKeyboard(out object keyboard) { keyboard = null; if (_keyboardType == null) { _keyboardType = Type.GetType("UnityEngine.InputSystem.Keyboard, Unity.InputSystem"); if (_keyboardType == null) { return false; } } if (_keyboardCurrentProperty == null) { _keyboardCurrentProperty = _keyboardType.GetProperty("current"); if (_keyboardCurrentProperty == null) { return false; } } keyboard = _keyboardCurrentProperty.GetValue(null); return keyboard != null; } private unsafe static string GetKeyboardPropertyName(KeyCode key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected I4, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Invalid comparison between Unknown and I4 //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected I4, but got Unknown if (KeyPropertyOverrides.TryGetValue(key, out var value)) { return value; } if ((int)key >= 97 && (int)key <= 122) { return char.ToLowerInvariant(((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString()[0]) + "Key"; } if ((int)key >= 48 && (int)key <= 57) { return $"digit{key - 48}Key"; } if ((int)key >= 256 && (int)key <= 265) { return $"numpad{key - 256}Key"; } if ((int)key >= 282 && (int)key <= 296) { return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString().ToLowerInvariant() + "Key"; } return null; } private static bool TryGetAction(string actionName, out InputAction action) { action = null; if (string.IsNullOrWhiteSpace(actionName)) { return false; } if (ActionCache.TryGetValue(actionName, out var value) && value != null) { action = value; return true; } PlayerControls playerControls = PlayerInputManager.PlayerControls; if ((Object)(object)((playerControls != null) ? playerControls.asset : null) == (Object)null) { return false; } InputAction val = null; int num = actionName.IndexOf('/'); if (num > 0 && num < actionName.Length - 1) { string text = actionName.Substring(0, num); string text2 = actionName.Substring(num + 1); InputActionMap obj = playerControls.asset.FindActionMap(text, false); val = ((obj != null) ? obj.FindAction(text2, false) : null); } if (val == null) { val = playerControls.asset.FindAction(actionName, false); } if (val == null) { return false; } ActionCache[actionName] = val; action = val; return true; } } } namespace BetterMarket.UI { public static class BankRatePanelUI { private const string CanvasObjectName = "BetterMarket_BankRateCanvas"; private const string PanelObjectName = "BetterMarket_BankRatePanel"; private static GameObject _canvasObject; private static GameObject _panelObject; public static void EnsureCreated() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panelObject != (Object)null) { return; } GameObject val = GameObject.Find("BetterMarket_BankRateCanvas"); if ((Object)(object)val != (Object)null) { _canvasObject = val; } if ((Object)(object)_canvasObject == (Object)null) { _canvasObject = new GameObject("BetterMarket_BankRateCanvas"); Canvas obj = _canvasObject.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 32000; Object.DontDestroyOnLoad((Object)(object)_canvasObject); } Transform val2 = _canvasObject.transform.Find("BetterMarket_BankRatePanel"); if ((Object)(object)val2 != (Object)null) { _panelObject = ((Component)val2).gameObject; if ((Object)(object)_panelObject.GetComponent<BankRatePanelController>() == (Object)null) { _panelObject.AddComponent<BankRatePanelController>(); } return; } _panelObject = new GameObject("BetterMarket_BankRatePanel"); _panelObject.transform.SetParent(_canvasObject.transform, false); TextMeshProUGUI obj2 = _panelObject.AddComponent<TextMeshProUGUI>(); ((Graphic)obj2).raycastTarget = false; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)516; ((TMP_Text)obj2).enableWordWrapping = false; ((TMP_Text)obj2).richText = true; RectTransform component = _panelObject.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 0.5f); component.anchorMax = new Vector2(1f, 0.5f); component.pivot = new Vector2(1f, 0.5f); component.anchoredPosition = new Vector2(-36f, 0f); component.sizeDelta = new Vector2(520f, 180f); _panelObject.AddComponent<BankRatePanelController>(); } } public class BankRatePanelController : MonoBehaviour { private TextMeshProUGUI _panelText; private float _refreshTimer; private float _styleSyncTimer; private string _cachedText; public BankRatePanelController(IntPtr pointer) : base(pointer) { } private void Awake() { _panelText = ((Component)this).GetComponent<TextMeshProUGUI>(); ((Behaviour)_panelText).enabled = BankRateDisplayState.IsVisible; SyncStyleFromGameText(force: true); RefreshDisplay(force: true); } private void Update() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panelText == (Object)null) { return; } ConfigManager instance = ConfigManager.Instance; if (instance == null || instance.EnableBankRateAlert?.Value != true) { if (((Behaviour)_panelText).enabled) { ((Behaviour)_panelText).enabled = false; } return; } if (instance?.ToggleBankRatePanelKey != null && WasTogglePressed(instance.ToggleBankRatePanelKey.Value)) { BankRateDisplayState.ToggleVisibility(); } bool isVisible = BankRateDisplayState.IsVisible; if (((Behaviour)_panelText).enabled != isVisible) { ((Behaviour)_panelText).enabled = isVisible; } if (isVisible) { _styleSyncTimer += Time.unscaledDeltaTime; if (_styleSyncTimer >= 1f) { _styleSyncTimer = 0f; SyncStyleFromGameText(force: false); } _refreshTimer += Time.unscaledDeltaTime; if (_refreshTimer >= 0.25f) { _refreshTimer = 0f; RefreshDisplay(force: false); } } } private void SyncStyleFromGameText(bool force) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) GeneralUIController instance = GeneralUIController.Instance; TextMeshProUGUI val = ((instance != null) ? instance.seasonText : null); if ((Object)(object)val != (Object)null) { if (force || (Object)(object)((TMP_Text)_panelText).font != (Object)(object)((TMP_Text)val).font) { ((TMP_Text)_panelText).font = ((TMP_Text)val).font; } ((TMP_Text)_panelText).fontSize = ((TMP_Text)val).fontSize * 0.92f; Color color = ((Graphic)val).color; color.r = 1f; color.g = 1f; color.b = 1f; color.a = 0.98f; ((Graphic)_panelText).color = color; ((TMP_Text)_panelText).outlineWidth = Mathf.Max(((TMP_Text)val).outlineWidth, 0.28f); ((TMP_Text)_panelText).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.95f)); } else if (force) { ((TMP_Text)_panelText).fontSize = 24f; ((Graphic)_panelText).color = new Color(1f, 1f, 1f, 0.98f); ((TMP_Text)_panelText).outlineWidth = 0.28f; ((TMP_Text)_panelText).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.95f)); } } private void RefreshDisplay(bool force) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) LocalizationManager instance = LocalizationManager.Instance; ConfigManager instance2 = ConfigManager.Instance; object obj; if (instance2 == null) { obj = null; } else { ConfigEntry<KeyCode> toggleBankRatePanelKey = instance2.ToggleBankRatePanelKey; obj = ((toggleBankRatePanelKey != null) ? ((object)toggleBankRatePanelKey.Value/*cast due to .constrained prefix*/).ToString() : null); } if (obj == null) { obj = ((object)(KeyCode)289/*cast due to .constrained prefix*/).ToString(); } string text = (string)obj; string text2 = (((Object)(object)PlayerData.Instance != (Object)null && PlayerData.Instance.SecondCurrency > 0) ? (" <color=#CE93D8>[" + instance.GetLocalizedText("ui.bank.panel.close_hint_inline", text) + "]</color>") : string.Empty); string value = instance.GetLocalizedText("ui.bank.panel.title") + text2; if (!BankRateDisplayState.HasData) { string text3 = $"<color=#FFE082>{value}</color>\n<color=#FFFFFF>{instance.GetLocalizedText("ui.bank.panel.current_rate", "-")}</color>\n<color=#B0BEC5>{instance.GetLocalizedText("ui.bank.panel.trend_flat")}</color>"; ApplyText(text3, force); return; } int lastDelta = BankRateDisplayState.LastDelta; string value2 = ((lastDelta > 0) ? ("<color=#66FF66>" + instance.GetLocalizedText("ui.bank.panel.trend_up", Math.Abs(lastDelta)) + "</color>") : ((lastDelta < 0) ? ("<color=#FF6E6E>" + instance.GetLocalizedText("ui.bank.panel.trend_down", Math.Abs(lastDelta)) + "</color>") : ("<color=#B0BEC5>" + instance.GetLocalizedText("ui.bank.panel.trend_flat") + "</color>"))); string value3 = ((BankRateDisplayState.LastUpdateHour >= 0) ? instance.GetLocalizedText("ui.bank.panel.updated_hour", BankRateDisplayState.LastUpdateHour.ToString("00")) : string.Empty); string text4 = (string.IsNullOrEmpty(value3) ? $"<color=#FFE082>{value}</color>\n<color=#FFFFFF>{instance.GetLocalizedText("ui.bank.panel.current_rate", BankRateDisplayState.CurrentRatio)}</color>\n{value2}" : $"<color=#FFE082>{value}</color>\n<color=#FFFFFF>{instance.GetLocalizedText("ui.bank.panel.current_rate", BankRateDisplayState.CurrentRatio)}</color>\n{value2}\n<color=#90CAF9>{value3}</color>"); ApplyText(text4, force); } private static bool WasTogglePressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return KeyboardInputHelper.WasKeyPressed(key); } private void ApplyText(string text, bool force) { if (force || !string.Equals(_cachedText, text, StringComparison.Ordinal)) { _cachedText = text; ((TMP_Text)_panelText).text = text; } } } } namespace BetterMarket.Patches { [HarmonyPatch(typeof(ItemManager), "ShowUI")] public static class AnimalRemainingDaysPatch { private const string RemainingColor = "#FFD54F"; private static readonly Dictionary<int, string> OriginalTextCache = new Dictionary<int, string>(); [HarmonyPostfix] private static void ShowUIPostfix(ItemManager __instance, Transform obj) { TextMeshProUGUI val = ((__instance != null) ? __instance.interactText : null); if ((Object)(object)val != (Object)null) { int instanceID = ((Object)val).GetInstanceID(); OriginalTextCache[instanceID] = ((TMP_Text)val).text ?? string.Empty; } if (ConfigManager.Instance == null || ConfigManager.Instance.EnableAnimalRemainingDaysDisplay == null || !ConfigManager.Instance.EnableAnimalRemainingDaysDisplay.Value || (Object)(object)obj == (Object)null || (Object)(object)val == (Object)null) { return; } Animal component = ((Component)obj).GetComponent<Animal>(); if ((Object)(object)component == (Object)null) { return; } int instanceID2 = ((Object)val).GetInstanceID(); if (!OriginalTextCache.TryGetValue(instanceID2, out var value)) { value = ((TMP_Text)val).text ?? string.Empty; } string[] array = value.Split('\n'); if (array.Length != 0) { string value2 = array[0]; int num = Mathf.Max(0, component.daysUntilGrowth); int num2 = Mathf.Max(0, component.daysUntilSubProductHarvest); int num3 = num + num2; if (num3 <= 0) { array[0] = $"{value2} <color={"#FFD54F"}>{LocalizationManager.Instance.GetLocalizedText("ui.status.harvestable")}</color>"; } else { array[0] = $"{value2} <color={"#FFD54F"}>{LocalizationManager.Instance.GetLocalizedText("ui.status.remaining_days", num3)}</color>"; } ((TMP_Text)val).text = string.Join("\n", array); } } } public static class BankRateDisplayState { public static int CurrentRatio { get; private set; } public static int LastDelta { get; private set; } public static int LastUpdateHour { get; private set; } = -1; public static bool HasData { get; private set; } public static bool IsVisible { get; private set; } public static void ApplyUpdate(int currentRatio, int delta, int currentHour) { CurrentRatio = currentRatio; LastDelta = delta; LastUpdateHour = currentHour; HasData = true; } public static void UpdateRatioOnly(int currentRatio) { CurrentRatio = currentRatio; HasData = true; } public static void ToggleVisibility() { IsVisible = !IsVisible; } public static void SetVisibility(bool visible) { IsVisible = visible; } } [HarmonyPatch(typeof(BankSystem), "OnChangeAmountChanged")] public static class BankRateAlertPatch { private static readonly HashSet<int> InitializedBanks = new HashSet<int>(); [HarmonyPostfix] private static void Postfix(BankSystem __instance, int oldVal, int newVal) { if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isClient) { return; } ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableBankRateAlert?.Value == true) { int instanceID = ((Object)__instance).GetInstanceID(); if (!InitializedBanks.Contains(instanceID)) { InitializedBanks.Add(instanceID); BankRateDisplayState.ApplyUpdate(__instance.currentRatio, newVal, GetCurrentHour()); } else { int currentRatio = __instance.currentRatio; int currentHour = GetCurrentHour(); BankRateDisplayState.ApplyUpdate(currentRatio, newVal, currentHour); } } } private static int GetCurrentHour() { if ((Object)(object)TimeManager.Instance == (Object)null || (Object)(object)TimeManager.Instance.cozyWeather == (Object)null || (Object)(object)TimeManager.Instance.cozyWeather.timeModule == (Object)null) { return -1; } return TimeManager.Instance.cozyWeather.timeModule.currentTime.hours; } } [HarmonyPatch(typeof(BankSystem), "OnRatioChanged")] public static class BankRateRatioSyncPatch { [HarmonyPostfix] private static void Postfix(BankSystem __instance, int oldVal, int newVal) { if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).isClient) { ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableBankRateAlert?.Value == true) { BankRateDisplayState.UpdateRatioOnly(newVal); } } } } [HarmonyPatch(typeof(GeneralUIController), "Start")] public static class BankRatePanelPatch { [HarmonyPostfix] private static void Postfix(GeneralUIController __instance) { ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableBankRateAlert?.Value == true) { BankRatePanelUI.EnsureCreated(); } } } [HarmonyPatch(typeof(PlayerData), "OnSecondCurrencyChanged")] public static class BankRatePanelVisibilityByHoldingPatch { private static readonly HashSet<int> InitializedPlayers = new HashSet<int>(); [HarmonyPostfix] private static void Postfix(PlayerData __instance, int oldValue, int newValue) { if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isClient) { return; } ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableBankRateAlert?.Value == true) { int instanceID = ((Object)__instance).GetInstanceID(); if (!InitializedPlayers.Contains(instanceID)) { InitializedPlayers.Add(instanceID); } else if (newValue > oldValue && newValue > 0) { BankRateDisplayState.SetVisibility(visible: true); } else if (oldValue > 0 && newValue <= 0) { BankRateDisplayState.SetVisibility(visible: false); } } } } internal static class InteractionUILayoutHelper { private const float MaxTextWidth = 900f; private const float TextWidthPadding = 12f; private const float TextHeightPadding = 10f; private static int _cachedTextId; private static Vector2 _baseSizeDelta; private static Vector2 _baseAnchoredPosition; private static Vector2 _basePivot; private static bool _baseWordWrapping; private static TextOverflowModes _baseOverflowMode; public static void Refresh(ItemManager itemManager) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_017e: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((itemManager != null) ? itemManager.interactText : null); if ((Object)(object)val == (Object)null) { return; } RectTransform rectTransform = ((TMP_Text)val).rectTransform; if (!((Object)(object)rectTransform == (Object)null)) { CaptureBaseLayout(val, rectTransform); string text = ((TMP_Text)val).text ?? string.Empty; ((TMP_Text)val).enableWordWrapping = false; ((TMP_Text)val).overflowMode = (TextOverflowModes)0; ((TMP_Text)val).ForceMeshUpdate(false, false); bool flag = (((TMP_Text)val).enableWordWrapping = ((TMP_Text)val).GetPreferredValues(text, 5000f, 5000f).x > 900f); ((TMP_Text)val).ForceMeshUpdate(false, false); Vector2 preferredValues = ((TMP_Text)val).GetPreferredValues(text, flag ? 900f : 5000f, 5000f); Rect rect; float num; if (!(_baseSizeDelta.x > 0f)) { rect = rectTransform.rect; num = ((Rect)(ref rect)).width; } else { num = _baseSizeDelta.x; } float num2 = num; float num3; if (!(_baseSizeDelta.y > 0f)) { rect = rectTransform.rect; num3 = ((Rect)(ref rect)).height; } else { num3 = _baseSizeDelta.y; } float num4 = Mathf.Max(num2, Mathf.Ceil((flag ? 900f : preferredValues.x) + 12f)); float num5 = Mathf.Max(num3, Mathf.Ceil(preferredValues.y + 10f)); float num6 = _baseAnchoredPosition.x - num2 * _basePivot.x + num4 * _basePivot.x; rectTransform.SetSizeWithCurrentAnchors((Axis)0, num4); rectTransform.SetSizeWithCurrentAnchors((Axis)1, num5); rectTransform.anchoredPosition = new Vector2(num6, _baseAnchoredPosition.y); } } private static void CaptureBaseLayout(TextMeshProUGUI interactText, RectTransform textRect) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) int instanceID = ((Object)interactText).GetInstanceID(); if (instanceID != _cachedTextId) { _cachedTextId = instanceID; _baseSizeDelta = textRect.sizeDelta; _baseAnchoredPosition = textRect.anchoredPosition; _basePivot = textRect.pivot; _baseWordWrapping = ((TMP_Text)interactText).enableWordWrapping; _baseOverflowMode = ((TMP_Text)interactText).overflowMode; } } public static void Restore(ItemManager itemManager) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((itemManager != null) ? itemManager.interactText : null); if (!((Object)(object)val == (Object)null) && ((Object)val).GetInstanceID() == _cachedTextId) { RectTransform rectTransform = ((TMP_Text)val).rectTransform; if ((Object)(object)rectTransform != (Object)null) { rectTransform.sizeDelta = _baseSizeDelta; rectTransform.anchoredPosition = _baseAnchoredPosition; } ((TMP_Text)val).enableWordWrapping = _baseWordWrapping; ((TMP_Text)val).overflowMode = _baseOverflowMode; } } } [HarmonyPatch(typeof(ItemManager), "ShowUI")] internal static class InteractionUILayoutShowPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ItemManager __instance) { InteractionUILayoutHelper.Refresh(__instance); } } internal static class InteractionUILayoutRestorePatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ItemManager), "HideUI", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ItemManager), "ClearHighlightAndUI", (Type[])null, (Type[])null); } [HarmonyPostfix] private static void Postfix(ItemManager __instance) { InteractionUILayoutHelper.Restore(__instance); } } [HarmonyPatch(typeof(GeneralUIController), "Start")] public static class OrderGuideInitPatch { [HarmonyPostfix] private static void Postfix(GeneralUIController __instance) { if (!((Object)(object)__instance == (Object)null)) { OrderGuideController.EnsureCreated(); } } } [HarmonyPatch(typeof(TabletActiveOrderSlotUI), "SetOrder")] public static class TabletActiveOrderSlotGuidePatch { [HarmonyPostfix] private static void Postfix(TabletActiveOrderSlotUI __instance, ActiveOrderData order) { if (!((Object)(object)__instance == (Object)null) && order != null) { OrderGuideState.BindSlot(((Component)__instance).gameObject, order); } } } [HarmonyPatch(typeof(CourierActiveOrderSlotUI), "SetOrder")] public static class CourierActiveOrderSlotGuidePatch { [HarmonyPostfix] private static void Postfix(CourierActiveOrderSlotUI __instance, ActiveOrderData order) { if (!((Object)(object)__instance == (Object)null) && order != null) { OrderGuideState.BindSlot(((Component)__instance).gameObject, order); } } } [HarmonyPatch(typeof(PlayerData))] public static class ReputationPatch { private static readonly Dictionary<int, TextMeshProUGUI> TextCache = new Dictionary<int, TextMeshProUGUI>(); private static bool IsDisplayEnabled() { if (ConfigManager.Instance != null && ConfigManager.Instance.EnableReputationDisplay != null) { return ConfigManager.Instance.EnableReputationDisplay.Value; } return false; } private static TextMeshProUGUI GetOrCreateText(Slider slider, string objectName, TextMeshProUGUI styleSource, float verticalOffset = -40f, float horizontalOffset = 0f) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00e6: 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_0119: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)slider == (Object)null) { return null; } int instanceID = ((Object)slider).GetInstanceID(); if (TextCache.TryGetValue(instanceID, out var value)) { if ((Object)(object)value != (Object)null) { return value; } TextCache.Remove(instanceID); } Transform parent = ((Component)slider).transform.parent; if ((Object)(object)parent == (Object)null) { return null; } Transform val = parent.Find(objectName); if ((Object)(object)val != (Object)null) { TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>(); if ((Object)(object)component != (Object)null) { TextCache[instanceID] = component; } return component; } GameObject val2 = new GameObject(objectName); val2.transform.SetParent(parent, false); RectTransform obj = val2.AddComponent<RectTransform>(); ((Transform)obj).localScale = Vector3.one; ((Transform)obj).localRotation = Quaternion.identity; obj.anchorMin = new Vector2(0.5f, 0f); obj.anchorMax = new Vector2(0.5f, 0f); obj.pivot = new Vector2(0.5f, 1f); obj.anchoredPosition = new Vector2(horizontalOffset, verticalOffset); RectTransform component2 = ((Component)slider).GetComponent<RectTransform>(); float num; if (!((Object)(object)component2 != (Object)null)) { num = 200f; } else { Rect rect = component2.rect; num = ((Rect)(ref rect)).width; } float num2 = num; obj.sizeDelta = new Vector2((num2 < 50f) ? 200f : num2, 80f); TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((TMP_Text)val3).enableAutoSizing = true; ((TMP_Text)val3).fontSizeMin = 20f; ((TMP_Text)val3).fontSizeMax = 120f; ((TMP_Text)val3).fontSize = 60f; ((Graphic)val3).color = Color.white; ((TMP_Text)val3).enableWordWrapping = false; ((Graphic)val3).raycastTarget = false; if ((Object)(object)styleSource != (Object)null) { ((TMP_Text)val3).font = ((TMP_Text)styleSource).font; } TextCache[instanceID] = val3; return val3; } private static void UpdateMarketReputationText(PlayerData playerData, Slider marketSlider, TextMeshProUGUI currencyText) { if (IsDisplayEnabled()) { TextMeshProUGUI orCreateText = GetOrCreateText(marketSlider, "MarketRepText", currencyText, -20f, -220f); if ((Object)(object)orCreateText != (Object)null) { ((TMP_Text)orCreateText).text = $"{playerData.Reputation:F1}"; } } } [HarmonyPatch("UpdateAllUI")] [HarmonyPostfix] private static void UpdateAllUIPostfix(PlayerData __instance) { UpdateMarketReputationText(__instance, (__instance != null) ? __instance.marketRepSlider : null, (__instance != null) ? __instance.currencyText : null); } [HarmonyPatch("OnReputationChanged")] [HarmonyPostfix] private static void OnReputationChangedPostfix(PlayerData __instance) { UpdateMarketReputationText(__instance, (__instance != null) ? __instance.marketRepSlider : null, (__instance != null) ? __instance.currencyText : null); } [HarmonyPatch("AdjustVillageSliders")] [HarmonyPostfix] private static void AdjustVillageSlidersPostfix(PlayerData __instance) { if (IsDisplayEnabled()) { TextMeshProUGUI orCreateText = GetOrCreateText((__instance != null) ? __instance.villageSliderPozitif : null, "VillageRepText", (__instance != null) ? __instance.currencyText : null); if ((Object)(object)orCreateText != (Object)null) { ((TMP_Text)orCreateText).text = $"{__instance.VillageReputation:F0}"; } } } [HarmonyPatch("AdjustKingdomSliders")] [HarmonyPostfix] private static void AdjustKingdomSlidersPostfix(PlayerData __instance) { if (IsDisplayEnabled()) { TextMeshProUGUI orCreateText = GetOrCreateText((__instance != null) ? __instance.kingdomSliderPozitif : null, "KingdomRepText", (__instance != null) ? __instance.currencyText : null); if ((Object)(object)orCreateText != (Object)null) { ((TMP_Text)orCreateText).text = $"{__instance.KingdomReputation:F0}"; } } } [HarmonyPatch("AdjustBanditSliders")] [HarmonyPostfix] private static void AdjustBanditSlidersPostfix(PlayerData __instance) { if (IsDisplayEnabled()) { TextMeshProUGUI orCreateText = GetOrCreateText((__instance != null) ? __instance.banditSliderPozitif : null, "BanditRepText", (__instance != null) ? __instance.currencyText : null); if ((Object)(object)orCreateText != (Object)null) { ((TMP_Text)orCreateText).text = $"{__instance.BanditReputation:F0}"; } } } } [HarmonyPatch(typeof(ItemManager), "ShowUI")] public static class SeedRemainingDaysPatch { private const string RemainingColor = "#FFD54F"; private static readonly Dictionary<int, string> OriginalTextCache = new Dictionary<int, string>(); [HarmonyPostfix] private static void ShowUIPostfix(ItemManager __instance, Transform obj) { TextMeshProUGUI val = ((__instance != null) ? __instance.interactText : null); if ((Object)(object)val != (Object)null) { int instanceID = ((Object)val).GetInstanceID(); OriginalTextCache[instanceID] = ((TMP_Text)val).text ?? string.Empty; } if (ConfigManager.Instance == null || ConfigManager.Instance.EnableSeedRemainingDaysDisplay == null || !ConfigManager.Instance.EnableSeedRemainingDaysDisplay.Value || (Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || !((Component)obj).CompareTag("Seeds")) { return; } SeedGrowth val2 = ((Component)obj).GetComponentInParent<SeedGrowth>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)obj).GetComponent<SeedGrowth>(); } if ((Object)(object)val2 == (Object)null) { return; } int instanceID2 = ((Object)val).GetInstanceID(); if (!OriginalTextCache.TryGetValue(instanceID2, out var value)) { value = ((TMP_Text)val).text ?? string.Empty; } string[] array = value.Split('\n'); if (array.Length != 0) { string value2 = array[0]; int num = Mathf.Max(0, val2.MaturityDays - val2.currentDay); if (num <= 0) { array[0] = $"{value2} <color={"#FFD54F"}>{LocalizationManager.Instance.GetLocalizedText("ui.status.harvestable")}</color>"; } else { array[0] = $"{value2} <color={"#FFD54F"}>{LocalizationManager.Instance.GetLocalizedText("ui.status.remaining_days", num)}</color>"; } ((TMP_Text)val).text = string.Join("\n", array); } } } [HarmonyPatch(typeof(BaseItem), "OnItemCountChanged")] public static class ShelfSoldOutAlertPatch { private static readonly HashSet<int> HighlightedSoldOutItems = new HashSet<int>(); [HarmonyPostfix] private static void Postfix(BaseItem __instance, int oldValue, int newValue) { if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).isClient || ConfigManager.Instance == null || ConfigManager.Instance.EnableShelfSoldOutAlert == null || !ConfigManager.Instance.EnableShelfSoldOutAlert.Value || (Object)(object)((Component)__instance).GetComponent<ContainerProduct>() == (Object)null) { return; } Transform parent = ((Component)__instance).transform.parent; if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<ShelfContainer>() == (Object)null) { return; } Outline component = ((Component)__instance).GetComponent<Outline>(); int instanceID = ((Object)__instance).GetInstanceID(); if (newValue <= 0) { if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; } HighlightedSoldOutItems.Add(instanceID); if (oldValue > 0) { ShowSoldOutPopup(__instance); } } else if (HighlightedSoldOutItems.Remove(instanceID) && (Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } } private static void ShowSoldOutPopup(BaseItem item) { PopUpManager instance = PopUpManager.Instance; if (!((Object)(object)instance == (Object)null)) { string text = WorkshopRemainingTimeState.GetLocalizedItemName(item.itemData); if (string.IsNullOrEmpty(text)) { text = ((Object)item).name; } string localizedText = LocalizationManager.Instance.GetLocalizedText("ui.shelf.sold_out", text); instance.PopUpOne(localizedText, 2f); } } } [HarmonyPatch(typeof(ThiefNpc), "OnStartClient")] public static class ThiefAlertPatch { [HarmonyPostfix] private static void Postfix(ThiefNpc __instance) { ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableThiefAlert?.Value == true) { PopUpManager instance2 = PopUpManager.Instance; if (!((Object)(object)instance2 == (Object)null)) { string localizedText = LocalizationManager.Instance.GetLocalizedText("ui.thief.alert"); instance2.PopUpOne(localizedText, 2f); } } } } [HarmonyPatch(typeof(ThiefNpc), "UserCode_RpcOnProductStolen__UInt32")] public static class ThiefStealAlertPatch { [HarmonyPostfix] private static void Postfix() { ConfigManager instance = ConfigManager.Instance; if (instance != null && instance.EnableThiefAlert?.Value == true) { PopUpManager instance2 = PopUpManager.Instance; if (!((Object)(object)instance2 == (Object)null)) { string localizedText = LocalizationManager.Instance.GetLocalizedText("ui.thief.stealing"); instance2.PopUpOne(localizedText, 2f); } } } } [HarmonyPatch(typeof(GeneralUIController), "Start")] public static class GeneralUIController_Start_Patch { private const string TimeDisplayObjectName = "BetterMarket_TimeDisplay"; private static GameObject _timeDisplayObj; [HarmonyPostfix] public static void Postfix(GeneralUIController __instance) { if (ConfigManager.Instance == null || ConfigManager.Instance.EnableTimeDisplay == null || !ConfigManager.Instance.EnableTimeDisplay.Value || (Object)(object)_timeDisplayObj != (Object)null) { return; } Transform val = null; if ((Object)(object)TimeManager.Instance != (Object)null && (Object)(object)TimeManager.Instance.clockArrowRectTransform != (Object)null) { val = ((Transform)TimeManager.Instance.clockArrowRectTransform).parent; } if ((Object)(object)val == (Object)null && (Object)(object)__instance.seasonText != (Object)null) { val = ((TMP_Text)__instance.seasonText).transform.parent; } if (!((Object)(object)val == (Object)null)) { Transform val2 = val.Find("BetterMarket_TimeDisplay"); if ((Object)(object)val2 != (Object)null) { _timeDisplayObj = ((Component)val2).gameObject; } else { CreateTimeDisplay(val); } } } private static void CreateTimeDisplay(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) _timeDisplayObj = new GameObject("BetterMarket_TimeDisplay"); _timeDisplayObj.transform.SetParent(parent, false); TextMeshProUGUI val = _timeDisplayObj.AddComponent<TextMeshProUGUI>(); if ((Object)(object)GeneralUIController.Instance != (Object)null && (Object)(object)GeneralUIController.Instance.seasonText != (Object)null) { TextMeshProUGUI seasonText = GeneralUIController.Instance.seasonText; ((TMP_Text)val).font = ((TMP_Text)seasonText).font; ((TMP_Text)val).fontSize = ((TMP_Text)seasonText).fontSize * 1.2f; ((Graphic)val).color = ((Graphic)seasonText).color; ((TMP_Text)val).alignment = (TextAlignmentOptions)514; ((TMP_Text)val).enableWordWrapping = false; } else { ((TMP_Text)val).fontSize = 24f; ((TMP_Text)val).alignment = (TextAlignmentOptions)514; ((Graphic)val).color = Color.white; } RectTransform component = _timeDisplayObj.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, -40f); component.sizeDelta = new Vector2(200f, 50f); _timeDisplayObj.AddComponent<TimeDisplayController>(); } } [HarmonyPatch(typeof(GeneralUIController), "OpenRecipeBook")] public static class WorkshopRecipeTimePatch { private static readonly Regex ReqPattern = new Regex("\\d+\\s*[xX×]|[xX×]\\s*\\d+", RegexOptions.Compiled); private static readonly Regex RichTextPattern = new Regex("<.*?>", RegexOptions.Compiled); private const string Tag = "bettermarket.recipe.time"; private static readonly HashSet<int> Registered = new HashSet<int>(); private static readonly Dictionary<int, MachineType> PanelTypes = new Dictionary<int, MachineType>(); [HarmonyPostfix] public static void Postfix(GeneralUIController __instance, GameObject panel) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) ConfigManager instance = ConfigManager.Instance; if (instance == null || instance.EnableWorkshopRecipeBookTimeDisplay?.Value != true || (Object)(object)__instance == (Object)null || (Object)(object)panel == (Object)null) { return; } MachineType? val = ResolveType(__instance, panel); if (!val.HasValue) { return; } PanelTypes[((Object)panel).GetInstanceID()] = val.Value; string text = BuildSuffix(val.Value); if (text == null) { return; } Il2CppArrayBase<TextMeshProUGUI> componentsInChildren = panel.GetComponentsInChildren<TextMeshProUGUI>(true); if (componentsInChildren == null) { return; } for (int i = 0; i < componentsInChildren.Length; i++) { TextMeshProUGUI val2 = componentsInChildren[i]; if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).gameObject).name != "Text (TMP) (1)" || !IsRecipeAmountText(val2)) { continue; } LocalizeStringEvent component = ((Component)val2).GetComponent<LocalizeStringEvent>(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { int instanceID = ((Object)component).GetInstanceID(); if (!Registered.Contains(instanceID)) { Registered.Add(instanceID); TextMeshProUGUI t = val2; string s = text; ((UnityEvent<string>)(object)component.OnUpdateString).AddListener(UnityAction<string>.op_Implicit((Action<string>)delegate(string localized) { AppendAfterLocalize(t, localized, s); })); } } Append(val2, text); } } private static MachineType? ResolveType(GeneralUIController ctrl, GameObject panel) { if ((Object)(object)panel == (Object)(object)ctrl.alcoholPanel) { return (MachineType)0; } if ((Object)(object)panel == (Object)(object)ctrl.ovenPanel) { return (MachineType)1; } if ((Object)(object)panel == (Object)(object)ctrl.jamPanel) { return (MachineType)2; } if ((Object)(object)panel == (Object)(object)ctrl.meatPanel) { return (MachineType)3; } return null; } private static void AppendAfterLocalize(TextMeshProUGUI tmp, string localized, string suffix) { if (!((Object)(object)tmp == (Object)null) && !string.IsNullOrWhiteSpace(localized) && !localized.Contains("bettermarket.recipe.time")) { string text = localized.Trim(); if (HasRequirementText(text)) { ((TMP_Text)tmp).text = text + suffix; } } } internal static void Append(TextMeshProUGUI tmp, string suffix) { string text = ((TMP_Text)tmp).text; if (!string.IsNullOrWhiteSpace(text) && !text.Contains("bettermarket.recipe.time")) { string text2 = text.Trim(); if (HasRequirementText(text2)) { ((TMP_Text)tmp).text = text2 + suffix; } } } internal static bool IsRecipeAmountText(TextMeshProUGUI tmp) { if ((Object)(object)tmp == (Object)null || ((Object)((Component)tmp).gameObject).name != "Text (TMP) (1)") { return false; } Transform parent = ((TMP_Text)tmp).transform.parent; Transform val = ((parent != null) ? parent.parent : null); if ((Object)(object)val != (Object)null) { return ((Object)val).name.StartsWith("Recipe"); } return false; } private static bool HasRequirementText(string text) { if (string.IsNullOrWhiteSpace(text)) { return false; } string input = RichTextPattern.Replace(text, string.Empty).Trim(); return ReqPattern.IsMatch(input); } internal static bool TryResolveTypeFromHierarchy(Transform transform, out MachineType type) { while ((Object)(object)transform != (Object)null) { if (PanelTypes.TryGetValue(((Object)((Component)transform).gameObject).GetInstanceID(), out type)) { return true; } transform = transform.parent; } type = (MachineType)0; return false; } internal static string BuildSuffix(MachineType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 string value = (((int)type == 3) ? FormatTime(5f) : LocalizationManager.Instance.GetLocalizedText("ui.time.need_day", 1)); if (string.IsNullOrEmpty(value)) { return null; } return $" <link=\"{"bettermarket.recipe.time"}\">- {value}</link>"; } private static string FormatTime(float seconds) { int num = Mathf.Max(1, Mathf.RoundToInt(seconds)); int num2 = num / 60; int num3 = num % 60; if (num2 <= 0) { return LocalizationManager.Instance.GetLocalizedText("ui.time.need_second", num); } if (num3 == 0) { return LocalizationManager.Instance.GetLocalizedText("ui.time.need_minute", num2); } return LocalizationManager.Instance.GetLocalizedText("ui.time.need_minute_second", num2, num3); } } [HarmonyPatch(typeof(LocalizedTextRTL), "OnStringChanged")] public static class WorkshopRecipeTimeRtlPatch { [HarmonyPostfix] public static void Postfix(LocalizedTextRTL __instance, string value) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) ConfigManager instance = ConfigManager.Instance; if (instance == null || instance.EnableWorkshopRecipeBookTimeDisplay?.Value != true || (Object)(object)__instance == (Object)null || string.IsNullOrWhiteSpace(value)) { return; } TextMeshProUGUI textComponent = __instance.textComponent; if (WorkshopRecipeTimePatch.IsRecipeAmountText(textComponent) && WorkshopRecipeTimePatch.TryResolveTypeFromHierarchy(((TMP_Text)textComponent).transform, out var type)) { string text = WorkshopRecipeTimePatch.BuildSuffix(type); if (text != null) { WorkshopRecipeTimePatch.Append(textComponent, text); } } } } public static class WorkshopRemainingTimeState { private static readonly Dictionary<int, float> RealtimeFinishTimeByMachine = new Dictionary<int, float>(); private static readonly Dictionary<int, int> DayFinishByMachine = new Dictionary<int, int>(); private static readonly Dictionary<BaseItemSO, string> ItemNameCache = new Dictionary<BaseItemSO, string>(); public static string GetLocalizedItemName(BaseItemSO item) { if ((Object)(object)item == (Object)null) { return string.Empty; } if (ItemNameCache.TryGetValue(item, out var value)) { return value; } LocalizedString displayName = item.displayName; string text = ((displayName != null) ? displayName.GetLocalizedString() : null); if (string.IsNullOrEmpty(text)) { text = item.baseName; } if (string.IsNullOrEmpty(text)) { text = ((Object)item).name; } if (!string.IsNullOrEmpty(text)) { ItemNameCache[item] = text; } return text ?? string.Empty; } public static string GetProductionItemName(WorkshopMachine machine) { if ((Object)(object)machine == (Object)null || machine.pendingRecipes == null || machine.pendingRecipes.Count == 0) { return null; } HashSet<string> hashSet = new HashSet<string>(); Enumerator<Recipe> enumerator = machine.pendingRecipes.GetEnumerator(); while (enumerator.MoveNext()) { Recipe current = enumerator.Current; if (!((Object)(object)((current != null) ? current.ResultItem : null) == (Object)null)) { string localizedItemName = GetLocalizedItemName(current.ResultItem); if (!string.IsNullOrEmpty(localizedItemName)) { hashSet.Add(localizedItemName); } } } if (hashSet.Count != 0) { return string.Join("/", hashSet); } return null; } public static bool TryGetRemainingText(WorkshopMachine machine, out string remainingText) { remainingText = string.Empty; if ((Object)(object)machine == (Object)null || !machine.NetworkisProducing) { return false; } int instanceID = ((Object)machine).GetInstanceID(); if (IsMeatMachine(machine)) { if (!RealtimeFinishTimeByMachine.TryGetValue(instanceID, out var value)) { value = Time.unscaledTime + 5f; RealtimeFinishTimeByMachine[instanceID] = value; } float seconds = Mathf.Max(0f, value - Time.unscaledTime); remainingText = FormatRealtimeText(seconds); return true; } TimeManager instance = TimeManager.Instance; if ((Object)(object)instance == (Object)null) { remainingText = LocalizationManager.Instance.GetLocalizedText("ui.time.day", 1); return true; } int num = Mathf.Max(1, instance.day); if (!DayFinishByMachine.TryGetValue(instanceID, out var value2)) { value2 = num + 1; DayFinishByMachine[instanceID] = value2; } remainingText = LocalizationManager.Instance.GetLocalizedText("ui.time.day", Mathf.Max(0, value2 - num)); return true; } public static void OnProductionStateChanged(WorkshopMachine machine, bool newValue) { if ((Object)(object)machine == (Object)null) { return; } int instanceID = ((Object)machine).GetInstanceID(); if (!newValue) { RealtimeFinishTimeByMachine.Remove(instanceID); DayFinishByMachine.Remove(instanceID); return; } if (IsMeatMachine(machine)) { RealtimeFinishTimeByMachine[instanceID] = Time.unscaledTime + 5f; DayFinishByMachine.Remove(instanceID); return; } TimeManager instance = TimeManager.Instance; if ((Object)(object)instance != (Object)null) { DayFinishByMachine[instanceID] = Mathf.Max(1, instance.day) + 1; } } private static string FormatRealtimeText(float seconds) { int num = Mathf.Max(0, Mathf.CeilToInt(seconds)); int num2 = num / 60; int num3 = num % 60; if (num2 <= 0) { return LocalizationManager.Instance.GetLocalizedText("ui.time.second", num); } if (num3 == 0) { return LocalizationManager.Instance.GetLocalizedText("ui.time.minute", num2); } return LocalizationManager.Instance.GetLocalizedText("ui.time.minute_second", num2, num3); } private static bool IsMeatMachine(WorkshopMachine machine) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((Object)(object)machine != (Object)null) { return (int)machine.machineType == 3; } return false; } } [HarmonyPatch(typeof(WorkshopMachine), "OnProductionStateChanged")] public static class WorkshopMachineProductionStatePatch { [HarmonyPostfix] private static void Postfix(WorkshopMachine __instance, bool oldValue, bool newValue) { WorkshopRemainingTimeState.OnProductionStateChanged(__instance, newValue); } } [HarmonyPatch(typeof(ItemManager), "ShowUI")] public static class WorkshopRemainingTimePromptPatch { private const string RemainingColor = "#FFD54F"; internal static readonly Dictionary<int, string> OriginalTextCache = new Dictionary<int, string>(); [HarmonyPostfix] private static void Postfix(ItemManager __instance, Transform obj) { TextMeshProUGUI val = ((__instance != null) ? __instance.interactText : null); if ((Object)(object)val != (Object)null) { OriginalTextCache[((Object)val).GetInstanceID()] = ((TMP_Text)val).text ?? string.Empty; } RefreshInteractText(obj, val); } internal static void RefreshInteractText(Transform obj, TextMeshProUGUI interactText) { ConfigManager instance = ConfigManager.Instance; if (instance == null || instance.EnableWorkshopRemainingTimeDisplay?.Value != true || (Object)(object)obj == (Object)null || (Object)(object)interactText == (Object)null) { return; } WorkshopItem component = ((Component)obj).GetComponent<WorkshopItem>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.workshopMachine == (Object)null)) { if (!OriginalTextCache.TryGetValue(((Object)interactText).GetInstanceID(), out var value)) { value = ((TMP_Text)interactText).text ?? string.Empty; } if (!WorkshopRemainingTimeState.TryGetRemainingText(component.workshopMachine, out var remainingText)) { ((TMP_Text)interactText).text = value; return; } string productionItemName = WorkshopRemainingTimeState.GetProductionItemName(component.workshopMachine); string localizedText = LocalizationManager.Instance.GetLocalizedText("ui.workshop.remaining_label"); string value2 = (string.IsNullOrEmpty(productionItemName) ? LocalizationManager.Instance.GetLocalizedText("ui.workshop.remaining_only", localizedText, remainingText) : LocalizationManager.Instance.GetLocalizedText("ui.workshop.remaining_with_item", productionItemName, localizedText, remainingText)); ((TMP_Text)interactText).text = $"{value}\n<color={"#FFD54F"}>{value2}</color>"; } } } [HarmonyPatch(typeof(ItemManager), "Update")] public static class WorkshopRemainingTimeRealtimePatch { [HarmonyPostfix] private static void Postfix(ItemManager __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.highlightedObject == (Object)null) && !((Object)(object)__instance.interactText == (Object)null)) { WorkshopRemainingTimePromptPatch.RefreshInteractText(__instance.highlightedObject, __instance.interactText); InteractionUILayoutHelper.Refresh(__instance); } } } } namespace BetterMarket.Localization { public static class LocalizationHelper { 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.name", "市场优化"); dictionary.Add("plugin.description", "为游戏增加多项实用的界面增强与提醒功能。"); dictionary.Add("config.enable_time_display", "启用时间显示"); dictionary.Add("config.enable_reputation_display", "启用声望数值显示"); dictionary.Add("config.enable_seed_remaining_days_display", "启用作物剩余天数显示"); dictionary.Add("config.enable_animal_remaining_days_display", "启用动物剩余时间显示"); dictionary.Add("config.enable_workshop_recipe_book_time_display", "启用工坊食谱书制作时长显示"); dictionary.Add("config.enable_workshop_remaining_time_display", "启用工坊交互提示剩余时间显示"); dictionary.Add("config.enable_order_guide_marker", "启用订单交付点标记"); dictionary.Add("config.enable_thief_alert", "启用小偷出现通知"); dictionary.Add("config.enable_shelf_sold_out_alert", "启用货架售空提醒与高亮"); dictionary.Add("config.enable_bank_rate_alert", "启用 IMS 币汇率涨跌通知"); dictionary.Add("config.toggle_bank_rate_panel_key", "切换 IMS 币状态窗口快捷键"); dictionary.Add("ui.status.harvestable", "[可收获]"); dictionary.Add("ui.status.remaining_days", "[剩余:{0} 天]"); dictionary.Add("ui.time.need_prefix", "需要 "); dictionary.Add("ui.time.day", "{0} 天"); dictionary.Add("ui.time.second", "{0} 秒"); dictionary.Add("ui.time.minute", "{0} 分钟"); dictionary.Add("ui.time.minute_second", "{0} 分钟 {1} 秒"); dictionary.Add("ui.time.need_day", "需要 {0} 天"); dictionary.Add("ui.time.need_second", "需要 {0} 秒"); dictionary.Add("ui.time.need_minute", "需要 {0} 分钟"); dictionary.Add("ui.time.need_minute_second", "需要 {0} 分钟 {1} 秒"); dictionary.Add("ui.workshop.remaining_label", "剩余:"); dictionary.Add("ui.workshop.remaining_with_item", "[{0} - {1}{2}]"); dictionary.Add("ui.workshop.remaining_only", "[{0}{1}]"); dictionary.Add("ui.thief.alert", "发现可疑人员在徘徊!"); dictionary.Add("ui.thief.stealing", "有人正在盗取你的商品!"); dictionary.Add("ui.shelf.sold_out", "一筐商品已售空:{0}"); dictionary.Add("ui.bank.rate_up", "{0} IMS币汇率上涨 +{1},当前汇率:{2}"); dictionary.Add("ui.bank.rate_down", "{0} IMS币汇率下跌 -{1},当前汇率:{2}"); dictionary.Add("ui.bank.panel.title", "IMS 币汇率"); dictionary.Add("ui.bank.panel.current_rate", "当前汇率:{0}"); dictionary.Add("ui.bank.panel.trend_up", "状态:上涨 +{0}"); dictionary.Add("ui.bank.panel.trend_down", "状态:下跌 -{0}"); dictionary.Add("ui.bank.panel.trend_flat", "状态:持平"); dictionary.Add("ui.bank.panel.updated_hour", "最近更新:{0}:00"); dictionary.Add("ui.bank.panel.close_hint_inline", "{0} 关闭"); break; case "zh-TW": dictionary.Add("plugin.initializing", "開始初始化..."); dictionary.Add("plugin.author_prefix", "作者:"); dictionary.Add("plugin.initialized", "初始化成功!"); dictionary.Add("plugin.patches_skipped", "補丁已套用,跳過..."); dictionary.Add("plugin.name", "市場優化"); dictionary.Add("plugin.description", "為遊戲加入多項實用的介面增強與提醒功能。"); dictionary.Add("config.enable_time_display", "啟用時間顯示"); dictionary.Add("config.enable_reputation_display", "啟用聲望數值顯示"); dictionary.Add("config.enable_seed_remaining_days_display", "啟用作物剩餘天數顯示"); dictionary.Add("config.enable_animal_remaining_days_display", "啟用動物剩餘時間顯示"); dictionary.Add("config.enable_workshop_recipe_book_time_display", "啟用工坊食譜書製作時長顯示"); dictionary.Add("config.enable_workshop_remaining_time_display", "啟用工坊互動提示剩餘時間顯示"); dictionary.Add("config.enable_order_guide_marker", "啟用訂單交付點標記"); dictionary.Add("config.enable_thief_alert", "啟用小偷出現通知"); dictionary.Add("config.enable_shelf_sold_out_alert", "啟用貨架售空提醒與高亮"); dictionary.Add("config.enable_bank_rate_alert", "啟用 IMS 幣匯率漲跌通知"); dictionary.Add("config.toggle_bank_rate_panel_key", "切換 IMS 幣狀態視窗快捷鍵"); dictionary.Add("ui.status.harvestable", "[可收穫]"); dictionary.Add("ui.status.remaining_days", "[剩餘:{0} 天]"); dictionary.Add("ui.time.need_prefix", "需要 "); dictionary.Add("ui.time.day", "{0} 天"); dictionary.Add("ui.time.second", "{0} 秒"); dictionary.Add("ui.time.minute", "{0} 分鐘"); dictionary.Add("ui.time.minute_second", "{0} 分鐘 {1} 秒"); dictionary.Add("ui.time.need_day", "需要 {0} 天"); dictionary.Add("ui.time.need_second", "需要 {0} 秒"); dictionary.Add("ui.time.need_minute", "需要 {0} 分鐘"); dictionary.Add("ui.time.need_minute_second", "需要 {0} 分鐘 {1} 秒"); dictionary.Add("ui.workshop.remaining_label", "剩餘:"); dictionary.Add("ui.workshop.remaining_with_item", "[{0} - {1}{2}]"); dictionary.Add("ui.workshop.remaining_only", "[{0}{1}]"); dictionary.Add("ui.thief.alert", "發現可疑人物在徘徊!"); dictionary.Add("ui.thief.stealing", "有人正在偷取你的商品!"); dictionary.Add("ui.shelf.sold_out", "一筐商品已售空:{0}"); dictionary.Add("ui.bank.rate_up", "{0} IMS幣匯率上漲 +{1},目前匯率:{2}"); dictionary.Add("ui.bank.rate_down", "{0} IMS幣匯率下跌 -{1},目前匯率:{2}"); dictionary.Add("ui.bank.panel.title", "IMS 幣匯率"); dictionary.Add("ui.bank.panel.current_rate", "目前匯率:{0}"); dictionary.Add("ui.bank.panel.trend_up", "狀態:上漲 +{0}"); dictionary.Add("ui.bank.panel.trend_down", "狀態:下跌 -{0}"); dictionary.Add("ui.bank.panel.trend_flat", "狀態:持平"); dictionary.Add("ui.bank.panel.updated_hour", "最近更新:{0}:00"); dictionary.Add("ui.bank.panel.close_hint_inline", "{0} 關閉"); break; case "en": dictionary.Add("plugin.initializing", "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.name", "Better Market"); dictionary.Add("plugin.description", "Adds a variety of practical UI enhancements and alert features."); dictionary.Add("config.enable_time_display", "Enable Time Display"); dictionary.Add("config.enable_reputation_display", "Enable Reputation Display"); dictionary.Add("config.enable_seed_remaining_days_display", "Enable Crop Remaining Days Display"); dictionary.Add("config.enable_animal_remaining_days_display", "Enable Animal Remaining Time Display"); dictionary.Add("config.enable_workshop_recipe_book_time_display", "Enable Workshop Recipe Book Craft Time Display"); dictionary.Add("config.enable_workshop_remaining_time_display", "Enable Workshop Remaining Time Prompt Display"); dictionary.Add("config.enable_order_guide_marker", "Enable Order Delivery Marker"); dictionary.Add("config.enable_thief_alert", "Enable Thief Alert Notification"); dictionary.Add("config.enable_shelf_sold_out_alert", "Enable Shelf Sold-Out Alert and Highlight"); dictionary.Add("config.enable_bank_rate_alert", "Enable IMS Coin Rate Change Notification"); dictionary.Add("config.toggle_bank_rate_panel_key", "Toggle IMS Coin Status Panel Hotkey"); dictionary.Add("ui.status.harvestable", "[Harvestable]"); dictionary.Add("ui.status.remaining_days", "[Remaining: {0} day(s)]"); dictionary.Add("ui.time.need_prefix", "Need "); dictionary.Add("ui.time.day", "{0} day(s)"); dictionary.Add("ui.time.second", "{0} second(s)"); dictionary.Add("ui.time.minute", "{0} minute(s)"); dictionary.Add("ui.time.minute_second", "{0} minute(s) {1} second(s)"); dictionary.Add("ui.time.need_day", "Need {0} day(s)"); dictionary.Add("ui.time.need_second", "Need {0} second(s)"); dictionary.Add("ui.time.need_minute", "Need {0} minute(s)"); dictionary.Add("ui.time.need_minute_second", "Need {0} minute(s) {1} second(s)"); dictionary.Add("ui.workshop.remaining_label", "Remaining: "); dictionary.Add("ui.workshop.remaining_with_item", "[{0} - {1}{2}]"); dictionary.Add("ui.workshop.remaining_only", "[{0}{1}]"); dictionary.Add("ui.thief.alert", "A suspicious person is lurking!"); dictionary.Add("ui.thief.stealing", "Someone is stealing your product!"); dictionary.Add("ui.shelf.sold_out", "Bag item sold out: {0}"); dictionary.Add("ui.bank.rate_up", "{0} IMS Coin rate increased +{1}, current rate: {2}"); dictionary.Add("ui.bank.rate_down", "{0} IMS Coin rate decreased -{1}, current rate: {2}"); dictionary.Add("ui.bank.panel.title", "IMS Coin Rate"); dictionary.Add("ui.bank.panel.current_rate", "Current Rate: {0}"); dictionary.Add("ui.bank.panel.trend_up", "Status: Up +{0}"); dictionary.Add("ui.bank.panel.trend_down", "Status: Down -{0}"); dictionary.Add("ui.bank.panel.trend_flat", "Status: Flat"); dictionary.Add("ui.bank.panel.updated_hour", "Last Update: {0}:00"); dictionary.Add("ui.bank.panel.close_hint_inline", "{0} hide"); break; case "ja": dictionary.Add("plugin.initializing", "初期化中..."); dictionary.Add("plugin.author_prefix", "作者: "); dictionary.Add("plugin.initialized", "初期化に成功しました!"); dictionary.Add("plugin.patches_skipped", "パッチは適用済みです。スキップします..."); dictionary.Add("plugin.name", "Better Market"); dictionary.Add("plugin.description", "便利なUI強化と通知機能を多数追加します。"); dictionary.Add("config.enable_time_display", "時間表示を有効化"); dictionary.Add("config.enable_reputation_display", "評判値表示を有効化"); dictionary.Add("config.enable_seed_remaining_days_display", "作物の残り日数表示を有効化"); dictionary.Add("config.enable_animal_remaining_days_display", "動物の残り時間表示を有効化"); dictionary.Add("config.enable_workshop_recipe_book_time_display", "作業場レシピ本の製作時間表示を有効化"); dictionary.Add("config.enable_workshop_remaining_time_display", "作業場インタラクト表示の残り時間表示を有効化"); dictionary.Add("config.enable_order_guide_marker", "注文配達地点マーカーを有効化"); dictionary.Add("config.enable_thief_alert", "泥棒出現通知を有効化"); dictionary.Add("config.enable_shelf_sold_out_alert", "棚の売り切れ通知と強調表示を有効化"); dictionary.Add("config.enable_bank_rate_alert", "IMSコイン為替変動通知を有効化"); dictionary.Add("config.toggle_bank_rate_panel_key", "IMSコイン状態パネル切替キー"); dictionary.Add("ui.status.harvestable", "[収穫可能]"); dictionary.Add("ui.status.remaining_days", "[残り:{0}日]"); dictionary.Add("ui.time.need_prefix", "必要 "); dictionary.Add("ui.time.day", "{0}日"); dictionary.Add("ui.time.second", "{0}秒"); dictionary.Add("ui.time.minute", "{0}分"); dictionary.Add("ui.time.minute_second", "{0}分 {1}秒"); dictionary.Add("ui.time.need_day", "{0}日必要"); dictionary.Add("ui.time.need_second", "{0}秒必要"); dictionary.Add("ui.time.need_minute", "{0}分必要"); dictionary.Add("ui.time.need_minute_second", "{0}分 {1}秒必要"); dictionary.Add("ui.workshop.remaining_label", "残り:"); dictionary.Add("ui.workshop.remaining_with_item", "[{0} - {1}{2}]"); dictionary.Add("ui.workshop.remaining_only", "[{0}{1}]"); dictionary.Add("ui.thief.alert", "不審な人物がうろついています!"); dictionary.Add("ui.thief.stealing", "誰かがあなたの商品を盗んでいます!"); dictionary.Add("ui.shelf.sold_out", "商品が売り切れました:{0}"); dictionary.Add("ui.bank.rate_up", "{0} IMSコインの為替レートが +{1} 上昇しました。現在のレート:{2}"); dictionary.Add("ui.bank.rate_down", "{0} IMSコインの為替レートが -{1} 下落しました。現在のレート:{2}"); dictionary.Add("ui.bank.panel.title", "IMSコイン為替レート"); dictionary.Add("ui.bank.panel.current_rate", "現在のレート:{0}"); dictionary.Add("ui.bank.panel.trend_up", "状態:上昇 +{0}"); dictionary.Add("ui.bank.panel.trend_down", "状態:下落 -{0}"); dictionary.Add("ui.bank.panel.trend_flat", "状態:横ばい"); dictionary.Add("ui.bank.panel.updated_hour", "最終更新:{0}:00"); dictionary.Add("ui.bank.panel.close_hint_inline", "{0} 閉じる"); break; } return dictionary; } } public class LocalizationManager { private static LocalizationManager _instance; private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>(); private string _currentLocale = "zh"; public static readonly string[] SupportedLanguages = new string[16] { "en", "tr", "fr", "es", "zh", "zh-TW", "de", "el", "pt-BR", "it", "ja", "pl", "pt-PT", "ru", "ko", "th" }; public static LocalizationManager Instance => _instance ?? (_instance = new LocalizationManager()); private LocalizationManager() { Initialize(); } public void Initialize() { RefreshCurrentLocale(); string[] supportedLanguages = SupportedLanguages; foreach (string text in supportedLanguages) { Dictionary<string, string> defaultTranslations = LocalizationHelper.GetDefaultTranslations(text); if (defaultTranslations != null && defaultTranslations.Count > 0) { _localizations[text] = defaultTranslations; } } } private void RefreshCurrentLocale() { if (PlayerPrefs.HasKey("Lang")) { int num = PlayerPrefs.GetInt("Lang"); ILocalesProvider availableLocales = LocalizationSettings.AvailableLocales; if (availableLocales != null && availableLocales.Locales != null && num >= 0 && num < availableLocales.Locales.Count) { string code = availableLocales.Locales[num].Identifier.Code; _currentLocale = (_localizations.ContainsKey(code) ? code : "en"); } } } public string GetLocalizedText(string key, params object[] args) { RefreshCurrentLocale(); 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 BetterMarket.Features { internal static class OrderGuideState { private static readonly Dictionary<int, string> SlotOrderIds = new Dictionary<int, string>(); private static readonly Dictionary<int, string> SlotPointIds = new Dictionary<int, string>(); private static readonly Dictionary<int, string> SlotDestinations = new Dictionary<int, string>(); private static readonly Dictionary<int, string> SlotProducts = new Dictionary<int, string>(); private static string _selectedOrderId = string.Empty; private static string _selectedPointId = string.Empty; private static string _selectedDestination = string.Empty; private static string _selectedProduct = string.Empty; public static bool HasSelection { get { if (!string.IsNullOrEmpty(_selectedOrderId)) { return !string.IsNullOrEmpty(_selectedPointId); } return false; } } public static string SelectedOrderId => _selectedOrderId; public static string SelectedPointId => _selectedPointId; public static string SelectedDestination => _selectedDestination; public static string SelectedProduct => _selectedProduct; public static void BindSlot(GameObject slotObject, ActiveOrderData order) { if (!((Object)(object)slotObject == (Object)null) && order != null) { int instanceID = ((Object)slotObject).GetInstanceID(); SlotOrderIds[instanceID] = order.orderId ?? string.Empty; SlotPointIds[instanceID] = order.pointId ?? string.Empty; SlotDestinations[instanceID] = order.displayName ?? string.Empty; SlotProducts[instanceID] = order.productBaseName ?? string.Empty; } } public static bool TryGetSlot(GameObject slotObject, out string orderId, out string pointId, out string destinationName, out string productName) { orderId = string.Empty; pointId = string.Empty; destinationName = string.Empty; productName = string.Empty; if ((Object)(object)slotObject == (Object)null) { return false; } int instanceID = ((Object)slotObject).GetInstanceID(); if (!SlotOrderIds.TryGetValue(instanceID, out orderId) || string.IsNullOrEmpty(orderId)) { return false; } if (!SlotPointIds.TryGetValue(instanceID, out pointId) || string.IsNullOrEmpty(pointId)) { return false; } SlotDestinations.TryGetValue(instanceID, out destinationName); SlotProducts.TryGetValue(instanceID, out productName); return true; } public static void Select(string orderId, string pointId, string destinationName, string productName) { if (!string.IsNullOrEmpty(orderId) && !string.IsNullOrEmpty(pointId)) { _selectedOrderId = orderId; _selectedPointId = pointId; _selectedDestination = destinationName ?? string.Empty; _selectedProduct = productName ?? string.Empty; } } public static void ClearSelection() { _selectedOrderId = string.Empty; _selectedPointId = string.Empty; _selectedDestination = string.Empty; _selectedProduct = string.Empty; } } public class OrderGuideController : MonoBehaviour { private const string RootObjectName = "BetterMarket_OrderGuide"; private const string MarkerObjectName = "Marker"; private const float WorldHeightOffset = 2.2f; private const float ScreenPadding = 72f; private static GameObject _rootObject; private readonly List<RaycastResult> _raycastResults = new List<RaycastResult>(); private RectTransform _markerRoot; private TextMeshProUGUI _markerIcon; private TextMeshProUGUI _markerLabel; private TMP_FontAsset _font; public OrderGuideController(IntPtr pointer) : base(pointer) { } public static void EnsureCreated() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown if ((Object)(object)_rootObject != (Object)null) { return; } GameObject val = GameObject.Find("BetterMarket_OrderGuide"); if ((Object)(object)val != (Object)null) { _rootObject = val; if ((Object)(object)_rootObject.GetComponent<OrderGuideController>() == (Object)null) { _rootObject.AddComponent<OrderGuideController>(); } } else { _rootObject = new GameObject("BetterMarket_OrderGuide"); Object.DontDestroyOnLoad((Object)(object)_rootObject); Canvas obj = _rootObject.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 31990; _rootObject.AddComponent<GraphicRaycaster>(); _rootObject.AddComponent<OrderGuideController>(); } } private void Awake() { _markerRoot = CreateGroup("Marker", out _markerIcon, out _markerLabel); ((TMP_Text)_markerIcon).text = "[O]"; SetVisible((Component)(object)_markerRoot, visible: false); SyncFont(); } private void Update() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if (!IsEnabled()) { SetVisible((Component)(object)_markerRoot, visible: false); return; } SyncFont(); HandleSlotSelectionClick(); if (!TryGetTrackedOrder(out var _, out var pointId, out var destinationName, out var productName)) { SetVisible((Component)(object)_markerRoot, visible: false); return; } if (!TryFindDeliveryPoint(pointId, out var deliveryPoint)) { SetVisible((Component)(object)_markerRoot, visible: false); return; } if (!TryGetActiveCamera(out var camera)) { SetVisible((Component)(object)_markerRoot, visible: false); return; } Vector3 val = ((Component)deliveryPoint).transform.position + Vector3.up * 2.2f; Vector3 val2 = camera.WorldToScreenPoint(val); float distance = Vector3.Distance(((Component)camera).transform.position, ((Component)deliveryPoint).transform.position); string label = BuildLabel(destinationName, productName, distance); if (val2.z > 0f && val2.x >= 72f && val2.x <= (float)Screen.width - 72f && val2.y >= 72f && val2.y <= (float)Screen.height - 72f) { ShowMarker(val2, label); } else { SetVisible((Component)(object)_markerRoot, visible: false); } } private void OnDestroy() { if ((Object)(object)_rootObject == (Object)(object)((Component)this).gameObject) { _rootObject = null; } } private RectTransform CreateGroup(string name, out TextMeshProUGUI icon, out TextMeshProUGUI label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(((Component)this).transform, false); RectTransform obj = val.AddComponent<RectTransform>(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.zero; obj.pivot = new Vector2(0.5f, 0.5f); obj.sizeDelta = new Vector2(220f, 72f); icon = CreateText(val.transform, "Icon", 30f, (TextAlignmentOptions)514); label = CreateText(val.transform, "Label", 20f, (TextAlignmentOptions)514); RectTransform component = ((Component)icon).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 14f); component.sizeDelta = new Vector2(72f, 40f); RectTransform component2 = ((Component)label).GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0.5f, 0.5f); component2.anchorMax = new Vector2(0.5f, 0.5f); component2.pivot = new Vector2(0.5f, 0.5f); component2.anchoredPosition = new Vector2(0f, -14f); component2.sizeDelta = new Vector2(220f, 36f); return obj; } private static TextMeshProUGUI CreateText(Transform parent, string name, float fontSize, TextAlignmentOptions alignment) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).fontSize = fontSize; ((TMP_Text)obj).alignment = alignment; ((TMP_Text)obj).enableWordWrapping = false; ((TMP_Text)obj).outlineWidth = 0.25f; ((TMP_Text)obj).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.95f)); ((Graphic)obj).color = new Color(1f, 0.93f, 0.45f, 1f); return obj; } private void SyncFont() { GeneralUIController instance = GeneralUIController.Instance; object obj; if (instance == null) { obj = null; } else { TextMeshProUGUI seasonText = instance.seasonText; obj = ((seasonText != null) ? ((TMP_Text)seasonText).font : null); } TMP_FontAsset val = (TMP_FontAsset)obj; if ((Object)(object)val == (Object)null) { TextMeshProUGUI obj2 = Object.FindObjectOfType<TextMeshProUGUI>(); val = ((obj2 != null) ? ((TMP_Text)obj2).font : null); } if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)_font)) { _font = val; ((TMP_Text)_markerIcon).font = val; ((TMP_Text)_markerLabel).font = val; } } private static bool TryGetActiveCamera(out Camera camera) { camera = Camera.main; if ((Object)(object)camera != (Object)null && ((Behaviour)camera).isActiveAndEnabled) { return true; } Camera[] array = Il2CppArrayBase<Camera>.op_Implicit(Object.FindObjectsOfType<Camera>()); foreach (Camera val in array) { if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && ((Component)val).gameObject.activeInHierarchy) { camera = val; return true; } } camera = null; return false; } private void HandleSlotSelectionClick() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (!Input.GetMouseButtonDown(0) || (Object)(object)EventSystem.current == (Object)null) { return; } _raycastResults.Clear(); PointerEventData val = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(Input.mousePosition) }; EventSystem.current.RaycastAll(val, _raycastResults); for (int i = 0; i < _raycastResults.Count; i++) { GameObject gameObject = _raycastResults[i].gameObject; if (!((Object)(object)gameObject == (Object)null)) { TabletActiveOrderSlotUI componentInParent = gameObject.GetComponentInParent<TabletActiveOrderSlotUI>(); if ((Object)(object)componentInParent != (Object)null && OrderGuideState.TryGetSlot(((Component)componentInParent).gameObject, out var orderId, out var pointId, out var destinationName, out var productName)) { OrderGuideState.Select(orderId, pointId, destinationName, productName); break; } CourierActiveOrderSlotUI componentInParent2 = gameObject.GetComponentInParent<CourierActiveOrderSlotUI>(); if ((Object)(object)componentInParent2 != (Object)null && OrderGuideState.TryGetSlot(((Component)componentInParent2).gameObject, out var orderId2, out var pointId2, out var destinationName2, out var productName2)) { OrderGuideState.Select(orderId2, pointId2, destinationName2, productName2); break; } } } } private bool TryGetTrackedOrder(out string orderId, out string pointId, out string destinationName, out string productName) { orderId = string.Empty; pointId = string.Empty; destinationName = string.Empty; productName = string.Empty; CourierOrderManager instance = CourierOrderManager.Instance; if ((Object)(object)instance == (Object)null || instance.activeOrders == null || instance.activeOrders.Count == 0) { OrderGuideState.ClearSelection(); return false; } if (OrderGuideState.HasSelection) { for (int i = 0; i < instance.activeOrders.Count; i++) { ActiveOrderData val = instance.activeOrders[i]; if (val != null && string.Equals(val.orderId, OrderGuideState.SelectedOrderId, StringComparison.Ordinal)) { orderId = val.orderId ?? string.Empty; pointId = val.pointId ?? string.Empty; destinationName = val.displayName ?? string.Empty; productName = val.productBaseName ?? string.Empty; OrderGuideState.Select(orderId, pointId, destinationName, productName); return true; } } } ActiveOrderData val2 = instance.activeOrders[0]; if (val2 == null) { return false; } orderId = val2.orderId ?? string.Empty; pointId = val2.pointId ?? string.Empty; destinationName = val2.displayName ?? string.Empty; productName = val2.productBaseName ?? string.Empty; OrderGuideState.Select(orderId, pointId, destinationName, productName); if (!string.IsNullOrEmpty(orderId)) { return !string.IsNullOrEmpty(pointId); } return false; } private static bool TryFindDeliveryPoint(string pointId, out DeliveryPoint deliveryPoint) { deliveryPoint = null; if (string.IsNullOrEmpty(pointId)) { return false; } CourierOrderManager instance = CourierOrderManager.Instance; if (((instance != null) ? instance.deliveryPoints : null) == null) { return false; } for (int i = 0; i < instance.deliveryPoints.Count; i++) { DeliveryPoint val = instance.deliveryPoints[i]; if (!((Object)(object)val == (Object)null) && string.Equals(val.pointId, pointId, StringComparison.Ordinal)) { deliveryPoint = val; return true; } } return false; } private string BuildLabel(string destinationName, string productName, float distance) { string value = ((!string.IsNullOrEmpty(destinationName)) ? destinationName : productName); if (string.IsNullOrEmpty(value)) { value = "订单"; } return $"{value} {Mathf.RoundToInt(distance)}m"; } private void ShowMarker(Vector3 screenPos, string label) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) _markerRoot.anchoredPosition = new Vector2(screenPos.x, screenPos.y); ((TMP_Text)_markerLabel).text = label; SetVisible((Component)(object)_markerRoot, visible: true); } private static void SetVisible(Component target, bool visible) { if ((Object)(object)target != (Object)null && target.gameObject.activeSelf != visible) { target.gameObject.SetActive(visible); } } private static bool IsEnabled() { return ConfigManager.Instance?.EnableOrderGuideMarker?.Value ?? true; } } public class TimeDisplayController : MonoBehaviour { private TextMeshProUGUI _timeText; private float _updateTimer; private int _lastHours = -1; private int _lastMinutes = -1; private const float UpdateInterval = 1f; public TimeDisplayController(IntPtr pointer) : base(pointer) { } private void Awake() { _timeText = ((Component)this).GetComponent<TextMeshProUGUI>(); UpdateTime(forceRefresh: true); } private void Update() { if (!((Object)(object)_timeText == (Object)null)) { _updateTimer += Time.unscaledDeltaTime; if (!(_updateTimer < 1f)) { _update