Decompiled source of TheVault v3.3.2

TheVault.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SunhavenMods.Shared;
using TheVault.Api;
using TheVault.Integration;
using TheVault.Modding;
using TheVault.Patches;
using TheVault.UI;
using TheVault.Vault;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Wish;

[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("TheVault")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.3.2.0")]
[assembly: AssemblyInformationalVersion("3.3.2+5c08b5aa5d0be9c4b93df77f697dc55d5ac97088")]
[assembly: AssemblyProduct("TheVault")]
[assembly: AssemblyTitle("TheVault")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.3.2.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 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
		{
			private ManualLogSource _pluginLog;

			public void StartCheck(string pluginGuid, string currentVersion, ManualLogSource pluginLog, Action<VersionCheckResult> onComplete)
			{
				_pluginLog = pluginLog;
				((MonoBehaviour)this).StartCoroutine(CheckVersionCoroutine(pluginGuid, currentVersion, onComplete));
			}

			private void LogInfo(string message)
			{
				ManualLogSource pluginLog = _pluginLog;
				if (pluginLog != null)
				{
					pluginLog.LogInfo((object)("[VersionChecker] " + message));
				}
			}

			private void LogWarningMsg(string message)
			{
				ManualLogSource pluginLog = _pluginLog;
				if (pluginLog != null)
				{
					pluginLog.LogWarning((object)("[VersionChecker] " + message));
				}
			}

			private void LogErrorMsg(string message)
			{
				ManualLogSource pluginLog = _pluginLog;
				if (pluginLog != null)
				{
					pluginLog.LogError((object)("[VersionChecker] " + message));
				}
			}

			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);
						LogWarningMsg(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);
							LogWarningMsg(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);
							LogWarningMsg(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)
						{
							LogInfo("Update available for " + result.ModName + ": " + currentVersion + " -> " + result.LatestVersion);
						}
						else
						{
							LogInfo(result.ModName + " is up to date (v" + currentVersion + ")");
						}
					}
					catch (Exception ex)
					{
						result.Success = false;
						result.ErrorMessage = "Parse error: " + ex.Message;
						RecordHealthError(pluginGuid, result.ErrorMessage);
						LogErrorMsg(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 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_000b: Unknown result type (might be due to invalid IL or missing references)
			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, logger, onComplete);
		}

		public static ModHealthSnapshot GetHealthSnapshot(string pluginGuid)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				return null;
			}
			lock (HealthLock)
			{
				if (!HealthByPluginGuid.TryGetValue(pluginGuid, out ModHealthSnapshot 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');
			int num = v1.IndexOfAny(new char[2] { '-', '+' });
			if (num >= 0)
			{
				v1 = v1.Substring(0, num);
			}
			int num2 = v2.IndexOfAny(new char[2] { '-', '+' });
			if (num2 >= 0)
			{
				v2 = v2.Substring(0, num2);
			}
			string[] array = v1.Split(new char[1] { '.' });
			string[] array2 = v2.Split(new char[1] { '.' });
			int num3 = Math.Max(array.Length, array2.Length);
			for (int i = 0; i < num3; i++)
			{
				int result;
				int num4 = ((i < array.Length && int.TryParse(array[i], out result)) ? result : 0);
				int result2;
				int num5 = ((i < array2.Length && int.TryParse(array2[i], out result2)) ? result2 : 0);
				if (num4 < num5)
				{
					return -1;
				}
				if (num4 > num5)
				{
					return 1;
				}
			}
			return 0;
		}

		private static void TouchHealth(string pluginGuid)
		{
			if (string.IsNullOrWhiteSpace(pluginGuid))
			{
				return;
			}
			lock (HealthLock)
			{
				if (!HealthByPluginGuid.TryGetValue(pluginGuid, out ModHealthSnapshot 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 ModHealthSnapshot 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 Regex 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)
		{
			string typeName2 = typeName;
			Type type = AccessTools.TypeByName(typeName2);
			if (type != null)
			{
				return type;
			}
			for (int i = 0; i < namespaces.Length; i++)
			{
				type = AccessTools.TypeByName(namespaces[i] + "." + typeName2);
				if (type != null)
				{
					return type;
				}
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					type = assembly.GetTypes().FirstOrDefault((Type t) => t.Name == typeName2 || t.FullName == typeName2);
					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;
			}
			try
			{
				PropertyInfo property = type.GetProperty(memberName, AllBindingFlags);
				if (property != null && property.GetMethod != null && property.GetIndexParameters().Length == 0)
				{
					return property.GetValue(null);
				}
			}
			catch (AmbiguousMatchException)
			{
				return 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 IconCache
	{
		private struct CachedIcon
		{
			public Texture2D Texture;

			public bool OwnsTexture;
		}

		private static readonly Dictionary<int, CachedIcon> _iconCache = new Dictionary<int, CachedIcon>();

		private const int MaxCacheSize = 200;

		private static readonly HashSet<int> _loadingItems = new HashSet<int>();

		private static readonly HashSet<int> _failedItems = new HashSet<int>();

		private static readonly Dictionary<string, int> _currencyToItemId = new Dictionary<string, int>();

		private static Texture2D _fallbackTexture;

		private static ManualLogSource _log;

		private static Type _databaseType;

		private static Type _itemDataType;

		private static MethodInfo _getDataMethod;

		private static bool _reflectionInitialized;

		private static bool _initialized;

		private static bool _iconsLoaded;

		private static int[] _pendingPreloadItemIds;

		public static void Initialize(ManualLogSource log, int[] preloadItemIds = null)
		{
			_log = log;
			if (_initialized)
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogDebug((object)"[IconCache] Already initialized");
				}
				return;
			}
			_initialized = true;
			ManualLogSource log3 = _log;
			if (log3 != null)
			{
				log3.LogInfo((object)"[IconCache] Initializing icon cache...");
			}
			_fallbackTexture = CreateFallbackTexture();
			ManualLogSource log4 = _log;
			if (log4 != null)
			{
				log4.LogInfo((object)"[IconCache] Created fallback texture");
			}
			if (preloadItemIds != null && preloadItemIds.Length != 0)
			{
				_pendingPreloadItemIds = (int[])preloadItemIds.Clone();
				ManualLogSource log5 = _log;
				if (log5 != null)
				{
					log5.LogInfo((object)$"[IconCache] Preload: {_pendingPreloadItemIds.Length} item ID(s) will queue with LoadAllIcons");
				}
			}
		}

		public static void RegisterCurrency(string currencyId, int itemId)
		{
			_currencyToItemId[currencyId] = itemId;
		}

		public static void LoadAllIcons()
		{
			if (_iconsLoaded)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)"[IconCache] Icons already loaded, skipping");
				}
				return;
			}
			if (!InitializeReflection())
			{
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogError((object)"[IconCache] Failed to initialize reflection, cannot load icons");
				}
				_iconsLoaded = true;
				return;
			}
			foreach (KeyValuePair<string, int> item in _currencyToItemId)
			{
				ManualLogSource log3 = _log;
				if (log3 != null)
				{
					log3.LogDebug((object)$"[IconCache] Queuing load for: {item.Key} (ItemID: {item.Value})");
				}
				LoadIcon(item.Value);
			}
			if (_pendingPreloadItemIds != null)
			{
				int[] pendingPreloadItemIds = _pendingPreloadItemIds;
				foreach (int num in pendingPreloadItemIds)
				{
					if (num > 0)
					{
						ManualLogSource log4 = _log;
						if (log4 != null)
						{
							log4.LogDebug((object)$"[IconCache] Queuing preload item ID: {num}");
						}
						LoadIcon(num);
					}
				}
			}
			_iconsLoaded = true;
			ManualLogSource log5 = _log;
			if (log5 != null)
			{
				log5.LogInfo((object)$"[IconCache] Queued {_currencyToItemId.Count} currency icon(s); preload queue processed.");
			}
		}

		public static Texture2D GetIconForCurrency(string currencyId)
		{
			if (_currencyToItemId.TryGetValue(currencyId, out var value))
			{
				return GetIcon(value);
			}
			return GetFallbackTexture();
		}

		public static Texture2D GetIcon(int itemId)
		{
			if (itemId <= 0)
			{
				return GetFallbackTexture();
			}
			if (_iconCache.TryGetValue(itemId, out var value))
			{
				return value.Texture;
			}
			if (!_loadingItems.Contains(itemId) && !_failedItems.Contains(itemId))
			{
				LoadIcon(itemId);
			}
			return GetFallbackTexture();
		}

		private static Texture2D GetFallbackTexture()
		{
			if ((Object)(object)_fallbackTexture == (Object)null)
			{
				_fallbackTexture = CreateFallbackTexture();
			}
			return _fallbackTexture;
		}

		public static bool IsIconLoaded(int itemId)
		{
			return _iconCache.ContainsKey(itemId);
		}

		public static bool IsIconLoaded(string currencyId)
		{
			if (_currencyToItemId.TryGetValue(currencyId, out var value))
			{
				return IsIconLoaded(value);
			}
			return false;
		}

		public static int GetItemIdForCurrency(string currencyId)
		{
			if (!_currencyToItemId.TryGetValue(currencyId, out var value))
			{
				return -1;
			}
			return value;
		}

		private static bool InitializeReflection()
		{
			if (_reflectionInitialized)
			{
				if (_databaseType != null && _itemDataType != null)
				{
					return _getDataMethod != null;
				}
				return false;
			}
			_reflectionInitialized = true;
			try
			{
				string[] array = new string[4] { "Database", "Wish.Database", "PSS.Database", "SunHaven.Database" };
				for (int i = 0; i < array.Length; i++)
				{
					_databaseType = AccessTools.TypeByName(array[i]);
					if (_databaseType != null)
					{
						ManualLogSource log = _log;
						if (log != null)
						{
							log.LogInfo((object)("[IconCache] Found Database type: " + _databaseType.FullName));
						}
						break;
					}
				}
				MethodInfo[] methods;
				if (_databaseType == null)
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					foreach (Assembly assembly in assemblies)
					{
						try
						{
							Type[] types = assembly.GetTypes();
							foreach (Type type in types)
							{
								if (!(type.Name == "Database") || type.IsNested)
								{
									continue;
								}
								methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
								foreach (MethodInfo methodInfo in methods)
								{
									if (methodInfo.Name == "GetData" && methodInfo.IsGenericMethod)
									{
										_databaseType = type;
										ManualLogSource log2 = _log;
										if (log2 != null)
										{
											log2.LogInfo((object)("[IconCache] Found Database type: " + type.FullName));
										}
										break;
									}
								}
								if (_databaseType != null)
								{
									break;
								}
							}
							if (_databaseType != null)
							{
								break;
							}
						}
						catch (Exception ex)
						{
							ManualLogSource log3 = _log;
							if (log3 != null)
							{
								log3.LogDebug((object)("[IconCache] Skipping assembly " + assembly.GetName().Name + ": " + ex.Message));
							}
						}
					}
				}
				if (_databaseType == null)
				{
					ManualLogSource log4 = _log;
					if (log4 != null)
					{
						log4.LogError((object)"[IconCache] Could not find Database type");
					}
					return false;
				}
				_itemDataType = AccessTools.TypeByName("Wish.ItemData");
				if (_itemDataType == null)
				{
					ManualLogSource log5 = _log;
					if (log5 != null)
					{
						log5.LogError((object)"[IconCache] Could not find Wish.ItemData type");
					}
					return false;
				}
				methods = _databaseType.GetMethods(BindingFlags.Static | BindingFlags.Public);
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (!(methodInfo2.Name == "GetData") || !methodInfo2.IsGenericMethod)
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (methodInfo2.GetGenericArguments().Length == 1 && parameters.Length == 3 && parameters[0].ParameterType == typeof(int))
					{
						_getDataMethod = methodInfo2.MakeGenericMethod(_itemDataType);
						ManualLogSource log6 = _log;
						if (log6 != null)
						{
							log6.LogInfo((object)"[IconCache] Found Database.GetData method");
						}
						break;
					}
				}
				if (_getDataMethod == null)
				{
					ManualLogSource log7 = _log;
					if (log7 != null)
					{
						log7.LogError((object)"[IconCache] Could not find Database.GetData method");
					}
					return false;
				}
				return true;
			}
			catch (Exception ex2)
			{
				ManualLogSource log8 = _log;
				if (log8 != null)
				{
					log8.LogError((object)("[IconCache] Error initializing reflection: " + ex2.Message));
				}
				return false;
			}
		}

		private static void LoadIcon(int itemId)
		{
			if (itemId <= 0 || _loadingItems.Contains(itemId) || _iconCache.ContainsKey(itemId))
			{
				return;
			}
			_loadingItems.Add(itemId);
			try
			{
				if (!InitializeReflection() || _getDataMethod == null)
				{
					_failedItems.Add(itemId);
					_loadingItems.Remove(itemId);
					return;
				}
				Type delegateType = typeof(Action<>).MakeGenericType(_itemDataType);
				ParameterExpression parameterExpression = Expression.Parameter(_itemDataType, "itemData");
				ConstantExpression arg = Expression.Constant(itemId);
				MethodCallExpression body = Expression.Call(typeof(IconCache).GetMethod("OnIconLoadedInternal", BindingFlags.Static | BindingFlags.NonPublic), arg, Expression.Convert(parameterExpression, typeof(object)));
				Delegate @delegate = Expression.Lambda(delegateType, body, parameterExpression).Compile();
				Action action = Expression.Lambda<Action>(Expression.Call(typeof(IconCache).GetMethod("OnIconLoadFailed", BindingFlags.Static | BindingFlags.NonPublic), arg), Array.Empty<ParameterExpression>()).Compile();
				_getDataMethod.Invoke(null, new object[3] { itemId, @delegate, action });
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)$"[IconCache] Error loading icon {itemId}: {ex.Message}");
				}
				_failedItems.Add(itemId);
				_loadingItems.Remove(itemId);
			}
		}

		private static void OnIconLoadedInternal(int itemId, object itemData)
		{
			_loadingItems.Remove(itemId);
			if (itemData == null)
			{
				_failedItems.Add(itemId);
				return;
			}
			try
			{
				Type type = itemData.GetType();
				object obj = null;
				BindingFlags[] array = new BindingFlags[4]
				{
					BindingFlags.Instance | BindingFlags.Public,
					BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy,
					BindingFlags.Instance | BindingFlags.NonPublic,
					BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy
				};
				BindingFlags[] array2 = array;
				foreach (BindingFlags bindingAttr in array2)
				{
					PropertyInfo property = type.GetProperty("icon", bindingAttr);
					if (property != null)
					{
						obj = property.GetValue(itemData);
						break;
					}
				}
				if (obj == null)
				{
					array2 = array;
					foreach (BindingFlags bindingAttr2 in array2)
					{
						FieldInfo field = type.GetField("icon", bindingAttr2);
						if (field != null)
						{
							obj = field.GetValue(itemData);
							break;
						}
					}
				}
				if (obj == null)
				{
					Type type2 = type;
					while (type2 != null && obj == null)
					{
						PropertyInfo[] properties = type2.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (PropertyInfo propertyInfo in properties)
						{
							if (propertyInfo.Name.Equals("icon", StringComparison.OrdinalIgnoreCase))
							{
								obj = propertyInfo.GetValue(itemData);
								break;
							}
						}
						if (obj == null)
						{
							FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							foreach (FieldInfo fieldInfo in fields)
							{
								if (fieldInfo.Name.Equals("icon", StringComparison.OrdinalIgnoreCase))
								{
									obj = fieldInfo.GetValue(itemData);
									break;
								}
							}
						}
						type2 = type2.BaseType;
					}
				}
				Sprite val = (Sprite)((obj is Sprite) ? obj : null);
				if (val != null)
				{
					CacheSprite(itemId, val);
				}
				else
				{
					_failedItems.Add(itemId);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)$"[IconCache] Error processing icon {itemId}: {ex.Message}");
				}
				_failedItems.Add(itemId);
			}
		}

		private static void OnIconLoadFailed(int itemId)
		{
			_loadingItems.Remove(itemId);
			_failedItems.Add(itemId);
		}

		private static void CacheSprite(int itemId, Sprite sprite)
		{
			//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)
			//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 ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				_failedItems.Add(itemId);
				return;
			}
			try
			{
				Rect rect = sprite.rect;
				Texture2D val;
				bool ownsTexture;
				if (((Rect)(ref rect)).width == (float)((Texture)sprite.texture).width)
				{
					rect = sprite.rect;
					if (((Rect)(ref rect)).height == (float)((Texture)sprite.texture).height)
					{
						val = sprite.texture;
						ownsTexture = false;
						goto IL_0077;
					}
				}
				val = ExtractSpriteTexture(sprite);
				ownsTexture = (Object)(object)val != (Object)null;
				goto IL_0077;
				IL_0077:
				if ((Object)(object)val != (Object)null)
				{
					_iconCache[itemId] = new CachedIcon
					{
						Texture = val,
						OwnsTexture = ownsTexture
					};
					if (_iconCache.Count <= 200)
					{
						return;
					}
					int num = -1;
					int num2 = -1;
					foreach (int key in _iconCache.Keys)
					{
						if (num2 < 0)
						{
							num2 = key;
						}
						if (!_loadingItems.Contains(key) && !_failedItems.Contains(key))
						{
							num = key;
							break;
						}
					}
					if (num < 0)
					{
						num = num2;
					}
					if (num >= 0 && _iconCache.TryGetValue(num, out var value))
					{
						if (value.OwnsTexture && (Object)(object)value.Texture != (Object)null)
						{
							Object.Destroy((Object)(object)value.Texture);
						}
						_iconCache.Remove(num);
					}
				}
				else
				{
					_failedItems.Add(itemId);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)$"[IconCache] Error caching sprite {itemId}: {ex.Message}");
				}
				_failedItems.Add(itemId);
			}
		}

		private static Texture2D ExtractSpriteTexture(Sprite sprite)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0066: Expected O, but got Unknown
			try
			{
				Rect rect = sprite.rect;
				int num = (int)((Rect)(ref rect)).width;
				int num2 = (int)((Rect)(ref rect)).height;
				if (!((Texture)sprite.texture).isReadable)
				{
					return CopyTextureViaRenderTexture(sprite);
				}
				Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false);
				Color[] pixels = sprite.texture.GetPixels((int)((Rect)(ref rect)).x, (int)((Rect)(ref rect)).y, num, num2);
				val.SetPixels(pixels);
				val.Apply();
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)("[IconCache] Error extracting sprite texture: " + ex.Message));
				}
				return null;
			}
		}

		private static Texture2D CopyTextureViaRenderTexture(Sprite sprite)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			RenderTexture val = null;
			RenderTexture active = RenderTexture.active;
			try
			{
				Rect rect = sprite.rect;
				int num = (int)((Rect)(ref rect)).width;
				int num2 = (int)((Rect)(ref rect)).height;
				val = RenderTexture.GetTemporary(((Texture)sprite.texture).width, ((Texture)sprite.texture).height, 0, (RenderTextureFormat)0);
				Graphics.Blit((Texture)(object)sprite.texture, val);
				RenderTexture.active = val;
				Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false);
				val2.ReadPixels(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, (float)num, (float)num2), 0, 0);
				val2.Apply();
				return val2;
			}
			catch (Exception ex)
			{
				ManualLogSource log = _log;
				if (log != null)
				{
					log.LogDebug((object)("[IconCache] Error copying texture via RenderTexture: " + ex.Message));
				}
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				if ((Object)(object)val != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val);
				}
			}
		}

		private static Texture2D CreateFallbackTexture()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			int num = 32;
			Texture2D val = new Texture2D(num, num);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.3f, 0.3f, 0.4f, 0.8f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.5f, 0.5f, 0.6f, 1f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					if (j == 0 || j == num - 1 || i == 0 || i == num - 1)
					{
						val.SetPixel(j, i, val3);
					}
					else
					{
						val.SetPixel(j, i, val2);
					}
				}
			}
			val.Apply();
			return val;
		}

		public static void Clear()
		{
			foreach (KeyValuePair<int, CachedIcon> item in _iconCache)
			{
				if (item.Value.OwnsTexture && (Object)(object)item.Value.Texture != (Object)null)
				{
					Object.Destroy((Object)(object)item.Value.Texture);
				}
			}
			_iconCache.Clear();
			_loadingItems.Clear();
			_failedItems.Clear();
			_initialized = false;
			_iconsLoaded = false;
			_pendingPreloadItemIds = null;
		}

		public static (int loaded, int loading, int failed) GetStats()
		{
			return (_iconCache.Count, _loadingItems.Count, _failedItems.Count);
		}

		public static void LogStatus()
		{
			(int, int, int) stats = GetStats();
			ManualLogSource log = _log;
			if (log != null)
			{
				log.LogInfo((object)$"[IconCache] Loaded: {stats.Item1}, Loading: {stats.Item2}, Failed: {stats.Item3}");
			}
		}
	}
	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 TheVault
{
	public static class ItemIds
	{
		public const int SpringToken = 18020;

		public const int SummerToken = 18021;

		public const int WinterToken = 18022;

		public const int FallToken = 18023;

		public const int CopperKey = 1251;

		public const int IronKey = 1252;

		public const int AdamantKey = 1253;

		public const int MithrilKey = 1254;

		public const int SuniteKey = 1255;

		public const int GloriteKey = 1256;

		public const int KingsLostMineKey = 1257;

		public const int CommunityToken = 18013;

		public const int Doubloon = 60014;

		public const int BlackBottleCap = 60013;

		public const int RedCarnivalTicket = 18012;

		public const int CandyCornPieces = 18016;

		public const int ManaShard = 18015;
	}
	public class PersistentUpdateRunner : MonoBehaviour
	{
		private string _lastKnownScene = "";

		private bool _wasInMenuScene = true;

		private float _sceneCheckTimer;

		private float _heartbeatTimer;

		private int _heartbeatCount;

		private const float SCENE_CHECK_INTERVAL = 0.5f;

		private const float HEARTBEAT_INTERVAL = 30f;

		private void Awake()
		{
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"[PersistentRunner] Created hidden persistent runner");
			}
		}

		private void Update()
		{
			Plugin.TickAutoSave();
			_sceneCheckTimer += Time.deltaTime;
			if (_sceneCheckTimer >= 0.5f)
			{
				_sceneCheckTimer = 0f;
				CheckForMenuSceneChange();
			}
			_heartbeatTimer += Time.deltaTime;
			if (_heartbeatTimer >= 30f)
			{
				_heartbeatTimer = 0f;
				_heartbeatCount++;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)string.Format("[PersistentRunner Heartbeat #{0}] Scene: {1}, VaultLoaded: {2}, Character: {3}", _heartbeatCount, _lastKnownScene, PlayerPatches.IsVaultLoaded, PlayerPatches.LoadedCharacterName ?? "none"));
				}
			}
			CheckHotkeys();
			if (PlayerPatches.IsVaultLoaded)
			{
				ItemPatches.DrainAutoDepositNotifications();
			}
			PlayerPatches.TrySynchronizeCharacterContext();
		}

		private void CheckHotkeys()
		{
			//IL_005b: 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_0073: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!TextInputFocusGuard.ShouldDeferModHotkeys(Plugin.Log) && !((Object)(object)Plugin.GetVaultUI() == (Object)null))
				{
					if ((!Plugin.StaticRequireCtrl || Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown(Plugin.StaticToggleKey))
					{
						Plugin.ToggleMainVaultWindow();
					}
					if ((int)Plugin.StaticAltToggleKey != 0 && Input.GetKeyDown(Plugin.StaticAltToggleKey))
					{
						Plugin.ToggleMainVaultWindow();
					}
					if (Input.GetKeyDown(Plugin.StaticHUDToggleKey))
					{
						Plugin.GetVaultHUD()?.Toggle();
					}
					if ((int)Plugin.StaticQuickConvertKey != 0 && Input.GetKeyDown(Plugin.StaticQuickConvertKey))
					{
						Plugin.TryQuickConvertHotkey();
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("[PersistentRunner] Hotkey error: " + ex.Message));
				}
			}
		}

		private void CheckForMenuSceneChange()
		{
			//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)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				if (!(name != _lastKnownScene))
				{
					return;
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("[PersistentRunner] Scene changed: '" + _lastKnownScene + "' -> '" + name + "'"));
				}
				_lastKnownScene = name;
				string text = name.ToLowerInvariant();
				bool flag = text.Contains("menu") || text.Contains("title");
				if (flag && !_wasInMenuScene)
				{
					ManualLogSource log2 = Plugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)("[PersistentRunner] Menu scene detected: " + name));
					}
					PlayerPatches.SaveAndReset();
				}
				_wasInMenuScene = flag;
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[PersistentRunner] Error: " + ex.Message));
				}
			}
		}

		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).");
				}
			}
		}
	}
	[BepInPlugin("com.azraelgodking.thevault", "The Vault", "3.3.2")]
	public class Plugin : BaseUnityPlugin
	{
		private readonly struct QuickConvertRule
		{
			public string FromCurrencyId { get; }

			public string ToCurrencyId { get; }

			public int FromAmount { get; }

			public int ToAmount { get; }

			public QuickConvertRule(string fromCurrencyId, string toCurrencyId, int fromAmount, int toAmount)
			{
				FromCurrencyId = fromCurrencyId;
				ToCurrencyId = toCurrencyId;
				FromAmount = fromAmount;
				ToAmount = toAmount;
			}
		}

		private static VaultManager _staticVaultManager;

		private static VaultSaveSystem _staticSaveSystem;

		private static VaultUI _staticVaultUI;

		private static VaultHUD _staticVaultHUD;

		internal static KeyCode StaticToggleKey = (KeyCode)118;

		internal static bool StaticRequireCtrl = true;

		internal static KeyCode StaticAltToggleKey = (KeyCode)289;

		internal static KeyCode StaticHUDToggleKey = (KeyCode)288;

		internal static KeyCode StaticQuickConvertKey = (KeyCode)287;

		private const float MinWindowScale = 0.5f;

		private const float MaxWindowScale = 3f;

		private Harmony _harmony;

		private VaultManager _vaultManager;

		private VaultSaveSystem _saveSystem;

		private VaultUI _vaultUI;

		private VaultHUD _vaultHUD;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<bool> _requireCtrlModifier;

		private ConfigEntry<KeyCode> _altToggleKey;

		private ConfigEntry<bool> _enableHUD;

		private ConfigEntry<string> _hudPosition;

		private ConfigEntry<float> _hudPositionX;

		private ConfigEntry<float> _hudPositionY;

		private ConfigEntry<float> _hudScale;

		private ConfigEntry<bool> _hudCompactMode;

		private ConfigEntry<string> _hudDensity;

		private ConfigEntry<KeyCode> _hudToggleKey;

		private ConfigEntry<KeyCode> _quickConvertKey;

		private ConfigEntry<string> _quickConvertTable;

		private ConfigEntry<float> _windowScale;

		private ConfigEntry<bool> _enableAutoSave;

		private ConfigEntry<float> _autoSaveInterval;

		private ConfigEntry<bool> _checkForUpdates;

		private string _hudPositionConfigBaseline;

		private static bool _debugFullVaultInspector;

		private bool _wasInMenuScene = true;

		private bool _applicationQuitting;

		private static GameObject _persistentRunner;

		private static PersistentUpdateRunner _updateRunner;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static ConfigFile ConfigFile { get; private set; }

		public static bool LastVaultLoadQuarantinedCorruptFile
		{
			get
			{
				if (_staticSaveSystem != null)
				{
					return _staticSaveSystem.LastLoadQuarantinedCorruptFile;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigFile = CreateNamedConfig();
			ConfigFileHelper.ReplacePluginConfig((BaseUnityPlugin)(object)this, ConfigFile, (Action<string>)Log.LogWarning);
			Log.LogInfo((object)"Loading The Vault v3.3.2");
			VaultSaveCompatibility.WarnIfBreakingRelease(Log);
			CreatePersistentRunner();
			try
			{
				InitializeConfig();
				SubscribeConfigChanged();
				_vaultManager = new VaultManager();
				_saveSystem = new VaultSaveSystem(_vaultManager);
				_staticVaultManager = _vaultManager;
				_staticSaveSystem = _saveSystem;
				_saveSystem.SetAutoSaveIntervalSeconds(Mathf.Max(10f, _autoSaveInterval.Value));
				_vaultManager.OnVaultLoaded += OnVaultDataLoaded;
				GameObject val = CreateTheVaultUiHost();
				Object.DontDestroyOnLoad((Object)(object)val);
				_vaultUI = val.AddComponent<VaultUI>();
				_vaultUI.Initialize(_vaultManager);
				_vaultUI.SetScale(GetValidatedWindowScale());
				_vaultUI.SetToggleKey(_toggleKey.Value, _requireCtrlModifier.Value);
				_vaultUI.SetAltToggleKey(_altToggleKey.Value);
				_staticVaultUI = _vaultUI;
				StaticToggleKey = _toggleKey.Value;
				StaticRequireCtrl = _requireCtrlModifier.Value;
				StaticAltToggleKey = _altToggleKey.Value;
				StaticHUDToggleKey = _hudToggleKey.Value;
				StaticQuickConvertKey = _quickConvertKey.Value;
				_vaultHUD = val.AddComponent<VaultHUD>();
				_vaultHUD.Initialize(_vaultManager);
				_vaultHUD.SetEnabled(_enableHUD.Value);
				ApplyVaultHudPlacementFromConfig(_vaultHUD);
				WireVaultHudPositionPersistence(_vaultHUD);
				_vaultHUD.SetScale(Mathf.Clamp(_hudScale.Value, 0.5f, 3f));
				_vaultHUD.SetHudDensity(GetResolvedHudDensity());
				_staticVaultHUD = _vaultHUD;
				VaultModApiBridge.Instance = (IVaultModApi)(object)new VaultModApiAdapter();
				IconCache.Initialize(Log);
				RegisterIconCacheCurrencies();
				RegisterItemMappings();
				_harmony = new Harmony("com.azraelgodking.thevault");
				ApplyPatches();
				PatchGameSave();
				SceneManager.sceneLoaded += OnSceneLoaded;
				Log.LogInfo((object)"Subscribed to SceneManager.sceneLoaded for vault loading");
				if (_checkForUpdates.Value)
				{
					VersionChecker.CheckForUpdate("com.azraelgodking.thevault", "3.3.2", Log, delegate(VersionChecker.VersionCheckResult result)
					{
						result.NotifyUpdateAvailable(Log);
					});
				}
				Log.LogInfo((object)"The Vault loaded successfully!");
				Log.LogInfo((object)string.Format("Press {0}{1} or {2} to open the vault", _requireCtrlModifier.Value ? "Ctrl+" : "", _toggleKey.Value, _altToggleKey.Value));
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("Failed to load {0}: {1}", "The Vault", arg));
			}
		}

		private void CreatePersistentRunner()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if ((Object)(object)_persistentRunner != (Object)null)
			{
				Log.LogInfo((object)"PersistentRunner already exists");
				return;
			}
			_persistentRunner = new GameObject("TheVault_PersistentRunner");
			Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
			((Object)_persistentRunner).hideFlags = (HideFlags)61;
			SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
			_updateRunner = _persistentRunner.AddComponent<PersistentUpdateRunner>();
			Log.LogInfo((object)"Created hidden PersistentRunner that survives game cleanup");
		}

		private static ConfigFile CreateNamedConfig()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "TheVault.cfg");
			string text2 = Path.Combine(Paths.ConfigPath, "com.azraelgodking.thevault.cfg");
			try
			{
				if (!File.Exists(text) && File.Exists(text2))
				{
					File.Copy(text2, text);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[Config] Migration to TheVault.cfg failed: " + ex.Message));
				}
			}
			return new ConfigFile(text, true);
		}

		private static GameObject CreateTheVaultUiHost()
		{
			//IL_0018: 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_002f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			GameObject val = new GameObject("TheVault_UI", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			component.anchoredPosition = Vector2.zero;
			((Transform)component).localScale = Vector3.one;
			return val;
		}

		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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_persistentRunner == (Object)null || (Object)(object)_updateRunner == (Object)null)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)"[EnsureUI] Recreating PersistentRunner...");
					}
					_persistentRunner = new GameObject("TheVault_PersistentRunner");
					Object.DontDestroyOnLoad((Object)(object)_persistentRunner);
					((Object)_persistentRunner).hideFlags = (HideFlags)61;
					SceneRootSurvivor.TryRegisterPersistentRunnerGameObject(_persistentRunner);
					_updateRunner = _persistentRunner.AddComponent<PersistentUpdateRunner>();
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogInfo((object)"[EnsureUI] PersistentRunner recreated");
					}
				}
				if ((Object)(object)_staticVaultUI == (Object)null)
				{
					ManualLogSource log3 = Log;
					if (log3 != null)
					{
						log3.LogInfo((object)"[EnsureUI] Recreating VaultUI...");
					}
					GameObject obj = CreateTheVaultUiHost();
					Object.DontDestroyOnLoad((Object)(object)obj);
					_staticVaultUI = obj.AddComponent<VaultUI>();
					_staticVaultUI.Initialize(_staticVaultManager);
					float scale = (((Object)(object)Instance != (Object)null) ? Instance.GetValidatedWindowScale() : 1f);
					_staticVaultUI.SetScale(scale);
					_staticVaultUI.SetToggleKey(StaticToggleKey, StaticRequireCtrl);
					_staticVaultUI.SetAltToggleKey(StaticAltToggleKey);
					_staticVaultHUD = obj.AddComponent<VaultHUD>();
					_staticVaultHUD.Initialize(_staticVaultManager);
					if ((Object)(object)Instance != (Object)null)
					{
						Instance._vaultUI = _staticVaultUI;
						Instance._vaultHUD = _staticVaultHUD;
						_staticVaultHUD.SetEnabled(Instance._enableHUD.Value);
						Instance.ApplyVaultHudPlacementFromConfig(_staticVaultHUD);
						Instance.WireVaultHudPositionPersistence(_staticVaultHUD);
						_staticVaultHUD.SetScale(Mathf.Clamp(Instance._hudScale.Value, 0.5f, 3f));
						_staticVaultHUD.SetHudDensity(GetResolvedHudDensity());
					}
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogInfo((object)"[EnsureUI] VaultUI and VaultHUD recreated");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log5 = Log;
				if (log5 != null)
				{
					log5.LogError((object)("[EnsureUI] Error recreating UI: " + ex.Message));
				}
			}
		}

		private void InitializeConfig()
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			_toggleKey = ConfigFile.Bind<KeyCode>("UI", "ToggleKey", (KeyCode)118, "Key to toggle the vault UI");
			_requireCtrlModifier = ConfigFile.Bind<bool>("UI", "RequireCtrlModifier", true, "Require Ctrl key to be held when pressing toggle key");
			_altToggleKey = ConfigFile.Bind<KeyCode>("UI", "AltToggleKey", (KeyCode)289, "Alternative key to toggle vault UI (no modifier required). Useful for Steam Deck.");
			_enableHUD = ConfigFile.Bind<bool>("HUD", "EnableHUD", true, "Show a persistent HUD bar displaying vault currency totals");
			_hudPosition = ConfigFile.Bind<string>("HUD", "Position", "TopLeft", "Anchor when not using a custom drag position. Changing this clears PositionX/PositionY. Drag the HUD top strip to save a custom position (like Sun Haven Todo).");
			_hudPositionX = ConfigFile.Bind<float>("HUD", "PositionX", -1f, "HUD left edge in pixels after dragging (-1 = use Position anchor only)");
			_hudPositionY = ConfigFile.Bind<float>("HUD", "PositionY", -1f, "HUD top edge in pixels after dragging (-1 = use Position anchor only)");
			_hudScale = ConfigFile.Bind<float>("HUD", "Scale", 1.25f, new ConfigDescription("Scale factor for the HUD bar (1.0 = smaller, 1.25 = new default, 2.0 = very large). Use a dot as decimal separator in the config file (e.g. 1.25).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			_hudCompactMode = ConfigFile.Bind<bool>("HUD", "CompactMode", false, "Legacy: when Density is Normal and this is true, HUD uses Compact spacing. Prefer [HUD] Density.");
			_hudDensity = ConfigFile.Bind<string>("HUD", "Density", "Normal", new ConfigDescription("HUD bar density: Normal, Compact, or Minimal.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Normal", "Compact", "Minimal" }), Array.Empty<object>()));
			_windowScale = ConfigFile.Bind<float>("Display", "WindowScale", 1f, new ConfigDescription("Scale factor for the main Vault window (1.0 = default, 1.5 = 50% larger)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			_hudToggleKey = ConfigFile.Bind<KeyCode>("HUD", "ToggleKey", (KeyCode)288, "Key to toggle the HUD display on/off");
			_quickConvertKey = ConfigFile.Bind<KeyCode>("Hotkeys", "QuickConvertKey", (KeyCode)287, "Key to trigger quick token/key conversion using [QuickConvert] ExchangeTable");
			_quickConvertTable = ConfigFile.Bind<string>("QuickConvert", "ExchangeTable", "seasonal_Winter->key_copper:10:1;key_copper->seasonal_Winter:1:10", "Conversion rules: from->to:fromAmount:toAmount;from->to:... (example seasonal_Winter->key_copper:10:1)");
			_enableAutoSave = ConfigFile.Bind<bool>("Saving", "EnableAutoSave", true, "Automatically save vault data periodically");
			_autoSaveInterval = ConfigFile.Bind<float>("Saving", "AutoSaveInterval", 300f, "Auto-save interval in seconds (default: 5 minutes)");
			_checkForUpdates = ConfigFile.Bind<bool>("Updates", "CheckForUpdates", true, "Check for mod updates on startup");
			_hudPositionConfigBaseline = _hudPosition.Value;
		}

		private void SubscribeConfigChanged()
		{
			if (ConfigFile != null)
			{
				ConfigFile.SettingChanged += OnAnyConfigSettingChanged;
			}
		}

		private void OnAnyConfigSettingChanged(object sender, SettingChangedEventArgs args)
		{
			try
			{
				if (((args != null) ? args.ChangedSetting : null) != null && args.ChangedSetting.ConfigFile == ConfigFile)
				{
					ApplyConfigToState();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[The Vault] Config change handler failed: " + ex.Message));
				}
			}
		}

		private void ApplyConfigToState()
		{
			//IL_000d: 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_002d: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float validatedWindowScale = GetValidatedWindowScale();
				StaticToggleKey = _toggleKey.Value;
				StaticRequireCtrl = _requireCtrlModifier.Value;
				StaticAltToggleKey = _altToggleKey.Value;
				StaticHUDToggleKey = _hudToggleKey.Value;
				StaticQuickConvertKey = _quickConvertKey.Value;
				_staticSaveSystem?.SetAutoSaveIntervalSeconds(Mathf.Max(10f, _autoSaveInterval.Value));
				VaultUI vaultUI = GetVaultUI();
				if ((Object)(object)vaultUI != (Object)null)
				{
					vaultUI.SetScale(validatedWindowScale);
					vaultUI.SetToggleKey(StaticToggleKey, StaticRequireCtrl);
					vaultUI.SetAltToggleKey(StaticAltToggleKey);
				}
				VaultHUD vaultHUD = GetVaultHUD();
				if ((Object)(object)vaultHUD != (Object)null)
				{
					vaultHUD.SetEnabled(_enableHUD.Value);
					string value = _hudPosition.Value;
					if (!string.Equals(value, _hudPositionConfigBaseline, StringComparison.OrdinalIgnoreCase))
					{
						((ConfigEntryBase)_hudPositionX).SetSerializedValue("-1");
						((ConfigEntryBase)_hudPositionY).SetSerializedValue("-1");
						vaultHUD.ClearCustomHudPlacement();
					}
					_hudPositionConfigBaseline = value;
					vaultHUD.SetPosition(ParseHUDPosition(value));
					if (_hudPositionX.Value >= 0f && _hudPositionY.Value >= 0f)
					{
						vaultHUD.RestoreHudPixelPosition(_hudPositionX.Value, _hudPositionY.Value);
					}
					vaultHUD.SetScale(Mathf.Clamp(_hudScale.Value, 0.5f, 3f));
					vaultHUD.SetHudDensity(GetResolvedHudDensity());
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[The Vault] ApplyConfigToState failed: " + ex.Message));
				}
			}
		}

		public void ApplyVaultWindowScaleToUi()
		{
			float validatedWindowScale = GetValidatedWindowScale();
			_staticVaultUI?.SetScale(validatedWindowScale);
		}

		public void ReloadConfig()
		{
			try
			{
				ConfigFile.Reload();
				ApplyConfigToState();
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"[The Vault] Config reloaded from file");
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogError((object)("[The Vault] Config reload failed: " + ex.Message));
				}
			}
		}

		public static KeyCode GetConfigToggleKey()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			return (Instance?._toggleKey?.Value).GetValueOrDefault((KeyCode)118);
		}

		public static void SetConfigToggleKey(KeyCode k)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Instance?._toggleKey != null)
			{
				Instance._toggleKey.Value = k;
			}
		}

		public static bool GetConfigRequireCtrl()
		{
			return (Instance?._requireCtrlModifier?.Value).GetValueOrDefault(true);
		}

		public static void SetConfigRequireCtrl(bool v)
		{
			if (Instance?._requireCtrlModifier != null)
			{
				Instance._requireCtrlModifier.Value = v;
			}
		}

		public static KeyCode GetConfigAltToggleKey()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			return (Instance?._altToggleKey?.Value).GetValueOrDefault((KeyCode)289);
		}

		public static void SetConfigAltToggleKey(KeyCode k)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Instance?._altToggleKey != null)
			{
				Instance._altToggleKey.Value = k;
			}
		}

		public static bool GetConfigHUDEnabled()
		{
			return (Instance?._enableHUD?.Value).GetValueOrDefault(true);
		}

		public static void SetConfigHUDEnabled(bool v)
		{
			if (Instance?._enableHUD != null)
			{
				Instance._enableHUD.Value = v;
			}
		}

		public static float GetConfigHUDScale()
		{
			return (Instance?._hudScale?.Value).GetValueOrDefault(1f);
		}

		public static void SetConfigHUDScale(float v)
		{
			if (Instance?._hudScale != null)
			{
				Instance._hudScale.Value = Mathf.Clamp(v, 0.5f, 3f);
			}
		}

		public static bool GetConfigHUDCompactMode()
		{
			return (Instance?._hudCompactMode?.Value).GetValueOrDefault();
		}

		public static void SetConfigHUDCompactMode(bool v)
		{
			if (Instance?._hudCompactMode != null)
			{
				Instance._hudCompactMode.Value = v;
			}
		}

		public static string GetConfigHudDensity()
		{
			return Instance?._hudDensity?.Value ?? "Normal";
		}

		public static void SetConfigHudDensity(string v)
		{
			if (Instance?._hudDensity != null)
			{
				if (string.IsNullOrWhiteSpace(v))
				{
					v = "Normal";
				}
				Instance._hudDensity.Value = v;
			}
		}

		public static VaultHudDensity GetResolvedHudDensity()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				return VaultHudDensity.Normal;
			}
			string a = Instance._hudDensity?.Value?.Trim() ?? "Normal";
			if (string.Equals(a, "Minimal", StringComparison.OrdinalIgnoreCase))
			{
				return VaultHudDensity.Minimal;
			}
			if (string.Equals(a, "Compact", StringComparison.OrdinalIgnoreCase))
			{
				return VaultHudDensity.Compact;
			}
			if (Instance._hudCompactMode != null && Instance._hudCompactMode.Value)
			{
				return VaultHudDensity.Compact;
			}
			return VaultHudDensity.Normal;
		}

		public static float GetConfigWindowScale()
		{
			return Instance?.GetValidatedWindowScale() ?? 1f;
		}

		public static void SetConfigWindowScale(float v)
		{
			if (Instance?._windowScale != null)
			{
				Instance._windowScale.Value = Instance.ClampWindowScaleValue(v);
			}
		}

		private float GetValidatedWindowScale()
		{
			if (_windowScale == null)
			{
				return 1f;
			}
			float num = ClampWindowScaleValue(_windowScale.Value);
			if (!Mathf.Approximately(_windowScale.Value, num))
			{
				_windowScale.Value = num;
			}
			return num;
		}

		private float ClampWindowScaleValue(float value)
		{
			return Mathf.Clamp(value, 0.5f, 3f);
		}

		public static bool GetConfigDebugFullVaultInspector()
		{
			return _debugFullVaultInspector;
		}

		public static void SetConfigDebugFullVaultInspector(bool v)
		{
			_debugFullVaultInspector = v;
		}

		private void RegisterIconCacheCurrencies()
		{
			IconCache.RegisterCurrency("seasonal_Spring", 18020);
			IconCache.RegisterCurrency("seasonal_Summer", 18021);
			IconCache.RegisterCurrency("seasonal_Fall", 18023);
			IconCache.RegisterCurrency("seasonal_Winter", 18022);
			IconCache.RegisterCurrency("key_copper", 1251);
			IconCache.RegisterCurrency("key_iron", 1252);
			IconCache.RegisterCurrency("key_adamant", 1253);
			IconCache.RegisterCurrency("key_mithril", 1254);
			IconCache.RegisterCurrency("key_sunite", 1255);
			IconCache.RegisterCurrency("key_glorite", 1256);
			IconCache.RegisterCurrency("key_kingslostmine", 1257);
			IconCache.RegisterCurrency("special_communitytoken", 18013);
			IconCache.RegisterCurrency("special_doubloon", 60014);
			IconCache.RegisterCurrency("special_blackbottlecap", 60013);
			IconCache.RegisterCurrency("special_redcarnivalticket", 18012);
			IconCache.RegisterCurrency("special_candycornpieces", 18016);
			IconCache.RegisterCurrency("special_manashard", 18015);
		}

		private void RegisterItemMappings()
		{
			ItemPatches.AutoDepositEnabled = true;
			ItemPatches.RegisterItemCurrencyMapping(18020, "seasonal_Spring", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18021, "seasonal_Summer", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18022, "seasonal_Winter", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18023, "seasonal_Fall", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1251, "key_copper", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1252, "key_iron", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1253, "key_adamant", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1254, "key_mithril", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1255, "key_sunite", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1256, "key_glorite", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(1257, "key_kingslostmine", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18013, "special_communitytoken", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(60014, "special_doubloon", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(60013, "special_blackbottlecap", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18012, "special_redcarnivalticket", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18016, "special_candycornpieces", autoDeposit: true);
			ItemPatches.RegisterItemCurrencyMapping(18015, "special_manashard", autoDeposit: true);
			ItemPatches.InitializePickupCache();
			Log.LogInfo((object)"Registered item-to-currency mappings with auto-deposit enabled");
		}

		private void ApplyPatches()
		{
			try
			{
				Type typeFromHandle = typeof(Player);
				PatchMethod(typeFromHandle, "InitializeAsOwner", typeof(PlayerPatches), "OnPlayerInitialized");
				PatchShopBuyItem();
				PatchGameSaveSaveLoad();
				PatchMethod(typeof(MainMenuController), "HomeMenu", typeof(SaveLoadPatches), "OnReturnToMenu");
				Type type = AccessTools.TypeByName("Wish.TitleScreen");
				if (type != null)
				{
					PatchMethod(type, "Start", typeof(SaveLoadPatches), "OnReturnToMenu");
				}
				PatchItemPickup(typeFromHandle);
				IEnumerable<MethodBase> patchedMethods = _harmony.GetPatchedMethods();
				int num = 0;
				foreach (MethodBase item in patchedMethods)
				{
					Log.LogInfo((object)("Patched: " + item.DeclaringType?.Name + "." + item.Name));
					num++;
				}
				Log.LogInfo((object)$"Total methods patched: {num}");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Harmony patching failed: {arg}");
			}
		}

		private void PatchMethod(Type targetType, string methodName, Type patchType, string patchMethodName, Type[] parameters = null)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = ((parameters == null) ? AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null) : AccessTools.Method(targetType, methodName, parameters, (Type[])null));
				if (methodInfo == null)
				{
					Log.LogWarning((object)("Could not find method " + targetType.Name + "." + methodName + ". Available methods: " + DescribeAvailableMethods(targetType)));
				}
				else
				{
					MethodInfo methodInfo2 = AccessTools.Method(patchType, patchMethodName, (Type[])null, (Type[])null);
					if (methodInfo2 == null)
					{
						Log.LogWarning((object)("Could not find patch method " + patchType.Name + "." + patchMethodName));
						return;
					}
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Successfully patched " + targetType.Name + "." + methodName));
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to patch " + targetType.Name + "." + methodName + ": " + ex.Message));
			}
		}

		private void PatchMethodPrefix(Type targetType, string methodName, Type patchType, string patchMethodName, Type[] parameters = null)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = ((parameters == null) ? AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null) : AccessTools.Method(targetType, methodName, parameters, (Type[])null));
				if (methodInfo == null)
				{
					Log.LogWarning((object)("Could not find method " + targetType.Name + "." + methodName + ". Available methods: " + DescribeAvailableMethods(targetType)));
					return;
				}
				MethodInfo methodInfo2 = AccessTools.Method(patchType, patchMethodName, (Type[])null, (Type[])null);
				if (methodInfo2 == null)
				{
					Log.LogWarning((object)("Could not find patch method " + patchType.Name + "." + patchMethodName));
					return;
				}
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)("Successfully patched " + targetType.Name + "." + methodName + " (prefix)"));
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to patch " + targetType.Name + "." + methodName + ": " + ex.Message));
			}
		}

		private void PatchGameSave()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			try
			{
				Type typeFromHandle = typeof(GameSave);
				MethodInfo methodInfo = AccessTools.Method(typeof(GameSavePatches), "OnLoadCharacterAny", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Log.LogWarning((object)"Could not find GameSavePatches.OnLoadCharacterAny");
					return;
				}
				List<MethodInfo> list = (from m in AccessTools.GetDeclaredMethods(typeFromHandle)
					where string.Equals(m.Name, "LoadCharacter", StringComparison.Ordinal)
					select m).ToList();
				if (list.Count == 0)
				{
					Log.LogWarning((object)"No GameSave.LoadCharacter overloads found to patch");
					return;
				}
				foreach (MethodInfo item in list)
				{
					_harmony.Patch((MethodBase)item, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					string text = string.Join(", ", from p in item.GetParameters()
						select p.ParameterType.Name);
					Log.LogInfo((object)("Patched GameSave.LoadCharacter(" + text + ")"));
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error patching GameSave: " + ex.Message));
			}
		}

		private void PatchGameSaveSaveLoad()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			try
			{
				Type typeFromHandle = typeof(GameSave);
				MethodInfo methodInfo = AccessTools.Method(typeFromHandle, "SaveGame", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					MethodInfo methodInfo2 = AccessTools.Method(typeof(SaveLoadPatches), "OnGameSaved", (Type[])null, (Type[])null);
					if (methodInfo2 != null)
					{
						_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched GameSave.SaveGame");
					}
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeFromHandle, "LoadGame", (Type[])null, (Type[])null);
				if (methodInfo3 != null)
				{
					MethodInfo methodInfo4 = AccessTools.Method(typeof(SaveLoadPatches), "OnGameLoaded", (Type[])null, (Type[])null);
					if (methodInfo4 != null)
					{
						_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched GameSave.LoadGame");
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error patching GameSave save/load: " + ex.Message));
			}
		}

		private void PatchShopBuyItem()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			try
			{
				Type typeFromHandle = typeof(Shop);
				Type typeFromHandle2 = typeof(ShopItemInfo2);
				Type typeFromHandle3 = typeof(ShopLoot2);
				if (typeFromHandle2 != null)
				{
					MethodInfo methodInfo = AccessTools.Method(typeFromHandle, "BuyItem", new Type[2]
					{
						typeFromHandle2,
						typeof(int)
					}, (Type[])null);
					if (methodInfo != null)
					{
						MethodInfo methodInfo2 = AccessTools.Method(typeof(ShopPatches), "OnBeforeBuyItem", (Type[])null, (Type[])null);
						MethodInfo methodInfo3 = AccessTools.Method(typeof(ShopPatches), "OnAfterBuyItem", (Type[])null, (Type[])null);
						if (methodInfo2 != null)
						{
							_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							Log.LogInfo((object)"Patched Shop.BuyItem(ShopItemInfo2,int) for vault (prefix)");
						}
						if (methodInfo3 != null)
						{
							_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
							Log.LogInfo((object)"Patched Shop.BuyItem(ShopItemInfo2,int) for vault (postfix)");
						}
					}
				}
				if (!(typeFromHandle3 != null))
				{
					return;
				}
				MethodInfo methodInfo4 = AccessTools.Method(typeFromHandle, "BuyItem", new Type[2]
				{
					typeFromHandle3,
					typeof(int)
				}, (Type[])null);
				if (methodInfo4 != null)
				{
					MethodInfo methodInfo5 = AccessTools.Method(typeof(ShopPatches), "OnBeforeBuyItem", (Type[])null, (Type[])null);
					MethodInfo methodInfo6 = AccessTools.Method(typeof(ShopPatches), "OnAfterBuyItem", (Type[])null, (Type[])null);
					if (methodInfo5 != null)
					{
						_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched Shop.BuyItem(ShopLoot2,int) for vault (prefix)");
					}
					if (methodInfo6 != null)
					{
						_harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched Shop.BuyItem(ShopLoot2,int) for vault (postfix)");
					}
				}
				MethodInfo methodInfo7 = AccessTools.Method(typeFromHandle, "BuyItem", new Type[1] { typeFromHandle3 }, (Type[])null);
				if (methodInfo7 != null)
				{
					MethodInfo methodInfo8 = AccessTools.Method(typeof(ShopPatches), "OnBeforeBuyItemSingle", (Type[])null, (Type[])null);
					MethodInfo methodInfo9 = AccessTools.Method(typeof(ShopPatches), "OnAfterBuyItemSingle", (Type[])null, (Type[])null);
					if (methodInfo8 != null)
					{
						_harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched Shop.BuyItem(ShopLoot2) for vault (prefix)");
					}
					if (methodInfo9 != null)
					{
						_harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(methodInfo9), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)"Patched Shop.BuyItem(ShopLoot2) for vault (postfix)");
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error patching Shop: " + ex.Message));
			}
		}

		private void PatchItemPickup(Type playerType)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Expected O, but got Unknown
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Expected O, but got Unknown
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Expected O, but got Unknown
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0561: Expected O, but got Unknown
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Expected O, but got Unknown
			//IL_063c: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(playerType, "Pickup", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeof(ItemPatches), "OnPlayerPickupPrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(ItemPatches), "OnPlayerPickup", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					object obj = _harmony;
					object obj2 = methodInfo;
					? val = new HarmonyMethod(methodInfo2);
					if (methodInfo3 != null)
					{
						obj = (object)new HarmonyMethod(methodInfo3);
						obj2 = (object)val;
						val = obj2;
					}
					else
					{
						obj = null;
						obj2 = (object)val;
						val = obj2;
					}
					((Harmony)obj).Patch((MethodBase)val, (HarmonyMethod)obj2, (HarmonyMethod)obj, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Patched " + playerType.Name + ".Pickup for auto-deposit"));
				}
			}
			else
			{
				Log.LogWarning((object)"Could not find Pickup method on Player");
			}
			Type typeFromHandle = typeof(Inventory);
			MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			Type typeFromHandle2 = typeof(Item);
			MethodInfo methodInfo4 = AccessTools.Method(typeFromHandle, "AddItem", new Type[6]
			{
				typeFromHandle2,
				typeof(int),
				typeof(int),
				typeof(bool),
				typeof(bool),
				typeof(bool)
			}, (Type[])null);
			if (methodInfo4 != null)
			{
				MethodInfo methodInfo5 = AccessTools.Method(typeof(ItemPatches), "OnInventoryAddItemObjectPrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(ItemPatches), "OnInventoryAddItemObjectPostfix", (Type[])null, (Type[])null);
				if (methodInfo5 != null)
				{
					object obj3 = _harmony;
					object obj4 = methodInfo4;
					? val2 = new HarmonyMethod(methodInfo5);
					if (methodInfo6 != null)
					{
						obj3 = (object)new HarmonyMethod(methodInfo6);
						obj4 = (object)val2;
						val2 = obj4;
					}
					else
					{
						obj3 = null;
						obj4 = (object)val2;
						val2 = obj4;
					}
					((Harmony)obj3).Patch((MethodBase)val2, (HarmonyMethod)obj4, (HarmonyMethod)obj3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Patched " + typeFromHandle.Name + ".AddItem(Item,...) for auto-deposit"));
				}
				else if (methodInfo6 != null)
				{
					_harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Patched " + typeFromHandle.Name + ".AddItem(Item,...) postfix only"));
				}
			}
			else
			{
				Log.LogWarning((object)"Could not find AddItem(Item,int,int,bool,bool,bool)");
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo7 in array)
				{
					if (methodInfo7.Name != "AddItem")
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo7.GetParameters();
					if (parameters.Length == 0 || !(parameters[0].ParameterType == typeFromHandle2))
					{
						continue;
					}
					MethodInfo methodInfo8 = AccessTools.Method(typeof(ItemPatches), "OnInventoryAddItemObjectPrefix", (Type[])null, (Type[])null);
					MethodInfo methodInfo9 = AccessTools.Method(typeof(ItemPatches), "OnInventoryAddItemObjectPostfix", (Type[])null, (Type[])null);
					if (methodInfo8 != null)
					{
						object obj5 = _harmony;
						object obj6 = methodInfo7;
						? val3 = new HarmonyMethod(methodInfo8);
						if (methodInfo9 != null)
						{
							obj5 = (object)new HarmonyMethod(methodInfo9);
							obj6 = (object)val3;
							val3 = obj6;
						}
						else
						{
							obj5 = null;
							obj6 = (object)val3;
							val3 = obj6;
						}
						((Harmony)obj5).Patch((MethodBase)val3, (HarmonyMethod)obj6, (HarmonyMethod)obj5, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)("Patched " + typeFromHandle.Name + "." + methodInfo7.Name + " for auto-deposit"));
						break;
					}
					if (methodInfo9 != null)
					{
						_harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(methodInfo9), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Log.LogInfo((object)("Patched " + typeFromHandle.Name + "." + methodInfo7.Name + " postfix only"));
						break;
					}
				}
			}
			MethodInfo methodInfo10 = AccessTools.Method(typeFromHandle, "AddItem", new Type[2]
			{
				typeof(int),
				typeof(int)
			}, (Type[])null);
			if (methodInfo10 == null)
			{
				methodInfo10 = AccessTools.Method(typeFromHandle, "AddItem", new Type[3]
				{
					typeof(int),
					typeof(int),
					typeof(bool)
				}, (Type[])null);
			}
			if (methodInfo10 != null)
			{
				MethodInfo methodInfo11 = AccessTools.Method(typeof(ItemPatches), "OnInventoryAddItem", (Type[])null, (Type[])null);
				if (methodInfo11 != null)
				{
					_harmony.Patch((MethodBase)methodInfo10, (HarmonyMethod)null, new HarmonyMethod(methodInfo11), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Successfully patched " + typeFromHandle.Name + ".AddItem for auto-deposit"));
				}
			}
			MethodInfo methodInfo12 = AccessTools.Method(typeFromHandle, "GetAmount", new Type[1] { typeof(int) }, (Type[])null);
			if (methodInfo12 != null)
			{
				MethodInfo methodInfo13 = AccessTools.Method(typeof(ItemPatches), "OnInventoryGetAmount", (Type[])null, (Type[])null);
				if (methodInfo13 != null)
				{
					_harmony.Patch((MethodBase)methodInfo12, (HarmonyMethod)null, new HarmonyMethod(methodInfo13), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Successfully patched " + typeFromHandle.Name + ".GetAmount for vault integration"));
				}
			}
			else
			{
				Log.LogWarning((object)"Could not find Inventory.GetAmount method");
			}
			MethodInfo methodInfo14 = AccessTools.Method(typeFromHandle, "HasEnough", new Type[2]
			{
				typeof(int),
				typeof(int)
			}, (Type[])null);
			if (methodInfo14 != null)
			{
				MethodInfo methodInfo15 = AccessTools.Method(typeof(ItemPatches), "OnInventoryHasEnough", (Type[])null, (Type[])null);
				if (methodInfo15 != null)
				{
					_harmony.Patch((MethodBase)methodInfo14, (HarmonyMethod)null, new HarmonyMethod(methodInfo15), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Successfully patched " + typeFromHandle.Name + ".HasEnough for vault integration"));
				}
			}
			else
			{
				Log.LogWarning((object)"Could not find Inventory.HasEnough method");
			}
			MethodInfo methodInfo16 = AccessTools.Method(typeFromHandle, "RemoveItem", new Type[3]
			{
				typeof(int),
				typeof(int),
				typeof(int)
			}, (Type[])null);
			if (methodInfo16 != null)
			{
				MethodInfo methodInfo17 = AccessTools.Method(typeof(ItemPatches), "OnInventoryRemoveItemPrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo18 = AccessTools.Method(typeof(ItemPatches), "OnInventoryRemoveItemPostfix", (Type[])null, (Type[])null);
				if (methodInfo17 != null && methodInfo18 != null)
				{
					_harmony.Patch((MethodBase)methodInfo16, new HarmonyMethod(methodInfo17), new HarmonyMethod(methodInfo18), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("Successfully patched " + typeFromHandle.Name + ".RemoveItem for vault integration"));
				}
			}
			else
			{
				Log.LogWarning((object)"Could not find Inventory.RemoveItem method");
			}
		}

		private static string DescribeAvailableMethods(Type targetType)
		{
			if (targetType == null)
			{
				return "<no target type>";
			}
			try
			{
				IOrderedEnumerable<string> values = from s in targetType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Select(delegate(MethodInfo m)
					{
						string text = string.Join(", ", from p in m.GetParameters()
							select p.ParameterType.Name);
						return m.Name + "(" + text + ")";
					}).Distinct()
					orderby s
					select s;
				return string.Join("; ", values);
			}
			catch (Exception ex)
			{
				return "<failed to enumerate methods: " + ex.Message + ">";
			}
		}

		private void ApplyVaultHudPlacementFromConfig(VaultHUD hud)
		{
			hud.SetPosition(ParseHUDPosition(_hudPosition.Value));
			if (_hudPositionX.Value >= 0f && _hudPositionY.Value >= 0f)
			{
				hud.RestoreHudPixelPosition(_hudPositionX.Value, _hudPositionY.Value);
			}
		}

		private void WireVaultHudPositionPersistence(VaultHUD hud)
		{
			hud.OnPositionChanged = delegate(float x, float y)
			{
				((ConfigEntryBase)_hudPositionX).SetSerializedValue(x.ToString(CultureInfo.InvariantCulture));
				((ConfigEntryBase)_hudPositionY).SetSerializedValue(y.ToString(CultureInfo.InvariantCulture));
			};
		}

		private static VaultHUD.HUDPosition ParseHUDPosition(string position)
		{
			return position?.ToLower() switch
			{
				"topleft" => VaultHUD.HUDPosition.TopLeft, 
				"topcenter" => VaultHUD.HUDPosition.TopCenter, 
				"topright" => VaultHUD.HUDPosition.TopRight, 
				"bottomleft" => VaultHUD.HUDPosition.BottomLeft, 
				"bottomcenter" => VaultHUD.HUDPosition.BottomCenter, 
				"bottomright" => VaultHUD.HUDPosition.BottomRight, 
				_ => VaultHUD.HUDPosition.TopLeft, 
			};
		}

		private void OnApplicationQuit()
		{
			_applicationQuitting = true;
			Log.LogInfo((object)"Application quitting - saving vault data");
			_saveSystem?.ForceSave();
		}

		private void OnDisable()
		{
			//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;
			string text2 = text.ToLowerInvariant();
			if (!Application.isPlaying || text2.Contains("menu") || text2.Contains("title"))
			{
				Log.LogInfo((object)("[Lifecycle] Plugin OnDisable during expected teardown (scene: " + text + ")"));
				return;
			}
			Log.LogWarning((object)"[CRITICAL] Plugin OnDisable called outside expected teardown.");
			Log.LogWarning((object)("[CRITICAL] Current scene: " + text));
			Log.LogWarning((object)("[CRITICAL] Stack trace: " + Environment.StackTrace));
		}

		private void OnDestroy()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			VaultModApiBridge.Instance = null;
			if (_vaultManager != null)
			{
				_vaultManager.OnVaultLoaded -= OnVaultDataLoaded;
			}
			if (ConfigFile != null)
			{
				ConfigFile.SettingChanged -= OnAnyConfigSettingChanged;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			string text = ((Scene)(ref activeScene)).name ?? string.Empty;
			string text2 = text.ToLowerInvariant();
			if (_applicationQuitting || !Application.isPlaying || text2.Contains("menu") || text2.Contains("title"))
			{
				Log.LogInfo((object)("[Lifecycle] Plugin OnDestroy during expected teardown (scene: " + text + ")"));
			}
			else
			{
				Log.LogWarning((object)"[CRITICAL] Plugin OnDestroy called outside expected teardown.");
				Log.LogWarning((object)("[CRITICAL] Current scene: " + text));
				Log.LogWarning((object)("[CRITICAL] Stack trace: " + Environment.StackTrace));
			}
			SceneManager.sceneLoaded -= OnSceneLoaded;
			_saveSystem?.ForceSave();
		}

		public static VaultManager GetVaultManager()
		{
			return _staticVaultManager;
		}

		public static VaultSaveSystem GetSaveSystem()
		{
			return _staticSaveSystem;
		}

		public static VaultUI GetVaultUI()
		{
			return _staticVaultUI;
		}

		public static bool IsMainVaultPanelVisible()
		{
			if ((Object)(object)_staticVaultUI != (Object)null)
			{
				return _staticVaultUI.IsVisible;
			}
			return false;
		}

		public static void ToggleMainVaultWindow()
		{
			_staticVaultUI?.Toggle();
		}

		public static void OpenVault()
		{
			_staticVaultUI?.Show();
		}

		public static void CloseVault()
		{
			_staticVaultUI?.Hide();
		}

		public static bool LoadVaultForPlayer(string playerName)
		{
			if (_staticSaveSystem == null)
			{
				return false;
			}
			return _staticSaveSystem.Load(playerName);
		}

		public static void SaveVault()
		{
			_staticSaveSystem?.ForceSave();
		}

		public static VaultHUD GetVaultHUD()
		{
			return _staticVaultHUD;
		}

		public static void ToggleHUD()
		{
			_staticVaultHUD?.Toggle();
		}

		internal static void TickAutoSave()
		{
			if (Instance?._enableAutoSave != null && Instance._enableAutoSave.Value)
			{
				_staticSaveSystem?.CheckAutoSave();
			}
		}

		internal static void T

TheVault.Abstractions.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("TheVault.Abstractions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Small reference assembly for mods integrating with The Vault (no game references).")]
[assembly: AssemblyFileVersion("3.3.2.0")]
[assembly: AssemblyInformationalVersion("3.3.2+5c08b5aa5d0be9c4b93df77f697dc55d5ac97088")]
[assembly: AssemblyProduct("TheVault.Abstractions")]
[assembly: AssemblyTitle("TheVault.Abstractions")]
[assembly: AssemblyVersion("3.3.2.0")]
[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 TheVault.Modding
{
	public interface IVaultModApi
	{
		bool IsVaultReady { get; }

		bool RegisterCustomCurrency(string id, string displayName, int gameItemId = -1, bool enableAutoDeposit = false);
	}
	public static class VaultModApiBridge
	{
		public static IVaultModApi Instance { get; set; }

		public static event Action OnVaultLoaded;

		public static void NotifyVaultLoaded()
		{
			VaultModApiBridge.OnVaultLoaded?.Invoke();
		}
	}
}