Decompiled source of TheVault v3.3.2
TheVault.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
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 agousing 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(); } } }