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<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;
}
}
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.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<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 = 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<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).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<KeyCode> 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) ? (" <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).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<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).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 <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
{
private int <>1__state;
private MethodBase <>2__current;
private int <>l__initialThreadId;
MethodBase IEnumerator<MethodBase>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TargetMethods>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<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <TargetMethods>d__0(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MethodBase>)this).GetEnumerator();
}
}
[IteratorStateMachine(typeof(<TargetMethods>d__0))]
private static IEnumerable<MethodBase> TargetMethods()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TargetMethods>d__0(-2);
}
[HarmonyPostfix]
private static void Postfix(ItemManager __instance)
{
InteractionUILayoutHelper.Restore(__instance);
}
}
[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).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<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×]", RegexOptions.Compiled);
private const string Tag = "bettermarket.recipe.time";
private static readonly HashSet<int> Registered = new HashSet<int>();
[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<TextMeshProUGUI> componentsInChildren = panel.GetComponentsInChildren<TextMeshProUGUI>(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<LocalizeStringEvent>();
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<string>)(object)component.OnUpdateString).AddListener(UnityAction<string>.op_Implicit((Action<string>)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 $" <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);
}
}
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)
{
//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>("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>("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<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).GetValueOrDefault() || (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_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<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 @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<TextMeshProUGUI>();
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<string, ConfigEntry<bool>> _boolConfigs = new Dictionary<string, ConfigEntry<bool>>();
private readonly Dictionary<string, ConfigEntry<string>> _stringConfigs = new Dictionary<string, ConfigEntry<string>>();
private readonly Dictionary<string, ConfigEntry<int>> _intConfigs = new Dictionary<string, ConfigEntry<int>>();
private readonly Dictionary<string, ConfigEntry<float>> _floatConfigs = new Dictionary<string, ConfigEntry<float>>();
private readonly Dictionary<string, ConfigEntry<KeyCode>> _keyCodeConfigs = new Dictionary<string, ConfigEntry<KeyCode>>();
public static ConfigManager Instance => _instance;
public ConfigEntry<bool> EnableTimeDisplay { get; private set; }
public ConfigEntry<bool> EnableReputationDisplay { get; private set; }
public ConfigEntry<bool> EnableSeedRemainingDaysDisplay { get; private set; }
public ConfigEntry<bool> EnableAnimalRemainingDaysDisplay { get; private set; }
public ConfigEntry<bool> EnableWorkshopRecipeBookTimeDisplay { get; private set; }
public ConfigEntry<bool> EnableWorkshopRemainingTimeDisplay { get; private set; }
public ConfigEntry<bool> EnableThiefAlert { get; private set; }
public ConfigEntry<bool> EnableShelfSoldOutAlert { get; private set; }
public ConfigEntry<bool> EnableBankRateAlert { get; private set; }
public ConfigEntry<KeyCode> 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<bool> RegisterBool(string section, string key, string description, bool defaultValue)
{
ConfigEntry<bool> val = _configFile.Bind<bool>(section, key, defaultValue, description);
_boolConfigs[key] = val;
return val;
}
public ConfigEntry<string> RegisterString(string section, string key, string description, string defaultValue)
{
ConfigEntry<string> val = _configFile.Bind<string>(section, key, defaultValue, description);
_stringConfigs[key] = val;
return val;
}
public ConfigEntry<KeyCode> RegisterKeyCode(string section, string key, string description, KeyCode defaultValue)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
ConfigEntry<KeyCode> val = _configFile.Bind<KeyCode>(section, key, defaultValue, description);
_keyCodeConfigs[key] = val;
return val;
}
public ConfigEntry<int> RegisterInt(string section, string key, string description, int defaultValue)
{
ConfigEntry<int> val = _configFile.Bind<int>(section, key, defaultValue, description);
_intConfigs[key] = val;
return val;
}
public ConfigEntry<int> 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<int> val = _configFile.Bind<int>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(minValue, maxValue), Array.Empty<object>()));
_intConfigs[key] = val;
return val;
}
public ConfigEntry<float> RegisterFloat(string section, string key, string description, float defaultValue)
{
ConfigEntry<float> val = _configFile.Bind<float>(section, key, defaultValue, description);
_floatConfigs[key] = val;
return val;
}
public ConfigEntry<float> 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<float> val = _configFile.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(minValue, maxValue), Array.Empty<object>()));
_floatConfigs[key] = val;
return val;
}
}
}