Decompiled source of HarvestTimes v1.0.0

plugins/HarvestTimes/HarvestTimes.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyMetadata("PluginVersion", "1.0.0")]
[assembly: AssemblyCompany("simplifydave")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Plant growth and optional berry bush respawn timers for Valheim.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HarvestTimes")]
[assembly: AssemblyTitle("HarvestTimes")]
[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 HarvestTimes
{
	[BepInPlugin("simplifydave.harvesttimes", "HarvestTimes", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Plant), "GetHoverText")]
		private static class HoverPatch
		{
			private static Func<Plant, float> growTime;

			private static Func<Plant, double> elapsedTime;

			internal static void Initialize()
			{
				growTime = AccessTools.MethodDelegate<Func<Plant, float>>(AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null), (object)null, true);
				elapsedTime = AccessTools.MethodDelegate<Func<Plant, double>>(AccessTools.Method(typeof(Plant), "TimeSincePlanted", (Type[])null, (Type[])null), (object)null, true);
			}

			[HarmonyPostfix]
			private static void Postfix(Plant __instance, ZNetView ___m_nview, ref string __result)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Invalid comparison between Unknown and I4
				if (!timerEnabled.Value || !showPlantGrowth.Value || (Object)(object)__instance == (Object)null || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || (Object)(object)ZNet.instance == (Object)null)
				{
					return;
				}
				if ((int)__instance.GetStatus() > 0)
				{
					__result += "\n<color=#FFB66B>Cannot mature under current conditions.</color>";
					return;
				}
				double num = (double)growTime(__instance) - elapsedTime(__instance);
				if (!double.IsNaN(num) && !double.IsInfinity(num))
				{
					__result += ((num <= 0.0) ? "\n<color=#A8E080>Ready soon…</color>" : ("\n<color=#A8E080>Ready in: " + Timing.FormatRemaining(num) + "</color>"));
				}
			}
		}

		[HarmonyPatch(typeof(Pickable), "GetHoverText")]
		private static class BushHoverPatch
		{
			[HarmonyPostfix]
			private static void Postfix(Pickable __instance, ZNetView ___m_nview, bool ___m_picked, int ___m_enabled, ref string __result)
			{
				if (!timerEnabled.Value || !showBushRespawn.Value || (Object)(object)__instance == (Object)null || !___m_picked || ___m_enabled == 0 || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || (Object)(object)ZNet.instance == (Object)null || !(__instance.m_respawnTimeMinutes > 0f) || (Object)(object)__instance.m_itemPrefab == (Object)null)
				{
					return;
				}
				string text = Timing.BushName(((Object)__instance.m_itemPrefab).name);
				if (text == null)
				{
					return;
				}
				long pickedTicks = ___m_nview.GetZDO().GetLong(ZDOVars.s_pickedTime, 0L);
				if (Timing.TryRespawnRemaining(pickedTicks, ZNet.instance.GetTime().Ticks, __instance.m_respawnTimeMinutes, out var remaining))
				{
					if (string.IsNullOrEmpty(__result))
					{
						__result = text;
					}
					__result += ((remaining <= 0.0) ? "\n<color=#A8E080>Respawning soon…</color>" : ("\n<color=#A8E080>Respawns in: " + Timing.FormatRemaining(remaining) + "</color>"));
				}
			}
		}

		public const string Id = "simplifydave.harvesttimes";

		private Harmony harmony;

		private static ConfigEntry<bool> timerEnabled;

		private static ConfigEntry<bool> showPlantGrowth;

		private static ConfigEntry<bool> showBushRespawn;

		private void Awake()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			timerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable all HarvestTimes hover information.");
			showPlantGrowth = ((BaseUnityPlugin)this).Config.Bind<bool>("Timers", "ShowPlantGrowth", true, "Show remaining growth time on planted crops and saplings.");
			showBushRespawn = ((BaseUnityPlugin)this).Config.Bind<bool>("Timers", "ShowBushRespawn", false, "Show remaining respawn time on harvested raspberry, blueberry, and cloudberry bushes. Disabled by default.");
			try
			{
				HoverPatch.Initialize();
				harmony = new Harmony("simplifydave.harvesttimes");
				harmony.PatchAll(typeof(Plugin).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"HarvestTimes loaded.");
			}
			catch (Exception ex)
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not initialize HarvestTimes: " + ex));
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	internal static class Timing
	{
		internal static string BushName(string itemPrefab)
		{
			return itemPrefab switch
			{
				"Raspberry" => "Raspberry bush", 
				"Blueberries" => "Blueberry bush", 
				"Cloudberry" => "Cloudberry bush", 
				_ => null, 
			};
		}

		internal static bool TryRespawnRemaining(long pickedTicks, long nowTicks, double respawnMinutes, out double remaining)
		{
			remaining = 0.0;
			if (pickedTicks >= 0)
			{
				DateTime maxValue = DateTime.MaxValue;
				if (pickedTicks <= maxValue.Ticks && nowTicks >= 0)
				{
					maxValue = DateTime.MaxValue;
					if (nowTicks <= maxValue.Ticks && !double.IsNaN(respawnMinutes) && !double.IsInfinity(respawnMinutes) && !(respawnMinutes <= 0.0))
					{
						switch (pickedTicks)
						{
						case 0L:
							return false;
						case 1L:
							return true;
						default:
							remaining = respawnMinutes * 60.0 - (double)(nowTicks - pickedTicks) / 10000000.0;
							return !double.IsNaN(remaining) && !double.IsInfinity(remaining);
						}
					}
				}
			}
			return false;
		}

		internal static string FormatRemaining(double seconds)
		{
			TimeSpan timeSpan = TimeSpan.FromSeconds(Math.Ceiling(Math.Max(0.0, seconds)));
			if (timeSpan.TotalHours >= 1.0)
			{
				return $"{(long)timeSpan.TotalHours}h {timeSpan.Minutes:00}m {timeSpan.Seconds:00}s";
			}
			return (timeSpan.Minutes > 0) ? $"{timeSpan.Minutes}m {timeSpan.Seconds:00}s" : $"{timeSpan.Seconds}s";
		}
	}
	internal static class VersionInfo
	{
		public const string Version = "1.0.0";
	}
}