using System; using System.Collections; 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.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.0.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace BetterMarket { [BepInPlugin("IceBoxStudio.IslandMarketSimulator.BetterMarket", "BetterMarket", "1.0.0")] [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 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("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(LocalizationManager.Instance.GetLocalizedText("plugin.initializing")); } logger.LogInfo(val); ManualLogSource logger2 = Logger; val = new BepInExInfoLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" 初始化错误: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("\n"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.StackTrace); } logger4.LogError(val2); } } private static void EnsureInjectedTypesRegistered() { if (!_timeDisplayControllerRegistered) { ClassInjector.RegisterTypeInIl2Cpp(); _timeDisplayControllerRegistered = true; } if (!_bankRatePanelControllerRegistered) { ClassInjector.RegisterTypeInIl2Cpp(); _bankRatePanelControllerRegistered = 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("BetterMarket"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" 应用补丁错误: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\n"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(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.0", "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.0"; } } namespace BetterMarket.Utils { public static class KeyboardInputHelper { private static readonly Dictionary KeyPropertyOverrides = new Dictionary { { (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 KeyboardPropertyCache = new Dictionary(); private static readonly Dictionary ActionCache = new Dictionary(); 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 = 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 = 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 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)(ref key)).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)(ref key)).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(); 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() == (Object)null) { _panelObject.AddComponent(); } return; } _panelObject = new GameObject("BetterMarket_BankRatePanel"); _panelObject.transform.SetParent(_canvasObject.transform, false); TextMeshProUGUI obj2 = _panelObject.AddComponent(); ((Graphic)obj2).raycastTarget = false; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)516; ((TMP_Text)obj2).enableWordWrapping = false; ((TMP_Text)obj2).richText = true; RectTransform component = _panelObject.GetComponent(); 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(); } } 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(); ((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).GetValueOrDefault()) { 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; KeyCode val; if (instance2 == null) { obj = null; } else { ConfigEntry toggleBankRatePanelKey = instance2.ToggleBankRatePanelKey; if (toggleBankRatePanelKey == null) { obj = null; } else { val = toggleBankRatePanelKey.Value; obj = ((object)(KeyCode)(ref val)).ToString(); } } if (obj == null) { val = (KeyCode)289; obj = ((object)(KeyCode)(ref val)).ToString(); } string text = (string)obj; string text2 = (((Object)(object)PlayerData.Instance != (Object)null && PlayerData.Instance.SecondCurrency > 0) ? (" [" + instance.GetLocalizedText("ui.bank.panel.close_hint_inline", text) + "]") : string.Empty); string value = instance.GetLocalizedText("ui.bank.panel.title") + text2; if (!BankRateDisplayState.HasData) { string text3 = $"{value}\n{instance.GetLocalizedText("ui.bank.panel.current_rate", "-")}\n{instance.GetLocalizedText("ui.bank.panel.trend_flat")}"; ApplyText(text3, force); return; } int lastDelta = BankRateDisplayState.LastDelta; string value2 = ((lastDelta > 0) ? ("" + instance.GetLocalizedText("ui.bank.panel.trend_up", Math.Abs(lastDelta)) + "") : ((lastDelta < 0) ? ("" + instance.GetLocalizedText("ui.bank.panel.trend_down", Math.Abs(lastDelta)) + "") : ("" + instance.GetLocalizedText("ui.bank.panel.trend_flat") + ""))); string value3 = ((BankRateDisplayState.LastUpdateHour >= 0) ? instance.GetLocalizedText("ui.bank.panel.updated_hour", BankRateDisplayState.LastUpdateHour.ToString("00")) : string.Empty); string text4 = (string.IsNullOrEmpty(value3) ? $"{value}\n{instance.GetLocalizedText("ui.bank.panel.current_rate", BankRateDisplayState.CurrentRatio)}\n{value2}" : $"{value}\n{instance.GetLocalizedText("ui.bank.panel.current_rate", BankRateDisplayState.CurrentRatio)}\n{value2}\n{value3}"); 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 OriginalTextCache = new Dictionary(); [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(); 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} {LocalizationManager.Instance.GetLocalizedText("ui.status.harvestable")}"; } else { array[0] = $"{value2} {LocalizationManager.Instance.GetLocalizedText("ui.status.remaining_days", num3)}"; } ((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 InitializedBanks = new HashSet(); [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).GetValueOrDefault()) { 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).GetValueOrDefault()) { 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).GetValueOrDefault()) { BankRatePanelUI.EnsureCreated(); } } } [HarmonyPatch(typeof(PlayerData), "OnSecondCurrencyChanged")] public static class BankRatePanelVisibilityByHoldingPatch { private static readonly HashSet InitializedPlayers = new HashSet(); [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).GetValueOrDefault()) { 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 flag2 = (((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, flag2 ? 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((flag2 ? 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 { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(ItemManager), "HideUI", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = AccessTools.Method(typeof(ItemManager), "ClearHighlightAndUI", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] private static IEnumerable TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2); } [HarmonyPostfix] private static void Postfix(ItemManager __instance) { InteractionUILayoutHelper.Restore(__instance); } } [HarmonyPatch(typeof(PlayerData))] public static class ReputationPatch { private static readonly Dictionary TextCache = new Dictionary(); 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(); 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(); ((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(); 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(); ((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 OriginalTextCache = new Dictionary(); [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(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)obj).GetComponent(); } 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} {LocalizationManager.Instance.GetLocalizedText("ui.status.harvestable")}"; } else { array[0] = $"{value2} {LocalizationManager.Instance.GetLocalizedText("ui.status.remaining_days", num)}"; } ((TMP_Text)val).text = string.Join("\n", array); } } } [HarmonyPatch(typeof(BaseItem), "OnItemCountChanged")] public static class ShelfSoldOutAlertPatch { private static readonly HashSet HighlightedSoldOutItems = new HashSet(); [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() == (Object)null) { return; } Transform parent = ((Component)__instance).transform.parent; if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent() == (Object)null) { return; } Outline component = ((Component)__instance).GetComponent(); 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).GetValueOrDefault()) { 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).GetValueOrDefault()) { 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(); 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(); 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(); } } [HarmonyPatch(typeof(GeneralUIController), "OpenRecipeBook")] public static class WorkshopRecipeTimePatch { private static readonly Regex ReqPattern = new Regex("\\d+\\s*[xX×]", RegexOptions.Compiled); private const string Tag = "bettermarket.recipe.time"; private static readonly HashSet Registered = new HashSet(); [HarmonyPostfix] public static void Postfix(GeneralUIController __instance, GameObject panel) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) ConfigManager instance = ConfigManager.Instance; if (instance == null || !(instance.EnableWorkshopRecipeBookTimeDisplay?.Value).GetValueOrDefault() || (Object)(object)__instance == (Object)null || (Object)(object)panel == (Object)null) { return; } MachineType? val2 = ResolveType(__instance, panel); if (!val2.HasValue) { return; } string text = BuildSuffix(val2.Value); if (text == null) { return; } Il2CppArrayBase componentsInChildren = panel.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } for (int i = 0; i < componentsInChildren.Length; i++) { TextMeshProUGUI val3 = componentsInChildren[i]; if ((Object)(object)val3 == (Object)null || ((Object)((Component)val3).gameObject).name != "Text (TMP) (1)") { continue; } Transform parent = ((TMP_Text)val3).transform.parent; if ((Object)(object)parent == (Object)null || ((Object)parent).name != "GameObject") { continue; } Transform parent2 = parent.parent; if ((Object)(object)parent2 == (Object)null || !((Object)parent2).name.StartsWith("Recipe")) { continue; } LocalizeStringEvent component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { int instanceID = ((Object)component).GetInstanceID(); if (!Registered.Contains(instanceID)) { Registered.Add(instanceID); TextMeshProUGUI t = val3; string s = text; ((UnityEvent)(object)component.OnUpdateString).AddListener(UnityAction.op_Implicit((Action)delegate(string val) { AppendAfterLocalize(t, val, s); })); } } Append(val3, 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 (ReqPattern.IsMatch(text)) { ((TMP_Text)tmp).text = text + suffix; } } } private 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 (ReqPattern.IsMatch(text2)) { ((TMP_Text)tmp).text = text2 + suffix; } } } private 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 $" - {value}"; } 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); } } public static class WorkshopRemainingTimeState { private static readonly Dictionary RealtimeFinishTimeByMachine = new Dictionary(); private static readonly Dictionary DayFinishByMachine = new Dictionary(); private static readonly Dictionary ItemNameCache = new Dictionary(); 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 hashSet = new HashSet(); Enumerator 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) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 remainingText = string.Empty; if ((Object)(object)machine == (Object)null || !machine.NetworkisProducing) { return false; } int instanceID = ((Object)machine).GetInstanceID(); if ((int)Traverse.Create((object)machine).Field("machineType").Value == 3) { 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) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 if ((Object)(object)machine == (Object)null) { return; } int instanceID = ((Object)machine).GetInstanceID(); if (!newValue) { RealtimeFinishTimeByMachine.Remove(instanceID); DayFinishByMachine.Remove(instanceID); return; } if ((int)Traverse.Create((object)machine).Field("machineType").Value == 3) { 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); } } [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 OriginalTextCache = new Dictionary(); [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).GetValueOrDefault() || (Object)(object)obj == (Object)null || (Object)(object)interactText == (Object)null) { return; } WorkshopItem component = ((Component)obj).GetComponent(); 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{value2}"; } } } [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 GetDefaultTranslations(string language) { Dictionary dictionary = new Dictionary(); 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_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_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_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_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> _localizations = new Dictionary>(); 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 defaultTranslations = LocalizationHelper.GetDefaultTranslations(text); if (defaultTranslations != null && defaultTranslations.Count > 0) { _localizations[text] = defaultTranslations; } } } private void RefreshCurrentLocale() { if (PlayerPrefs.HasKey("Lang")) { int @int = PlayerPrefs.GetInt("Lang"); ILocalesProvider availableLocales = LocalizationSettings.AvailableLocales; if (availableLocales != null && availableLocales.Locales != null && @int >= 0 && @int < availableLocales.Locales.Count) { string code = availableLocales.Locales[@int].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 { 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(); UpdateTime(forceRefresh: true); } private void Update() { if (!((Object)(object)_timeText == (Object)null)) { _updateTimer += Time.unscaledDeltaTime; if (!(_updateTimer < 1f)) { _updateTimer -= 1f; UpdateTime(forceRefresh: false); } } } private void UpdateTime(bool forceRefresh) { if (!((Object)(object)_timeText == (Object)null) && !((Object)(object)TimeManager.Instance == (Object)null) && !((Object)(object)TimeManager.Instance.cozyWeather == (Object)null) && !((Object)(object)TimeManager.Instance.cozyWeather.timeModule == (Object)null)) { MeridiemTime currentTime = TimeManager.Instance.cozyWeather.timeModule.currentTime; if (forceRefresh || currentTime.hours != _lastHours || currentTime.minutes != _lastMinutes) { _lastHours = currentTime.hours; _lastMinutes = currentTime.minutes; ((TMP_Text)_timeText).text = $"{currentTime.hours:00}:{currentTime.minutes:00}"; } } } } } namespace BetterMarket.Configuration { public class ConfigManager { private static ConfigManager _instance; private readonly ConfigFile _configFile; private readonly Dictionary> _boolConfigs = new Dictionary>(); private readonly Dictionary> _stringConfigs = new Dictionary>(); private readonly Dictionary> _intConfigs = new Dictionary>(); private readonly Dictionary> _floatConfigs = new Dictionary>(); private readonly Dictionary> _keyCodeConfigs = new Dictionary>(); public static ConfigManager Instance => _instance; public ConfigEntry EnableTimeDisplay { get; private set; } public ConfigEntry EnableReputationDisplay { get; private set; } public ConfigEntry EnableSeedRemainingDaysDisplay { get; private set; } public ConfigEntry EnableAnimalRemainingDaysDisplay { get; private set; } public ConfigEntry EnableWorkshopRecipeBookTimeDisplay { get; private set; } public ConfigEntry EnableWorkshopRemainingTimeDisplay { get; private set; } public ConfigEntry EnableThiefAlert { get; private set; } public ConfigEntry EnableShelfSoldOutAlert { get; private set; } public ConfigEntry EnableBankRateAlert { get; private set; } public ConfigEntry ToggleBankRatePanelKey { get; private set; } private ConfigManager(ConfigFile configFile) { _configFile = configFile; InitializeDefaultConfigs(); } public static void Initialize(ConfigFile configFile) { if (_instance == null) { _instance = new ConfigManager(configFile); } } private void InitializeDefaultConfigs() { EnableTimeDisplay = RegisterBool("UI 相关 - UI related", "EnableTimeDisplay", GetLocalizedDescription("config.enable_time_display"), defaultValue: true); EnableReputationDisplay = RegisterBool("UI 相关 - UI related", "EnableReputationDisplay", GetLocalizedDescription("config.enable_reputation_display"), defaultValue: true); EnableSeedRemainingDaysDisplay = RegisterBool("UI 相关 - UI related", "EnableSeedRemainingDaysDisplay", GetLocalizedDescription("config.enable_seed_remaining_days_display"), defaultValue: true); EnableAnimalRemainingDaysDisplay = RegisterBool("UI 相关 - UI related", "EnableAnimalRemainingDaysDisplay", GetLocalizedDescription("config.enable_animal_remaining_days_display"), defaultValue: true); EnableWorkshopRecipeBookTimeDisplay = RegisterBool("工坊相关 - Workshop related", "EnableWorkshopRecipeBookTimeDisplay", GetLocalizedDescription("config.enable_workshop_recipe_book_time_display"), defaultValue: true); EnableWorkshopRemainingTimeDisplay = RegisterBool("工坊相关 - Workshop related", "EnableWorkshopRemainingTimeDisplay", GetLocalizedDescription("config.enable_workshop_remaining_time_display"), defaultValue: true); EnableThiefAlert = RegisterBool("小偷相关 - Thief related", "EnableThiefAlert", GetLocalizedDescription("config.enable_thief_alert"), defaultValue: true); EnableShelfSoldOutAlert = RegisterBool("货架相关 - Shelf related", "EnableShelfSoldOutAlert", GetLocalizedDescription("config.enable_shelf_sold_out_alert"), defaultValue: true); EnableBankRateAlert = RegisterBool("银行相关 - Bank related", "EnableBankRateAlert", GetLocalizedDescription("config.enable_bank_rate_alert"), defaultValue: true); ToggleBankRatePanelKey = RegisterKeyCode("银行相关 - Bank related", "ToggleBankRatePanelKey", GetLocalizedDescription("config.toggle_bank_rate_panel_key"), (KeyCode)289); } private string GetLocalizedDescription(string key) { return LocalizationManager.Instance?.GetLocalizedText(key) ?? key; } public ConfigEntry RegisterBool(string section, string key, string description, bool defaultValue) { ConfigEntry val = _configFile.Bind(section, key, defaultValue, description); _boolConfigs[key] = val; return val; } public ConfigEntry RegisterString(string section, string key, string description, string defaultValue) { ConfigEntry val = _configFile.Bind(section, key, defaultValue, description); _stringConfigs[key] = val; return val; } public ConfigEntry RegisterKeyCode(string section, string key, string description, KeyCode defaultValue) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ConfigEntry val = _configFile.Bind(section, key, defaultValue, description); _keyCodeConfigs[key] = val; return val; } public ConfigEntry RegisterInt(string section, string key, string description, int defaultValue) { ConfigEntry val = _configFile.Bind(section, key, defaultValue, description); _intConfigs[key] = val; return val; } public ConfigEntry RegisterIntMax(string section, string key, string description, int defaultValue, int minValue, int maxValue) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ConfigEntry val = _configFile.Bind(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(minValue, maxValue), Array.Empty())); _intConfigs[key] = val; return val; } public ConfigEntry RegisterFloat(string section, string key, string description, float defaultValue) { ConfigEntry val = _configFile.Bind(section, key, defaultValue, description); _floatConfigs[key] = val; return val; } public ConfigEntry RegisterFloatMax(string section, string key, string description, float defaultValue, float minValue, float maxValue) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ConfigEntry val = _configFile.Bind(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(minValue, maxValue), Array.Empty())); _floatConfigs[key] = val; return val; } } }