Decompiled source of ClockDaddy v0.1.4

plugins/ClockDaddy/ClockDaddy.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
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: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Laoch")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) Laoch")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+3b951b365e298e3c10c7ae2563261f3761bf7ba6")]
[assembly: AssemblyProduct("ClockDaddy")]
[assembly: AssemblyTitle("ClockDaddy")]
[assembly: InternalsVisibleTo("ClockDaddy.Harness")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[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 ClockDaddy
{
	public enum PingSound
	{
		None,
		Chime,
		Bell,
		Beeps
	}
	internal static class Chime
	{
		private const int Rate = 44100;

		private static AudioClip _chime;

		private static AudioClip _bell;

		private static AudioClip _beeps;

		public static AudioClip Get(PingSound sound)
		{
			return (AudioClip)(sound switch
			{
				PingSound.Chime => _chime ?? (_chime = Build("ClockDaddy_Chime", ChimeSamples())), 
				PingSound.Bell => _bell ?? (_bell = Build("ClockDaddy_Bell", BellSamples())), 
				PingSound.Beeps => _beeps ?? (_beeps = Build("ClockDaddy_Beeps", BeepSamples())), 
				_ => null, 
			});
		}

		private static AudioClip Build(string name, float[] samples)
		{
			AudioClip obj = AudioClip.Create(name, samples.Length, 1, 44100, false);
			obj.SetData(samples, 0);
			return obj;
		}

		private static float[] ChimeSamples()
		{
			float[] buf = new float[70560];
			AddBell(buf, 0f, 1318.5f, 0.9f, 3.5f);
			AddBell(buf, 0.45f, 1046.5f, 1.1f, 3f);
			return Normalize(buf, 0.8f);
		}

		private static float[] BellSamples()
		{
			float[] buf = new float[105840];
			AddBell(buf, 0f, 523.25f, 2.3f, 1.8f);
			return Normalize(buf, 0.8f);
		}

		private static float[] BeepSamples()
		{
			float[] array = new float[39690];
			for (int i = 0; i < 3; i++)
			{
				int num = (int)((float)(44100 * i) * 0.28f);
				int num2 = 6174;
				for (int j = 0; j < num2 && num + j < array.Length; j++)
				{
					float num3 = (float)j / 44100f;
					float num4 = Mathf.Min(1f, (float)Mathf.Min(j, num2 - j) / 220.5f);
					float num5 = Mathf.Sin(MathF.PI * 3520f * num3) + 0.3f * Mathf.Sin(MathF.PI * 7040f * num3);
					array[num + j] += num5 * num4;
				}
			}
			return Normalize(array, 0.6f);
		}

		private static void AddBell(float[] buf, float startSec, float freq, float lengthSec, float decay)
		{
			float[] array = new float[4] { 1f, 2f, 2.76f, 5.4f };
			float[] array2 = new float[4] { 1f, 0.5f, 0.25f, 0.1f };
			int num = (int)(startSec * 44100f);
			int num2 = (int)(lengthSec * 44100f);
			for (int i = 0; i < num2 && num + i < buf.Length; i++)
			{
				float num3 = (float)i / 44100f;
				float num4 = Mathf.Min(1f, num3 / 0.004f);
				float num5 = 0f;
				for (int j = 0; j < array.Length; j++)
				{
					num5 += array2[j] * Mathf.Sin(MathF.PI * 2f * freq * array[j] * num3) * Mathf.Exp((0f - num3) * decay * (1f + (float)j));
				}
				buf[num + i] += num5 * num4;
			}
		}

		private static float[] Normalize(float[] buf, float peak)
		{
			float num = 0f;
			foreach (float num2 in buf)
			{
				num = Mathf.Max(num, Mathf.Abs(num2));
			}
			if (num > 0f)
			{
				for (int j = 0; j < buf.Length; j++)
				{
					buf[j] *= peak / num;
				}
			}
			return buf;
		}
	}
	[BepInPlugin("com.laoch.clockdaddy", "ClockDaddy", "0.1.4")]
	public class ClockDaddyPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.laoch.clockdaddy";

		private const string OldPluginGuid = "com.n8daniels.clockdaddy";

		public const string PluginName = "ClockDaddy";

		public const string PluginVersion = "0.1.4";

		private static readonly Regex ColorTags = new Regex("</?color[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);

		private GUIStyle _style;

		private Font _font;

		private float _nextFontSearch;

		private readonly GUIContent _content = new GUIContent();

		internal static ClockDaddyPlugin Instance { get; private set; }

		internal Reminder Reminder { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			MigrateOldConfig();
			Settings.Bind(((BaseUnityPlugin)this).Config);
			new Harmony("com.laoch.clockdaddy").PatchAll(typeof(ClockDaddyPlugin).Assembly);
			AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
			val.playOnAwake = false;
			val.spatialBlend = 0f;
			val.ignoreListenerPause = true;
			Reminder = new Reminder(val);
			WeatherIcons.OverrideDir = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath, "icons");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ClockDaddy 0.1.4 loaded. Press F1 (Configuration Manager) to set it up.");
		}

		private void MigrateOldConfig()
		{
			string text = Path.Combine(Paths.ConfigPath, "com.n8daniels.clockdaddy.cfg");
			if (!File.Exists(text) || File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				return;
			}
			try
			{
				File.Move(text, ((BaseUnityPlugin)this).Config.ConfigFilePath);
				((BaseUnityPlugin)this).Config.Reload();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Moved settings from com.n8daniels.clockdaddy.cfg to com.laoch.clockdaddy.cfg.");
			}
			catch (IOException ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not move old settings from " + text + ": " + ex.Message));
			}
		}

		private void Update()
		{
			//IL_000c: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTyping())
			{
				KeyboardShortcut value = Settings.SilenceKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Reminder.ToggleSilence();
				}
				value = Settings.ToggleAlarmKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Reminder.ToggleEnabled();
				}
				value = Settings.ToggleClockKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Settings.ClockEnabled.Value = !Settings.ClockEnabled.Value;
				}
			}
			Reminder.Update();
			if (Settings.WeatherEnabled.Value && GameClock.Ready)
			{
				Weather.Update();
			}
		}

		private static bool IsTyping()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible())
			{
				return InputGuard.TypingInConfigManager;
			}
			return true;
		}

		private static bool HudAllowed()
		{
			if (!GameClock.Ready)
			{
				return false;
			}
			if (Settings.HideWhenMapOpen.Value && Minimap.IsOpen())
			{
				return false;
			}
			if (Settings.HideWithHud.Value && Hud.IsUserHidden())
			{
				return false;
			}
			if (Settings.HideInMenus.Value && (InventoryGui.IsVisible() || Menu.IsVisible() || StoreGui.IsVisible() || TextInput.IsVisible() || Console.IsVisible()))
			{
				return false;
			}
			return true;
		}

		private void OnGUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			if ((int)Event.current.type == 7 && HudAllowed())
			{
				float scale = (Settings.ScaleWithResolution.Value ? ((float)Screen.height / 1080f) : 1f);
				if (Settings.ClockEnabled.Value)
				{
					DrawClock(scale);
				}
				if (Settings.WeatherEnabled.Value)
				{
					DrawWeather(scale);
				}
			}
		}

		private void DrawClock(float scale)
		{
			//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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			string text = GameClock.Expand(Settings.ClockText.Value, Reminder);
			if (Reminder.Active && !string.IsNullOrEmpty(Settings.BedtimeLine.Value))
			{
				text = text + "\n" + GameClock.Expand(Settings.BedtimeLine.Value, Reminder);
			}
			if (text.Length != 0)
			{
				GUIStyle style = GetStyle();
				style.fontSize = Mathf.Max(6, Mathf.RoundToInt((float)Settings.FontSize.Value * scale));
				style.alignment = (TextAnchor)((Settings.Alignment.Value != ClockAlign.Left) ? ((Settings.Alignment.Value != ClockAlign.Right) ? 1 : 2) : 0);
				_content.text = text;
				Vector2 val = style.CalcSize(_content);
				float num = (float)Screen.width * Settings.PositionX.Value / 100f;
				float num2 = (float)Screen.height * Settings.PositionY.Value / 100f;
				if (Settings.Alignment.Value == ClockAlign.Center)
				{
					num -= val.x / 2f;
				}
				else if (Settings.Alignment.Value == ClockAlign.Right)
				{
					num -= val.x;
				}
				Color color = (BlinkOn() ? Settings.BlinkColor.Value : Settings.TextColor.Value);
				DrawText(ClampToScreen(new Rect(num, num2, val.x, val.y)), text, style, color, scale);
			}
		}

		private void DrawWeather(float scale)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			if (Weather.NextEnv == null)
			{
				return;
			}
			Texture2D val = WeatherIcons.For(Weather.Classify(Weather.NextEnv), Weather.NextAtNight);
			float num = (float)Settings.WeatherIconSize.Value * scale;
			string text = GameClock.Expand(Settings.WeatherLabel.Value, Reminder);
			GUIStyle style = GetStyle();
			style.fontSize = Mathf.Max(6, Mathf.RoundToInt((float)Settings.WeatherLabelSize.Value * scale));
			style.alignment = (TextAnchor)3;
			_content.text = text;
			Vector2 val2 = ((text.Length > 0) ? style.CalcSize(_content) : Vector2.zero);
			float num2 = (((Object)(object)val != (Object)null && text.Length > 0) ? (6f * scale) : 0f);
			float num3 = (((Object)(object)val != (Object)null) ? num : 0f) + num2 + val2.x;
			float num4 = Mathf.Max(((Object)(object)val != (Object)null) ? num : 0f, val2.y);
			if (!(num3 <= 0f))
			{
				Rect val3 = ClampToScreen(new Rect((float)Screen.width * Settings.WeatherX.Value / 100f, (float)Screen.height * Settings.WeatherY.Value / 100f, num3, num4));
				float num5 = ((Rect)(ref val3)).x;
				if ((Object)(object)val != (Object)null)
				{
					GUI.DrawTexture(new Rect(num5, ((Rect)(ref val3)).y + (num4 - num) / 2f, num, num), (Texture)(object)val, (ScaleMode)2, true);
					num5 += num + num2;
				}
				if (text.Length > 0)
				{
					DrawText(new Rect(num5, ((Rect)(ref val3)).y, val2.x, num4), text, style, Settings.TextColor.Value, scale);
				}
			}
		}

		private static Rect ClampToScreen(Rect r)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			((Rect)(ref r)).x = Mathf.Clamp(((Rect)(ref r)).x, 0f, Mathf.Max(0f, (float)Screen.width - ((Rect)(ref r)).width));
			((Rect)(ref r)).y = Mathf.Clamp(((Rect)(ref r)).y, 0f, Mathf.Max(0f, (float)Screen.height - ((Rect)(ref r)).height));
			return r;
		}

		private void DrawText(Rect rect, string text, GUIStyle style, Color color, float scale)
		{
			//IL_0125: 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_0035: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			if (Settings.Outline.Value)
			{
				_content.text = ColorTags.Replace(text, "");
				style.normal.textColor = Settings.OutlineColor.Value;
				float num = Mathf.Max(1f, Mathf.Round(1.5f * scale));
				GUI.Label(new Rect(((Rect)(ref rect)).x - num, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), _content, style);
				GUI.Label(new Rect(((Rect)(ref rect)).x + num, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), _content, style);
				GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y - num, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), _content, style);
				GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + num, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), _content, style);
			}
			_content.text = text;
			style.normal.textColor = color;
			GUI.Label(rect, _content, style);
		}

		private bool BlinkOn()
		{
			if (Reminder.Active && Settings.BlinkEnabled.Value)
			{
				return Mathf.Repeat(Time.unscaledTime * Settings.BlinkSpeed.Value, 1f) < 0.5f;
			}
			return false;
		}

		private GUIStyle GetStyle()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					wordWrap = false,
					clipping = (TextClipping)0
				};
			}
			if ((Object)(object)_font == (Object)null && Time.unscaledTime >= _nextFontSearch)
			{
				_nextFontSearch = Time.unscaledTime + 5f;
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				foreach (Font val in array)
				{
					if (((Object)val).name == "AveriaSerifLibre-Bold")
					{
						_font = val;
						break;
					}
				}
				if ((Object)(object)_font != (Object)null)
				{
					_style.font = _font;
				}
			}
			_style.fontStyle = (FontStyle)(Settings.BoldText.Value ? 1 : 0);
			return _style;
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public Action<ConfigEntryBase> CustomDrawer;

		public bool? HideDefaultButton;

		public bool? HideSettingName;

		public bool? IsAdvanced;
	}
	internal static class GameClock
	{
		public static bool Ready
		{
			get
			{
				if ((Object)(object)EnvMan.instance != (Object)null && (Object)(object)ZNet.instance != (Object)null)
				{
					return (Object)(object)Player.m_localPlayer != (Object)null;
				}
				return false;
			}
		}

		public static float Hour => EnvMan.instance.GetDayFraction() * 24f;

		public static int LogicDay => EnvMan.instance.GetCurrentDay();

		public static float LogicHour
		{
			get
			{
				EnvMan instance = EnvMan.instance;
				double num = instance.m_dayLengthSec;
				float num2 = (float)(instance.m_totalSeconds % num / num);
				return instance.RescaleDayFraction(num2) * 24f;
			}
		}

		public static int Day => EnvMan.instance.GetDay();

		public static string FormatTime(float hour, int minuteStep)
		{
			int num = (int)(hour * 60f);
			if (minuteStep > 1)
			{
				num -= num % minuteStep;
			}
			return Format(DateTime.Today.AddMinutes(num % 1440));
		}

		public static string Format(DateTime time)
		{
			try
			{
				return time.ToString(Settings.TimeFormat.Value, CultureInfo.InvariantCulture);
			}
			catch (FormatException)
			{
				return time.ToString("h:mm tt", CultureInfo.InvariantCulture);
			}
		}

		public static string TimeOfDay(float hour)
		{
			if (hour >= 5f && hour < 12f)
			{
				return "Morning";
			}
			if (hour >= 12f && hour < 17f)
			{
				return "Afternoon";
			}
			if (hour >= 17f && hour < 21f)
			{
				return "Evening";
			}
			return "Night";
		}

		public static string Duration(float hours)
		{
			int num = (int)(hours * 60f);
			if (num <= 0)
			{
				return "now";
			}
			if (num < 60)
			{
				return $"{num}m";
			}
			return $"{num / 60}h {num % 60:00}m";
		}

		public static string Expand(string template, Reminder reminder)
		{
			if (string.IsNullOrEmpty(template))
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder(template);
			stringBuilder.Replace("\\n", "\n");
			if (template.IndexOf('{') < 0)
			{
				return stringBuilder.ToString();
			}
			float hour = Hour;
			int step = Settings.MinuteStep.Value;
			stringBuilder.Replace("{0}", "{gametime}").Replace("{1}", "{tod}").Replace("{2}", "{day}")
				.Replace("{3}", "{realtime}");
			Replace(stringBuilder, "{gametime}", () => FormatTime(hour, step));
			Replace(stringBuilder, "{day}", () => Day.ToString());
			Replace(stringBuilder, "{tod}", () => TimeOfDay(hour));
			Replace(stringBuilder, "{realtime}", () => Format(DateTime.Now));
			Replace(stringBuilder, "{bedtime}", () => FormatTime(Reminder.StartHour, 1));
			Replace(stringBuilder, "{bedtimein}", () => Duration(reminder.HoursUntilBedtime(hour)));
			Replace(stringBuilder, "{biome}", () => BiomeName(Player.m_localPlayer.GetCurrentBiome()));
			Replace(stringBuilder, "{weather}", () => Weather.DisplayName(Weather.CurrentEnv));
			Replace(stringBuilder, "{nextweather}", () => (Weather.NextEnv == null) ? "?" : Weather.DisplayName(Weather.NextEnv));
			Replace(stringBuilder, "{weatherin}", () => Weather.Countdown(Weather.SecondsUntilChange));
			Replace(stringBuilder, "{silencekey}", () => ((object)Settings.SilenceKey.Value/*cast due to .constrained prefix*/).ToString());
			return stringBuilder.ToString();
		}

		private static void Replace(StringBuilder sb, string token, Func<string> value)
		{
			if (sb.ToString().IndexOf(token, StringComparison.Ordinal) >= 0)
			{
				sb.Replace(token, value());
			}
		}

		private unsafe static string BiomeName(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			if ((int)biome <= 8)
			{
				if ((int)biome == 0)
				{
					return "";
				}
				if ((int)biome == 8)
				{
					return "Black Forest";
				}
			}
			else
			{
				if ((int)biome == 32)
				{
					return "Ashlands";
				}
				if ((int)biome == 64)
				{
					return "Deep North";
				}
				if ((int)biome == 512)
				{
					return "Mistlands";
				}
			}
			return ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString();
		}
	}
	internal static class InputGuard
	{
		[HarmonyPatch(typeof(TextInput), "IsVisible")]
		private static class TextInputIsVisible
		{
			private static void Postfix(ref bool __result)
			{
				if (!__result && TypingInConfigManager)
				{
					__result = true;
				}
			}
		}

		private const string ConfigManagerGuid = "com.bepis.bepinex.configurationmanager";

		private static object _cm;

		private static PropertyInfo _displaying;

		private static bool _looked;

		public static bool TypingInConfigManager
		{
			get
			{
				if (GUIUtility.keyboardControl == 0)
				{
					return false;
				}
				if (!_looked)
				{
					_looked = true;
					if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var value) && (Object)(object)value.Instance != (Object)null)
					{
						_cm = value.Instance;
						_displaying = _cm.GetType().GetProperty("DisplayingWindow", BindingFlags.Instance | BindingFlags.Public);
					}
				}
				if (_cm == null || _displaying == null)
				{
					return false;
				}
				try
				{
					return (bool)_displaying.GetValue(_cm, null);
				}
				catch
				{
					return false;
				}
			}
		}
	}
	internal sealed class Reminder
	{
		private const int NoNight = int.MinValue;

		private readonly AudioSource _audio;

		private int _night = int.MinValue;

		private int _silencedNight = int.MinValue;

		private int _pingCount;

		private int _headsUpNight = int.MinValue;

		private int _wentToBedNight = int.MinValue;

		private float _lastPing;

		public bool Active { get; private set; }

		internal int PingCount => _pingCount;

		internal int HeadsUpCount { get; private set; }

		public static float StartHour => Settings.ToHour(Settings.BedTime.Value, 17f);

		private static float EndHour => Settings.ToHour(Settings.GiveUpTime.Value, 6f);

		private static float HeadsUpHour => Settings.ToHour(Settings.HeadsUpTime.Value, 16f);

		private static bool CrossesMidnight => EndHour < StartHour;

		public bool SilencedTonight
		{
			get
			{
				if (GameClock.Ready)
				{
					return _silencedNight == CurrentOrNextNight(GameClock.LogicDay, GameClock.LogicHour);
				}
				return false;
			}
		}

		internal bool WentToBedTonight
		{
			get
			{
				if (GameClock.Ready)
				{
					return _wentToBedNight == CurrentOrNextNight(GameClock.LogicDay, GameClock.LogicHour);
				}
				return false;
			}
		}

		public Reminder(AudioSource audio)
		{
			_audio = audio;
		}

		private static bool InWindow(float hour)
		{
			if (CrossesMidnight)
			{
				if (!(hour >= StartHour))
				{
					return hour < EndHour;
				}
				return true;
			}
			if (EndHour > StartHour)
			{
				if (hour >= StartHour)
				{
					return hour < EndHour;
				}
				return false;
			}
			return hour >= StartHour;
		}

		private static int NightOf(int day, float hour)
		{
			if (!CrossesMidnight || !(hour < EndHour))
			{
				return day;
			}
			return day - 1;
		}

		private static int CurrentOrNextNight(int day, float hour)
		{
			if (InWindow(hour))
			{
				return NightOf(day, hour);
			}
			if (!(hour < StartHour))
			{
				return day + 1;
			}
			return day;
		}

		public float HoursUntilBedtime(float hour)
		{
			if (!InWindow(hour))
			{
				return Mathf.Repeat(StartHour - hour, 24f);
			}
			return 0f;
		}

		public void Update()
		{
			Active = false;
			if (!Settings.ReminderEnabled.Value || !GameClock.Ready)
			{
				return;
			}
			float logicHour = GameClock.LogicHour;
			Player localPlayer = Player.m_localPlayer;
			bool flag = ((Character)localPlayer).InBed() || localPlayer.IsSleeping();
			if (flag)
			{
				MarkWentToBed(logicHour);
			}
			if (!InWindow(logicHour))
			{
				MaybeHeadsUp(logicHour);
				return;
			}
			int num = NightOf(GameClock.LogicDay, logicHour);
			if (num != _night)
			{
				_night = num;
				_pingCount = 0;
			}
			if (_silencedNight == num || _wentToBedNight == num || flag || ((Character)localPlayer).IsDead() || (Settings.OnlyWhenBedUsable.Value && !EnvMan.CanSleep()))
			{
				return;
			}
			Active = true;
			if (_pingCount == 0)
			{
				Ping();
				return;
			}
			int value = Settings.RepeatSeconds.Value;
			int value2 = Settings.MaxRepeats.Value;
			bool flag2 = value2 == 0 || _pingCount <= value2;
			if (value > 0 && flag2 && Time.realtimeSinceStartup - _lastPing >= (float)value)
			{
				Ping();
			}
		}

		private void MarkWentToBed(float hour)
		{
			if (InWindow(hour))
			{
				_wentToBedNight = NightOf(GameClock.LogicDay, hour);
			}
			else if (hour >= 12f && hour < StartHour)
			{
				_wentToBedNight = GameClock.LogicDay;
			}
		}

		private void MaybeHeadsUp(float hour)
		{
			if (!Settings.HeadsUpEnabled.Value)
			{
				return;
			}
			float headsUpHour = HeadsUpHour;
			if (headsUpHour >= StartHour || hour < headsUpHour || hour >= StartHour)
			{
				return;
			}
			int num = CurrentOrNextNight(GameClock.LogicDay, hour);
			if (_headsUpNight != num && _silencedNight != num && _wentToBedNight != num)
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Character)localPlayer).InBed() && !localPlayer.IsSleeping() && !((Character)localPlayer).IsDead())
				{
					_headsUpNight = num;
					HeadsUpCount++;
					PlaySound();
					Show(Settings.HeadsUpMessage.Value);
				}
			}
		}

		private void Ping()
		{
			_pingCount++;
			_lastPing = Time.realtimeSinceStartup;
			PlayAndShow();
		}

		public void TestPing()
		{
			if (!GameClock.Ready)
			{
				PlaySound();
			}
			else
			{
				PlayAndShow();
			}
		}

		private void PlayAndShow()
		{
			PlaySound();
			Show(Settings.MessageText.Value);
		}

		private void Show(string template)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			ReminderMessage value = Settings.MessageStyle.Value;
			if (value != ReminderMessage.None && !((Object)(object)MessageHud.instance == (Object)null) && GameClock.Ready && !string.IsNullOrEmpty(template))
			{
				string text = GameClock.Expand(template, this);
				MessageType val = (MessageType)((value == ReminderMessage.TopLeft) ? 1 : 2);
				MessageHud.instance.ShowMessage(val, text, 0, (Sprite)null, true, true);
			}
		}

		private void PlaySound()
		{
			AudioClip val = Chime.Get(Settings.Sound.Value);
			if ((Object)(object)val != (Object)null && (Object)(object)_audio != (Object)null)
			{
				_audio.PlayOneShot(val, Settings.Volume.Value);
			}
		}

		public void ToggleSilence()
		{
			if (GameClock.Ready)
			{
				int num = CurrentOrNextNight(GameClock.LogicDay, GameClock.LogicHour);
				bool flag = _silencedNight != num;
				_silencedNight = (flag ? num : int.MinValue);
				_lastPing = Time.realtimeSinceStartup;
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)1, flag ? "ClockDaddy: silenced for tonight. Fine. Stay up." : "ClockDaddy: bedtime reminder back on.", 0, (Sprite)null, false, true);
				}
			}
		}

		public void ToggleEnabled()
		{
			bool flag = !Settings.ReminderEnabled.Value;
			Settings.ReminderEnabled.Value = flag;
			_lastPing = Time.realtimeSinceStartup;
			if ((Object)(object)MessageHud.instance != (Object)null && GameClock.Ready)
			{
				MessageHud.instance.ShowMessage((MessageType)1, flag ? "ClockDaddy: alarm on" : "ClockDaddy: alarm off", 0, (Sprite)null, false, true);
			}
		}
	}
	public enum ClockAlign
	{
		Left,
		Center,
		Right
	}
	public enum ReminderMessage
	{
		None,
		Center,
		TopLeft
	}
	internal static class Settings
	{
		private const string SClock = "1 - Clock";

		private const string SLook = "2 - Clock Look";

		private const string SBed = "3 - Bedtime Reminder";

		private const string SBlink = "4 - Blink";

		private const string SWeather = "5 - Weather Icon";

		private const string SKeys = "6 - Hotkeys";

		public static ConfigEntry<bool> ClockEnabled;

		public static ConfigEntry<string> ClockText;

		public static ConfigEntry<string> TimeFormat;

		public static ConfigEntry<int> MinuteStep;

		public static ConfigEntry<bool> HideWhenMapOpen;

		public static ConfigEntry<bool> HideInMenus;

		public static ConfigEntry<bool> HideWithHud;

		public static ConfigEntry<float> PositionX;

		public static ConfigEntry<float> PositionY;

		public static ConfigEntry<ClockAlign> Alignment;

		public static ConfigEntry<int> FontSize;

		public static ConfigEntry<bool> ScaleWithResolution;

		public static ConfigEntry<Color> TextColor;

		public static ConfigEntry<bool> BoldText;

		public static ConfigEntry<bool> Outline;

		public static ConfigEntry<Color> OutlineColor;

		public static ConfigEntry<bool> ReminderEnabled;

		public static ConfigEntry<string> BedTime;

		public static ConfigEntry<string> GiveUpTime;

		public static ConfigEntry<bool> HeadsUpEnabled;

		public static ConfigEntry<string> HeadsUpTime;

		public static ConfigEntry<string> HeadsUpMessage;

		public static ConfigEntry<ReminderMessage> MessageStyle;

		public static ConfigEntry<string> MessageText;

		public static ConfigEntry<PingSound> Sound;

		public static ConfigEntry<float> Volume;

		public static ConfigEntry<int> RepeatSeconds;

		public static ConfigEntry<int> MaxRepeats;

		public static ConfigEntry<bool> OnlyWhenBedUsable;

		public static ConfigEntry<bool> TestButtons;

		public static ConfigEntry<bool> BlinkEnabled;

		public static ConfigEntry<Color> BlinkColor;

		public static ConfigEntry<float> BlinkSpeed;

		public static ConfigEntry<string> BedtimeLine;

		public static ConfigEntry<bool> WeatherEnabled;

		public static ConfigEntry<float> WeatherX;

		public static ConfigEntry<float> WeatherY;

		public static ConfigEntry<int> WeatherIconSize;

		public static ConfigEntry<string> WeatherLabel;

		public static ConfigEntry<int> WeatherLabelSize;

		public static ConfigEntry<KeyboardShortcut> SilenceKey;

		public static ConfigEntry<KeyboardShortcut> ToggleClockKey;

		public static ConfigEntry<KeyboardShortcut> ToggleAlarmKey;

		internal static readonly string[] TimeChoices = BuildTimeChoices();

		private static ConfigFile _cfg;

		private static int _order;

		private static string[] BuildTimeChoices()
		{
			string[] array = new string[96];
			for (int i = 0; i < 96; i++)
			{
				array[i] = DateTime.Today.AddMinutes(i * 15).ToString("h:mm tt", CultureInfo.InvariantCulture);
			}
			return array;
		}

		internal static float ToHour(string time, float fallback)
		{
			if (DateTime.TryParseExact(time?.Trim(), "h:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result))
			{
				return (float)result.Hour + (float)result.Minute / 60f;
			}
			return fallback;
		}

		public static void Bind(ConfigFile cfg)
		{
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			_cfg = cfg;
			_order = 1000;
			ClockEnabled = B("1 - Clock", "Show Clock", value: true, "Show the clock on screen. The bedtime reminder still works when the clock is hidden.");
			ClockText = B("1 - Clock", "Clock Text", "<size=28><color=#FFD700>Game Time:</color></size> {gametime}<size=24><color=#ADFF2F>  Current Day:</color></size> {day}<size=28><color=#FF69B4>  Real Time:</color></size> {realtime}", "What the clock shows. Use \\n for a new line; <b>, <i>, <color=#hex> and <size=N> work.\nTokens: {gametime} {day} {tod} (Morning/Afternoon/Evening/Night) {realtime} {bedtime} (the reminder time) {bedtimein} (game time until the reminder) {biome} {weather} {nextweather} {weatherin}. AzuClock's {0} {1} {2} {3} work too.");
			TimeFormat = B("1 - Clock", "Time Format", "hh:mm tt", "How {gametime} and {realtime} are written. hh:mm tt = 05:00 PM, h:mm tt = 5:00 PM, HH:mm = 17:00.");
			MinuteStep = B("1 - Clock", "Minute Step", 1, "Round the displayed game minutes down to this step. A game minute passes in about a real second.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[6] { 1, 5, 10, 15, 30, 60 }));
			HideWhenMapOpen = B("1 - Clock", "Hide When Map Open", value: false, "Hide the clock and weather icon while the big map is open.");
			HideInMenus = B("1 - Clock", "Hide In Menus", value: false, "Hide the clock and weather icon in the inventory, the Esc menu, stores and text boxes.");
			HideWithHud = B("1 - Clock", "Hide With HUD", value: true, "Hide the clock and weather icon when you hide the HUD (Ctrl+F3).");
			_order = 1000;
			PositionX = B("2 - Clock Look", "Position X (%)", 48f, "Horizontal position, 0 = left edge, 100 = right edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
			PositionY = B("2 - Clock Look", "Position Y (%)", 0f, "Vertical position, 0 = top edge, 100 = bottom edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
			Alignment = B("2 - Clock Look", "Alignment", ClockAlign.Center, "Which side of the text sits on the position above.");
			FontSize = B("2 - Clock Look", "Font Size", 24, "Text size (sizes set with <size=N> in the text are fixed).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 72));
			ScaleWithResolution = B("2 - Clock Look", "Scale With Resolution", value: false, "Treat Font Size as 1080p and grow or shrink it with the screen height.");
			TextColor = B<Color>("2 - Clock Look", "Text Color", Color.white, "Normal clock color (text without its own <color>).");
			BoldText = B("2 - Clock Look", "Bold Text", value: true, "Draw the clock, the bedtime line and the weather label in bold.");
			Outline = B("2 - Clock Look", "Outline", value: false, "Draw a dark outline so the clock is readable over snow and sky.");
			OutlineColor = B<Color>("2 - Clock Look", "Outline Color", new Color(0f, 0f, 0f, 0.85f), "Outline color.");
			_order = 1000;
			ReminderEnabled = B("3 - Bedtime Reminder", "Reminder Enabled", value: true, "Ping everyone who has ClockDaddy installed when it is time for bed.");
			HeadsUpEnabled = B("3 - Bedtime Reminder", "Heads-Up Ping", value: true, "One ping before bedtime to get people heading home. Plays once, no blinking, no repeats.");
			HeadsUpTime = B("3 - Bedtime Reminder", "Heads-Up Time", "4:00 PM", "Game time of the heads-up ping. Must be before Bedtime.", (AcceptableValueBase)(object)new AcceptableValueList<string>(TimeChoices));
			HeadsUpMessage = B("3 - Bedtime Reminder", "Heads-Up Message", "Head for bed soon.", "Text shown with the heads-up ping. Empty = sound only. Tokens from Clock Text work here too.");
			BedTime = B("3 - Bedtime Reminder", "Bedtime", "5:00 PM", "Game time the bedtime reminder starts: ping, message, blinking clock. Beds work from 12:00 PM onward.", (AcceptableValueBase)(object)new AcceptableValueList<string>(TimeChoices));
			MessageText = B("3 - Bedtime Reminder", "Message Text", "Time for bed.", "The bedtime text. Use \\n for a new line. Tokens from Clock Text work here too.");
			GiveUpTime = B("3 - Bedtime Reminder", "Give Up At", "6:00 AM", "Game time the reminder stops nagging if nobody slept.", (AcceptableValueBase)(object)new AcceptableValueList<string>(TimeChoices));
			MessageStyle = B("3 - Bedtime Reminder", "Message Style", ReminderMessage.Center, "Where the messages pop up, or None for sound and blink only.");
			Sound = B("3 - Bedtime Reminder", "Ping Sound", PingSound.Chime, "Sound played with each reminder.");
			Volume = B("3 - Bedtime Reminder", "Ping Volume", 0.7f, "Reminder volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
			RepeatSeconds = B("3 - Bedtime Reminder", "Repeat Every (seconds)", 120, "Real seconds between repeat pings while you are still awake. 0 = ping once per night.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 900));
			MaxRepeats = B("3 - Bedtime Reminder", "Max Repeats", 3, "Repeat pings after the first one. 0 = keep going until you sleep or silence it.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50));
			OnlyWhenBedUsable = B("3 - Bedtime Reminder", "Only When Bed Is Usable", value: true, "Hold the reminder while the game would refuse to let you sleep (e.g. the cooldown right after waking).");
			TestButtons = B("3 - Bedtime Reminder", "Test", value: false, "Try the reminder without waiting for 5 PM.", null, DrawTestButtons, hideName: true);
			_order = 1000;
			BlinkEnabled = B("4 - Blink", "Blink Clock At Bedtime", value: true, "Flash the clock from reminder time until you sleep or silence it.");
			BlinkColor = B<Color>("4 - Blink", "Blink Color", new Color(1f, 0.35f, 0.2f, 1f), "Color the clock flashes to.");
			BlinkSpeed = B("4 - Blink", "Blink Speed", 1.5f, "Flashes per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f));
			BedtimeLine = B("4 - Blink", "Bedtime Clock Line", "BEDTIME  ({silencekey} to silence)", "Extra line added under the clock while the reminder is active. Empty = none. {silencekey} shows the Silence hotkey.");
			_order = 1000;
			WeatherEnabled = B("5 - Weather Icon", "Show Next Weather Icon", value: true, "Show an icon of the weather that is coming next. Hidden where the weather is fixed (crypts, raids, caves).");
			WeatherX = B("5 - Weather Icon", "Position X (%)", 70f, "Horizontal position of the icon, 0 = left edge, 100 = right edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
			WeatherY = B("5 - Weather Icon", "Position Y (%)", 0f, "Vertical position of the icon, 0 = top edge, 100 = bottom edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f));
			WeatherIconSize = B("5 - Weather Icon", "Icon Size", 36, "Icon size in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(16, 128));
			WeatherLabel = B("5 - Weather Icon", "Label", "{nextweather} in {weatherin}", "Text to the right of the icon. Empty = icon only. Tokens: {nextweather} {weatherin} {weather} and the clock tokens.");
			WeatherLabelSize = B("5 - Weather Icon", "Label Font Size", 20, "Label text size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 48));
			_order = 1000;
			SilenceKey = B<KeyboardShortcut>("6 - Hotkeys", "Silence Tonight", new KeyboardShortcut((KeyCode)279, Array.Empty<KeyCode>()), "Stop the pings and blinking until tomorrow night. Press again to undo.");
			ToggleAlarmKey = B<KeyboardShortcut>("6 - Hotkeys", "Toggle Alarm", new KeyboardShortcut((KeyCode)279, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Turn the whole alarm (heads-up, bedtime ping, blink) off or on. Stays that way until pressed again.");
			ToggleClockKey = B<KeyboardShortcut>("6 - Hotkeys", "Toggle Clock", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Show or hide the clock.");
		}

		private static ConfigEntry<T> B<T>(string section, string key, T value, string description, AcceptableValueBase acceptable = null, Action<ConfigEntryBase> drawer = null, bool hideName = false)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
			{
				Order = _order--
			};
			if (drawer != null)
			{
				configurationManagerAttributes.CustomDrawer = drawer;
				configurationManagerAttributes.HideDefaultButton = true;
				configurationManagerAttributes.HideSettingName = hideName;
			}
			return _cfg.Bind<T>(section, key, value, new ConfigDescription(description, acceptable, new object[1] { configurationManagerAttributes }));
		}

		private static void DrawTestButtons(ConfigEntryBase _)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Test Ping", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ClockDaddyPlugin.Instance?.Reminder.TestPing();
			}
			if (GUILayout.Button(((Object)(object)ClockDaddyPlugin.Instance != (Object)null && ClockDaddyPlugin.Instance.Reminder.SilencedTonight) ? "Un-silence Tonight" : "Silence Tonight", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ClockDaddyPlugin.Instance?.Reminder.ToggleSilence();
			}
			if (GUILayout.Button(ReminderEnabled.Value ? "Alarm: ON" : "Alarm: OFF", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ClockDaddyPlugin.Instance?.Reminder.ToggleEnabled();
			}
			GUILayout.EndHorizontal();
		}
	}
	public enum WeatherKind
	{
		Unknown,
		Clear,
		Mist,
		LightRain,
		Rain,
		Storm,
		Snow,
		Snowstorm,
		AshRain,
		Dark
	}
	internal static class Weather
	{
		private static float _nextRefresh;

		private static readonly Dictionary<string, string> Names = new Dictionary<string, string>
		{
			{ "Clear", "Clear" },
			{ "Misty", "Misty" },
			{ "Rain", "Rain" },
			{ "LightRain", "Light Rain" },
			{ "ThunderStorm", "Thunderstorm" },
			{ "Snow", "Snow" },
			{ "SnowStorm", "Snowstorm" },
			{ "Twilight_Clear", "Clear" },
			{ "Twilight_Snow", "Snow" },
			{ "Twilight_SnowStorm", "Snowstorm" },
			{ "Heath_clear", "Clear" },
			{ "DeepForest_Mist", "Misty" },
			{ "Darklands_dark", "Dark" },
			{ "GDKing", "Elder's Fog" },
			{ "Mistlands_clear", "Clear" },
			{ "Mistlands_rain", "Rain" },
			{ "Mistlands_thunder", "Thunderstorm" },
			{ "Ashlands_ashrain", "Ash Rain" },
			{ "Ashlands_misty", "Ash Mist" },
			{ "Ashlands_darklands", "Dark" },
			{ "Ashlands_SeaStorm", "Sea Storm" },
			{ "SunkenCrypt", "Crypt" },
			{ "Caves", "Caves" },
			{ "Crypt", "Crypt" },
			{ "InfectedMine", "Infested Mine" }
		};

		public static string NextEnv { get; private set; }

		public static bool NextAtNight { get; private set; }

		public static float SecondsUntilChange { get; private set; }

		public static string CurrentEnv => (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetCurrentEnvironment() : null)?.m_name;

		public static void Update()
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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)
			//IL_009b: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < _nextRefresh)
			{
				return;
			}
			_nextRefresh = Time.unscaledTime + 0.5f;
			NextEnv = null;
			EnvMan instance = EnvMan.instance;
			if ((Object)(object)instance == (Object)null || instance.m_environmentDuration <= 0)
			{
				return;
			}
			long environmentDuration = instance.m_environmentDuration;
			long num = (long)instance.m_totalSeconds;
			SecondsUntilChange = environmentDuration - num % environmentDuration;
			if (instance.m_environmentPeriod < 0)
			{
				return;
			}
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)mainCamera).transform.position;
			bool flag = WorldGenerator.IsAshlands(position.x, position.z);
			bool flag2 = WorldGenerator.IsDeepnorth(position.x, position.y);
			long num2 = num / environmentDuration + 1;
			EnvSetup val = null;
			State state = Random.state;
			try
			{
				Random.InitState((int)num2);
				List<EnvEntry> availableEnvironments = instance.GetAvailableEnvironments(instance.m_currentBiome);
				if (availableEnvironments != null && availableEnvironments.Count > 0)
				{
					val = instance.SelectWeightedEnvironment(availableEnvironments);
					foreach (EnvEntry item in availableEnvironments)
					{
						if (item.m_ashlandsOverride && flag)
						{
							val = item.m_env;
						}
						if (item.m_deepnorthOverride && flag2)
						{
							val = item.m_env;
						}
					}
				}
			}
			finally
			{
				Random.state = state;
			}
			if (val != null)
			{
				NextEnv = val.m_name;
				float num3 = (float)(num2 * environmentDuration % instance.m_dayLengthSec) / (float)instance.m_dayLengthSec;
				float num4 = instance.RescaleDayFraction(num3);
				NextAtNight = num4 < 0.25f || num4 > 0.75f;
			}
		}

		public static WeatherKind Classify(string env)
		{
			if (string.IsNullOrEmpty(env))
			{
				return WeatherKind.Unknown;
			}
			string text = env.ToLowerInvariant();
			if (text.Contains("thunder") || text.Contains("seastorm"))
			{
				return WeatherKind.Storm;
			}
			if (text.Contains("snowstorm"))
			{
				return WeatherKind.Snowstorm;
			}
			if (text.Contains("snow"))
			{
				return WeatherKind.Snow;
			}
			if (text.Contains("ashrain"))
			{
				return WeatherKind.AshRain;
			}
			if (text.Contains("lightrain"))
			{
				return WeatherKind.LightRain;
			}
			if (text.Contains("rain"))
			{
				return WeatherKind.Rain;
			}
			if (text.Contains("mist") || text.Contains("gdking") || text.Contains("fog"))
			{
				return WeatherKind.Mist;
			}
			if (text.Contains("dark"))
			{
				return WeatherKind.Dark;
			}
			if (text.Contains("clear"))
			{
				return WeatherKind.Clear;
			}
			return WeatherKind.Unknown;
		}

		public static string DisplayName(string env)
		{
			if (string.IsNullOrEmpty(env))
			{
				return "?";
			}
			if (Names.TryGetValue(env, out var value))
			{
				return value;
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < env.Length; i++)
			{
				char c = env[i];
				if (c == '_')
				{
					stringBuilder.Append(' ');
					continue;
				}
				if (i > 0 && char.IsUpper(c) && char.IsLower(env[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append((stringBuilder.Length == 0 || stringBuilder[stringBuilder.Length - 1] == ' ') ? char.ToUpperInvariant(c) : c);
			}
			return stringBuilder.ToString();
		}

		public static string Countdown(float seconds)
		{
			int num = Mathf.Max(0, Mathf.CeilToInt(seconds));
			if (num < 60)
			{
				return $"{num}s";
			}
			return $"{num / 60}m {num % 60:00}s";
		}
	}
	internal static class WeatherIcons
	{
		private static readonly Dictionary<string, Texture2D> Cache = new Dictionary<string, Texture2D>();

		public static string OverrideDir { get; set; }

		public static Texture2D For(WeatherKind kind, bool night)
		{
			return (Texture2D)(kind switch
			{
				WeatherKind.Clear => Load(night ? "clear_night" : "clear_day"), 
				WeatherKind.Mist => Load("mist"), 
				WeatherKind.LightRain => Load("light_rain"), 
				WeatherKind.Rain => Load("rain"), 
				WeatherKind.Storm => Load("storm"), 
				WeatherKind.Snow => Load("snow"), 
				WeatherKind.Snowstorm => Load("snowstorm"), 
				WeatherKind.AshRain => Load("ash_rain"), 
				WeatherKind.Dark => Load("dark"), 
				_ => null, 
			});
		}

		private static Texture2D Load(string name)
		{
			//IL_00b7: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			if (Cache.TryGetValue(name, out var value))
			{
				return value;
			}
			byte[] array = null;
			if (!string.IsNullOrEmpty(OverrideDir))
			{
				string path = Path.Combine(OverrideDir, name + ".png");
				if (File.Exists(path))
				{
					array = File.ReadAllBytes(path);
				}
			}
			if (array == null)
			{
				using Stream stream = typeof(WeatherIcons).Assembly.GetManifestResourceStream("ClockDaddy.Icons." + name + ".png");
				if (stream != null)
				{
					array = new byte[stream.Length];
					for (int i = 0; i < array.Length; i += stream.Read(array, i, array.Length - i))
					{
					}
				}
			}
			Texture2D val = null;
			if (array != null)
			{
				val = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					name = "ClockDaddy_" + name,
					filterMode = (FilterMode)1
				};
				if (!ImageConversion.LoadImage(val, array))
				{
					Object.Destroy((Object)(object)val);
					val = null;
				}
			}
			Cache[name] = val;
			return val;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}