Decompiled source of DayNightRobust v2.0.2

plugins/DayNight4010.dll

Decompiled 4 days 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 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.2.0")]
[assembly: AssemblyInformationalVersion("2.0.2")]
[assembly: AssemblyProduct("DayNight4010")]
[assembly: AssemblyTitle("DayNight4010")]
[assembly: AssemblyVersion("2.0.2.0")]
namespace DayNight4010;

[BepInPlugin("local.daynight4010", "DayNight4010", "2.0.2")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string Id = "local.daynight4010";

	public const string Release = "2.0.2";

	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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Expected O, but got Unknown
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Expected O, but got Unknown
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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)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)new AcceptableValueRange<double>(1.0, 1440.0), Array.Empty<object>()));
		BindCountdown();
		string text = ((object)Version.CurrentVersion/*cast due to .constrained prefix*/).ToString();
		if (text != "1.0.12")
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Running on Valheim " + text + " (originally validated against 1.0.12). EnvMan patch targets are verified at load; watch for errors below."));
		}
		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.2 loaded: calendar only, normal production time. Required on server and clients."));
		}
		catch (Exception ex)
		{
			Harmony val = harmony;
			if (val != null)
			{
				val.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)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_001a: Expected O, but got Unknown
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Expected O, but got Unknown
		//IL_0032: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		if ((Object)session != (Object)ZNet.instance || (Object)sessionEnvironment != (Object)env)
		{
			session = ZNet.instance;
			sessionEnvironment = env;
			calendar = null;
			synced = false;
			sessionChecked = false;
			snapPhase = false;
			observedDayLength = (Object.op_Implicit((Object)env) ? env.m_dayLengthSec : 0);
		}
		if (!Object.op_Implicit((Object)session) || !Object.op_Implicit((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)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		Plugin plugin = instance;
		if ((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)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((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)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((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)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((Object)plugin == (Object)null)
		{
			return true;
		}
		__result = plugin.calendar.DayNumber(time);
		return false;
	}

	private static bool ReadCurrentDay(EnvMan __instance, ref int __result)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((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)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((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)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		Plugin plugin = Ready(__instance);
		if ((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()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_002b: Expected O, but got Unknown
		ClearCountdown();
		Harmony val = harmony;
		if (val != null)
		{
			val.UnpatchSelf();
		}
		if ((Object)instance == (Object)this)
		{
			instance = null;
		}
	}

	private void BindCountdown()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Expected O, but got Unknown
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: 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)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)new AcceptableValueRange<int>(12, 40), Array.Empty<object>()));
		offset = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "OffsetY", 8, new ConfigDescription("Pixels below minimap.", (AcceptableValueBase)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()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown
		//IL_001a: Expected O, but got Unknown
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		if ((Object)clockNetwork != (Object)ZNet.instance)
		{
			ClearCountdown();
			clockNetwork = ZNet.instance;
		}
		if (!Object.op_Implicit((Object)clockNetwork) || Time.realtimeSinceStartup < nextPoll)
		{
			return;
		}
		nextPoll = Time.realtimeSinceStartup + 1f;
		if (Object.op_Implicit((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_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Expected O, but got Unknown
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Expected O, but got Unknown
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		if (!Object.op_Implicit((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)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)val));
			val2.Write(Object.op_Implicit((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)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)clockNetwork) || clockNetwork.IsServer() || rpc != clockNetwork.GetServerRPC() || failed || !Object.op_Implicit((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()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		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)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 ? "DZIEŃ" : "DAY") : (flag ? "NOC" : "NIGHT")) + "  " + (num2 / 60).ToString("00") + ":" + (num2 % 60).ToString("00");
	}

	private void OnGUI()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Expected O, but got Unknown
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: 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_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: 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_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Expected O, but got Unknown
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Expected O, but got Unknown
		if (showClock == null || !showClock.Value || !Object.op_Implicit((Object)clockNetwork) || !Object.op_Implicit((Object)Player.m_localPlayer) || !Object.op_Implicit((Object)Minimap.instance) || !Object.op_Implicit((Object)Minimap.instance.m_smallRoot) || !Minimap.instance.m_smallRoot.activeInHierarchy)
		{
			return;
		}
		RectTransform component = Minimap.instance.m_smallRoot.GetComponent<RectTransform>();
		if (Object.op_Implicit((Object)component))
		{
			Canvas componentInParent = ((Component)component).GetComponentInParent<Canvas>();
			Camera obj = ((Object.op_Implicit((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);
		}
	}
}