Decompiled source of DayNight4010 v2.0.1

plugins/DayNight4010.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("DayNight4010")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("DayNight4010")]
[assembly: AssemblyTitle("DayNight4010")]
[assembly: AssemblyVersion("2.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 DayNight4010
{
	[BepInPlugin("local.daynight4010", "DayNight4010", "2.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "local.daynight4010";

		public const string Release = "2.0.0";

		private const string SupportedGame = "1.0.12";

		private static Plugin instance;

		private ConfigEntry<bool> modEnabled;

		private ConfigEntry<double> dayMinutes;

		private ConfigEntry<double> nightMinutes;

		private Harmony harmony;

		private ZNet session;

		private EnvMan sessionEnvironment;

		private CalendarClock calendar;

		private bool failed;

		private bool sessionChecked;

		private bool synced;

		private bool snapPhase;

		private long observedDayLength;

		private const string Request = "DayNight4010_CalendarRequest_v2";

		private const string Reply = "DayNight4010_CalendarReply_v2";

		private ConfigEntry<bool> showClock;

		private ConfigEntry<string> clockLanguage;

		private ConfigEntry<int> fontSize;

		private ConfigEntry<int> offset;

		private readonly Dictionary<ZRpc, float> clockPeers = new Dictionary<ZRpc, float>();

		private readonly Dictionary<ZRpc, float> lastReply = new Dictionary<ZRpc, float>();

		private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

		private ZNet clockNetwork;

		private float nextPoll;

		private float snapshotAt;

		private bool received;

		private bool active;

		private bool skipping;

		private double world;

		private GUIStyle clockStyle;

		private void Awake()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00fd: Expected O, but got Unknown
			instance = this;
			modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the server calendar. Restart after editing.");
			dayMinutes = ((BaseUnityPlugin)this).Config.Bind<double>("Cycle", "DayMinutes", 40.0, new ConfigDescription("Real minutes of day. Restart server after editing.", (AcceptableValueBase)(object)new AcceptableValueRange<double>(1.0, 1440.0), Array.Empty<object>()));
			nightMinutes = ((BaseUnityPlugin)this).Config.Bind<double>("Cycle", "NightMinutes", 10.0, new ConfigDescription("Real minutes of night. Sleep still skips to morning. Restart server after editing.", (AcceptableValueBase)(object)new AcceptableValueRange<double>(1.0, 1440.0), Array.Empty<object>()));
			BindCountdown();
			if (((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString() != "1.0.12")
			{
				Stop("Requires Valheim 1.0.12");
				return;
			}
			try
			{
				harmony = new Harmony("local.daynight4010");
				Patch("FixedUpdate", "BeforeEnvironment");
				Patch("RescaleDayFraction", "ScalePhase", new Type[1] { typeof(float) });
				Patch("GetDay", "ReadDay", new Type[1] { typeof(double) });
				Patch("GetCurrentDay", "ReadCurrentDay");
				Patch("GetMorningStartSec", "ReadMorning", new Type[1] { typeof(int) });
				Patch("SkipToMorning", "SkipMorning");
				((BaseUnityPlugin)this).Logger.LogInfo((object)"DayNight4010 2.0.0 loaded: calendar only, normal production time. Required on server and clients.");
			}
			catch (Exception ex)
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				Stop(ex.ToString());
			}
		}

		private void Patch(string method, string prefix, Type[] args = null)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(EnvMan), method, args, (Type[])null);
			if (methodInfo == null)
			{
				throw new MissingMethodException("EnvMan." + method);
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), prefix, (Type[])null)
			{
				priority = 0
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static bool ValidMinutes(double n)
		{
			if (!double.IsNaN(n) && !double.IsInfinity(n) && n >= 1.0)
			{
				return n <= 1440.0;
			}
			return false;
		}

		private void Stop(string reason)
		{
			failed = true;
			calendar = null;
			((BaseUnityPlugin)this).Logger.LogError((object)("DayNight4010 calendar inactive: " + reason + ". Native world seconds remain unchanged."));
		}

		private void EnsureSession(EnvMan env)
		{
			if ((Object)(object)session != (Object)(object)ZNet.instance || (Object)(object)sessionEnvironment != (Object)(object)env)
			{
				session = ZNet.instance;
				sessionEnvironment = env;
				calendar = null;
				synced = false;
				sessionChecked = false;
				snapPhase = false;
				observedDayLength = (Object.op_Implicit((Object)(object)env) ? env.m_dayLengthSec : 0);
			}
			if (!Object.op_Implicit((Object)(object)session) || !Object.op_Implicit((Object)(object)env) || failed)
			{
				return;
			}
			if (env.m_dayLengthSec != observedDayLength)
			{
				Stop("Competing day-length change detected");
				return;
			}
			if (!sessionChecked)
			{
				string[] source = new string[8] { "longerdays", "mrdaynight", "extendeddaytime", "controltime", "dagrnott", "seasons", "zenworldsettings", "valheimplus" };
				foreach (PluginInfo value in Chainloader.PluginInfos.Values)
				{
					string text = (value.Metadata.GUID + value.Metadata.Name).ToLowerInvariant().Replace(" ", "");
					if (value.Metadata.GUID != "local.daynight4010" && source.Any(text.Contains))
					{
						Stop("Competing clock mod: " + value.Metadata.Name);
						return;
					}
				}
				string[] array = new string[4] { "RescaleDayFraction", "GetCurrentDay", "SkipToMorning", "GetMorningStartSec" };
				foreach (string text2 in array)
				{
					Patches patchInfo = Harmony.GetPatchInfo((MethodBase)AccessTools.Method(typeof(EnvMan), text2, (Type[])null, (Type[])null));
					if (patchInfo != null && patchInfo.Owners.Any((string x) => x != "local.daynight4010"))
					{
						Stop("Competing calendar patch: " + text2);
						return;
					}
				}
				Patches patchInfo2 = Harmony.GetPatchInfo((MethodBase)AccessTools.Method(typeof(ZNet), "UpdateNetTime", (Type[])null, (Type[])null));
				if (patchInfo2 != null && patchInfo2.Owners.Any())
				{
					Stop("Another mod changes ZNet.UpdateNetTime");
					return;
				}
				sessionChecked = true;
			}
			if (!session.IsServer() || calendar != null || !modEnabled.Value || session.GetNrOfPlayers() == 0 || ZNet.World == null)
			{
				return;
			}
			try
			{
				if (!ValidMinutes(dayMinutes.Value) || !ValidMinutes(nightMinutes.Value))
				{
					throw new InvalidDataException("Invalid durations");
				}
				long uid = ZNet.World.m_uid;
				string text3 = Path.Combine(Paths.ConfigPath, "DayNight4010", "world-" + uid + ".calendar");
				double timeSeconds = session.GetTimeSeconds();
				double num = dayMinutes.Value * 60.0;
				double num2 = nightMinutes.Value * 60.0;
				CalendarClock calendarClock;
				if (File.Exists(text3))
				{
					calendarClock = CalendarClock.Parse(File.ReadAllText(text3), uid);
					if (calendarClock.DayNumber(timeSeconds) < 0)
					{
						throw new InvalidDataException("World predates calendar anchor; restore matching calendar backup");
					}
					if (calendarClock.DaySeconds != num || calendarClock.NightSeconds != num2)
					{
						calendarClock = calendarClock.Reconfigure(timeSeconds, num, num2);
						calendarClock.Save(text3, uid);
					}
				}
				else
				{
					calendarClock = CalendarClock.FromLegacy(timeSeconds, observedDayLength, num, num2);
					calendarClock.Save(text3, uid);
				}
				calendar = calendarClock;
				synced = true;
				snapPhase = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"SERVER CALENDAR ACTIVE: {num / 60.0:0.##} min day / {num2 / 60.0:0.##} min night; normal production seconds; day {calendarClock.DayNumber(timeSeconds)}. State: {text3}");
			}
			catch (Exception ex)
			{
				Stop("Cannot load/save calendar: " + ex.Message);
			}
		}

		private static Plugin Ready(EnvMan env)
		{
			Plugin plugin = instance;
			if ((Object)(object)plugin == (Object)null || plugin.failed)
			{
				return null;
			}
			plugin.EnsureSession(env);
			if (plugin.calendar == null || plugin.failed)
			{
				return null;
			}
			return plugin;
		}

		private static void BeforeEnvironment(EnvMan __instance, ref float ___m_smoothDayFraction)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin != (Object)null && plugin.snapPhase)
			{
				___m_smoothDayFraction = (float)plugin.calendar.Phase(plugin.session.GetTimeSeconds());
				plugin.snapPhase = false;
			}
		}

		private static bool ScalePhase(EnvMan __instance, ref float __result)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin == (Object)null)
			{
				return true;
			}
			__result = (float)plugin.calendar.Phase(plugin.session.GetTimeSeconds());
			return false;
		}

		private static bool ReadDay(EnvMan __instance, double time, ref int __result)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin == (Object)null)
			{
				return true;
			}
			__result = plugin.calendar.DayNumber(time);
			return false;
		}

		private static bool ReadCurrentDay(EnvMan __instance, ref int __result)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin == (Object)null)
			{
				return true;
			}
			__result = plugin.calendar.DayNumber(plugin.session.GetTimeSeconds());
			return false;
		}

		private static bool ReadMorning(EnvMan __instance, int day, ref double __result)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin == (Object)null)
			{
				return true;
			}
			__result = plugin.calendar.Morning(day);
			return false;
		}

		private static bool SkipMorning(EnvMan __instance, ref bool ___m_skipTime, ref double ___m_skipToTime, ref double ___m_timeSkipSpeed)
		{
			Plugin plugin = Ready(__instance);
			if ((Object)(object)plugin == (Object)null)
			{
				return true;
			}
			if (!plugin.session.IsServer())
			{
				return false;
			}
			double timeSeconds = plugin.session.GetTimeSeconds();
			___m_skipToTime = plugin.calendar.NextMorning(timeSeconds);
			___m_skipTime = true;
			___m_timeSkipSpeed = (___m_skipToTime - timeSeconds) / 12.0;
			return false;
		}

		private void OnDestroy()
		{
			ClearCountdown();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}

		private void BindCountdown()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			showClock = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowCountdown", true, "Display countdown; synchronization stays enabled when hidden.");
			clockLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("HUD", "Language", "pl", new ConfigDescription("Client language.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "pl", "en" }), Array.Empty<object>()));
			fontSize = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "FontSize", 20, new ConfigDescription("Client text size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(12, 40), Array.Empty<object>()));
			offset = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "OffsetY", 8, new ConfigDescription("Pixels below minimap.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), Array.Empty<object>()));
		}

		private void ClearCountdown()
		{
			foreach (ZRpc key in clockPeers.Keys)
			{
				key.Unregister("DayNight4010_CalendarRequest_v2");
				key.Unregister("DayNight4010_CalendarReply_v2");
			}
			clockPeers.Clear();
			lastReply.Clear();
			clockNetwork = null;
			received = false;
			nextPoll = 0f;
		}

		private void RejectPeer(ZNetPeer peer, string reason)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("DayNight4010 connection rejected: " + reason + ". Install 2.0.0 on server and ALL clients."));
			peer.m_rpc.Invoke("Disconnect", Array.Empty<object>());
			clockNetwork.Disconnect(peer);
		}

		private void Update()
		{
			if ((Object)(object)clockNetwork != (Object)(object)ZNet.instance)
			{
				ClearCountdown();
				clockNetwork = ZNet.instance;
			}
			if (!Object.op_Implicit((Object)(object)clockNetwork) || Time.realtimeSinceStartup < nextPoll)
			{
				return;
			}
			nextPoll = Time.realtimeSinceStartup + 1f;
			if (Object.op_Implicit((Object)(object)EnvMan.instance))
			{
				EnsureSession(EnvMan.instance);
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			HashSet<ZRpc> hashSet = new HashSet<ZRpc>();
			foreach (ZNetPeer item in new List<ZNetPeer>(clockNetwork.GetPeers()))
			{
				if (!item.IsReady())
				{
					continue;
				}
				ZRpc rpc = item.m_rpc;
				hashSet.Add(rpc);
				if (!clockPeers.ContainsKey(rpc))
				{
					clockPeers.Add(rpc, realtimeSinceStartup);
					if (clockNetwork.IsServer())
					{
						rpc.Register<string>("DayNight4010_CalendarRequest_v2", (Action<ZRpc, string>)SendClock);
					}
					else
					{
						rpc.Register<ZPackage>("DayNight4010_CalendarReply_v2", (Action<ZRpc, ZPackage>)ReceiveClock);
					}
				}
				if ((!clockNetwork.IsServer() || modEnabled.Value) && (failed || realtimeSinceStartup - clockPeers[rpc] > 30f))
				{
					RejectPeer(item, failed ? "Local calendar failed; see earlier log" : "Missing calendar handshake/heartbeat");
				}
				else if (!clockNetwork.IsServer() && rpc == clockNetwork.GetServerRPC() && !failed)
				{
					rpc.Invoke("DayNight4010_CalendarRequest_v2", new object[1] { "2.0.0" });
				}
			}
			foreach (ZRpc item2 in new List<ZRpc>(clockPeers.Keys))
			{
				if (!hashSet.Contains(item2))
				{
					item2.Unregister("DayNight4010_CalendarRequest_v2");
					item2.Unregister("DayNight4010_CalendarReply_v2");
					clockPeers.Remove(item2);
					lastReply.Remove(item2);
				}
			}
		}

		private void SendClock(ZRpc rpc, string version)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)clockNetwork) || !clockNetwork.IsServer() || !clockPeers.ContainsKey(rpc) || version != "2.0.0")
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!lastReply.TryGetValue(rpc, out var value) || !(realtimeSinceStartup - value < 0.5f))
			{
				lastReply[rpc] = realtimeSinceStartup;
				clockPeers[rpc] = realtimeSinceStartup;
				EnvMan val = EnvMan.instance;
				if (Object.op_Implicit((Object)(object)val))
				{
					EnsureSession(val);
				}
				ZPackage val2 = new ZPackage();
				val2.Write("2.0.0");
				val2.Write(modEnabled.Value);
				val2.Write(!failed && calendar != null && Object.op_Implicit((Object)(object)val));
				val2.Write(Object.op_Implicit((Object)(object)val) && val.IsTimeSkipping());
				val2.Write(clockNetwork.GetTimeSeconds());
				val2.Write(calendar?.AnchorWorld ?? 0.0);
				val2.Write(calendar?.AnchorCalendar ?? 0.0);
				val2.Write(calendar?.DaySeconds ?? 2400.0);
				val2.Write(calendar?.NightSeconds ?? 600.0);
				rpc.Invoke("DayNight4010_CalendarReply_v2", new object[1] { val2 });
			}
		}

		private void ReceiveClock(ZRpc rpc, ZPackage package)
		{
			if (!Object.op_Implicit((Object)(object)clockNetwork) || clockNetwork.IsServer() || rpc != clockNetwork.GetServerRPC() || failed || !Object.op_Implicit((Object)(object)EnvMan.instance))
			{
				return;
			}
			try
			{
				if (package.ReadString() != "2.0.0")
				{
					return;
				}
				bool flag = package.ReadBool();
				bool flag2 = package.ReadBool();
				bool flag3 = package.ReadBool();
				double num = package.ReadDouble();
				CalendarClock calendarClock = new CalendarClock(package.ReadDouble(), package.ReadDouble(), package.ReadDouble(), package.ReadDouble());
				if (double.IsNaN(num) || double.IsInfinity(num) || num < 0.0 || calendarClock.DayNumber(num) < 0)
				{
					return;
				}
				EnsureSession(EnvMan.instance);
				if (!failed && (!flag || flag2))
				{
					clockPeers[rpc] = Time.realtimeSinceStartup;
					snapPhase = flag2 && (!synced || calendar == null || calendar.AnchorWorld != calendarClock.AnchorWorld || calendar.AnchorCalendar != calendarClock.AnchorCalendar || calendar.DaySeconds != calendarClock.DaySeconds || calendar.NightSeconds != calendarClock.NightSeconds);
					calendar = (flag2 ? calendarClock : null);
					if (!synced)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)(flag2 ? "SERVER CALENDAR SYNCED: normal production time" : "Server calendar disabled"));
					}
					synced = true;
					world = num;
					active = flag2;
					skipping = flag3;
					snapshotAt = Time.realtimeSinceStartup;
					received = true;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Rejected calendar snapshot: " + ex.Message));
			}
		}

		private string ClockText()
		{
			bool flag = clockLanguage.Value == "pl";
			if (failed)
			{
				if (!flag)
				{
					return "Calendar error — check log";
				}
				return "Błąd kalendarza — sprawdź log";
			}
			if (calendar == null)
			{
				if (!flag)
				{
					return "Waiting for server calendar...";
				}
				return "Oczekiwanie na kalendarz serwera...";
			}
			double num;
			if (clockNetwork.IsServer())
			{
				if (Object.op_Implicit((Object)(object)EnvMan.instance) && EnvMan.instance.IsTimeSkipping())
				{
					if (!flag)
					{
						return "Skipping night...";
					}
					return "Pomijanie nocy...";
				}
				num = clockNetwork.GetTimeSeconds();
			}
			else
			{
				if (!received || Time.realtimeSinceStartup - snapshotAt > 8f)
				{
					if (!flag)
					{
						return "Waiting for server calendar...";
					}
					return "Oczekiwanie na kalendarz serwera...";
				}
				if (!active)
				{
					if (!flag)
					{
						return "Calendar inactive";
					}
					return "Kalendarz nieaktywny";
				}
				if (skipping)
				{
					if (!flag)
					{
						return "Skipping night...";
					}
					return "Pomijanie nocy...";
				}
				num = world + (double)Math.Max(0f, Time.realtimeSinceStartup - snapshotAt);
			}
			bool isDay;
			int num2 = (int)Math.Ceiling(Math.Max(0.0, calendar.Remaining(num, out isDay) - 1E-06));
			return ((!isDay) ? (flag ? "NOC" : "NIGHT") : (flag ? "DZIEŃ" : "DAY")) + "  " + (num2 / 60).ToString("00") + ":" + (num2 % 60).ToString("00");
		}

		private void OnGUI()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00eb: Expected O, but got Unknown
			if (showClock == null || !showClock.Value || !Object.op_Implicit((Object)(object)clockNetwork) || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)Minimap.instance) || !Object.op_Implicit((Object)(object)Minimap.instance.m_smallRoot) || !Minimap.instance.m_smallRoot.activeInHierarchy)
			{
				return;
			}
			RectTransform component = Minimap.instance.m_smallRoot.GetComponent<RectTransform>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Canvas componentInParent = ((Component)component).GetComponentInParent<Canvas>();
				Camera obj = ((Object.op_Implicit((Object)(object)componentInParent) && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
				component.GetWorldCorners(corners);
				Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, corners[0]);
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, corners[3]);
				if (clockStyle == null)
				{
					clockStyle = new GUIStyle(GUI.skin.box)
					{
						alignment = (TextAnchor)4
					};
				}
				clockStyle.fontSize = fontSize.Value;
				clockStyle.normal.textColor = Color.white;
				float val3 = Math.Max(230f, val2.x - val.x);
				string text = ClockText();
				val3 = Math.Max(val3, clockStyle.CalcSize(new GUIContent(text)).x + 20f);
				float num = Mathf.Clamp(val2.x - val3, 0f, Math.Max(0f, (float)Screen.width - val3));
				float num2 = Mathf.Clamp((float)Screen.height - val.y + (float)offset.Value, 0f, (float)(Screen.height - fontSize.Value - 16));
				GUI.Box(new Rect(num, num2, val3, (float)(fontSize.Value + 16)), text, clockStyle);
			}
		}
	}
	public sealed class CalendarClock
	{
		public readonly double AnchorWorld;

		public readonly double AnchorCalendar;

		public readonly double DaySeconds;

		public readonly double NightSeconds;

		public double Cycle => DaySeconds + NightSeconds;

		public CalendarClock(double world, double calendar, double day, double night)
		{
			Check(world, 0.0, 100000000000000.0);
			Check(calendar, 0.0, 100000000000000.0);
			Check(day, 60.0, 86400.0);
			Check(night, 60.0, 86400.0);
			AnchorWorld = world;
			AnchorCalendar = calendar;
			DaySeconds = day;
			NightSeconds = night;
		}

		private static void Check(double n, double min, double max)
		{
			if (double.IsNaN(n) || double.IsInfinity(n) || n < min || n > max)
			{
				throw new ArgumentOutOfRangeException("n", "Invalid calendar value");
			}
		}

		public double At(double world)
		{
			return AnchorCalendar + (world - AnchorWorld);
		}

		public double PhaseSeconds(double world)
		{
			double num = At(world);
			return num - Math.Floor(num / Cycle) * Cycle;
		}

		public int DayNumber(double world)
		{
			return checked((int)Math.Floor(At(world) / Cycle));
		}

		public double Phase(double world)
		{
			double num = PhaseSeconds(world);
			double num2 = NightSeconds / 2.0;
			if (num < num2)
			{
				return num / num2 * 0.25;
			}
			if (num < num2 + DaySeconds)
			{
				return 0.25 + (num - num2) / DaySeconds * 0.5;
			}
			return 0.75 + (num - num2 - DaySeconds) / num2 * 0.25;
		}

		public double Remaining(double world, out bool isDay)
		{
			double num = PhaseSeconds(world);
			double num2 = NightSeconds / 2.0;
			double num3 = num2 + DaySeconds;
			isDay = num >= num2 && num < num3;
			if (!isDay)
			{
				if (!(num < num2))
				{
					return Cycle - num + num2;
				}
				return num2 - num;
			}
			return num3 - num;
		}

		public double Morning(int day)
		{
			return AnchorWorld + ((double)day * Cycle + NightSeconds / 2.0 - AnchorCalendar);
		}

		public double NextMorning(double world)
		{
			int day = checked((int)Math.Floor((At(world) - NightSeconds / 2.0) / Cycle) + 1);
			return Morning(day);
		}

		private static double Position(double phase, double day, double night)
		{
			if (phase < 0.25)
			{
				return phase / 0.25 * night / 2.0;
			}
			if (phase < 0.75)
			{
				return night / 2.0 + (phase - 0.25) / 0.5 * day;
			}
			return night / 2.0 + day + (phase - 0.75) / 0.25 * night / 2.0;
		}

		public static CalendarClock FromLegacy(double world, double baseCycle, double day, double night)
		{
			Check(baseCycle, 1.0, 1000000000.0);
			double num = world % baseCycle / baseCycle;
			double phase = ((num < 0.15) ? (num / 0.15 * 0.25) : ((num < 0.85) ? (0.25 + (num - 0.15) / 0.7 * 0.5) : (0.75 + (num - 0.85) / 0.15 * 0.25)));
			double calendar = Math.Floor(world / baseCycle) * (day + night) + Position(phase, day, night);
			return new CalendarClock(world, calendar, day, night);
		}

		public CalendarClock Reconfigure(double world, double day, double night)
		{
			double calendar = (double)DayNumber(world) * (day + night) + Position(Phase(world), day, night);
			return new CalendarClock(world, calendar, day, night);
		}

		public string Serialize(long uid)
		{
			return string.Join("\n", "DayNight4010-calendar-2", uid.ToString(CultureInfo.InvariantCulture), AnchorWorld.ToString("R", CultureInfo.InvariantCulture), AnchorCalendar.ToString("R", CultureInfo.InvariantCulture), DaySeconds.ToString("R", CultureInfo.InvariantCulture), NightSeconds.ToString("R", CultureInfo.InvariantCulture));
		}

		public static CalendarClock Parse(string text, long uid)
		{
			string[] array = text.Replace("\r", "").Trim().Split('\n');
			if (array.Length != 6 || array[0] != "DayNight4010-calendar-2" || long.Parse(array[1], CultureInfo.InvariantCulture) != uid)
			{
				throw new InvalidDataException("Calendar world/schema mismatch");
			}
			return new CalendarClock(double.Parse(array[2], CultureInfo.InvariantCulture), double.Parse(array[3], CultureInfo.InvariantCulture), double.Parse(array[4], CultureInfo.InvariantCulture), double.Parse(array[5], CultureInfo.InvariantCulture));
		}

		public void Save(string path, long uid)
		{
			Directory.CreateDirectory(Path.GetDirectoryName(path));
			string text = path + ".tmp";
			File.WriteAllText(text, Serialize(uid));
			if (File.Exists(path))
			{
				File.Replace(text, path, path + ".bak");
			}
			else
			{
				File.Move(text, path);
			}
		}
	}
}