using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Better_Info.Utils; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HZ_MoreInfo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HZ_MoreInfo")] [assembly: AssemblyTitle("HZ_MoreInfo")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Better_Info { [HarmonyPatch(typeof(Beehive), "GetHoverText")] internal static class BeehiveHoverPatch { private static readonly MethodInfo CheckBiomeMethod = AccessTools.Method(typeof(Beehive), "CheckBiome", (Type[])null, (Type[])null); private static readonly MethodInfo HaveFreeSpaceMethod = AccessTools.Method(typeof(Beehive), "HaveFreeSpace", (Type[])null, (Type[])null); [HarmonyPostfix] private static void Postfix(Beehive __instance, ref string __result) { if (!ModConfig.ShowBeehiveTimer.Value) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); int num = zDO.GetInt(ZDOVars.s_level, 0); int maxHoney = __instance.m_maxHoney; if (num < maxHoney) { bool num2 = (bool)CheckBiomeMethod.Invoke(__instance, null) && (bool)HaveFreeSpaceMethod.Invoke(__instance, null) && (!__instance.m_effectOnlyInDaylight || EnvMan.IsDaylight()); long ticks = zDO.GetLong(ZDOVars.s_lastTime, ZNet.instance.GetTime().Ticks); DateTime dateTime = new DateTime(ticks); double num3 = (ZNet.instance.GetTime() - dateTime).TotalSeconds; if (num3 < 0.0) { num3 = 0.0; } float num4 = zDO.GetFloat(ZDOVars.s_product, 0f); float secPerUnit = __instance.m_secPerUnit; float num5 = (num2 ? (num4 + (float)num3) : num4); float num6 = Mathf.Max(0f, secPerUnit - num5); if (!num2) { __result += "\nProdução pausada"; return; } int num7 = maxHoney - num - 1; float num8 = num6 + (float)num7 * secPerUnit; __result = __result + "\nPróxima carga em: " + TimeConverter.FormatDuration(num6); __result = __result + "\nCarga completa em: " + TimeConverter.FormatDuration(num8); } } } internal class ClockUI : MonoBehaviour { private Text _text; private float _timer; private void Awake() { _text = ((Component)this).GetComponent(); } private void Update() { _timer += Time.deltaTime; if (!(_timer < 1f)) { _timer = 0f; _text.text = TimeConverter.GetCurrentTime(); } } } [HarmonyPatch(typeof(Fermenter), "GetHoverText")] internal static class FermenterHoverPatch { [HarmonyPostfix] private static void Postfix(Fermenter __instance, ref string __result) { if (!ModConfig.ShowFermenterTimer.Value) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || component.GetZDO() == null) { return; } ZDO zDO = component.GetZDO(); if (string.IsNullOrEmpty(zDO.GetString(ZDOVars.s_content, ""))) { return; } long num = zDO.GetLong(ZDOVars.s_startTime, 0L); if (num != 0L) { DateTime dateTime = new DateTime(num); double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds; double num2 = (double)__instance.m_fermentationDuration - totalSeconds; if (!(num2 <= 0.0)) { __result = __result + "\nTempo restante: " + TimeConverter.FormatDuration(num2); } } } } [HarmonyPatch(typeof(Pickable), "GetHoverText")] internal static class FiddleheadModifierHoverPatch { private const string FireFlagZdoKey = "HZ_fh_fire"; private const string StoneFlagZdoKey = "HZ_fh_stone"; [HarmonyPostfix] private static void Postfix(Pickable __instance, ref string __result) { if (!ModConfig.ShowPickableTimer.Value) { return; } ZNetView component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { ZDO zDO = component.GetZDO(); bool flag = zDO.GetBool("HZ_fh_fire", false); bool num = zDO.GetBool("HZ_fh_stone", false); if (flag) { __result += "\nA planta está aquecida"; } if (num) { __result += "\nA planta se sente em casa"; } } } } [HarmonyPatch(typeof(Minimap), "Awake")] internal static class MinimapClockPatch { public static Color C0C0C0 { get; private set; } [HarmonyPostfix] private static void Postfix(Minimap __instance) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) C0C0C0 = new Color(64f / 85f, 64f / 85f, 64f / 85f); if (ModConfig.ShowClock.Value) { GameObject val = new GameObject("Clock", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(__instance.m_smallRoot.transform, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(10f, -8.5f); Text obj = val.AddComponent(); obj.font = Resources.GetBuiltinResource("Arial.ttf"); obj.fontSize = 17; obj.alignment = (TextAnchor)0; obj.horizontalOverflow = (HorizontalWrapMode)1; obj.verticalOverflow = (VerticalWrapMode)1; ((Graphic)obj).color = new Color(0.9411765f, 0.9411765f, 0.9411765f); obj.fontStyle = (FontStyle)0; Outline obj2 = val.AddComponent(); ((Shadow)obj2).effectColor = Color.black; ((Shadow)obj2).effectDistance = new Vector2(1f, -1f); val.AddComponent(); } } } internal static class ModConfig { private const string GeneralSection = "General"; public static ConfigEntry ShowClock { get; private set; } public static ConfigEntry UseGameTimeFormat { get; private set; } public static ConfigEntry ShowPlantTimer { get; private set; } public static ConfigEntry ShowFermenterTimer { get; private set; } public static ConfigEntry ShowPickableTimer { get; private set; } public static ConfigEntry ShowBeehiveTimer { get; private set; } public static ConfigEntry ShowTameableTimer { get; private set; } public static void Init(ConfigFile config) { ShowClock = config.Bind("General", "ShowClock", true, "Mostra o relógio do jogo (hora atual) no minimapa."); UseGameTimeFormat = config.Bind("General", "UseGameTimeFormat", true, "Se ativado, os timers (plantas, fermentador, coletáveis) mostram o tempo restante em dias/horas de JOGO (baseado em EnvMan.m_dayLengthSec) em vez de minutos/segundos do relógio real."); ShowPlantTimer = config.Bind("General", "ShowPlantTimer", true, "Mostra tempo total e restante para a planta crescer, ao passar o mouse sobre ela."); ShowTameableTimer = config.Bind("General", "ShowTameableTimer", true, "Mostra o tempo restante para domesticar um animal, ao passar o mouse sobre ele."); ShowFermenterTimer = config.Bind("General", "ShowFermenterTimer", true, "Mostra tempo total e restante de fermentação, ao passar o mouse sobre o fermentador."); ShowPickableTimer = config.Bind("General", "ShowPickableTimer", true, "Mostra tempo restante para bagas/cogumelos/etc. reaparecerem, ao passar o mouse sobre o local."); ShowBeehiveTimer = config.Bind("General", "ShowBeehiveTimer", true, "Mostra tempo restante para o apiário produzir mel, ao passar o mouse sobre ele."); } } [HarmonyPatch(typeof(Pickable), "GetHoverText")] internal static class PickableHoverPatch { [HarmonyPostfix] private static void Postfix(Pickable __instance, ref string __result) { if (!ModConfig.ShowPickableTimer.Value || __instance.m_respawnTimeMinutes <= 0f) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || component.GetZDO() == null) { return; } ZDO zDO = component.GetZDO(); if (!zDO.GetBool(ZDOVars.s_picked, __instance.m_defaultPicked) || __instance.GetEnabled == 0) { return; } long num = zDO.GetLong(ZDOVars.s_pickedTime, 0L); if (num > 1) { DateTime dateTime = new DateTime(num); double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds; double num2 = (double)__instance.m_respawnTimeMinutes * 60.0 - totalSeconds; if (!(num2 <= 0.0)) { string text = Localization.instance.Localize(__instance.GetHoverName()); __result = text + "\nTempo restante: " + TimeConverter.FormatDuration(num2); } } } } [HarmonyPatch(typeof(Pickable), "GetHoverText")] internal static class PickableSpreadHoverPatch { private const string LastSpreadKey = "HZ_spread_last"; private const string SpreadDelayKey = "HZ_spread_delay"; [HarmonyPostfix] private static void Postfix(Pickable __instance, ref string __result) { if (!ModConfig.ShowPickableTimer.Value || string.IsNullOrEmpty(__result)) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || component.GetZDO() == null) { return; } ZDO zDO = component.GetZDO(); float num = zDO.GetFloat("HZ_spread_delay", 0f); if (num <= 0f) { return; } long num2 = zDO.GetLong("HZ_spread_last", 0L); if (num2 != 0L) { DateTime dateTime = new DateTime(num2); double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds; double num3 = (double)num - totalSeconds; if (num3 <= 0.0) { __result += "\nPronto pra se espalhar"; } else { __result = __result + "\nPróximo broto em: " + TimeConverter.FormatDuration(num3); } } } } [HarmonyPatch(typeof(Plant), "GetHoverText")] internal static class PlantHoverPatch { [HarmonyPostfix] private static void Postfix(Plant __instance, ref string __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.ShowPlantTimer.Value || (int)__instance.GetStatus() != 0) { return; } ZNetView component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && component.GetZDO() != null) { ZDO zDO = component.GetZDO(); long ticks = zDO.GetLong(ZDOVars.s_plantTime, ZNet.instance.GetTime().Ticks); DateTime dateTime = new DateTime(ticks); double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds; int num = zDO.GetInt(ZDOVars.s_seed, 0); State state = Random.state; Random.InitState(num); float value = Random.value; Random.state = state; double num2 = (double)Mathf.Lerp(__instance.m_growTime, __instance.m_growTimeMax, value) - totalSeconds; if (!(num2 <= 0.0)) { __result = __result + "\nTempo restante: " + TimeConverter.FormatDuration(num2); } } } } [BepInPlugin("hz.hz_nmore_info", "HZ_MoreInfo", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string ModGuid = "hz.hz_nmore_info"; public const string ModName = "HZ_MoreInfo"; public const string ModVersion = "1.0.0"; public static ConfigEntry ShowTimer { get; private set; } public static ConfigEntry ProductionMultiplier { get; private set; } internal static Plugin Instance { get; private set; } internal static Harmony Harmony { get; private set; } internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger; private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown Instance = this; ModConfig.Init(((BaseUnityPlugin)this).Config); Harmony = new Harmony("hz.hz_nmore_info"); Harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HZ_MoreInfo 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] internal static class TameableHoverPatch { [HarmonyPostfix] private static void Postfix(Tameable __instance, ref string __result) { if (!ModConfig.ShowTameableTimer.Value || __instance.IsTamed()) { return; } ZNetView component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { float num = component.GetZDO().GetFloat(ZDOVars.s_tameTimeLeft, __instance.m_tamingTime); if (!(num <= 0f)) { __result = __result + "\nTempo restante para domesticar: " + TimeConverter.FormatDuration(num); } } } } internal static class TimeConverter { public static string GetCurrentTime() { if ((Object)(object)EnvMan.instance == (Object)null) { return "--:--"; } int num = Mathf.FloorToInt(EnvMan.instance.GetDayFraction() * 24f * 60f) % 1440; int num2 = num / 60; int num3 = num % 60; return $"{num2:00}:{num3:00}"; } public static string FormatDuration(double realSeconds) { if (realSeconds <= 0.0) { return "0s"; } if (ModConfig.UseGameTimeFormat != null && ModConfig.UseGameTimeFormat.Value && (Object)(object)EnvMan.instance != (Object)null) { return FormatAsGameTime(realSeconds); } return FormatAsRealTime(realSeconds); } private static string FormatAsRealTime(double seconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (timeSpan.TotalDays >= 1.0) { return $"{(int)timeSpan.TotalDays}d {timeSpan.Hours}h"; } if (timeSpan.TotalHours >= 1.0) { return $"{(int)timeSpan.TotalHours}h {timeSpan.Minutes}m"; } return $"{timeSpan.Minutes}m {timeSpan.Seconds}s"; } private static string FormatAsGameTime(double realSeconds) { double num = EnvMan.instance.m_dayLengthSec; if (num <= 0.0) { return FormatAsRealTime(realSeconds); } double num2 = realSeconds / num; int num3 = (int)num2; double num4 = num2 - (double)num3; int num5 = (int)(num4 * 24.0); int num6 = (int)((num4 * 24.0 - (double)num5) * 60.0); if (num3 > 0) { return $"{num3}d {num5}h"; } if (num5 > 0) { return $"{num5}h {num6}m"; } return $"{num6}m"; } } [HarmonyPatch(typeof(Plant), "GetHoverText")] internal static class WitchingHourHoverPatch { private const string GateFlagZdoKey = "HZ_witch_gate"; [HarmonyPostfix] private static void Postfix(Plant __instance, ref string __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00a6: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.ShowPlantTimer.Value || (int)__instance.GetStatus() != 0) { return; } ZNetView component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (!zDO.GetBool("HZ_witch_gate", false)) { return; } long ticks = zDO.GetLong(ZDOVars.s_plantTime, ZNet.instance.GetTime().Ticks); DateTime dateTime = new DateTime(ticks); double totalSeconds = (ZNet.instance.GetTime() - dateTime).TotalSeconds; int num = zDO.GetInt(ZDOVars.s_seed, 0); State state = Random.state; Random.InitState(num); float value = Random.value; Random.state = state; if ((double)Mathf.Lerp(__instance.m_growTime, __instance.m_growTimeMax, value) - totalSeconds > 0.0) { return; } if (GameClock.IsWithinHourWindow(0.0, 3.0)) { __result += "\nPronto para brotar na calada da noite!"; return; } double num2 = GameClock.SecondsUntilHour(0.0); if (!(num2 < 0.0)) { __result = __result + "\nAguardando a calada da noite (faltam " + TimeConverter.FormatDuration(num2) + ")"; } } } } namespace Better_Info.Utils { internal static class GameClock { private const double DayOffsetSec = 0.0; public static double GetCurrentGameHour() { if ((Object)(object)EnvMan.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return -1.0; } double num = EnvMan.instance.m_dayLengthSec; if (num <= 0.0) { return -1.0; } double num2 = (ZNet.instance.GetTimeSeconds() + 0.0) % num / num; if (num2 < 0.0) { num2 += 1.0; } return num2 * 24.0; } public static bool IsWithinHourWindow(double startHour, double endHour) { double currentGameHour = GetCurrentGameHour(); if (currentGameHour < 0.0) { return false; } if (currentGameHour >= startHour) { return currentGameHour < endHour; } return false; } public static double SecondsUntilHour(double targetHour) { double currentGameHour = GetCurrentGameHour(); if (currentGameHour < 0.0 || (Object)(object)EnvMan.instance == (Object)null) { return -1.0; } double num = EnvMan.instance.m_dayLengthSec; double num2 = targetHour - currentGameHour; if (num2 < 0.0) { num2 += 24.0; } return num2 / 24.0 * num; } } }