Decompiled source of HavensAlmanac v1.3.0

HavensAlmanac.dll

Decompiled 2 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BirthdayReminder;
using BirthdayReminder.Data;
using CropOptimizer.Data;
using HarmonyLib;
using HavenDevTools;
using HavensAlmanac.Config;
using HavensAlmanac.Data;
using HavensAlmanac.Integration;
using HavensAlmanac.UI;
using HavensBirthright;
using Microsoft.CodeAnalysis;
using SunHavenMuseumUtilityTracker;
using SunHavenMuseumUtilityTracker.Data;
using SunhavenMods.Shared;
using SunhavenTodo;
using SunhavenTodo.Data;
using TheVault;
using TheVault.Vault;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("HavensAlmanac")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9c743905a6a1ecc5bdd54cfadfb24c03b53de21b")]
[assembly: AssemblyProduct("HavensAlmanac")]
[assembly: AssemblyTitle("HavensAlmanac")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 SunhavenMods.Shared
{
	public static class ConfigFileHelper
	{
		public static ConfigFile CreateNamedConfig(string pluginGuid, string configFileName, Action<string> logWarning = null)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, configFileName);
			string text2 = Path.Combine(Paths.ConfigPath, pluginGuid + ".cfg");
			try
			{
				if (!File.Exists(text) && File.Exists(text2))
				{
					File.Copy(text2, text);
				}
			}
			catch (Exception ex)
			{
				logWarning?.Invoke("[Config] Migration to " + configFileName + " failed: " + ex.Message);
			}
			return new ConfigFile(text, true);
		}

		public static bool ReplacePluginConfig(BaseUnityPlugin plugin, ConfigFile newConfig, Action<string> logWarning = null)
		{
			if ((Object)(object)plugin == (Object)null || newConfig == null)
			{
				return false;
			}
			try
			{
				Type typeFromHandle = typeof(BaseUnityPlugin);
				PropertyInfo property = typeFromHandle.GetProperty("Config", BindingFlags.Instance | BindingFlags.Public);
				if (property != null && property.CanWrite)
				{
					property.SetValue(plugin, newConfig, null);
					return true;
				}
				FieldInfo field = typeFromHandle.GetField("<Config>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(plugin, newConfig);
					return true;
				}
				FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.FieldType == typeof(ConfigFile))
					{
						fieldInfo.SetValue(plugin, newConfig);
						return true;
					}
				}
			}
			catch (Exception ex)
			{
				logWarning?.Invoke("[Config] ReplacePluginConfig failed: " + ex.Message);
			}
			return false;
		}
	}
	public static class OvernightHookUtility
	{
		public static bool TryHookOvernightEvent(ref bool overnightHooked, ref UnityAction overnightCallback, UnityAction callback, Func<Type, object> singletonResolver, Action<string> logInfo = null, Action<string> logWarning = null)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			if (overnightHooked)
			{
				return true;
			}
			try
			{
				Type type = AccessTools.TypeByName("Wish.DayCycle");
				if (type != null)
				{
					FieldInfo fieldInfo = AccessTools.Field(type, "OnDayStart");
					if (fieldInfo != null)
					{
						object? value = fieldInfo.GetValue(null);
						UnityAction val = (UnityAction)((value is UnityAction) ? value : null);
						overnightCallback = callback;
						if (val != null)
						{
							val = (UnityAction)Delegate.Remove((Delegate?)(object)val, (Delegate?)(object)overnightCallback);
							val = (UnityAction)Delegate.Combine((Delegate?)(object)val, (Delegate?)(object)overnightCallback);
							fieldInfo.SetValue(null, val);
						}
						else
						{
							fieldInfo.SetValue(null, overnightCallback);
						}
						overnightHooked = true;
						logInfo?.Invoke("Hooked into DayCycle.OnDayStart");
						return true;
					}
				}
				Type type2 = AccessTools.TypeByName("Wish.UIHandler");
				if (type2 == null)
				{
					return false;
				}
				object obj = singletonResolver?.Invoke(type2);
				if (obj == null)
				{
					return false;
				}
				FieldInfo fieldInfo2 = AccessTools.Field(type2, "OnCompleteOvernight");
				if (fieldInfo2 == null)
				{
					return false;
				}
				object? value2 = fieldInfo2.GetValue(obj);
				UnityAction val2 = (UnityAction)((value2 is UnityAction) ? value2 : null);
				overnightCallback = callback;
				if (val2 != null)
				{
					val2 = (UnityAction)Delegate.Remove((Delegate?)(object)val2, (Delegate?)(object)overnightCallback);
					val2 = (UnityAction)Delegate.Combine((Delegate?)(object)val2, (Delegate?)(object)overnightCallback);
					fieldInfo2.SetValue(obj, val2);
				}
				else
				{
					fieldInfo2.SetValue(obj, overnightCallback);
				}
				overnightHooked = true;
				logInfo?.Invoke("Hooked into UIHandler.OnCompleteOvernight");
				return true;
			}
			catch (Exception ex)
			{
				logWarning?.Invoke("Failed to hook overnight event: " + ex.Message);
				return false;
			}
		}
	}
	public static class VersionChecker
	{
		public class VersionCheckResult
		{
			public bool Success { get; set; }

			public bool UpdateAvailable { get; set; }

			public string CurrentVersion { get; set; }

			public string LatestVersion { get; set; }

			public string ModName { get; set; }

			public string NexusUrl { get; set; }

			public string Changelog { get; set; }

			public string ErrorMessage { get; set; }
		}

		public class ModHealthSnapshot
		{
			public string PluginGuid { get; set; }

			public DateTime LastCheckUtc { get; set; }

			public int ExceptionCount { get; set; }

			public string LastError { get; set; }
		}

		private class VersionCheckRunner : MonoBehaviour
		{
			public void StartCheck(string pluginGuid, string currentVersion, Action<VersionCheckResult> onComplete)
			{
				((MonoBehaviour)this).StartCoroutine(CheckVersionCoroutine(pluginGuid, currentVersion, onComplete));
			}

			private IEnumerator CheckVersionCoroutine(string pluginGuid, string currentVersion, Action<VersionCheckResult> onComplete)
			{
				VersionCheckResult result = new VersionCheckResult
				{
					CurrentVersion = currentVersion
				};
				UnityWebRequest www = UnityWebRequest.Get("https://azraelgodking.github.io/SunhavenMod/versions.json");
				try
				{
					www.timeout = 10;
					yield return www.SendWebRequest();
					if ((int)www.result == 2 || (int)www.result == 3)
					{
						result.Success = false;
						result.ErrorMessage = "Network error: " + www.error;
						RecordHealthError(pluginGuid, result.ErrorMessage);
						LogWarning(result.ErrorMessage);
						onComplete?.Invoke(result);
						Object.Destroy((Object)(object)((Component)this).gameObject);
						yield break;
					}
					try
					{
						string text = www.downloadHandler.text;
						Match match = GetModPattern(pluginGuid).Match(text);
						if (!match.Success)
						{
							result.Success = false;
							result.ErrorMessage = "Mod '" + pluginGuid + "' not found in versions.json";
							RecordHealthError(pluginGuid, result.ErrorMessage);
							LogWarning(result.ErrorMessage);
							onComplete?.Invoke(result);
							Object.Destroy((Object)(object)((Component)this).gameObject);
							yield break;
						}
						string value = match.Groups[1].Value;
						result.LatestVersion = ExtractJsonString(value, "version");
						result.ModName = ExtractJsonString(value, "name");
						result.NexusUrl = ExtractJsonString(value, "nexus");
						result.Changelog = ExtractJsonString(value, "changelog");
						if (string.IsNullOrEmpty(result.LatestVersion))
						{
							result.Success = false;
							result.ErrorMessage = "Could not parse version from response";
							RecordHealthError(pluginGuid, result.ErrorMessage);
							LogWarning(result.ErrorMessage);
							onComplete?.Invoke(result);
							Object.Destroy((Object)(object)((Component)this).gameObject);
							yield break;
						}
						result.Success = true;
						result.UpdateAvailable = CompareVersions(currentVersion, result.LatestVersion) < 0;
						if (result.UpdateAvailable)
						{
							Log("Update available for " + result.ModName + ": " + currentVersion + " -> " + result.LatestVersion);
						}
						else
						{
							Log(result.ModName + " is up to date (v" + currentVersion + ")");
						}
					}
					catch (Exception ex)
					{
						result.Success = false;
						result.ErrorMessage = "Parse error: " + ex.Message;
						RecordHealthError(pluginGuid, result.ErrorMessage);
						LogError(result.ErrorMessage);
					}
				}
				finally
				{
					((IDisposable)www)?.Dispose();
				}
				onComplete?.Invoke(result);
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}

			private string ExtractJsonString(string json, string key)
			{
				Match match = ExtractFieldRegex.Match(json);
				while (match.Success)
				{
					if (string.Equals(match.Groups["key"].Value, key, StringComparison.Ordinal))
					{
						return match.Groups["value"].Value;
					}
					match = match.NextMatch();
				}
				return null;
			}
		}

		private const string VersionsUrl = "https://azraelgodking.github.io/SunhavenMod/versions.json";

		private static ManualLogSource _logger;

		private static readonly Dictionary<string, ModHealthSnapshot> HealthByPluginGuid = new Dictionary<string, ModHealthSnapshot>(StringComparer.OrdinalIgnoreCase);

		private static readonly object HealthLock = new object();

		private static readonly Dictionary<string, Regex> ModPatternCache = new Dictionary<string, Regex>(StringComparer.Ordinal);

		private static readonly object ModPatternCacheLock = new object();

		private static readonly Regex ExtractFieldRegex = new Regex("\"(?<key>[^\"]+)\"\\s*:\\s*(?:\"(?<value>[^\"]*)\"|null)", RegexOptions.Compiled);

		public static void CheckForUpdate(string pluginGuid, string currentVersion, ManualLogSource logger = null, Action<VersionCheckResult> onComplete = null)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_logger = logger;
			TouchHealth(pluginGuid);
			VersionCheckRunner versionCheckRunner = new GameObject("VersionChecker").AddComponent<VersionCheckRunner>();
			Object.DontDestroyOnLoad((Object)(object)((Component)versionCheckRunner).gameObject);
			SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(((Component)versionCheckRunner).gameObject);
			versionCheckRunner.StartCheck(pluginGuid, currentVersion, onComplete);
		}

		public static ModHealthSnapshot GetHealthSnapshot(string pluginGuid)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				return null;
			}
			lock (HealthLock)
			{
				if (!HealthByPluginGuid.TryGetValue(pluginGuid, out var value))
				{
					return null;
				}
				return new ModHealthSnapshot
				{
					PluginGuid = value.PluginGuid,
					LastCheckUtc = value.LastCheckUtc,
					ExceptionCount = value.ExceptionCount,
					LastError = value.LastError
				};
			}
		}

		public static int CompareVersions(string v1, string v2)
		{
			if (string.IsNullOrEmpty(v1) || string.IsNullOrEmpty(v2))
			{
				return 0;
			}
			v1 = v1.TrimStart('v', 'V');
			v2 = v2.TrimStart('v', 'V');
			string[] array = v1.Split(new char[1] { '.' });
			string[] array2 = v2.Split(new char[1] { '.' });
			int num = Math.Max(array.Length, array2.Length);
			for (int i = 0; i < num; i++)
			{
				int result;
				int num2 = ((i < array.Length && int.TryParse(array[i], out result)) ? result : 0);
				int result2;
				int num3 = ((i < array2.Length && int.TryParse(array2[i], out result2)) ? result2 : 0);
				if (num2 < num3)
				{
					return -1;
				}
				if (num2 > num3)
				{
					return 1;
				}
			}
			return 0;
		}

		internal static void Log(string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo((object)("[VersionChecker] " + message));
			}
		}

		internal static void LogWarning(string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogWarning((object)("[VersionChecker] " + message));
			}
		}

		internal static void LogError(string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError((object)("[VersionChecker] " + message));
			}
		}

		private static void TouchHealth(string pluginGuid)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				return;
			}
			lock (HealthLock)
			{
				if (!HealthByPluginGuid.TryGetValue(pluginGuid, out var value))
				{
					value = new ModHealthSnapshot
					{
						PluginGuid = pluginGuid
					};
					HealthByPluginGuid[pluginGuid] = value;
				}
				value.LastCheckUtc = DateTime.UtcNow;
			}
		}

		private static void RecordHealthError(string pluginGuid, string errorMessage)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				return;
			}
			lock (HealthLock)
			{
				if (!HealthByPluginGuid.TryGetValue(pluginGuid, out var value))
				{
					value = new ModHealthSnapshot
					{
						PluginGuid = pluginGuid
					};
					HealthByPluginGuid[pluginGuid] = value;
				}
				value.LastCheckUtc = DateTime.UtcNow;
				value.ExceptionCount++;
				value.LastError = errorMessage;
			}
		}

		private static Regex GetModPattern(string pluginGuid)
		{
			lock (ModPatternCacheLock)
			{
				if (!ModPatternCache.TryGetValue(pluginGuid, out var value))
				{
					value = new Regex("\"" + Regex.Escape(pluginGuid) + "\"\\s*:\\s*\\{([^}]+)\\}", RegexOptions.Compiled | RegexOptions.Singleline);
					ModPatternCache[pluginGuid] = value;
				}
				return value;
			}
		}
	}
	public static class VersionCheckerExtensions
	{
		public static void NotifyUpdateAvailable(this VersionChecker.VersionCheckResult result, ManualLogSource logger = null)
		{
			if (!result.UpdateAvailable)
			{
				return;
			}
			string text = result.ModName + " update available: v" + result.LatestVersion;
			try
			{
				Type type = ReflectionHelper.FindWishType("NotificationStack");
				if (type != null)
				{
					Type type2 = ReflectionHelper.FindType("SingletonBehaviour`1", "Wish");
					if (type2 != null)
					{
						object obj = type2.MakeGenericType(type).GetProperty("Instance")?.GetValue(null);
						if (obj != null)
						{
							MethodInfo method = type.GetMethod("SendNotification", new Type[5]
							{
								typeof(string),
								typeof(int),
								typeof(int),
								typeof(bool),
								typeof(bool)
							});
							if (method != null)
							{
								method.Invoke(obj, new object[5] { text, 0, 1, false, true });
								return;
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				if (logger != null)
				{
					logger.LogWarning((object)("Failed to send native notification: " + ex.Message));
				}
			}
			if (logger != null)
			{
				logger.LogWarning((object)("[UPDATE AVAILABLE] " + text));
			}
			if (!string.IsNullOrEmpty(result.NexusUrl) && logger != null)
			{
				logger.LogWarning((object)("Download at: " + result.NexusUrl));
			}
		}
	}
	public static class SceneRootSurvivor
	{
		private static readonly object Lock = new object();

		private static readonly List<string> NoKillSubstrings = new List<string>();

		private static Harmony _harmony;

		public static void TryRegisterPersistentRunnerGameObject(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				TryAddNoKillListSubstring(((Object)go).name);
			}
		}

		public static void TryAddNoKillListSubstring(string nameSubstring)
		{
			if (string.IsNullOrEmpty(nameSubstring))
			{
				return;
			}
			lock (Lock)
			{
				bool flag = false;
				for (int i = 0; i < NoKillSubstrings.Count; i++)
				{
					if (string.Equals(NoKillSubstrings[i], nameSubstring, StringComparison.OrdinalIgnoreCase))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					NoKillSubstrings.Add(nameSubstring);
				}
			}
			EnsurePatched();
		}

		private static void EnsurePatched()
		{
			//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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00a3: Expected O, but got Unknown
			if (_harmony != null)
			{
				return;
			}
			lock (Lock)
			{
				if (_harmony == null)
				{
					MethodInfo methodInfo = AccessTools.Method(typeof(Scene), "GetRootGameObjects", Type.EmptyTypes, (Type[])null);
					if (!(methodInfo == null))
					{
						string text = typeof(SceneRootSurvivor).Assembly.GetName().Name ?? "Unknown";
						Harmony val = new Harmony("SunhavenMods.SceneRootSurvivor." + text);
						val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(SceneRootSurvivor), "OnGetRootGameObjectsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						_harmony = val;
					}
				}
			}
		}

		private static void OnGetRootGameObjectsPostfix(ref GameObject[] __result)
		{
			if (__result == null || __result.Length == 0)
			{
				return;
			}
			List<string> list;
			lock (Lock)
			{
				if (NoKillSubstrings.Count == 0)
				{
					return;
				}
				list = new List<string>(NoKillSubstrings);
			}
			List<GameObject> list2 = new List<GameObject>(__result);
			for (int i = 0; i < list.Count; i++)
			{
				string noKill = list[i];
				list2.RemoveAll((GameObject a) => (Object)(object)a != (Object)null && ((Object)a).name.IndexOf(noKill, StringComparison.OrdinalIgnoreCase) >= 0);
			}
			__result = list2.ToArray();
		}
	}
	public static class ReflectionHelper
	{
		public static readonly BindingFlags AllBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy;

		public static Type FindType(string typeName, params string[] namespaces)
		{
			Type type = AccessTools.TypeByName(typeName);
			if (type != null)
			{
				return type;
			}
			for (int i = 0; i < namespaces.Length; i++)
			{
				type = AccessTools.TypeByName(namespaces[i] + "." + typeName);
				if (type != null)
				{
					return type;
				}
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					type = assembly.GetTypes().FirstOrDefault((Type t) => t.Name == typeName || t.FullName == typeName);
					if (type != null)
					{
						return type;
					}
				}
				catch (ReflectionTypeLoadException)
				{
				}
			}
			return null;
		}

		public static Type FindWishType(string typeName)
		{
			return FindType(typeName, "Wish");
		}

		public static object GetStaticValue(Type type, string memberName)
		{
			if (type == null)
			{
				return null;
			}
			PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
			if (property != null && property.GetMethod != null)
			{
				return property.GetValue(null);
			}
			FieldInfo field = type.GetField(memberName, AllBindingFlags);
			if (field != null)
			{
				return field.GetValue(null);
			}
			return null;
		}

		public static object GetSingletonInstance(Type type)
		{
			if (type == null)
			{
				return null;
			}
			string[] array = new string[5] { "Instance", "instance", "_instance", "Singleton", "singleton" };
			foreach (string memberName in array)
			{
				object staticValue = GetStaticValue(type, memberName);
				if (staticValue != null)
				{
					return staticValue;
				}
			}
			return null;
		}

		public static object GetInstanceValue(object instance, string memberName)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			while (type != null)
			{
				PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
				if (property != null && property.GetMethod != null)
				{
					return property.GetValue(instance);
				}
				FieldInfo field = type.GetField(memberName, AllBindingFlags);
				if (field != null)
				{
					return field.GetValue(instance);
				}
				type = type.BaseType;
			}
			return null;
		}

		public static bool SetInstanceValue(object instance, string memberName, object value)
		{
			if (instance == null)
			{
				return false;
			}
			Type type = instance.GetType();
			while (type != null)
			{
				PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
				if (property != null && property.SetMethod != null)
				{
					property.SetValue(instance, value);
					return true;
				}
				FieldInfo field = type.GetField(memberName, AllBindingFlags);
				if (field != null)
				{
					field.SetValue(instance, value);
					return true;
				}
				type = type.BaseType;
			}
			return false;
		}

		public static object InvokeMethod(object instance, string methodName, params object[] args)
		{
			if (instance == null)
			{
				return null;
			}
			Type type = instance.GetType();
			Type[] array = args?.Select((object a) => a?.GetType() ?? typeof(object)).ToArray() ?? Type.EmptyTypes;
			MethodInfo methodInfo = AccessTools.Method(type, methodName, array, (Type[])null);
			if (methodInfo == null)
			{
				methodInfo = type.GetMethod(methodName, AllBindingFlags);
			}
			if (methodInfo == null)
			{
				return null;
			}
			return methodInfo.Invoke(instance, args);
		}

		public static object InvokeStaticMethod(Type type, string methodName, params object[] args)
		{
			if (type == null)
			{
				return null;
			}
			Type[] array = args?.Select((object a) => a?.GetType() ?? typeof(object)).ToArray() ?? Type.EmptyTypes;
			MethodInfo methodInfo = AccessTools.Method(type, methodName, array, (Type[])null);
			if (methodInfo == null)
			{
				methodInfo = type.GetMethod(methodName, AllBindingFlags);
			}
			if (methodInfo == null)
			{
				return null;
			}
			return methodInfo.Invoke(null, args);
		}

		public static FieldInfo[] GetAllFields(Type type)
		{
			if (type == null)
			{
				return Array.Empty<FieldInfo>();
			}
			FieldInfo[] fields = type.GetFields(AllBindingFlags);
			IEnumerable<FieldInfo> second;
			if (!(type.BaseType != null) || !(type.BaseType != typeof(object)))
			{
				second = Enumerable.Empty<FieldInfo>();
			}
			else
			{
				IEnumerable<FieldInfo> allFields = GetAllFields(type.BaseType);
				second = allFields;
			}
			return fields.Concat(second).Distinct().ToArray();
		}

		public static PropertyInfo[] GetAllProperties(Type type)
		{
			if (type == null)
			{
				return Array.Empty<PropertyInfo>();
			}
			PropertyInfo[] properties = type.GetProperties(AllBindingFlags);
			IEnumerable<PropertyInfo> second;
			if (!(type.BaseType != null) || !(type.BaseType != typeof(object)))
			{
				second = Enumerable.Empty<PropertyInfo>();
			}
			else
			{
				IEnumerable<PropertyInfo> allProperties = GetAllProperties(type.BaseType);
				second = allProperties;
			}
			return (from p in properties.Concat(second)
				group p by p.Name into g
				select g.First()).ToArray();
		}

		public static T TryGetValue<T>(object instance, string memberName, T defaultValue = default(T))
		{
			try
			{
				object instanceValue = GetInstanceValue(instance, memberName);
				if (instanceValue is T result)
				{
					return result;
				}
				if (instanceValue != null && typeof(T).IsAssignableFrom(instanceValue.GetType()))
				{
					return (T)instanceValue;
				}
				return defaultValue;
			}
			catch
			{
				return defaultValue;
			}
		}
	}
	public static class GUIStyleHelper
	{
		public static class SunHavenColors
		{
			public static readonly Color Parchment = new Color(0.96f, 0.93f, 0.85f);

			public static readonly Color ParchmentDark = new Color(0.85f, 0.82f, 0.72f);

			public static readonly Color Wood = new Color(0.45f, 0.32f, 0.22f);

			public static readonly Color WoodLight = new Color(0.55f, 0.42f, 0.32f);

			public static readonly Color Gold = new Color(0.85f, 0.65f, 0.13f);

			public static readonly Color GoldDark = new Color(0.72f, 0.53f, 0.04f);

			public static readonly Color TextDark = new Color(0.2f, 0.15f, 0.1f);

			public static readonly Color TextLight = new Color(0.95f, 0.92f, 0.85f);

			public static readonly Color Success = new Color(0.2f, 0.6f, 0.2f);

			public static readonly Color Warning = new Color(0.8f, 0.6f, 0.2f);

			public static readonly Color Error = new Color(0.8f, 0.2f, 0.2f);

			public static readonly Color TransparentDark = new Color(0f, 0f, 0f, 0.7f);

			public static readonly Color TransparentLight = new Color(1f, 1f, 1f, 0.1f);
		}

		public static Texture2D MakeSolidTexture(Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		public static Texture2D MakeSolidTexture(int width, int height, Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = color;
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		public static Texture2D MakeGradientTexture(int height, Color topColor, Color bottomColor)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, height, (TextureFormat)4, false);
			for (int i = 0; i < height; i++)
			{
				float num = (float)i / (float)(height - 1);
				val.SetPixel(0, i, Color.Lerp(bottomColor, topColor, num));
			}
			val.Apply();
			return val;
		}

		public static Texture2D MakeBorderedTexture(int width, int height, Color fillColor, Color borderColor, int borderWidth = 1)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0048: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[width * height];
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					bool flag = j < borderWidth || j >= width - borderWidth || i < borderWidth || i >= height - borderWidth;
					array[i * width + j] = (flag ? borderColor : fillColor);
				}
			}
			val.SetPixels(array);
			val.Apply();
			return val;
		}

		public static GUIStyle CreateWindowStyle(Texture2D background, int padding = 10)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0046: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.window);
			val.normal.background = background;
			val.onNormal.background = background;
			val.padding = new RectOffset(padding, padding, padding, padding);
			val.border = new RectOffset(4, 4, 4, 4);
			return val;
		}

		public static GUIStyle CreateLabelStyle(Color textColor, int fontSize = 14, TextAnchor alignment = 3, Texture2D background = null)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = fontSize,
				alignment = alignment,
				wordWrap = true
			};
			val.normal.textColor = textColor;
			GUIStyle val2 = val;
			if ((Object)(object)background != (Object)null)
			{
				val2.normal.background = background;
			}
			return val2;
		}

		public static GUIStyle CreateButtonStyle(Color textColor, Texture2D normalBg, Texture2D hoverBg = null, int fontSize = 14)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.button)
			{
				fontSize = fontSize,
				alignment = (TextAnchor)4
			};
			val.normal.textColor = textColor;
			val.normal.background = normalBg;
			val.hover.textColor = textColor;
			val.hover.background = hoverBg ?? normalBg;
			val.active.textColor = textColor;
			val.active.background = normalBg;
			return val;
		}

		public static GUIStyle CreateTextFieldStyle(Color textColor, Color bgColor, int fontSize = 14, int padding = 4)
		{
			//IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			Texture2D background = MakeSolidTexture(bgColor);
			GUIStyle val = new GUIStyle(GUI.skin.textField)
			{
				fontSize = fontSize,
				padding = new RectOffset(padding, padding, padding, padding)
			};
			val.normal.textColor = textColor;
			val.normal.background = background;
			val.focused.textColor = textColor;
			val.focused.background = background;
			val.hover.textColor = textColor;
			val.hover.background = background;
			return val;
		}

		public static GUIStyle CreateHeaderStyle(Color textColor, int fontSize = 18, TextAnchor alignment = 4)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				fontSize = fontSize,
				fontStyle = (FontStyle)1,
				alignment = alignment
			};
			val.normal.textColor = textColor;
			return val;
		}

		public static GUIStyle CreateScrollViewStyle(Texture2D background)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(GUI.skin.scrollView);
			val.normal.background = background;
			return val;
		}
	}
	public static class TextInputFocusGuard
	{
		private const float DefaultPollIntervalSeconds = 0.25f;

		private static float _nextPollTime = -1f;

		private static bool _cachedDefer;

		private static bool _tmpTypeLookupDone;

		private static Type _tmpInputFieldType;

		private static bool _qcLookupDone;

		private static Type _qcType;

		private static PropertyInfo _qcInstanceProp;

		private static PropertyInfo _qcIsActiveProp;

		private static FieldInfo _qcIsActiveField;

		public static bool ShouldDeferModHotkeys(ManualLogSource debugLog = null, float pollIntervalSeconds = 0.25f)
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (realtimeSinceStartup < _nextPollTime)
			{
				return _cachedDefer;
			}
			_nextPollTime = realtimeSinceStartup + Mathf.Max(0.05f, pollIntervalSeconds);
			bool flag = false;
			try
			{
				if (GUIUtility.keyboardControl != 0)
				{
					flag = true;
				}
				if (!flag)
				{
					EventSystem current = EventSystem.current;
					GameObject val = ((current != null) ? current.currentSelectedGameObject : null);
					if ((Object)(object)val != (Object)null)
					{
						if ((Object)(object)val.GetComponent<InputField>() != (Object)null)
						{
							flag = true;
						}
						else if (TryGetTmpInputField(val))
						{
							flag = true;
						}
					}
				}
				if (!flag && IsQuantumConsoleActive(debugLog))
				{
					flag = true;
				}
			}
			catch (Exception ex)
			{
				if (debugLog != null)
				{
					debugLog.LogDebug((object)("[TextInputFocusGuard] " + ex.Message));
				}
			}
			_cachedDefer = flag;
			return flag;
		}

		private static bool TryGetTmpInputField(GameObject go)
		{
			if (!_tmpTypeLookupDone)
			{
				_tmpTypeLookupDone = true;
				_tmpInputFieldType = AccessTools.TypeByName("TMPro.TMP_InputField");
			}
			if (_tmpInputFieldType == null)
			{
				return false;
			}
			return (Object)(object)go.GetComponent(_tmpInputFieldType) != (Object)null;
		}

		private static bool IsQuantumConsoleActive(ManualLogSource debugLog)
		{
			try
			{
				if (!_qcLookupDone)
				{
					_qcLookupDone = true;
					_qcType = AccessTools.TypeByName("QFSW.QC.QuantumConsole");
					if (_qcType != null)
					{
						_qcInstanceProp = AccessTools.Property(_qcType, "Instance");
						_qcIsActiveProp = AccessTools.Property(_qcType, "IsActive");
						_qcIsActiveField = AccessTools.Field(_qcType, "isActive") ?? AccessTools.Field(_qcType, "_isActive");
					}
				}
				if (_qcType == null)
				{
					return false;
				}
				object obj = _qcInstanceProp?.GetValue(null);
				if (obj == null)
				{
					return false;
				}
				if (_qcIsActiveProp != null && _qcIsActiveProp.PropertyType == typeof(bool))
				{
					return (bool)_qcIsActiveProp.GetValue(obj);
				}
				if (_qcIsActiveField != null && _qcIsActiveField.FieldType == typeof(bool))
				{
					return (bool)_qcIsActiveField.GetValue(obj);
				}
			}
			catch (Exception ex)
			{
				if (debugLog != null)
				{
					debugLog.LogDebug((object)("[TextInputFocusGuard] Quantum Console focus check failed: " + ex.Message));
				}
			}
			return false;
		}
	}
}
namespace HavensAlmanac
{
	[BepInPlugin("com.azraelgodking.havensalmanac", "Haven's Almanac", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__OnOvernightComplete;

			public static Func<Type, object> <1>__ResolveSingletonInstance;
		}

		private static AlmanacDataAggregator _staticAggregator;

		private static AlmanacHUD _staticHUD;

		private static AlmanacDashboard _staticDashboard;

		private static DailyBriefing _staticBriefing;

		private static GameObject _persistentRunner;

		private static AlmanacPersistentRunner _persistentRunnerComponent;

		private static bool _overnightHooked;

		private static UnityAction _overnightCallback;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static ConfigFile ConfigFile { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigFile = CreateNamedConfig();
			ConfigFileHelper.ReplacePluginConfig((BaseUnityPlugin)(object)this, ConfigFile, (Action<string>)Log.LogWarning);
			Log.LogInfo((object)"Loading Haven's Almanac v1.3.0");
			AlmanacConfig.Initialize(ConfigFile);
			CreatePersistentRunner();
			_staticAggregator = new AlmanacDataAggregator();
			InitializeIntegrations();
			CreateUIComponents();
			ApplyPatches();
			SceneManager.sceneLoaded += OnSceneLoaded;
			if (AlmanacConfig.CheckForUpdates.Value)
			{
				VersionChecker.CheckForUpdate("com.azraelgodking.havensalmanac", "1.3.0", Log, delegate(VersionChecker.VersionCheckResult result)
				{
					result.NotifyUpdateAvailable(Log);
				});
			}
			int integrationModCount = _staticAggregator.IntegrationModCount;
			Log.LogInfo((object)string.Format("{0} loaded with {1} integration{2} + built-in Mod Health telemetry", "Haven's Almanac", integrationModCount, (integrationModCount == 1) ? string.Empty : "s"));
			if (integrationModCount == 0)
			{
				Log.LogWarning((object)"No supported companion mods detected. Haven's Almanac is most useful alongside SunhavenTodo, Birthday Reminder, Museum Tracker, Senpai's Chest, The Vault, Haven's Birthright, Haven Dev Tools, or Crop Optimizer.");
			}
		}

		private static ConfigFile CreateNamedConfig()
		{
			return ConfigFileHelper.CreateNamedConfig("com.azraelgodking.havensalmanac", "HavensAlmanac.cfg", delegate(string message)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)message);
				}
			});
		}

		private void CreatePersistentRunner()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (!((Object)(object)_persistentRunner != (Object)null) || !((Object)(object)_persistentRunnerComponent != (Object)null))
			{
				_persistentRunner = new GameObject("HavensAlmanac_PersistentRunner");
				Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
				((Object)_persistentRunner).hideFlags = (HideFlags)61;
				SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
				_persistentRunnerComponent = _persistentRunner.AddComponent<AlmanacPersistentRunner>();
				Log.LogInfo((object)"[PersistentRunner] Created");
			}
		}

		private void InitializeIntegrations()
		{
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			_staticAggregator.RegisterProvider(new ModHealthDataProvider());
			TryRegisterProvider(pluginInfos, "com.azraelgodking.sunhaventodo", () => new TodoDataProvider(), "SunhavenTodo");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.squirrelsbirthdayreminder", () => new BirthdayDataProvider(), "BirthdayReminder");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.sunhavenmuseumutilitytracker", () => new MuseumDataProvider(), "S.M.U.T.");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.senpaischest", () => new ChestDataProvider(), "SenpaisChest");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.thevault", () => new VaultDataProvider(), "TheVault");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.havensbirthright", () => new BirthrightDataProvider(), "HavensBirthright");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.havendevtools", () => new DevToolsDataProvider(), "HavenDevTools");
			TryRegisterProvider(pluginInfos, "com.azraelgodking.cropoptimizer", () => new CropOptimizerDataProvider(), "CropOptimizer");
		}

		private void TryRegisterProvider(Dictionary<string, PluginInfo> pluginInfos, string guid, Func<IModDataProvider> factory, string displayName)
		{
			try
			{
				if (pluginInfos.ContainsKey(guid))
				{
					_staticAggregator.RegisterProvider(factory());
					Log.LogInfo((object)("[Integration] " + displayName + " detected and registered"));
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Integration] Failed to load " + displayName + " provider: " + ex.Message));
			}
		}

		private void CreateUIComponents()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_007a: 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_0085: Expected O, but got Unknown
			try
			{
				GameObject val = new GameObject("HavensAlmanac_HUD");
				Object.DontDestroyOnLoad((Object)val);
				_staticHUD = val.AddComponent<AlmanacHUD>();
				_staticHUD.Initialize(_staticAggregator);
				_staticHUD.SetScale(AlmanacConfig.StaticUIScale);
				WireHudPositionPersistence();
				GameObject val2 = new GameObject("HavensAlmanac_Dashboard");
				Object.DontDestroyOnLoad((Object)val2);
				_staticDashboard = val2.AddComponent<AlmanacDashboard>();
				_staticDashboard.Initialize(_staticAggregator);
				_staticDashboard.SetScale(AlmanacConfig.StaticUIScale);
				GameObject val3 = new GameObject("HavensAlmanac_Briefing");
				Object.DontDestroyOnLoad((Object)val3);
				_staticBriefing = val3.AddComponent<DailyBriefing>();
				_staticBriefing.Initialize(_staticAggregator);
				_staticBriefing.SetScale(AlmanacConfig.StaticUIScale);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"[UI] Error creating UI components: {arg}");
			}
		}

		public void ApplyUIScaleToAllUI()
		{
			float staticUIScale = AlmanacConfig.StaticUIScale;
			_staticHUD?.SetScale(staticUIScale);
			_staticDashboard?.SetScale(staticUIScale);
			_staticBriefing?.SetScale(staticUIScale);
		}

		public static void EnsureUIComponentsExist()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			try
			{
				if ((Object)(object)_persistentRunner == (Object)null || (Object)(object)_persistentRunnerComponent == (Object)null)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)"[EnsureUI] Recreating PersistentRunner...");
					}
					_persistentRunner = new GameObject("HavensAlmanac_PersistentRunner");
					Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
					((Object)_persistentRunner).hideFlags = (HideFlags)61;
					SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
					_persistentRunnerComponent = _persistentRunner.AddComponent<AlmanacPersistentRunner>();
				}
				if ((Object)(object)_staticHUD == (Object)null)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"[EnsureUI] Recreating HUD...");
					}
					GameObject val = new GameObject("HavensAlmanac_HUD");
					Object.DontDestroyOnLoad((Object)val);
					_staticHUD = val.AddComponent<AlmanacHUD>();
					_staticHUD.Initialize(_staticAggregator);
					_staticHUD.SetScale(AlmanacConfig.StaticUIScale);
					WireHudPositionPersistence();
				}
				if ((Object)(object)_staticDashboard == (Object)null)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)"[EnsureUI] Recreating Dashboard...");
					}
					GameObject val2 = new GameObject("HavensAlmanac_Dashboard");
					Object.DontDestroyOnLoad((Object)val2);
					_staticDashboard = val2.AddComponent<AlmanacDashboard>();
					_staticDashboard.Initialize(_staticAggregator);
					_staticDashboard.SetScale(AlmanacConfig.StaticUIScale);
				}
				if ((Object)(object)_staticBriefing == (Object)null)
				{
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogInfo((object)"[EnsureUI] Recreating Briefing...");
					}
					GameObject val3 = new GameObject("HavensAlmanac_Briefing");
					Object.DontDestroyOnLoad((Object)val3);
					_staticBriefing = val3.AddComponent<DailyBriefing>();
					_staticBriefing.Initialize(_staticAggregator);
					_staticBriefing.SetScale(AlmanacConfig.StaticUIScale);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log5 = Log;
				if (log5 != null)
				{
					log5.LogError((object)("[EnsureUI] Error: " + ex.Message));
				}
			}
		}

		private void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			_harmony = new Harmony("com.azraelgodking.havensalmanac");
			try
			{
				Type type = AccessTools.TypeByName("Wish.Player");
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "InitializeAsOwner", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), "OnPlayerInitialized", (Type[])null, (Type[])null);
						_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Applied player initialization patch");
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Failed to apply patches: " + ex.Message));
			}
		}

		private static void OnPlayerInitialized(object __instance)
		{
			try
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"[Almanac] Player initialized");
				}
				EnsureUIComponentsExist();
				_staticAggregator?.RefreshAll();
				ResetOvernightHook();
				TryHookOvernightEvent();
				_staticBriefing?.ShowBriefing();
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogError((object)("Error in OnPlayerInitialized: " + ex.Message));
				}
			}
		}

		public static void ResetOvernightHook()
		{
			_overnightHooked = false;
			_overnightCallback = null;
		}

		public static void TryHookOvernightEvent()
		{
			//IL_001a: 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_0025: Expected O, but got Unknown
			object obj = <>O.<0>__OnOvernightComplete;
			if (obj == null)
			{
				UnityAction val = OnOvernightComplete;
				<>O.<0>__OnOvernightComplete = val;
				obj = (object)val;
			}
			OvernightHookUtility.TryHookOvernightEvent(ref _overnightHooked, ref _overnightCallback, (UnityAction)obj, ResolveSingletonInstance, delegate(string message)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogInfo((object)message);
				}
			}, delegate(string message)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)message);
				}
			});
		}

		private static void OnOvernightComplete()
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"[Almanac] Day started - refreshing data and showing briefing");
			}
			_staticAggregator?.RefreshAll();
			_staticBriefing?.ShowBriefing();
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (((Scene)(ref scene)).name == "MainMenu" || ((Scene)(ref scene)).name == "Bootstrap")
			{
				Log.LogInfo((object)"[Almanac] Main menu detected - hiding UI");
				_staticHUD?.Hide();
				_staticDashboard?.Hide();
				_staticBriefing?.Hide();
			}
			else
			{
				EnsureUIComponentsExist();
			}
		}

		private static void WireHudPositionPersistence()
		{
			if ((Object)(object)_staticHUD == (Object)null)
			{
				return;
			}
			_staticHUD.OnPositionChanged = delegate(float x, float y)
			{
				AlmanacConfig.StaticHUDPositionX = x;
				AlmanacConfig.StaticHUDPositionY = y;
				ConfigEntry<float> hUDPositionX = AlmanacConfig.HUDPositionX;
				if (hUDPositionX != null)
				{
					((ConfigEntryBase)hUDPositionX).SetSerializedValue(x.ToString());
				}
				ConfigEntry<float> hUDPositionY = AlmanacConfig.HUDPositionY;
				if (hUDPositionY != null)
				{
					((ConfigEntryBase)hUDPositionY).SetSerializedValue(y.ToString());
				}
			};
		}

		private static object ResolveSingletonInstance(Type targetType)
		{
			if (targetType == null)
			{
				return null;
			}
			Type type = AccessTools.TypeByName("Wish.SingletonBehaviour`1");
			if (type == null)
			{
				return null;
			}
			return AccessTools.Property(type.MakeGenericType(targetType), "Instance")?.GetValue(null);
		}

		internal static AlmanacDataAggregator GetDataAggregator()
		{
			return _staticAggregator;
		}

		internal static AlmanacHUD GetAlmanacHUD()
		{
			return _staticHUD;
		}

		internal static AlmanacDashboard GetAlmanacDashboard()
		{
			return _staticDashboard;
		}

		internal static DailyBriefing GetDailyBriefing()
		{
			return _staticBriefing;
		}

		private void OnDestroy()
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"Plugin OnDestroy called - static references preserved");
			}
		}
	}
	public class AlmanacPersistentRunner : MonoBehaviour
	{
		private void Update()
		{
			DetectHotkeys();
		}

		private void DetectHotkeys()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!TextInputFocusGuard.ShouldDeferModHotkeys(Plugin.Log))
			{
				bool flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
				if (Input.GetKeyDown(AlmanacConfig.StaticDashboardToggleKey) && (!AlmanacConfig.StaticDashboardRequireCtrl || flag))
				{
					Plugin.EnsureUIComponentsExist();
					Plugin.GetAlmanacDashboard()?.Toggle();
				}
				if (Input.GetKeyDown(AlmanacConfig.StaticHUDToggleKey))
				{
					Plugin.EnsureUIComponentsExist();
					Plugin.GetAlmanacHUD()?.Toggle();
				}
			}
		}

		private void OnDestroy()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string text = (((Scene)(ref activeScene)).name ?? string.Empty).ToLowerInvariant();
			if (!Application.isPlaying || text.Contains("menu") || text.Contains("title"))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"[PersistentRunner] OnDestroy during app quit/menu unload (expected).");
				}
			}
			else
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[PersistentRunner] OnDestroy outside quit/menu (unexpected).");
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.azraelgodking.havensalmanac";

		public const string PLUGIN_NAME = "Haven's Almanac";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace HavensAlmanac.UI
{
	public class AlmanacDashboard : MonoBehaviour
	{
		private const int WINDOW_ID = 98781;

		private const float BASE_WIDTH = 500f;

		private const float BASE_HEIGHT = 550f;

		private float _scale = 1f;

		private AlmanacDataAggregator _aggregator;

		private Rect _windowRect;

		private bool _isVisible;

		private Vector2 _scrollPosition;

		private Dictionary<string, bool> _sectionExpanded = new Dictionary<string, bool>();

		private bool _stylesInitialized;

		private GUIStyle _windowStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _sectionHeaderStyle;

		private GUIStyle _sectionHeaderExpandedStyle;

		private GUIStyle _contentStyle;

		private GUIStyle _closeButtonStyle;

		private GUIStyle _noModsStyle;

		private Texture2D _bgTexture;

		private Texture2D _sectionBgTexture;

		private Texture2D _sectionExpandedBgTexture;

		private float Width => 500f * _scale;

		private float Height => 550f * _scale;

		public bool IsVisible => _isVisible;

		private float Scaled(float value)
		{
			return value * _scale;
		}

		private int ScaledFont(int baseSize)
		{
			return Mathf.Max(8, Mathf.RoundToInt((float)baseSize * _scale));
		}

		private int ScaledInt(float value)
		{
			return Mathf.RoundToInt(value * _scale);
		}

		public void Initialize(AlmanacDataAggregator aggregator)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			_aggregator = aggregator;
			_windowRect = new Rect(((float)Screen.width - Width) / 2f, ((float)Screen.height - Height) / 2f, Width, Height);
		}

		public void SetScale(float scale)
		{
			_scale = Mathf.Clamp(scale, 0.5f, 2.5f);
			_stylesInitialized = false;
		}

		public void Show()
		{
			_aggregator?.RefreshAll();
			_isVisible = true;
		}

		public void Hide()
		{
			_isVisible = false;
		}

		public void Toggle()
		{
			if (_isVisible)
			{
				Hide();
			}
			else
			{
				Show();
			}
		}

		private void Update()
		{
			if (_isVisible && Input.GetKeyDown((KeyCode)27))
			{
				Hide();
			}
		}

		private void OnGUI()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (_isVisible && _aggregator != null)
			{
				if (!_stylesInitialized)
				{
					InitializeStyles();
				}
				_windowRect = GUI.Window(98781, _windowRect, new WindowFunction(DrawWindow), "", _windowStyle);
			}
		}

		private void DrawWindow(int id)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_02a1: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Haven's Almanac - Dashboard", _titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("X", _closeButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(Scaled(24f)),
				GUILayout.Height(Scaled(24f))
			}))
			{
				Hide();
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(Scaled(6f));
			if (_aggregator.IntegrationModCount == 0)
			{
				GUILayout.Label("No supported companion mods detected.", _noModsStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Install any of: SunhavenTodo, Birthday Reminder, Museum Tracker, Senpai's Chest, The Vault, Haven's Birthright, Haven Dev Tools, or Crop Optimizer.", _noModsStyle, Array.Empty<GUILayoutOption>());
				GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, Scaled(30f)));
				return;
			}
			_scrollPosition = GUILayout.BeginScrollView(_scrollPosition, Array.Empty<GUILayoutOption>());
			foreach (IModDataProvider provider in _aggregator.Providers)
			{
				if (!_sectionExpanded.ContainsKey(provider.ModName))
				{
					_sectionExpanded[provider.ModName] = true;
				}
				bool flag = _sectionExpanded[provider.ModName];
				GUIStyle val = (flag ? _sectionHeaderExpandedStyle : _sectionHeaderStyle);
				string text = (flag ? "▼" : "▶");
				string providerError = _aggregator.GetProviderError(provider);
				string text2 = ((providerError != null) ? " [!]" : "");
				if (GUILayout.Button(text + "  " + provider.ModIcon + "  " + provider.ModName + text2 + "  —  " + provider.HudSummary, val, Array.Empty<GUILayoutOption>()))
				{
					_sectionExpanded[provider.ModName] = !flag;
				}
				if (flag)
				{
					GUILayout.BeginVertical(_contentStyle, Array.Empty<GUILayoutOption>());
					try
					{
						if (providerError != null)
						{
							GUILayout.Label("[!] Last refresh error: " + providerError, _contentStyle, Array.Empty<GUILayoutOption>());
						}
						provider.DrawDashboardSection();
					}
					catch (Exception ex)
					{
						GUILayout.Label("Error: " + ex.Message, Array.Empty<GUILayoutOption>());
					}
					GUILayout.EndVertical();
				}
				GUILayout.Space(Scaled(4f));
			}
			GUILayout.EndScrollView();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, Scaled(30f)));
		}

		private void InitializeStyles()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_012b: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_0193: 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)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Expected O, but got Unknown
			//IL_0201: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Expected O, but got Unknown
			//IL_02d4: Expected O, but got Unknown
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Expected O, but got Unknown
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			_stylesInitialized = true;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.12f, 0.1f, 0.08f, 0.96f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.18f, 0.15f, 0.11f, 0.9f);
			Color color3 = default(Color);
			((Color)(ref color3))..ctor(0.22f, 0.18f, 0.13f, 0.9f);
			Color textColor = default(Color);
			((Color)(ref textColor))..ctor(0.95f, 0.85f, 0.55f);
			Color textColor2 = default(Color);
			((Color)(ref textColor2))..ctor(0.91f, 0.87f, 0.82f);
			_bgTexture = GUIStyleHelper.MakeSolidTexture(color);
			_sectionBgTexture = GUIStyleHelper.MakeSolidTexture(color2);
			_sectionExpandedBgTexture = GUIStyleHelper.MakeSolidTexture(color3);
			_windowStyle = new GUIStyle(GUI.skin.window)
			{
				padding = new RectOffset(ScaledInt(12f), ScaledInt(12f), ScaledInt(10f), ScaledInt(10f)),
				border = new RectOffset(ScaledInt(2f), ScaledInt(2f), ScaledInt(2f), ScaledInt(2f))
			};
			_windowStyle.normal.background = _bgTexture;
			_windowStyle.onNormal.background = _bgTexture;
			_titleStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(16),
				alignment = (TextAnchor)3
			};
			_titleStyle.normal.textColor = textColor;
			_sectionHeaderStyle = new GUIStyle(GUI.skin.button)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(13),
				alignment = (TextAnchor)3,
				padding = new RectOffset(ScaledInt(8f), ScaledInt(8f), ScaledInt(6f), ScaledInt(6f))
			};
			_sectionHeaderStyle.normal.background = _sectionBgTexture;
			_sectionHeaderStyle.normal.textColor = textColor2;
			_sectionHeaderStyle.hover.background = _sectionExpandedBgTexture;
			_sectionHeaderStyle.hover.textColor = textColor;
			_sectionHeaderExpandedStyle = new GUIStyle(_sectionHeaderStyle);
			_sectionHeaderExpandedStyle.normal.background = _sectionExpandedBgTexture;
			_sectionHeaderExpandedStyle.normal.textColor = textColor;
			_contentStyle = new GUIStyle(GUI.skin.box)
			{
				padding = new RectOffset(ScaledInt(12f), ScaledInt(12f), ScaledInt(8f), ScaledInt(8f))
			};
			_contentStyle.normal.textColor = textColor2;
			_closeButtonStyle = new GUIStyle(GUI.skin.button)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(14),
				alignment = (TextAnchor)4
			};
			_noModsStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = ScaledFont(13),
				fontStyle = (FontStyle)2,
				alignment = (TextAnchor)4,
				wordWrap = true
			};
			_noModsStyle.normal.textColor = new Color(0.7f, 0.6f, 0.5f);
		}

		private void OnDestroy()
		{
			if ((Object)(object)_bgTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_bgTexture);
			}
			if ((Object)(object)_sectionBgTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_sectionBgTexture);
			}
			if ((Object)(object)_sectionExpandedBgTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_sectionExpandedBgTexture);
			}
		}
	}
	public class AlmanacHUD : MonoBehaviour
	{
		private const int WINDOW_ID = 98780;

		private const float BASE_WIDTH = 260f;

		private const float BASE_MIN_HEIGHT = 60f;

		private const float REFRESH_INTERVAL = 5f;

		private float _scale = 1f;

		private AlmanacDataAggregator _aggregator;

		private Rect _windowRect;

		private bool _isVisible = true;

		private float _refreshTimer;

		private bool _stylesInitialized;

		private GUIStyle _windowStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _iconStyle;

		private GUIStyle _summaryStyle;

		private GUIStyle _noModsStyle;

		private Texture2D _bgTexture;

		private Texture2D _headerTexture;

		public Action<float, float> OnPositionChanged;

		private float Width => 260f * _scale;

		private float MinHeight => 60f * _scale;

		public bool IsVisible => _isVisible;

		private float Scaled(float value)
		{
			return value * _scale;
		}

		private int ScaledFont(int baseSize)
		{
			return Mathf.Max(8, Mathf.RoundToInt((float)baseSize * _scale));
		}

		private int ScaledInt(float value)
		{
			return Mathf.RoundToInt(value * _scale);
		}

		public void Initialize(AlmanacDataAggregator aggregator)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			_aggregator = aggregator;
			float num = AlmanacConfig.StaticHUDPositionX;
			float num2 = AlmanacConfig.StaticHUDPositionY;
			if (num < 0f || num2 < 0f)
			{
				num = (float)Screen.width - Width - Scaled(20f);
				num2 = Scaled(80f);
			}
			_windowRect = new Rect(num, num2, Width, MinHeight);
		}

		public void SetScale(float scale)
		{
			_scale = Mathf.Clamp(scale, 0.5f, 2.5f);
			_stylesInitialized = false;
		}

		public void Show()
		{
			_isVisible = true;
		}

		public void Hide()
		{
			_isVisible = false;
		}

		public void Toggle()
		{
			_isVisible = !_isVisible;
		}

		public void SetPosition(float x, float y)
		{
			((Rect)(ref _windowRect)).x = x;
			((Rect)(ref _windowRect)).y = y;
		}

		private void Update()
		{
			if (_isVisible && _aggregator != null)
			{
				_refreshTimer += Time.unscaledDeltaTime;
				if (_refreshTimer >= 5f)
				{
					_refreshTimer = 0f;
					_aggregator.RefreshAll();
				}
			}
		}

		private void OnGUI()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_007a: 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)
			if (!_isVisible || !AlmanacConfig.StaticHUDEnabled || _aggregator == null)
			{
				return;
			}
			AlmanacDashboard almanacDashboard = Plugin.GetAlmanacDashboard();
			DailyBriefing dailyBriefing = Plugin.GetDailyBriefing();
			if ((!((Object)(object)almanacDashboard != (Object)null) || !almanacDashboard.IsVisible) && (!((Object)(object)dailyBriefing != (Object)null) || !dailyBriefing.IsVisible))
			{
				if (!_stylesInitialized)
				{
					InitializeStyles();
				}
				_windowRect = GUI.Window(98780, _windowRect, new WindowFunction(DrawWindow), "", _windowStyle);
				ClampToScreen();
			}
		}

		private void DrawWindow(int id)
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Haven's Almanac", _titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("x", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(Scaled(18f)),
				GUILayout.Height(Scaled(18f))
			}))
			{
				Hide();
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(Scaled(2f));
			if (_aggregator.IntegrationModCount == 0)
			{
				GUILayout.Label("No supported mods detected", _noModsStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Install SunhavenTodo, Birthday, Museum, Vault, Chests, Birthright, DevTools, or CropOptimizer", _noModsStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (IModDataProvider provider in _aggregator.Providers)
				{
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label(provider.ModIcon, _iconStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(Scaled(22f)) });
					GUILayout.Label(provider.ModName + ": " + provider.HudSummary, _summaryStyle, Array.Empty<GUILayoutOption>());
					GUILayout.EndHorizontal();
				}
			}
			GUI.DragWindow();
		}

		private void ClampToScreen()
		{
			float x = ((Rect)(ref _windowRect)).x;
			float y = ((Rect)(ref _windowRect)).y;
			((Rect)(ref _windowRect)).x = Mathf.Clamp(((Rect)(ref _windowRect)).x, 0f, (float)Screen.width - ((Rect)(ref _windowRect)).width);
			((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, 0f, (float)Screen.height - ((Rect)(ref _windowRect)).height);
			if (Math.Abs(x - ((Rect)(ref _windowRect)).x) > 1f || Math.Abs(y - ((Rect)(ref _windowRect)).y) > 1f)
			{
				OnPositionChanged?.Invoke(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).y);
			}
		}

		private void InitializeStyles()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0104: Expected O, but got Unknown
			//IL_013b: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_016c: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			_stylesInitialized = true;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.18f, 0.14f, 0.1f, 0.92f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.22f, 0.17f, 0.12f, 0.95f);
			Color textColor = default(Color);
			((Color)(ref textColor))..ctor(0.95f, 0.85f, 0.55f);
			Color textColor2 = default(Color);
			((Color)(ref textColor2))..ctor(0.91f, 0.87f, 0.82f);
			_bgTexture = GUIStyleHelper.MakeSolidTexture(color);
			_headerTexture = GUIStyleHelper.MakeSolidTexture(color2);
			_windowStyle = new GUIStyle(GUI.skin.window)
			{
				padding = new RectOffset(ScaledInt(8f), ScaledInt(8f), ScaledInt(6f), ScaledInt(6f)),
				border = new RectOffset(ScaledInt(2f), ScaledInt(2f), ScaledInt(2f), ScaledInt(2f))
			};
			_windowStyle.normal.background = _bgTexture;
			_windowStyle.onNormal.background = _bgTexture;
			_titleStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(13),
				alignment = (TextAnchor)3
			};
			_titleStyle.normal.textColor = textColor;
			_iconStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = ScaledFont(14),
				alignment = (TextAnchor)4
			};
			_summaryStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = ScaledFont(12),
				alignment = (TextAnchor)3
			};
			_summaryStyle.normal.textColor = textColor2;
			_noModsStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = ScaledFont(11),
				fontStyle = (FontStyle)2,
				alignment = (TextAnchor)4
			};
			_noModsStyle.normal.textColor = new Color(0.7f, 0.6f, 0.5f);
		}

		private void OnDestroy()
		{
			if ((Object)(object)_bgTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_bgTexture);
			}
			if ((Object)(object)_headerTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_headerTexture);
			}
		}
	}
	public class DailyBriefing : MonoBehaviour
	{
		private const int WINDOW_ID = 98782;

		private const float BASE_WIDTH = 500f;

		private const float BASE_MIN_HEIGHT = 250f;

		private float _scale = 1f;

		private AlmanacDataAggregator _aggregator;

		private Rect _windowRect;

		private bool _isVisible;

		private float _contentHeight = 250f;

		private float _visibleSinceUnscaledTime;

		private float _autoDismissSeconds;

		private bool _stylesInitialized;

		private GUIStyle _windowStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _sectionTitleStyle;

		private GUIStyle _contentStyle;

		private GUIStyle _dismissButtonStyle;

		private Texture2D _bgTexture;

		private float Width => 500f * _scale;

		private float MinHeight => 250f * _scale;

		public bool IsVisible => _isVisible;

		private float Scaled(float value)
		{
			return value * _scale;
		}

		private int ScaledFont(int baseSize)
		{
			return Mathf.Max(8, Mathf.RoundToInt((float)baseSize * _scale));
		}

		private int ScaledInt(float value)
		{
			return Mathf.RoundToInt(value * _scale);
		}

		public void Initialize(AlmanacDataAggregator aggregator)
		{
			_aggregator = aggregator;
			CenterWindow();
		}

		public void ShowBriefing()
		{
			if (AlmanacConfig.StaticBriefingEnabled && _aggregator != null && _aggregator.InstalledModCount != 0)
			{
				_aggregator.RefreshAll();
				if (_aggregator.HasAnyBriefingContent)
				{
					CenterWindow();
					_isVisible = true;
					_visibleSinceUnscaledTime = Time.unscaledTime;
					_autoDismissSeconds = Mathf.Max(0f, AlmanacConfig.StaticBriefingAutoDismiss);
				}
			}
		}

		public void Hide()
		{
			_isVisible = false;
		}

		public void SetScale(float scale)
		{
			_scale = Mathf.Clamp(scale, 0.5f, 2.5f);
			_stylesInitialized = false;
		}

		private void CenterWindow()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			_windowRect = new Rect(((float)Screen.width - Width) / 2f, ((float)Screen.height - MinHeight) / 2f - Scaled(50f), Width, MinHeight);
		}

		private void Update()
		{
			if (_isVisible)
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					Hide();
				}
				else if (_autoDismissSeconds > 0f && Time.unscaledTime - _visibleSinceUnscaledTime >= _autoDismissSeconds)
				{
					Hide();
				}
			}
		}

		private float GetAutoDismissRemaining()
		{
			if (_autoDismissSeconds <= 0f)
			{
				return -1f;
			}
			float num = _autoDismissSeconds - (Time.unscaledTime - _visibleSinceUnscaledTime);
			return Mathf.Max(0f, num);
		}

		private void OnGUI()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (_isVisible && _aggregator != null)
			{
				if (!_stylesInitialized)
				{
					InitializeStyles();
				}
				float num = (float)Screen.height - Scaled(60f);
				((Rect)(ref _windowRect)).height = Mathf.Clamp(_contentHeight, MinHeight, num);
				((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
				((Rect)(ref _windowRect)).y = Mathf.Clamp(((Rect)(ref _windowRect)).y, Scaled(20f), (float)Screen.height - ((Rect)(ref _windowRect)).height - Scaled(20f));
				_windowRect = GUI.Window(98782, _windowRect, new WindowFunction(DrawWindow), "", _windowStyle);
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Invalid comparison between Unknown and I4
			//IL_019d: 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_0162: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Good Morning!", _titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(Scaled(6f));
			bool flag = false;
			foreach (IModDataProvider provider in _aggregator.Providers)
			{
				if (provider.HasBriefingContent && TryDrawProviderSection(provider))
				{
					flag = true;
					GUILayout.Space(Scaled(6f));
				}
			}
			if (!flag)
			{
				GUILayout.Label("Nothing noteworthy today. Have a great day!", _contentStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(Scaled(10f));
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Dismiss", _dismissButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(Scaled(120f)),
				GUILayout.Height(Scaled(30f))
			}))
			{
				Hide();
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			float autoDismissRemaining = GetAutoDismissRemaining();
			if (autoDismissRemaining >= 0f)
			{
				int num = Mathf.CeilToInt(autoDismissRemaining);
				GUILayout.Space(Scaled(4f));
				GUILayout.Label($"Auto-dismissing in {num}s ({_autoDismissSeconds:F0}s total)", _contentStyle, Array.Empty<GUILayoutOption>());
			}
			if ((int)Event.current.type == 7)
			{
				Rect lastRect = GUILayoutUtility.GetLastRect();
				_contentHeight = ((Rect)(ref lastRect)).yMax + Scaled(28f);
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, Scaled(30f)));
		}

		private bool TryDrawProviderSection(IModDataProvider provider)
		{
			bool flag = false;
			try
			{
				GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
				flag = true;
				GUILayout.Label(provider.ModIcon + " " + provider.ModName, _sectionTitleStyle, Array.Empty<GUILayoutOption>());
				bool result = provider.DrawBriefingSection();
				GUILayout.EndVertical();
				flag = false;
				return result;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Briefing] " + provider.ModName + " threw during DrawBriefingSection: " + ex.Message));
				}
			}
			finally
			{
				if (flag)
				{
					try
					{
						GUILayout.EndVertical();
					}
					catch (Exception ex2)
					{
						ManualLogSource log2 = Plugin.Log;
						if (log2 != null)
						{
							log2.LogWarning((object)("[Briefing] Layout recovery: " + ex2.Message));
						}
					}
				}
			}
			return false;
		}

		private void InitializeStyles()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00f2: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			_stylesInitialized = true;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.15f, 0.12f, 0.09f, 0.96f);
			Color textColor = default(Color);
			((Color)(ref textColor))..ctor(0.95f, 0.85f, 0.55f);
			Color textColor2 = default(Color);
			((Color)(ref textColor2))..ctor(0.91f, 0.87f, 0.82f);
			new Color(0.6f, 0.55f, 0.45f);
			_bgTexture = GUIStyleHelper.MakeSolidTexture(color);
			_windowStyle = new GUIStyle(GUI.skin.window)
			{
				padding = new RectOffset(ScaledInt(16f), ScaledInt(16f), ScaledInt(12f), ScaledInt(12f)),
				border = new RectOffset(ScaledInt(2f), ScaledInt(2f), ScaledInt(2f), ScaledInt(2f))
			};
			_windowStyle.normal.background = _bgTexture;
			_windowStyle.onNormal.background = _bgTexture;
			_titleStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(18),
				alignment = (TextAnchor)4
			};
			_titleStyle.normal.textColor = textColor;
			_sectionTitleStyle = new GUIStyle(GUI.skin.label)
			{
				fontStyle = (FontStyle)1,
				fontSize = ScaledFont(13)
			};
			_sectionTitleStyle.normal.textColor = textColor;
			_contentStyle = new GUIStyle(GUI.skin.label)
			{
				fontSize = ScaledFont(12),
				fontStyle = (FontStyle)2,
				alignment = (TextAnchor)4,
				wordWrap = true
			};
			_contentStyle.normal.textColor = textColor2;
			_dismissButtonStyle = new GUIStyle(GUI.skin.button)
			{
				fontSize = ScaledFont(13),
				fontStyle = (FontStyle)1
			};
		}

		private void OnDestroy()
		{
			if ((Object)(object)_bgTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_bgTexture);
			}
		}
	}
}
namespace HavensAlmanac.Integration
{
	public class BirthdayDataProvider : IModDataProvider
	{
		private List<BirthdayDisplayInfo> _birthdays = new List<BirthdayDisplayInfo>();

		private int _ungiftedCount;

		private string _hudSummary = "Loading...";

		private bool _isReady;

		public string ModName => "Birthday";

		public string ModIcon => "★";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent
		{
			get
			{
				if (_isReady && _birthdays != null)
				{
					return _birthdays.Count > 0;
				}
				return false;
			}
		}

		public void Refresh()
		{
			try
			{
				BirthdayManager manager = Plugin.GetManager();
				if (manager == null)
				{
					_isReady = false;
					return;
				}
				_birthdays = manager.TodaysBirthdays ?? new List<BirthdayDisplayInfo>();
				_ungiftedCount = 0;
				foreach (BirthdayDisplayInfo birthday in _birthdays)
				{
					if (!birthday.HasBeenGifted)
					{
						_ungiftedCount++;
					}
				}
				if (_birthdays.Count == 0)
				{
					_hudSummary = "No birthdays";
				}
				else
				{
					_hudSummary = string.Format("{0} birthday{1} / {2} ungifted", _birthdays.Count, (_birthdays.Count != 1) ? "s" : "", _ungiftedCount);
				}
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[BirthdayProvider] Refresh error: " + ex.Message));
				}
			}
		}

		public void DrawDashboardSection()
		{
			if (_birthdays.Count == 0)
			{
				GUILayout.Label("No birthdays today.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label($"Today's Birthdays ({_birthdays.Count}):", Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			foreach (BirthdayDisplayInfo birthday in _birthdays)
			{
				string text = (birthday.HasBeenGifted ? " [Gifted]" : " [Not gifted]");
				GUILayout.Label("  " + birthday.NPCName + text, Array.Empty<GUILayoutOption>());
				if (!string.IsNullOrEmpty(birthday.GiftHint))
				{
					GUILayout.Label("    " + birthday.GiftHint, Array.Empty<GUILayoutOption>());
				}
			}
		}

		public bool DrawBriefingSection()
		{
			if (_birthdays.Count == 0)
			{
				return false;
			}
			foreach (BirthdayDisplayInfo birthday in _birthdays)
			{
				string text = (birthday.HasBeenGifted ? " (gifted)" : "");
				GUILayout.Label("  It's " + birthday.NPCName + "'s birthday!" + text, Array.Empty<GUILayoutOption>());
			}
			if (_ungiftedCount > 0)
			{
				GUILayout.Label("  Don't forget to bring a gift!", Array.Empty<GUILayoutOption>());
			}
			return true;
		}
	}
	public class BirthrightDataProvider : IModDataProvider
	{
		private string _raceName = "None";

		private int _bonusCount;

		private List<RacialBonus> _bonuses = new List<RacialBonus>();

		private string _hudSummary = "Loading...";

		private bool _isReady;

		public string ModName => "Birthright";

		public string ModIcon => "⚔";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent => false;

		public void Refresh()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RacialBonusManager racialBonusManager = Plugin.GetRacialBonusManager();
				if (racialBonusManager == null)
				{
					_isReady = false;
					return;
				}
				Race? playerRace = racialBonusManager.GetPlayerRace();
				if (playerRace.HasValue)
				{
					Race value = playerRace.Value;
					_raceName = ((object)(Race)(ref value)).ToString();
					_bonuses = racialBonusManager.GetCurrentPlayerBonuses() ?? new List<RacialBonus>();
					_bonusCount = _bonuses.Count;
					_hudSummary = string.Format("{0} ({1} bonus{2})", _raceName, _bonusCount, (_bonusCount != 1) ? "es" : "");
				}
				else
				{
					_raceName = "None";
					_bonusCount = 0;
					_bonuses.Clear();
					_hudSummary = "No race set";
				}
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[BirthrightProvider] Refresh error: " + ex.Message));
				}
			}
		}

		public void DrawDashboardSection()
		{
			GUILayout.Label("Race: " + _raceName, Array.Empty<GUILayoutOption>());
			if (_bonusCount == 0)
			{
				GUILayout.Label("No active bonuses.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label($"Active Bonuses ({_bonusCount}):", Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			foreach (RacialBonus bonuse in _bonuses)
			{
				string formattedValue = bonuse.GetFormattedValue();
				GUILayout.Label("  " + bonuse.Description + ": " + formattedValue, Array.Empty<GUILayoutOption>());
			}
		}

		public bool DrawBriefingSection()
		{
			return false;
		}
	}
	public class ChestDataProvider : IModDataProvider
	{
		private int _smartChestCount;

		private string _hudSummary = "Loading...";

		private bool _isReady;

		private Type _pluginType;

		private MethodInfo _getManagerMethod;

		private Type _managerType;

		private MethodInfo _getSaveDataMethod;

		private Type _saveDataType;

		private PropertyInfo _chestConfigsProperty;

		private FieldInfo _chestConfigsField;

		public string ModName => "Chests";

		public string ModIcon => "▣";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent => false;

		public void Refresh()
		{
			try
			{
				if (!TryResolvePluginType())
				{
					_isReady = false;
					return;
				}
				object managerCached = GetManagerCached();
				if (managerCached == null)
				{
					_isReady = false;
					return;
				}
				object saveDataCached = GetSaveDataCached(managerCached);
				_smartChestCount = ((saveDataCached != null) ? ReadChestConfigCount(saveDataCached) : 0);
				_hudSummary = ((_smartChestCount == 0) ? "No smart chests" : string.Format("{0} smart chest{1}", _smartChestCount, (_smartChestCount != 1) ? "s" : ""));
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[ChestProvider] Refresh error: " + ex.Message));
				}
			}
		}

		private bool TryResolvePluginType()
		{
			if (_pluginType != null)
			{
				return true;
			}
			_pluginType = ReflectionHelper.FindType("SenpaisChest.Plugin");
			return _pluginType != null;
		}

		private object GetManagerCached()
		{
			if (_getManagerMethod == null)
			{
				_getManagerMethod = _pluginType.GetMethod("GetManager", ReflectionHelper.AllBindingFlags, null, Type.EmptyTypes, null);
				if (_getManagerMethod == null)
				{
					return null;
				}
			}
			return _getManagerMethod.Invoke(null, null);
		}

		private object GetSaveDataCached(object manager)
		{
			Type type = manager.GetType();
			if (_managerType != type || _getSaveDataMethod == null)
			{
				_managerType = type;
				_getSaveDataMethod = _managerType.GetMethod("GetSaveData", ReflectionHelper.AllBindingFlags, null, Type.EmptyTypes, null);
			}
			return _getSaveDataMethod?.Invoke(manager, null);
		}

		private int ReadChestConfigCount(object saveData)
		{
			Type type = saveData.GetType();
			if (_saveDataType != type)
			{
				_saveDataType = type;
				_chestConfigsProperty = _saveDataType.GetProperty("ChestConfigs", ReflectionHelper.AllBindingFlags);
				_chestConfigsField = ((_chestConfigsProperty == null) ? _saveDataType.GetField("ChestConfigs", ReflectionHelper.AllBindingFlags) : null);
			}
			if (!(((_chestConfigsProperty != null) ? _chestConfigsProperty.GetValue(saveData) : _chestConfigsField?.GetValue(saveData)) is ICollection collection))
			{
				return 0;
			}
			return collection.Count;
		}

		public void DrawDashboardSection()
		{
			GUILayout.Label($"Configured Smart Chests: {_smartChestCount}", Array.Empty<GUILayoutOption>());
		}

		public bool DrawBriefingSection()
		{
			return false;
		}
	}
	public class CropOptimizerDataProvider : IModDataProvider
	{
		private string _hudSummary = "Loading...";

		private bool _isReady;

		private List<(string name, int totalGold, int count)> _topCrops = new List<(string, int, int)>();

		public string ModName => "Crop Optimizer";

		public string ModIcon => "o";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent => false;

		public void Refresh()
		{
			//IL_0026: 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)
			try
			{
				_hudSummary = CropOptimizerDataProvider.GetSummary();
				_topCrops.Clear();
				string text = default(string);
				foreach (CropTypeSummary topCrop in CropOptimizerDataProvider.GetTopCrops(5))
				{
					CropTypeSummary current = topCrop;
					CropOptimizerDataProvider.TryGetCropDisplayName(((CropTypeSummary)(ref current)).ItemId, ref text);
					_topCrops.Add((text ?? $"Item #{((CropTypeSummary)(ref current)).ItemId}", ((CropTypeSummary)(ref current)).TotalGold, ((CropTypeSummary)(ref current)).CropCount));
				}
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[CropOptimizerProvider] Refresh error: " + ex.Message));
				}
			}
		}

		public void DrawDashboardSection()
		{
			GUILayout.Label(_hudSummary, Array.Empty<GUILayoutOption>());
			if (_topCrops.Count > 0)
			{
				GUILayout.Space(4f);
				GUILayout.Label("Top crops by projected value:", Array.Empty<GUILayoutOption>());
				for (int i = 0; i < _topCrops.Count; i++)
				{
					var (text, num, num2) = _topCrops[i];
					GUILayout.Label(string.Format("  {0}. {1} — {2}g ({3} plant{4})", i + 1, text, num, num2, (num2 == 1) ? "" : "s"), Array.Empty<GUILayoutOption>());
				}
			}
		}

		public bool DrawBriefingSection()
		{
			return false;
		}
	}
	public class DevToolsDataProvider : IModDataProvider
	{
		private bool _isAuthorized;

		private string _playerName = "";

		private string _hudSummary = "Loading...";

		private bool _isReady;

		public string ModName => "DevTools";

		public string ModIcon => "⚒";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent => false;

		public void Refresh()
		{
			try
			{
				_isAuthorized = Plugin.IsAuthorized;
				_playerName = Plugin.CurrentPlayerName ?? "";
				_hudSummary = (_isAuthorized ? "Active" : "Inactive");
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[DevToolsProvider] Refresh error: " + ex.Message));
				}
			}
		}

		public void DrawDashboardSection()
		{
			GUILayout.Label("Status: " + (_isAuthorized ? "Authorized" : "Not Authorized"), Array.Empty<GUILayoutOption>());
			if (!string.IsNullOrEmpty(_playerName))
			{
				GUILayout.Label("Player: " + _playerName, Array.Empty<GUILayoutOption>());
			}
		}

		public bool DrawBriefingSection()
		{
			return false;
		}
	}
	public class ModHealthDataProvider : IModDataProvider
	{
		private struct HealthEntry
		{
			public string PluginGuid;

			public DateTime LastCheckUtc;

			public int ExceptionCount;

			public string LastError;
		}

		private struct SnapshotShape
		{
			public PropertyInfo LastCheckUtc;

			public PropertyInfo ExceptionCount;

			public PropertyInfo LastError;
		}

		private readonly List<string> _lines = new List<string>();

		private string _hudSummary = "No checks";

		private bool _isReady;

		private static readonly object CacheLock = new object();

		private static List<FieldInfo> _cachedHealthFields;

		private static int _cachedAssemblyCount;

		private static DateTime _cacheBuiltAt = DateTime.MinValue;

		private static readonly TimeSpan CacheMaxAge = TimeSpan.FromMinutes(5.0);

		private static readonly Dictionary<Type, SnapshotShape> SnapshotShapeCache = new Dictionary<Type, SnapshotShape>();

		public string ModName => "Mod Health";

		public string ModIcon => "+";

		public string HudSummary => _hudSummary;

		public bool IsReady => _isReady;

		public bool HasBriefingContent => false;

		public void Refresh()
		{
			_lines.Clear();
			try
			{
				List<HealthEntry> list = CollectHealthSnapshotsAcrossLoadedMods();
				int num = 0;
				int num2 = 0;
				foreach (HealthEntry item in list)
				{
					num++;
					if (item.ExceptionCount > 0)
					{
						num2++;
					}
					object obj;
					if (!(item.LastCheckUtc == default(DateTime)))
					{
						DateTime lastCheckUtc = item.LastCheckUtc;
						obj = lastCheckUtc.ToLocalTime().ToString("HH:mm:ss");
					}
					else
					{
						obj = "never";
					}
					string arg = (string)obj;
					string arg2 = ResolvePluginDisplayName(item.PluginGuid) ?? item.PluginGuid;
					_lines.Add($"{arg2}: last check {arg}, exceptions {item.ExceptionCount}");
				}
				_hudSummary = ((num == 0) ? "No checks" : string.Format("{0} checked / {1} issue{2}", num, num2, (num2 == 1) ? string.Empty : "s"));
				_isReady = true;
			}
			catch (Exception ex)
			{
				_hudSummary = "Error";
				_isReady = false;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[ModHealthProvider] Refresh error: " + ex.Message));
				}
			}
		}

		public void DrawDashboardSection()
		{
			if (_lines.Count == 0)
			{
				GUILayout.Label("No VersionChecker telemetry yet.", Array.Empty<GUILayoutOption>());
				return;
			}
			foreach (string line in _lines)
			{
				GUILayout.Label(line, Array.Empty<GUILayoutOption>());
			}
		}

		public bool DrawBriefingSection()
		{
			return false;
		}

		private stat