using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HavensRespec.Config; using HavensRespec.Patches; using HavensRespec.Services; using HavensRespec.UI; using Microsoft.CodeAnalysis; using SunhavenMods.Shared; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; 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("HavensRespec")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+5c08b5aa5d0be9c4b93df77f697dc55d5ac97088")] [assembly: AssemblyProduct("HavensRespec")] [assembly: AssemblyTitle("HavensRespec")] [assembly: AssemblyVersion("1.0.0.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.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 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 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("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 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 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 HealthByPluginGuid = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly object HealthLock = new object(); private static readonly Dictionary ModPatternCache = new Dictionary(StringComparer.Ordinal); private static readonly object ModPatternCacheLock = new object(); private static readonly Regex ExtractFieldRegex = new Regex("\"(?[^\"]+)\"\\s*:\\s*(?:\"(?[^\"]*)\"|null)", RegexOptions.Compiled); public static void CheckForUpdate(string pluginGuid, string currentVersion, ManualLogSource logger = null, Action onComplete = null) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) TouchHealth(pluginGuid); VersionCheckRunner versionCheckRunner = new GameObject("VersionChecker").AddComponent(); 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 NoKillSubstrings = new List(); 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 list; lock (Lock) { if (NoKillSubstrings.Count == 0) { return; } list = new List(NoKillSubstrings); } List list2 = new List(__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[] fields = type.GetFields(AllBindingFlags); IEnumerable second; if (!(type.BaseType != null) || !(type.BaseType != typeof(object))) { second = Enumerable.Empty(); } else { IEnumerable 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[] properties = type.GetProperties(AllBindingFlags); IEnumerable second; if (!(type.BaseType != null) || !(type.BaseType != typeof(object))) { second = Enumerable.Empty(); } else { IEnumerable 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(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; } } } } namespace HavensRespec { [BepInPlugin("com.azraelgodking.havensrespec", "Haven's Respec", "1.3.2")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; private RespecConfig _config; private SkillResetService _resetService; private CostService _costService; private RespecController _controller; private bool _applicationQuitting; public static ManualLogSource Log { get; private set; } public static Plugin Instance { get; private set; } public static bool IsDebugLoggingEnabled { get { Plugin instance = Instance; if (instance == null) { return false; } return (instance._config?.DebugLogging?.Value).GetValueOrDefault(); } } private void Awake() { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; try { ConfigFile val = ConfigFileHelper.CreateNamedConfig("com.azraelgodking.havensrespec", "HavensRespec.cfg", (Action)Log.LogWarning); ConfigFileHelper.ReplacePluginConfig((BaseUnityPlugin)(object)this, val, (Action)Log.LogWarning); _config = new RespecConfig(val); if (!_config.Enabled.Value) { Log.LogInfo((object)"Haven's Respec disabled in config."); return; } _resetService = new SkillResetService(Log, () => IsDebugLoggingEnabled); _costService = new CostService(Log, _config); _controller = new RespecController(Log, _config, _resetService, _costService); _controller.Install(); _harmony = new Harmony("com.azraelgodking.havensrespec"); _harmony.PatchAll(typeof(SkillsSetupProfessionPatch)); try { VersionChecker.CheckForUpdate("com.azraelgodking.havensrespec", "1.3.2", Log); } catch (Exception ex) { Log.LogDebug((object)("[Respec] VersionChecker swallowed: " + ex.Message)); } Log.LogInfo((object)"Haven's Respec v1.3.2 loaded."); } catch (Exception arg) { Log.LogError((object)string.Format("{0} Awake failed: {1}", "Haven's Respec", arg)); } } private void OnApplicationQuit() { _applicationQuitting = true; } 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; string text2 = text.ToLowerInvariant(); if (_applicationQuitting || !Application.isPlaying || text2.Contains("menu") || text2.Contains("title")) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[Lifecycle] Haven's Respec OnDestroy during expected teardown (scene: " + text + ")")); } } else { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("[Lifecycle] Haven's Respec OnDestroy outside expected teardown (scene: " + text + ")")); } } try { _controller?.Uninstall(); } catch (Exception ex) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)("Haven's Respec OnDestroy: Uninstall failed: " + ex.Message)); } } finally { try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex2) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogWarning((object)("Haven's Respec OnDestroy: UnpatchSelf failed: " + ex2.Message)); } } } } private void Update() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_008e: Unknown result type (might be due to invalid IL or missing references) if (_controller == null || _config == null) { return; } KeyCode value = _config.ResetCurrentTabHotkey.Value; if ((int)value != 0 && Input.GetKeyDown(value)) { ProfessionType? val = _controller.TryGetActiveProfessionTab(); if (val.HasValue) { _controller.TryResetCurrentTab(val.Value, bypassConfirm: false); } } KeyCode value2 = _config.UndoHotkey.Value; if ((int)value2 != 0 && Input.GetKeyDown(value2)) { ProfessionType? val2 = _controller.TryGetActiveProfessionTab(); if (val2.HasValue) { _controller.TryUndoCurrentTab(val2.Value); } } } } internal static class PluginInfo { public const string PLUGIN_GUID = "com.azraelgodking.havensrespec"; public const string PLUGIN_NAME = "Haven's Respec"; public const string PLUGIN_VERSION = "1.3.2"; } } namespace HavensRespec.UI { internal sealed class ConfirmResetDialog : MonoBehaviour { private sealed class ButtonHoverTint : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler { public Image Target; public Color Normal; public Color Hover; public Color Pressed; private bool _isOver; public void OnPointerEnter(PointerEventData _) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) _isOver = true; Apply(Hover); } public void OnPointerExit(PointerEventData _) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) _isOver = false; Apply(Normal); } public void OnPointerDown(PointerEventData _) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Apply(Pressed); } public void OnPointerUp(PointerEventData _) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Apply(_isOver ? Hover : Normal); } private void Apply(Color fill) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Target == (Object)null)) { ((Graphic)Target).color = fill; } } } private TextMeshProUGUI _title; private TextMeshProUGUI _body; private Action _onConfirm; public static ConfirmResetDialog BuildUnder(Transform parent) { //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_002c: 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) //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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("HavensRespec_ConfirmDialog", new Type[1] { typeof(RectTransform) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent(parent, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; ((Transform)component).localScale = Vector3.one; Canvas val2 = ((Component)parent).GetComponent() ?? ((Component)parent).GetComponentInParent(); Canvas val3 = val.AddComponent(); if ((Object)(object)val2 != (Object)null) { val3.renderMode = val2.renderMode; val3.worldCamera = val2.worldCamera; val3.planeDistance = val2.planeDistance; } val3.overrideSorting = true; val3.sortingOrder = (((Object)(object)val2 != (Object)null) ? (val2.sortingOrder + 200) : 32000); val.AddComponent(); ConfirmResetDialog confirmResetDialog = val.AddComponent(); confirmResetDialog.BuildHierarchy(); confirmResetDialog.Hide(); return confirmResetDialog; } public void Show(string title, string body, Action onConfirm) { ((TMP_Text)_title).text = title ?? "Confirm reset?"; ((TMP_Text)_body).text = body ?? string.Empty; _onConfirm = onConfirm; ((Component)this).gameObject.SetActive(true); ((Component)this).transform.SetAsLastSibling(); } public void Hide() { ((Component)this).gameObject.SetActive(false); _onConfirm = null; } private void BuildHierarchy() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Scrim"); val.transform.SetParent(((Component)this).transform, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; Image obj2 = val.AddComponent(); obj2.sprite = RespecStyle.Solid(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj2).raycastTarget = true; Button obj3 = val.AddComponent