Decompiled source of NKVDebugMod v0.2.0
NKVDebugMod.dll
Decompiled a day 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.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using NKVDebugMod.Features.MonsterInspector; using NKVDebugMod.Features.MonsterInspector.Configuration; using NKVDebugMod.Features.MonsterInspector.HarmonyPatches; using NKVDebugMod.Features.MonsterInspector.UI; using NKVDebugMod.Features.SaveSlotsManager; using NKVDebugMod.Features.SaveSlotsManager.Configuration; using NKVDebugMod.Features.SaveSlotsManager.UI; using NKVDebugMod.Features.TimeControl; using NKVDebugMod.Features.TimeControl.Configuration; using NKVDebugMod.Features.TimeControl.UI; using NKVDebugMod.Features.UI; using NKVDebugMod.Features.UI.Controls; using NKVDebugMod.Features.UI.Controls.Fields; using NKVDebugMod.Features.UI.Drawing; using NineSolsAPI; using NineSolsAPI.Utils; using UnityEngine; using UnityEngine.SceneManagement; using UnityExplorer; using UnityExplorer.CacheObject; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NKVDebugMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("NKV Debug Mod")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+459e02dffc60529a5562d35b7c9ebda0c976f98b")] [assembly: AssemblyProduct("NKVDebugMod")] [assembly: AssemblyTitle("NKVDebugMod")] [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 NKVDebugMod { internal static class Log { private static ManualLogSource? logSource; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void Debug(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogDebug(data); } } internal static void Error(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogError(data); } } internal static void Fatal(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogFatal(data); } } internal static void Info(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogInfo(data); } } internal static void Message(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogMessage(data); } } internal static void Warning(object data) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogWarning(data); } } internal static void Exception(Exception ex, string message = "") { if (string.IsNullOrEmpty(message)) { ManualLogSource? obj = logSource; if (obj != null) { obj.LogError((object)(ex.Message + ", " + ex.StackTrace)); } return; } ManualLogSource? obj2 = logSource; if (obj2 != null) { obj2.LogError((object)(message + ". " + ex.Message + ", " + ex.StackTrace)); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("NKVDebugMod", "NKVDebugMod", "1.0.0")] public class NKVDebugMod : BaseUnityPlugin { private Harmony harmony; internal static bool IsUnityExplorerPresent; internal static ConfigFile ModConfig; private void Awake() { ModConfig = ((BaseUnityPlugin)this).Config; Log.Init(((BaseUnityPlugin)this).Logger); RCGLifeCycle.DontDestroyForever(((Component)this).gameObject); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; harmony = Harmony.CreateAndPatchAll(typeof(NKVDebugMod).Assembly, (string)null); MonsterInspectorFeature.Initialize(); TimeControlFeature.Initialize(); SaveManagerFeature.Initialize(); if (Chainloader.PluginInfos.ContainsKey("com.sinai.unityexplorer")) { IsUnityExplorerPresent = true; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin NKVDebugMod is loaded!"); } private void OnDestroy() { harmony.UnpatchSelf(); MonsterInspectorFeature.Destroy(); TimeControlFeature.Destroy(); SaveManagerFeature.Destroy(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "NKVDebugMod"; public const string PLUGIN_NAME = "NKVDebugMod"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace NKVDebugMod.Features.UI { internal class ModWindow { private bool _isVisible; private float _verticalRatio; private float _horizontalRatio; private float _verticalOffsetRatio; private float _horizontalOffsetRatio; private WindowFunction _windowDrawFunction; private string _title; public bool IsVisible { get { return _isVisible; } set { _isVisible = value; if (_isVisible) { CalculateWindowRect(); } } } public int Id { get; private set; } public Rect WindowSettingRect { get; private set; } public ModWindow(int id, float verticalRatio, float horizontalRatio, float offsetRatioX, float offsetRatioY, WindowFunction windowDrawFunction, string title) { _verticalRatio = Mathf.Min(1f, verticalRatio); _horizontalRatio = Mathf.Min(1f, horizontalRatio); _horizontalOffsetRatio = Mathf.Min(1f, offsetRatioX); _verticalOffsetRatio = Mathf.Min(1f, offsetRatioY); Id = id; _windowDrawFunction = windowDrawFunction; _title = title; } public void Draw() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0045: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_007d: Unknown result type (might be due to invalid IL or missing references) if (IsVisible) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; Texture2D background = new Texture2D(1, 1, (TextureFormat)5, false); GUI.Box(WindowSettingRect, GUIContent.none, new GUIStyle { normal = new GUIStyleState { background = background } }); Rect val = GUILayout.Window(Id, WindowSettingRect, new WindowFunction(DrawFunction), _title, Array.Empty<GUILayoutOption>()); if (val != WindowSettingRect) { WindowSettingRect = val; } } } private void DrawFunction(int id) { _windowDrawFunction.Invoke(id); GUI.DragWindow(); } private void CalculateWindowRect() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) float num = (float)Screen.width * _horizontalRatio; float num2 = (float)Screen.height * _verticalRatio; int num3 = Mathf.RoundToInt((float)Screen.width * _horizontalOffsetRatio); int num4 = Mathf.RoundToInt(((float)Screen.height - num2) * _verticalOffsetRatio); WindowSettingRect = new Rect((float)num3, (float)num4, num, num2); } } } namespace NKVDebugMod.Features.UI.Drawing { public static class Drawing { private static Texture2D? aaLineTex; private static Texture2D? lineTex; private static Material? blitMaterial; private static Material? blendMaterial; private static Rect lineRect; public static void DrawLine(Vector2 pointA, Vector2 pointB, Color color, float width, bool antiAlias) { //IL_0000: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_006e: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) float num = pointB.x - pointA.x; float num2 = pointB.y - pointA.y; float num3 = Mathf.Sqrt(num * num + num2 * num2); if (!(num3 < 0.001f)) { Texture2D val; Material val2; if (antiAlias) { width *= 3f; val = aaLineTex; val2 = blendMaterial; } else { val = lineTex; val2 = blitMaterial; } float num4 = width * num2 / num3; float num5 = width * num / num3; Matrix4x4 identity = Matrix4x4.identity; identity.m00 = num; identity.m01 = 0f - num4; identity.m03 = pointA.x + 0.5f * num4; identity.m10 = num2; identity.m11 = num5; identity.m13 = pointA.y - 0.5f * num5; GL.PushMatrix(); GL.MultMatrix(identity); Graphics.DrawTexture(lineRect, (Texture)(object)val, lineRect, 0, 0, 0, 0, color, val2); if (antiAlias) { Graphics.DrawTexture(lineRect, (Texture)(object)val, lineRect, 0, 0, 0, 0, color, val2); } GL.PopMatrix(); } } public static void DrawCircle(Vector2 center, int radius, Color color, float width, int segmentsPerQuarter) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) DrawCircle(center, radius, color, width, antiAlias: false, segmentsPerQuarter); } public static void DrawCircle(Vector2 center, int radius, Color color, float width, bool antiAlias, int segmentsPerQuarter) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0067: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) float num = (float)radius * 0.55191505f; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(center.x, center.y - (float)radius); Vector2 endTangent = default(Vector2); ((Vector2)(ref endTangent))..ctor(center.x - num, center.y - (float)radius); Vector2 startTangent = default(Vector2); ((Vector2)(ref startTangent))..ctor(center.x + num, center.y - (float)radius); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(center.x + (float)radius, center.y); Vector2 endTangent2 = default(Vector2); ((Vector2)(ref endTangent2))..ctor(center.x + (float)radius, center.y - num); Vector2 startTangent2 = default(Vector2); ((Vector2)(ref startTangent2))..ctor(center.x + (float)radius, center.y + num); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(center.x, center.y + (float)radius); Vector2 startTangent3 = default(Vector2); ((Vector2)(ref startTangent3))..ctor(center.x - num, center.y + (float)radius); Vector2 endTangent3 = default(Vector2); ((Vector2)(ref endTangent3))..ctor(center.x + num, center.y + (float)radius); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(center.x - (float)radius, center.y); Vector2 startTangent4 = default(Vector2); ((Vector2)(ref startTangent4))..ctor(center.x - (float)radius, center.y - num); Vector2 endTangent4 = default(Vector2); ((Vector2)(ref endTangent4))..ctor(center.x - (float)radius, center.y + num); DrawBezierLine(val, startTangent, val2, endTangent2, color, width, antiAlias, segmentsPerQuarter); DrawBezierLine(val2, startTangent2, val3, endTangent3, color, width, antiAlias, segmentsPerQuarter); DrawBezierLine(val3, startTangent3, val4, endTangent4, color, width, antiAlias, segmentsPerQuarter); DrawBezierLine(val4, startTangent4, val, endTangent, color, width, antiAlias, segmentsPerQuarter); } public static void DrawBezierLine(Vector2 start, Vector2 startTangent, Vector2 end, Vector2 endTangent, Color color, float width, bool antiAlias, int segments) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Vector2 pointA = CubeBezier(start, startTangent, end, endTangent, 0f); for (int i = 1; i < segments + 1; i++) { Vector2 val = CubeBezier(start, startTangent, end, endTangent, (float)i / (float)segments); DrawLine(pointA, val, color, width, antiAlias); pointA = val; } } private static Vector2 CubeBezier(Vector2 s, Vector2 st, Vector2 e, Vector2 et, float t) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) float num = 1f - t; return num * num * num * s + 3f * num * num * t * st + 3f * num * t * t * et + t * t * t * e; } static Drawing() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) aaLineTex = null; lineTex = null; blitMaterial = null; blendMaterial = null; lineRect = new Rect(0f, 0f, 1f, 1f); Initialize(); } private static void Initialize() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_006c: 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_00a2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)lineTex == (Object)null) { lineTex = new Texture2D(1, 1, (TextureFormat)5, false); lineTex.SetPixel(0, 1, Color.white); lineTex.Apply(); } if ((Object)(object)aaLineTex == (Object)null) { aaLineTex = new Texture2D(1, 3, (TextureFormat)5, false); aaLineTex.SetPixel(0, 0, new Color(1f, 1f, 1f, 0f)); aaLineTex.SetPixel(0, 1, Color.white); aaLineTex.SetPixel(0, 2, new Color(1f, 1f, 1f, 0f)); aaLineTex.Apply(); } blitMaterial = (Material)typeof(GUI).GetMethod("get_blitMaterial", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null); blendMaterial = (Material)typeof(GUI).GetMethod("get_blendMaterial", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, null); } } internal static class HitboxDrawer { private static Vector2 LocalToScreenPoint(Camera camera, Collider2D collider2D, Vector2 point) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) return LocalToScreenPoint(camera, Vector2.op_Implicit(((Component)collider2D).transform.TransformPoint(Vector2.op_Implicit(point + collider2D.offset)))); } private static Vector2 LocalToScreenPoint(Camera camera, Vector2 point) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(camera.WorldToScreenPoint(Vector2.op_Implicit(point))); return new Vector2((float)(int)Math.Round(val.x), (float)(int)Math.Round((float)Screen.height - val.y)); } internal static void DrawCollider2D(Collider2D collider2D, Color color) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_013e: Unknown result type (might be due to invalid IL or missing references) GameLevel gameLevel = SingletonBehaviour<GameCore>.Instance.gameLevel; if (gameLevel == null) { return; } Camera val = gameLevel.cameraCore?.theRealSceneCamera; if (val == null || !Object.op_Implicit((Object)(object)collider2D) || !((Behaviour)collider2D).isActiveAndEnabled || (!(collider2D is BoxCollider2D) && !(collider2D is EdgeCollider2D) && !(collider2D is PolygonCollider2D)) || 1 == 0) { return; } BoxCollider2D val2 = (BoxCollider2D)(object)((collider2D is BoxCollider2D) ? collider2D : null); if (val2 == null) { EdgeCollider2D val3 = (EdgeCollider2D)(object)((collider2D is EdgeCollider2D) ? collider2D : null); if (val3 == null) { PolygonCollider2D val4 = (PolygonCollider2D)(object)((collider2D is PolygonCollider2D) ? collider2D : null); if (val4 == null) { return; } for (int i = 0; i < val4.pathCount; i++) { List<Vector2> list = val4.GetPath(i).ToList(); if (list.Count > 0) { list.Add(list[0]); } DrawPoints(val, collider2D, list, color); } } else { DrawPoints(val, collider2D, val3.points.ToList(), color); } } else { Vector2 val5 = val2.size / 2f; Vector2 item = default(Vector2); ((Vector2)(ref item))..ctor(0f - val5.x, val5.y); Vector2 item2 = val5; Vector2 item3 = default(Vector2); ((Vector2)(ref item3))..ctor(val5.x, 0f - val5.y); Vector2 item4 = -val5; List<Vector2> points = new List<Vector2> { item, item2, item3, item4, item }; DrawPoints(val, collider2D, points, color); } } private static void DrawPoints(Camera camera, Collider2D collider, List<Vector2> points, Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) for (int i = 0; i < points.Count - 1; i++) { Vector2 pointA = LocalToScreenPoint(camera, collider, points[i]); Vector2 pointB = LocalToScreenPoint(camera, collider, points[i + 1]); Drawing.DrawLine(pointA, pointB, color, 3f, antiAlias: true); } } } } namespace NKVDebugMod.Features.UI.Controls { internal class ModButton { private bool _wasPressed; private string _text; public event Action? OnClick; public event Action? OnRelease; public ModButton(string text, Action? onClick = null, Action? onRelease = null) { _text = text; this.OnClick = onClick; this.OnRelease = onRelease; } public void SetText(string text) { _text = text; } public void Draw() { if (GUILayout.Button(_text, Array.Empty<GUILayoutOption>())) { if (!_wasPressed) { _wasPressed = true; this.OnClick?.Invoke(); } } else if (_wasPressed) { _wasPressed = false; this.OnRelease?.Invoke(); } } } internal class ModSelectControl<T> where T : IComparable { internal record SelectOption(string Text, T Value, Action? OnSelect = null); private SelectOption? _selected; private List<SelectOption> _options = new List<SelectOption>(); private bool _showDropdown; private Vector2 _scrollPos; private const float OPTION_HEIGHT = 24f; private const float MAX_POPUP_HEIGHT = 216f; public SelectOption? Selected { get { return _selected; } private set { if (!(_selected == value)) { _selected = value; this.OnSelectChanged?.Invoke(_selected); _selected?.OnSelect?.Invoke(); } } } public event Action<SelectOption?>? OnSelectChanged; public void SetSelection(T value) { T value2 = value; Log.Warning(value2); if (value2 == null) { Selected = null; return; } SelectOption selectOption = _options.FirstOrDefault((SelectOption op) => op.Value.Equals(value2)); if (!(selectOption == null) && !(selectOption == Selected)) { Selected = selectOption; } } public void DropSelection() { Selected = null; } public void AddOption(SelectOption option) { _options.Add(option); } public void SetOptions(IEnumerable<SelectOption> options) { _options.Clear(); _options.AddRange(options); } public void Draw() { //IL_0045: 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_0098: 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) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: 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) try { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button((Selected == null) ? "Not selected" : Selected.Text, Array.Empty<GUILayoutOption>())) { _showDropdown = !_showDropdown; } Rect lastRect = GUILayoutUtility.GetLastRect(); if (_showDropdown) { float num = Mathf.Min((float)_options.Count * 24f, 216f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y + ((Rect)(ref lastRect)).height, ((Rect)(ref lastRect)).width, num); GUI.Box(val, GUIContent.none); GUI.BeginGroup(val); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref val)).width, ((Rect)(ref val)).height); float num2 = 24f * (float)(1 + _options.Count); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val)).width - 16f, num2); _scrollPos = GUI.BeginScrollView(val2, _scrollPos, val3); float num3 = 0f; if (GUI.Button(new Rect(0f, num3, ((Rect)(ref val)).width, 24f), "Not selected")) { Selected = null; _showDropdown = false; _scrollPos = Vector2.zero; } num3 += 24f; for (int i = 0; i < _options.Count; i++) { SelectOption selectOption = _options[i]; if (GUI.Button(new Rect(0f, num3 + (float)i * 24f, ((Rect)(ref val)).width, 24f), selectOption.Text)) { Selected = selectOption; _showDropdown = false; _scrollPos = Vector2.zero; } } GUI.EndScrollView(); GUI.EndGroup(); if ((int)Event.current.type == 0) { Vector2 mousePosition = Event.current.mousePosition; if (!((Rect)(ref val)).Contains(mousePosition) && !((Rect)(ref lastRect)).Contains(mousePosition)) { _showDropdown = false; Event.current.Use(); } } } GUILayout.EndHorizontal(); } catch (Exception ex) { Log.Exception(ex); } } } } namespace NKVDebugMod.Features.UI.Controls.Fields { public class BooleanField : ILabeledField<bool>, IField<bool>, IField, ILabeledField { private float maxWidth; private bool value; private readonly bool nonChangeable; private Func<float>? maxWidthFunc; private string _label = ""; private string? _tooltip; public string Label { get { return _label; } set { _label = value; } } public string? Tooltip { get { return _tooltip; } set { _tooltip = value; } } public event Action<object?>? ValueChanged; public event Action<bool>? FieldValueChanged; public BooleanField(string label, Func<float>? maxWidthFunc, string? tooltip, bool defaultValue, bool nonChangeable) { Label = label; this.maxWidthFunc = maxWidthFunc; Tooltip = tooltip; value = defaultValue; this.nonChangeable = nonChangeable; } public void AddValueChangeHandler(Action<bool> handler) { FieldValueChanged += handler; } public void AddValueChangeHandler(Action<object?> handler) { ValueChanged += handler; } public void Draw() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (!string.IsNullOrEmpty(_label)) { GUILayout.Label(new GUIContent(_label, _tooltip), GetLabelOptions()); } bool flag = GUILayout.Toggle(value, value ? "Enabled" : "Disabled", GetFieldOptions()); if (flag != value && !nonChangeable) { value = flag; this.ValueChanged?.Invoke(value); this.FieldValueChanged?.Invoke(value); } GUILayout.EndHorizontal(); } public void SetLabel(string label) { _label = label; } public void SetMaxWidth(float maxWidth) { this.maxWidth = maxWidth; } public void SetTooltip(string tooltip) { _tooltip = tooltip; } protected GUILayoutOption[] GetLabelOptions() { List<GUILayoutOption> obj = new List<GUILayoutOption> { GUILayout.ExpandWidth(true) }; float num = (maxWidthFunc?.Invoke() ?? maxWidth) / 2f; obj.Add(GUILayout.MaxWidth(num)); return obj.ToArray(); } protected GUILayoutOption[] GetFieldOptions() { List<GUILayoutOption> obj = new List<GUILayoutOption> { GUILayout.ExpandWidth(true) }; float num = maxWidthFunc?.Invoke() ?? maxWidth; float num2 = (string.IsNullOrEmpty(_label) ? num : (num / 2f)); obj.Add(GUILayout.MaxWidth(num2)); return obj.ToArray(); } public void SetMaxWidthFunction(Func<float> func) { maxWidthFunc = func; } } internal abstract class FieldBase<T> : ILabeledField<T>, IField<T>, IField, ILabeledField { protected T? value; private readonly bool nonChangeable; private string _label = ""; private string? _tooltip; private float maxWidth; private Func<float>? maxWidthFunc; protected string oldText = ""; public string Label { get { return _label; } set { _label = value; } } public string? Tooltip { get { return _tooltip; } set { _tooltip = value; } } public event Action<object?>? ValueChanged; public event Action<T?>? FieldValueChanged; protected virtual bool Validate(string input) { return !nonChangeable; } protected abstract T ConvertToValue(string input); protected abstract string ConvertToString(T? input); protected FieldBase(string label, float maxWidth, string? tooltip, T defaultValue, bool nonChangeable = false) { value = defaultValue; this.nonChangeable = nonChangeable; oldText = ConvertToString(value); _label = label; this.maxWidth = maxWidth; _tooltip = tooltip; } protected FieldBase(string label, Func<float>? maxWidthFunc, string? tooltip, T defaultValue, bool nonChangeable = false) { value = defaultValue; this.nonChangeable = nonChangeable; oldText = ConvertToString(value); Label = label; this.maxWidthFunc = maxWidthFunc; Tooltip = tooltip; } public void Draw() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (!string.IsNullOrEmpty(_label)) { GUILayout.Label(new GUIContent(_label, _tooltip), GetLabelOptions()); } string text = GUILayout.TextField(oldText, GetFieldOptions()); if (text != oldText) { UpdateValueIfValid(text); } GUILayout.EndHorizontal(); } protected void UpdateValueIfValid(string input) { if (Validate(input)) { value = ConvertToValue(input); this.ValueChanged?.Invoke(value); this.FieldValueChanged?.Invoke(value); oldText = ConvertToString(value); } } public void AddValueChangeHandler(Action<object?> handler) { ValueChanged += handler; } public void AddValueChangeHandler(Action<T?> handler) { FieldValueChanged += handler; } public void SetLabel(string label) { _label = label; } public void SetTooltip(string tooltip) { _tooltip = tooltip; } public void SetMaxWidth(float maxWidth) { this.maxWidth = maxWidth; } public void SetMaxWidthFunction(Func<float> func) { maxWidthFunc = func; } public void SetValue(T newValue) { value = newValue; oldText = ConvertToString(value); } protected GUILayoutOption[] GetLabelOptions() { List<GUILayoutOption> obj = new List<GUILayoutOption> { GUILayout.ExpandWidth(true) }; float num = (maxWidthFunc?.Invoke() ?? maxWidth) / 2f; obj.Add(GUILayout.MaxWidth(num)); return obj.ToArray(); } protected GUILayoutOption[] GetFieldOptions() { List<GUILayoutOption> obj = new List<GUILayoutOption> { GUILayout.ExpandWidth(true) }; float num = maxWidthFunc?.Invoke() ?? maxWidth; float num2 = (string.IsNullOrEmpty(_label) ? num : (num / 2f)); obj.Add(GUILayout.MaxWidth(num2)); return obj.ToArray(); } } internal class FloatField : FieldBase<float> { public FloatField(string label, float maxWidth, string? tooltip, float defaultValue) : base(label, maxWidth, tooltip, defaultValue, nonChangeable: false) { } public FloatField(string label, Func<float>? maxWidthFunc, string? tooltip, float defaultValue) : base(label, maxWidthFunc, tooltip, defaultValue, nonChangeable: false) { } protected override float ConvertToValue(string input) { if (float.TryParse(input, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var result)) { return result; } return 0f; } protected override string ConvertToString(float input) { return input.ToString("F3", CultureInfo.InvariantCulture); } protected override bool Validate(string input) { if (!base.Validate(input)) { return false; } if (!input.Contains('.')) { return false; } float result; return float.TryParse(input, NumberStyles.Integer | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result); } } internal interface IField { void SetMaxWidth(float maxWidth); void SetMaxWidthFunction(Func<float> func); void AddValueChangeHandler(Action<object?> handler); void Draw(); } internal interface IField<T> : IField { void AddValueChangeHandler(Action<T?> handler); } internal interface ILabeledField : IField { void SetLabel(string label); void SetTooltip(string tooltip); } internal interface ILabeledField<T> : IField<T>, IField, ILabeledField { } internal class IntField : FieldBase<int> { public IntField(string label, float maxWidth, string? tooltip, int defaultValue) : base(label, maxWidth, tooltip, defaultValue, nonChangeable: false) { } public IntField(string label, Func<float>? maxWidthFunc, string? tooltip, int defaultValue) : base(label, maxWidthFunc, tooltip, defaultValue, nonChangeable: false) { } protected override string ConvertToString(int input) { return input.ToString(); } protected override int ConvertToValue(string input) { if (int.TryParse(input, out var result)) { return result; } return 0; } protected override bool Validate(string input) { if (!base.Validate(input)) { return false; } int result; return int.TryParse(input, out result); } } internal class StringField : FieldBase<string> { public StringField(string label, float maxWidth, string? tooltip, string defaultValue, bool nonChangeable = false) : base(label, maxWidth, tooltip, defaultValue, nonChangeable) { } public StringField(string label, Func<float>? maxWidthFunc, string? tooltip, string defaultValue, bool nonChangeable = false) : base(label, maxWidthFunc, tooltip, defaultValue, nonChangeable) { } protected override string ConvertToString(string? input) { return input ?? string.Empty; } protected override string ConvertToValue(string input) { return input; } } } namespace NKVDebugMod.Features.TimeControl { internal static class TimeControlFeature { private static GameObject _timeController; public static void Initialize() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _timeController = new GameObject("TimeController"); TimeController timeController = _timeController.AddComponent<TimeController>(); TimeControllerConfiguration.Init(); timeController.Hook(); Object.DontDestroyOnLoad((Object)(object)_timeController); ((Object)_timeController).hideFlags = (HideFlags)61; } public static void Destroy() { Object.Destroy((Object)(object)_timeController); } } internal class TimeController : MonoBehaviour { private float _timeScale = 1f; private int _advanceFramesValue = 1; private float _advanceTimeValue = 0.2f; private bool _isTimeScaled; private bool _isPaused; private float _timeToAdvance; private int _framesToAdvance; private float _timer; private int _framesTimer; private bool _isEnabled; private TimeControlUI? _timeControlWindow; internal static TimeController? Instance; private bool _firstFrameSkipped; public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; if (_timeControlWindow != null) { _timeControlWindow.IsUIEnabled = _isEnabled; } } } public bool IsPaused { get { return _isPaused; } set { _isPaused = value; if (_timeControlWindow != null) { _timeControlWindow.IsPaused = _isPaused; } } } public bool IsTimeScaled { get { return _isTimeScaled; } set { _isTimeScaled = value; if (_timeControlWindow != null) { _timeControlWindow.IsTimeScaled = _isTimeScaled; } } } private void Awake() { Instance = this; _timeControlWindow = new TimeControlUI(); _timeControlWindow.OnPauseResume += ToggleTime; _timeControlWindow.OnAdvanceFrames += AdvanceFrames; _timeControlWindow.OnAdvanceTime += AdvanceTime; _timeControlWindow.OnAdvanceFramesValueChange += ChangeAdvanceFramesValue; _timeControlWindow.OnAdvanceTimeValueChange += ChangeAdvanceTimeValue; _timeControlWindow.OnTimeScaleToggle += ToggleTimeScale; _timeControlWindow.OnTimeScaleValueChange += ChangeTimeScale; } public void Hook() { TimeControllerConfiguration.OnToggleTimeControlInvoked += ToggleUI; TimeControllerConfiguration.OnResumePausedInvoked += ToggleTime; TimeControllerConfiguration.OnAdvanceFramesInvoked += AdvanceFrames; TimeControllerConfiguration.OnAdvanceTimeInvoked += AdvanceTime; TimeControllerConfiguration.OnToggleTimeScaleInvoked += ToggleTimeScale; } private void Update() { if (!IsEnabled) { return; } if (IsPaused) { if (_timer >= _timeToAdvance && _timeToAdvance != 0f) { _timer = 0f; _timeToAdvance = 0f; } else if (_timer != 0f || _timeToAdvance != 0f) { if (_timer > 0f) { _timer += RCGTime.unscaledDeltaTime; } else { _timer += float.Epsilon; } RCGTime.timeScale = 1f; return; } if (_framesTimer >= _framesToAdvance && _framesToAdvance != 0) { _framesTimer = 0; _framesToAdvance = 0; _firstFrameSkipped = false; } else if (_framesTimer != 0 || _framesToAdvance != 0) { if (!_firstFrameSkipped) { _framesTimer++; } else { _firstFrameSkipped = true; } RCGTime.timeScale = 1f; return; } RCGTime.timeScale = 0f; } else if (IsTimeScaled && SingletonBehaviour<PlayerInputBinder>.Instance.IsAction) { RCGTime.timeScale = _timeScale; } } private void OnGUI() { _timeControlWindow?.Draw(); } private void ChangeTimeScale(float value) { _timeScale = value; } private void ChangeAdvanceTimeValue(float value) { _advanceTimeValue = value; } private void ChangeAdvanceFramesValue(int value) { _advanceFramesValue = value; } private void ToggleTimeScale() { IsTimeScaled = !IsTimeScaled; } private void AdvanceTime() { if (IsPaused) { _timeToAdvance += _advanceTimeValue; } } private void AdvanceFrames() { if (IsPaused) { _framesToAdvance += _advanceFramesValue; } } private void ToggleTime() { IsPaused = !IsPaused; } private void ToggleUI() { IsEnabled = !IsEnabled; } private void OnDestroy() { TimeControllerConfiguration.OnToggleTimeControlInvoked -= ToggleUI; TimeControllerConfiguration.OnResumePausedInvoked -= ToggleTime; TimeControllerConfiguration.OnAdvanceFramesInvoked -= AdvanceFrames; TimeControllerConfiguration.OnAdvanceTimeInvoked -= AdvanceTime; TimeControllerConfiguration.OnToggleTimeScaleInvoked -= ToggleTimeScale; } } } namespace NKVDebugMod.Features.TimeControl.UI { internal class TimeControlUI { private ModWindow _timeControlWindow; private ModButton _pauseResumeButton; private ModButton _toggleTimeScale; private ModButton _advanceFramesButton; private ModButton _advanceTimeButton; private FloatField _timeScaleValueField; private FloatField _advanceTimeValueField; private IntField _advanceFramesValueField; private bool isPaused; private bool _isUIEnabled; public bool IsPaused { get { return isPaused; } set { isPaused = value; if (isPaused) { _pauseResumeButton.SetText("Resume"); } else { _pauseResumeButton.SetText("Play"); } } } public bool IsTimeScaled { get; set; } public bool IsUIEnabled { get { return _isUIEnabled; } set { _isUIEnabled = value; _timeControlWindow.IsVisible = _isUIEnabled; } } public event Action? OnPauseResume; public event Action? OnTimeScaleToggle; public event Action? OnAdvanceFrames; public event Action? OnAdvanceTime; public event Action<int>? OnAdvanceFramesValueChange; public event Action<float>? OnAdvanceTimeValueChange; public event Action<float>? OnTimeScaleValueChange; public TimeControlUI() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown _timeControlWindow = new ModWindow(898, 0.2f, 0.1f, 0f, 0.5f, new WindowFunction(DrawTimeControlFunction), "Time controller"); _pauseResumeButton = new ModButton("Pause", delegate { this.OnPauseResume?.Invoke(); }); _toggleTimeScale = new ModButton("Time scale", delegate { this.OnTimeScaleToggle?.Invoke(); }); _advanceFramesButton = new ModButton("Advance frames", delegate { this.OnAdvanceFrames?.Invoke(); }); _advanceTimeButton = new ModButton("Advance time", delegate { this.OnAdvanceTime?.Invoke(); }); _timeScaleValueField = new FloatField("Time scale", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect3 = _timeControlWindow.WindowSettingRect; return ((Rect)(ref windowSettingRect3)).width; }, "Game time scale", 1f); _timeScaleValueField.FieldValueChanged += delegate(float f) { this.OnTimeScaleValueChange?.Invoke(f); }; _advanceTimeValueField = new FloatField("Advance time seconds", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect2 = _timeControlWindow.WindowSettingRect; return ((Rect)(ref windowSettingRect2)).width; }, "How many seconds will be advanced on call", 0.2f); _advanceTimeValueField.FieldValueChanged += delegate(float f) { this.OnAdvanceTimeValueChange?.Invoke(f); }; _advanceFramesValueField = new IntField("Advance time frames", delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect = _timeControlWindow.WindowSettingRect; return ((Rect)(ref windowSettingRect)).width; }, "How many frames will be advanced on call", 1); _advanceFramesValueField.FieldValueChanged += delegate(int i) { this.OnAdvanceFramesValueChange?.Invoke(i); }; } public void Draw() { if (IsUIEnabled) { _timeControlWindow.Draw(); } } private void DrawTimeControlFunction(int id) { GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); _pauseResumeButton.Draw(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(IsTimeScaled ? "Scaled" : "Not scaled", Array.Empty<GUILayoutOption>()); _toggleTimeScale.Draw(); GUILayout.EndHorizontal(); _timeScaleValueField.Draw(); _advanceFramesButton.Draw(); _advanceFramesValueField.Draw(); _advanceTimeButton.Draw(); _advanceTimeValueField.Draw(); GUILayout.EndVertical(); } } } namespace NKVDebugMod.Features.TimeControl.Configuration { internal static class TimeControllerConfiguration { private static ConfigEntry<KeyboardShortcut>? _toggleTimeControlPanel; private static ConfigEntry<KeyboardShortcut>? _toggleTimeScaleKey; private static ConfigEntry<KeyboardShortcut>? _advanceFramesKey; private static ConfigEntry<KeyboardShortcut>? _advanceTimeKey; private static ConfigEntry<KeyboardShortcut>? _pauseResumeKey; public static event Action? OnToggleTimeControlInvoked; public static event Action? OnToggleTimeScaleInvoked; public static event Action? OnAdvanceFramesInvoked; public static event Action? OnAdvanceTimeInvoked; public static event Action? OnResumePausedInvoked; internal static void Init() { //IL_000f: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) _toggleTimeControlPanel = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Time Control", "Toggle time control panel", TimeControllerConstants.ToggleInspectorConfigDefault, (ConfigDescription)null); _advanceFramesKey = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Time Control", "Advance frames", TimeControllerConstants.AdvanceFramesConfigDefault, (ConfigDescription)null); _advanceTimeKey = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Time Control", "Advance time", TimeControllerConstants.AdvanceTimeConfigDefault, (ConfigDescription)null); _pauseResumeKey = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Time Control", "Pause/Resume", TimeControllerConstants.PauseResumeConfigDefault, (ConfigDescription)null); _toggleTimeScaleKey = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Time Control", "Toggle time scaling", TimeControllerConstants.ToggleTimeScaleConfigDefault, (ConfigDescription)null); if ((Object)(object)TimeController.Instance != (Object)null) { KeybindManager.Add((MonoBehaviour)(object)TimeController.Instance, (Action)delegate { TimeControllerConfiguration.OnToggleTimeScaleInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _toggleTimeScaleKey.Value)); KeybindManager.Add((MonoBehaviour)(object)TimeController.Instance, (Action)delegate { TimeControllerConfiguration.OnToggleTimeControlInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _toggleTimeControlPanel.Value)); KeybindManager.Add((MonoBehaviour)(object)TimeController.Instance, (Action)delegate { TimeControllerConfiguration.OnAdvanceFramesInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _advanceFramesKey.Value)); KeybindManager.Add((MonoBehaviour)(object)TimeController.Instance, (Action)delegate { TimeControllerConfiguration.OnAdvanceTimeInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _advanceTimeKey.Value)); KeybindManager.Add((MonoBehaviour)(object)TimeController.Instance, (Action)delegate { TimeControllerConfiguration.OnResumePausedInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _pauseResumeKey.Value)); } } } internal static class TimeControllerConstants { public const string ConfigSectionName = "Time Control"; public const string ToggleTimePanelConfigName = "Toggle time control panel"; public static KeyboardShortcut ToggleInspectorConfigDefault = new KeyboardShortcut((KeyCode)116, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const string AdvanceFramesConfigName = "Advance frames"; public static KeyboardShortcut AdvanceFramesConfigDefault = new KeyboardShortcut((KeyCode)275, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const int ADVANCE_FRAMES_DEFAULT = 1; public const string AdvanceTimeConfigName = "Advance time"; public static KeyboardShortcut AdvanceTimeConfigDefault = new KeyboardShortcut((KeyCode)104, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const float ADVANCE_TIME_DEFAULT = 0.2f; public const string PauseResumeConfigName = "Pause/Resume"; public static KeyboardShortcut PauseResumeConfigDefault = new KeyboardShortcut((KeyCode)306, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }); public const string ToggleTimeScaleConfigName = "Toggle time scaling"; public static KeyboardShortcut ToggleTimeScaleConfigDefault = new KeyboardShortcut((KeyCode)308, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); } } namespace NKVDebugMod.Features.SaveSlotsManager { internal record SaveFileDescriptor(string Name, string FileName, DateTime CreatedAt, DateTime LastTimeUsed); internal static class SaveManagerFeature { private static GameObject _saveManagerObject; public static void Initialize() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _saveManagerObject = new GameObject("NKVDM SaveManager"); SaveSlotsManager saveSlotsManager = _saveManagerObject.AddComponent<SaveSlotsManager>(); SaveManagerConfiguration.Init(); saveSlotsManager.Hook(); RCGLifeCycle.DontDestroyForever(_saveManagerObject); ((Object)_saveManagerObject).hideFlags = (HideFlags)61; } public static void Destroy() { Object.Destroy((Object)(object)_saveManagerObject); } } internal class SaveSlotsManager : MonoBehaviour { internal enum SavesDisplayMode { Pinned, OrderedByCreationTimeDesc, OrderedByCreationTimeAsc, LatestUsedDuringSession, CreatedDuringSession } private Dictionary<string, SaveFileDescriptor> _savesCache = new Dictionary<string, SaveFileDescriptor>(); private static int _saveSlotIndex = 5; internal static bool IsSaveSlotLoadRequested = false; internal static string _rootPath = Application.persistentDataPath; internal static string _savesRoot = Path.Combine(_rootPath, "NKVDebug_saves"); internal static string _debugSavePath = Path.Combine(_rootPath, $"saveslot{_saveSlotIndex}"); internal static string _pinnedSavesFilePath = Path.Combine(_savesRoot, "pinned.txt"); private object _lock = new object(); private string? _lastSave; private SaveManagerUI? _managerUi; private HashSet<string> _pinnedSaves = new HashSet<string>(); private HashSet<string> _createdDuringSession = new HashSet<string>(); private HashSet<string> _lastUsed = new HashSet<string>(); private readonly Regex _invalidFileNameRegex = new Regex("^(?!^(?:PRN|AUX|CLOCK\\$|NUL|CON|COM\\d|LPT\\d)(?:\\..+)?$)(?:\\.*?(?!\\.))[^\\x00-\\x1f\\\\?*:\\\";|\\/<>]+(?<![\\s.])$"); private static MethodInfo _readMetaInSaveMethod = AccessTools.Method(typeof(SaveManager), "ReadMetaInSave", new Type[2] { typeof(string), typeof(bool) }, (Type[])null); private bool _saveOnPosition => SaveManagerConfiguration.SaveOnPosition; private bool _isPlaying => GameCore.IsPlayingReady(); public static SaveSlotsManager? Instance { get; private set; } private void Awake() { Instance = this; _debugSavePath = Path.Combine(_rootPath, $"saveslot{_saveSlotIndex}"); EnsureDirectoriesPresent(); _managerUi = new SaveManagerUI(); _managerUi.OnLoadSaveClicked += HandleLoadSaveEvent; _managerUi.OnSaveButtonClicked += HandleSave; _managerUi.OnRenameConfirmed += HandleRename; _managerUi.OnDeleteClicked += HandleDelete; _managerUi.OnSearch += HandleSearch; _managerUi.OnPinClicked += HandlePin; _managerUi.OnUnpinClicked += HandleUnpin; FindSaves(); } private void HandleUnpin(string key) { if (_pinnedSaves.Contains(key)) { RemovePinnedSave(key); } } private void HandlePin(string key) { if (!_pinnedSaves.Contains(key)) { AddPinnedSave(key); } } private void EnsureDirectoriesPresent() { if (!Directory.Exists(_savesRoot)) { Directory.CreateDirectory(_savesRoot); } if (!Directory.Exists(_debugSavePath)) { Directory.CreateDirectory(_debugSavePath); } if (!File.Exists(_pinnedSavesFilePath)) { File.Create(_pinnedSavesFilePath); } else { _pinnedSaves = new HashSet<string>(File.ReadAllLines(_pinnedSavesFilePath)); } } private void HandleSearch(string searchText, SavesDisplayMode displayMode) { if (_managerUi != null) { List<SaveFileDescriptor> descriptors = PerformSearch(searchText, displayMode); _managerUi.SetSaveSlotsList(ProduceSaveSlotListItems(descriptors)); } } private List<SaveFileDescriptor> PerformSearch(string searchNameText, SavesDisplayMode displayMode) { List<SaveFileDescriptor> list = new List<SaveFileDescriptor>(); IEnumerable<SaveFileDescriptor> enumerable = displayMode switch { SavesDisplayMode.Pinned => _savesCache.Values.Where((SaveFileDescriptor i) => _pinnedSaves.Contains(i.Name)), SavesDisplayMode.CreatedDuringSession => _savesCache.Values.Where((SaveFileDescriptor i) => _createdDuringSession.Contains(i.Name)), SavesDisplayMode.LatestUsedDuringSession => from lu in _lastUsed select _savesCache[lu] into i orderby i.LastTimeUsed descending select i, SavesDisplayMode.OrderedByCreationTimeDesc => _savesCache.Values.OrderByDescending((SaveFileDescriptor i) => i.CreatedAt), SavesDisplayMode.OrderedByCreationTimeAsc => _savesCache.Values.OrderBy((SaveFileDescriptor i) => i.CreatedAt), _ => _savesCache.Values, }; if (!string.IsNullOrEmpty(searchNameText)) { List<SaveFileDescriptor> list2 = new List<SaveFileDescriptor>(); List<SaveFileDescriptor> list3 = new List<SaveFileDescriptor>(); List<SaveFileDescriptor> list4 = new List<SaveFileDescriptor>(); foreach (SaveFileDescriptor item in enumerable) { if (item.Name == searchNameText) { list2.Add(item); } else if (item.Name.StartsWith(searchNameText)) { list3.Add(item); } else if (item.Name.Contains(searchNameText)) { list4.Add(item); } } list = new List<SaveFileDescriptor>(list2.Count + list3.Count + list4.Count); list.AddRange(list2); list.AddRange(list3); list.AddRange(list4); } else { list.AddRange(enumerable); } return list; } private void HandleDelete(string saveName) { if (!_savesCache.TryGetValue(saveName, out SaveFileDescriptor value)) { Log.Error("Tried to delete a save " + saveName + " but couldn't find it"); return; } RemoveFileFromCache(saveName); Directory.Delete(value.FileName, recursive: true); } private void HandleRename(string oldName, string newName) { if (!_savesCache.TryGetValue(oldName, out SaveFileDescriptor value)) { Log.Error("Tried to rename a save " + oldName + " but couldn't find it"); } else if (!ValidateSaveName(newName) && _managerUi != null) { _managerUi.RenameValidationError = "Incorrect file name - OS doesn't allow files with such names or special symbols"; } else if (!(value.Name == newName)) { Directory.Move(value.FileName, Path.Combine(_savesRoot, newName)); if (_createdDuringSession.Contains(oldName)) { _createdDuringSession.Remove(oldName); _createdDuringSession.Add(newName); } if (_lastUsed.Contains(oldName)) { _lastUsed.Remove(oldName); _lastUsed.Add(newName); } if (_pinnedSaves.Contains(oldName)) { RemovePinnedSave(oldName); AddPinnedSave(newName); } FindSaves(); } } private void HandleSave() { try { string text = _managerUi?.NewSaveName ?? string.Empty; if (string.IsNullOrEmpty(text)) { text = GetSceneSaveName(); } SaveGame(text); } catch (Exception ex) { Log.Exception(ex); } } private string GetSceneSaveName() { //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) string empty = string.Empty; Scene activeScene = SceneManager.GetActiveScene(); string sceneName = ((Scene)(ref activeScene)).name; var anon = (from sv in Directory.EnumerateDirectories(_savesRoot) select new { Name = Path.GetFileName(sv), CreationDate = Directory.GetCreationTime(sv) } into sv where sv.Name.StartsWith(sceneName) orderby sv.CreationDate descending select sv).FirstOrDefault(); if (anon != null) { return anon.Name + " (1)"; } return sceneName + " - Save"; } private void HandleLoadSaveEvent(string saveName) { LoadSave(saveName); } public void Hook() { SaveManagerConfiguration.OnQuickSaveInvoked += HandleQuickSave; SaveManagerConfiguration.OnQuickloadInvoked += HandleQuickLoad; SaveManagerConfiguration.OnOpenManagerInvoked += HandleManagerToggle; } private void HandleManagerToggle() { if (_managerUi != null) { _managerUi.IsEnabled = !_managerUi.IsEnabled; } } private void HandleQuickLoad() { if (!string.IsNullOrEmpty(_lastSave)) { LoadSave(_lastSave); } } private void HandleQuickSave() { SaveGame(GetSceneSaveName()); } public void LoadSave(string name) { try { if (!_savesCache.TryGetValue(name, out SaveFileDescriptor value)) { Log.Error("A save named \"" + name + "\" isn't present in the cache"); return; } string[] files = Directory.GetFiles(value.FileName); string[] files2 = Directory.GetFiles(_debugSavePath, "*.*"); foreach (string path in files2) { try { File.Delete(path); } catch (Exception ex) { Log.Exception(ex); } } files2 = files; foreach (string text in files2) { try { File.Copy(text, Path.Combine(_debugSavePath, Path.GetFileName(text))); } catch (Exception ex2) { Log.Exception(ex2); } } value.LastTimeUsed = DateTime.Now; _lastUsed.Add(value.Name); NotifySavesCollectionChanged(); SingletonBehaviour<ApplicationUIGroupManager>.Instance.PopAll(); EffectReceiver.EffectReceiverCache.Clear(); IsSaveSlotLoadRequested = true; if (SingletonBehaviour<GameCore>.IsAvailable()) { ((Component)SingletonBehaviour<GameCore>.Instance.gameLevel).gameObject.SetActive(false); SingletonBehaviour<GameCore>.Instance.gameLevel.SetLevelDestroy(false); } SingletonBehaviour<SaveManager>.Instance.SetSlot(5); SceneManager.LoadScene("ClearTransition"); if ((Object)(object)SingletonBehaviour<ApplicationCore>.Instance.soundManager != (Object)null && SingletonBehaviour<GameCore>.IsAvailable()) { SingletonBehaviour<ApplicationCore>.Instance.soundManager.SetListenerTarget(((Component)SingletonBehaviour<ApplicationCore>.Instance).transform); } } catch (Exception ex3) { Log.Exception(ex3); } } public void SaveGame(string name) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (!_isPlaying) { if (_managerUi != null) { _managerUi.NewSaveNameValidationError = "No save loaded"; } return; } if (!ValidateSaveName(name)) { if (_managerUi != null) { _managerUi.NewSaveNameValidationError = "Incorrect file name - OS doesn't allow files with such names or special symbols"; } return; } if (_savesCache.ContainsKey(name)) { if (_managerUi != null) { _managerUi.NewSaveNameValidationError = "This name is already taken"; } return; } string text = Path.Combine(_savesRoot, name); SaveFileDescriptor saveFileDescriptor = new SaveFileDescriptor(name, text, DateTime.Now, DateTime.MinValue); if (SaveManagerConfiguration.SaveOnPosition) { SingletonBehaviour<SaveManager>.Instance.ForceSaveAt((SaveSceneScheme)2, (Transform)null); } if (!SaveManagerConfiguration.SaveOnPosition) { SingletonBehaviour<SaveManager>.Instance.ForceSaveAt((SaveSceneScheme)1, (Transform)null); } SingletonBehaviour<SaveManager>.Instance.SaveAllFlagsAndMeta(text); AddFileToCache(saveFileDescriptor); _createdDuringSession.Add(saveFileDescriptor.Name); _lastSave = saveFileDescriptor.Name; NotifySavesCollectionChanged(); } private void AddFileToCache(SaveFileDescriptor descriptor) { _savesCache[descriptor.Name] = descriptor; NotifySavesCollectionChanged(); } private void RemoveFileFromCache(string key) { _savesCache.Remove(key); _createdDuringSession.Remove(key); _lastUsed.Remove(key); RemovePinnedSave(key); NotifySavesCollectionChanged(); } private void AddPinnedSave(string key) { _pinnedSaves.Add(key); NotifySavesCollectionChanged(); Task.Run(delegate { lock (_lock) { File.WriteAllLines(_pinnedSavesFilePath, _pinnedSaves); } }); } private void RemovePinnedSave(string key) { _pinnedSaves.Remove(key); NotifySavesCollectionChanged(); Task.Run(delegate { lock (_lock) { File.WriteAllLines(_pinnedSavesFilePath, _pinnedSaves); } }); } private void FindSaves() { _savesCache.Clear(); foreach (string item in Directory.EnumerateDirectories(_savesRoot)) { try { string fileName = Path.GetFileName(item); DateTime creationTime = Directory.GetCreationTime(item); AddFileToCache(new SaveFileDescriptor(fileName, item, creationTime, DateTime.MinValue)); } catch (Exception ex) { Log.Exception(ex); } } } private void NotifySavesCollectionChanged() { if (_managerUi != null) { _managerUi.SetSaveSlotsList(ProduceSaveSlotListItems(PerformSearch(_managerUi.SearchText, _managerUi.DisplayMode))); } } private List<SaveSlotListItem> ProduceSaveSlotListItems(IEnumerable<SaveFileDescriptor> descriptors) { return descriptors.Select((SaveFileDescriptor d) => new SaveSlotListItem(d.Name, d.CreatedAt, _pinnedSaves.Contains(d.Name))).ToList(); } private void OnGUI() { _managerUi?.Draw(); } private bool ValidateSaveName(string name) { if (string.IsNullOrEmpty(name)) { return false; } return _invalidFileNameRegex.IsMatch(name); } } } namespace NKVDebugMod.Features.SaveSlotsManager.UI { internal class SaveManagerUI { private ModWindow _window; private Vector2 _scrollPosition = Vector2.zero; private string? _renamingSave; private string? _deletingSave; private string _renamedSaveName = string.Empty; private string? _dateTimeFormatString = string.Empty; private StringField _newSaveNameField; private StringField _renameSaveField; private StringField _searchField; private bool _isEnabled; public string RenameValidationError { get; set; } = string.Empty; public string NewSaveNameValidationError { get; set; } = string.Empty; public List<SaveSlotListItem> SaveSlots { get; private set; } = new List<SaveSlotListItem>(); public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; _window.IsVisible = _isEnabled; } } public SaveSlotsManager.SavesDisplayMode DisplayMode { get; set; } = SaveSlotsManager.SavesDisplayMode.OrderedByCreationTimeAsc; public string SearchText { get; set; } = string.Empty; public string NewSaveName { get; private set; } = string.Empty; public event Action? OnSaveButtonClicked; public event Action<string>? OnLoadSaveClicked; public event Action<string>? OnDeleteClicked; public event Action<string>? OnPinClicked; public event Action<string>? OnUnpinClicked; public event Action<string, string>? OnRenameConfirmed; public event Action<string, SaveSlotsManager.SavesDisplayMode>? OnSearch; public SaveManagerUI() { //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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown _window = new ModWindow(999, 0.5f, 0.6f, 0.2f, 0.5f, new WindowFunction(DrawWindow), "Save manager"); _newSaveNameField = new StringField(string.Empty, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect3 = _window.WindowSettingRect; return ((Rect)(ref windowSettingRect3)).width / 4f; }, string.Empty, string.Empty); _newSaveNameField.FieldValueChanged += HandleNewSaveNameValueChange; _renameSaveField = new StringField(string.Empty, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect2 = _window.WindowSettingRect; return ((Rect)(ref windowSettingRect2)).width / 4f; }, string.Empty, string.Empty); _renameSaveField.FieldValueChanged += HandleRenameFieldChange; _searchField = new StringField(string.Empty, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect windowSettingRect = _window.WindowSettingRect; return ((Rect)(ref windowSettingRect)).width / 4f; }, string.Empty, string.Empty); _searchField.FieldValueChanged += HandleSearchFieldChange; DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat; _dateTimeFormatString = dateTimeFormat.ShortDatePattern + " (ddd) - " + dateTimeFormat.ShortTimePattern; } public void SetSaveSlotsList(IEnumerable<SaveSlotListItem> items) { SaveSlots = new List<SaveSlotListItem>(items); } private void HandleSearchFieldChange(string? value) { SearchText = value ?? string.Empty; this.OnSearch?.Invoke(SearchText, DisplayMode); } private void HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode mode) { DisplayMode = mode; this.OnSearch?.Invoke(SearchText, DisplayMode); } private void HandleRenameFieldChange(string? value) { if (!string.IsNullOrEmpty(value)) { _renamedSaveName = value; RenameValidationError = string.Empty; } } private void HandleNewSaveNameValueChange(string? value) { if (!string.IsNullOrEmpty(value)) { NewSaveName = value; NewSaveNameValidationError = string.Empty; } } private void HandleRenameConfirm() { if (!string.IsNullOrEmpty(_renamingSave)) { this.OnRenameConfirmed?.Invoke(_renamingSave, _renamedSaveName); if (string.IsNullOrEmpty(RenameValidationError)) { _renamingSave = null; } } } private void HandleRenameCancel() { _renamingSave = null; } private void DrawWindow(int id) { //IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_0615: Unknown result type (might be due to invalid IL or missing references) //IL_061a: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_0665: Unknown result type (might be due to invalid IL or missing references) //IL_066a: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Unknown result type (might be due to invalid IL or missing references) _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, false, true, Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label("New save:", Array.Empty<GUILayoutOption>()); _newSaveNameField.Draw(); if (GUILayout.Button("Save", Array.Empty<GUILayoutOption>())) { this.OnSaveButtonClicked?.Invoke(); } if (!string.IsNullOrEmpty(NewSaveNameValidationError)) { GUILayout.Label(NewSaveNameValidationError, Array.Empty<GUILayoutOption>()); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayoutOption[] array = new GUILayoutOption[1]; Rect windowSettingRect = _window.WindowSettingRect; array[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); GUILayout.Label("Display:", (GUILayoutOption[])(object)array); if (DisplayMode == SaveSlotsManager.SavesDisplayMode.Pinned) { GUI.enabled = false; } GUILayoutOption[] array2 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array2[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); if (GUILayout.Button("Pinned", (GUILayoutOption[])(object)array2)) { HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode.Pinned); } GUI.enabled = true; if (DisplayMode == SaveSlotsManager.SavesDisplayMode.OrderedByCreationTimeDesc) { GUI.enabled = false; } GUILayoutOption[] array3 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array3[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); if (GUILayout.Button("Creation time ↓", (GUILayoutOption[])(object)array3)) { HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode.OrderedByCreationTimeDesc); } GUI.enabled = true; if (DisplayMode == SaveSlotsManager.SavesDisplayMode.OrderedByCreationTimeAsc) { GUI.enabled = false; } GUILayoutOption[] array4 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array4[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); if (GUILayout.Button("Creation time ↑", (GUILayoutOption[])(object)array4)) { HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode.OrderedByCreationTimeAsc); } GUI.enabled = true; if (DisplayMode == SaveSlotsManager.SavesDisplayMode.CreatedDuringSession) { GUI.enabled = false; } GUILayoutOption[] array5 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array5[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); if (GUILayout.Button("Recently created", (GUILayoutOption[])(object)array5)) { HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode.CreatedDuringSession); } GUI.enabled = true; if (DisplayMode == SaveSlotsManager.SavesDisplayMode.LatestUsedDuringSession) { GUI.enabled = false; } GUILayoutOption[] array6 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array6[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 6f); if (GUILayout.Button("Last used", (GUILayoutOption[])(object)array6)) { HandleDisplayModeChange(SaveSlotsManager.SavesDisplayMode.LatestUsedDuringSession); } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.Label("Search:", Array.Empty<GUILayoutOption>()); _searchField.Draw(); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); if (SaveSlots.Count > 0) { foreach (SaveSlotListItem saveSlot in SaveSlots) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (_renamingSave == saveSlot.Name || _deletingSave == saveSlot.Name) { GUI.enabled = false; } if (!saveSlot.IsPinned) { if (GUILayout.Button("Pin", Array.Empty<GUILayoutOption>())) { HandlePin(saveSlot.Name); } } else if (GUILayout.Button("Unpin", Array.Empty<GUILayoutOption>())) { HandleUnpin(saveSlot.Name); } if (GUILayout.Button("Rename", Array.Empty<GUILayoutOption>())) { _renamingSave = saveSlot.Name; _renameSaveField.SetValue(saveSlot.Name); _renamedSaveName = saveSlot.Name; } GUI.enabled = true; if (_renamingSave == saveSlot.Name) { _renameSaveField.Draw(); if (!string.IsNullOrEmpty(RenameValidationError)) { GUILayout.Label(RenameValidationError, Array.Empty<GUILayoutOption>()); } } else { GUILayout.Label(saveSlot.Name, Array.Empty<GUILayoutOption>()); GUILayout.Label("-", Array.Empty<GUILayoutOption>()); GUILayout.Label(saveSlot.CreatedAt.ToString(_dateTimeFormatString), Array.Empty<GUILayoutOption>()); } GUILayout.FlexibleSpace(); if (_renamingSave == saveSlot.Name) { GUILayoutOption[] array7 = new GUILayoutOption[2]; windowSettingRect = _window.WindowSettingRect; array7[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f); array7[1] = GUILayout.ExpandWidth(true); GUILayout.BeginHorizontal((GUILayoutOption[])(object)array7); GUILayoutOption[] array8 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array8[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Save", (GUILayoutOption[])(object)array8)) { HandleRenameConfirm(); } GUILayoutOption[] array9 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array9[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)array9)) { HandleRenameCancel(); } GUILayout.EndHorizontal(); } else if (_deletingSave == saveSlot.Name) { GUILayout.Label("Sure Delete?", Array.Empty<GUILayoutOption>()); GUILayoutOption[] array10 = new GUILayoutOption[2]; windowSettingRect = _window.WindowSettingRect; array10[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f); array10[1] = GUILayout.ExpandWidth(true); GUILayout.BeginHorizontal((GUILayoutOption[])(object)array10); GUILayoutOption[] array11 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array11[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Yes", (GUILayoutOption[])(object)array11)) { HandleDelete(saveSlot.Name); } GUILayoutOption[] array12 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array12[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)array12)) { HandleDeleteCancel(); } GUILayout.EndHorizontal(); } else { GUILayoutOption[] array13 = new GUILayoutOption[2]; windowSettingRect = _window.WindowSettingRect; array13[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f); array13[1] = GUILayout.ExpandWidth(true); GUILayout.BeginHorizontal((GUILayoutOption[])(object)array13); GUILayoutOption[] array14 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array14[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Load", (GUILayoutOption[])(object)array14)) { this.OnLoadSaveClicked?.Invoke(saveSlot.Name); } GUILayoutOption[] array15 = new GUILayoutOption[1]; windowSettingRect = _window.WindowSettingRect; array15[0] = GUILayout.MaxWidth(((Rect)(ref windowSettingRect)).width / 2f / 2f); if (GUILayout.Button("Delete", (GUILayoutOption[])(object)array15)) { if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { HandleDelete(saveSlot.Name); } _deletingSave = saveSlot.Name; } GUILayout.EndHorizontal(); } GUILayout.EndHorizontal(); } } else { GUILayout.Label("No saves", Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); GUILayout.EndScrollView(); } private void HandleUnpin(string name) { this.OnUnpinClicked?.Invoke(name); } private void HandlePin(string name) { this.OnPinClicked?.Invoke(name); } private void HandleDelete(string name) { _deletingSave = null; this.OnDeleteClicked?.Invoke(name); } private void HandleDeleteCancel() { _deletingSave = null; } public void Draw() { if (_isEnabled) { _window.Draw(); } } } internal class SaveSlotListItem { public string Name { get; set; } = string.Empty; public bool IsPinned { get; set; } public DateTime CreatedAt { get; set; } public SaveSlotListItem(string name, DateTime createdAt, bool isPinned = false) { Name = name; CreatedAt = createdAt; IsPinned = isPinned; } } } namespace NKVDebugMod.Features.SaveSlotsManager.HarmonyPatches { [HarmonyPatch(typeof(DestroyAllGameObjects))] internal static class DestroyAllGameObjectsPatches { [HarmonyPatch("BackToTitle")] [HarmonyPrefix] private static bool BackToTitle_Prefix() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!SaveSlotsManager.IsSaveSlotLoadRequested) { return true; } SingletonBehaviour<SaveManager>.Instance.LoadWithCommand("saveslot5", ""); SaveSlotsManager.IsSaveSlotLoadRequested = false; return false; } } [HarmonyPatch] internal static class SaveManagerPatches { [CompilerGenerated] private sealed class <Transpiler>d__1 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private IEnumerator<CodeInstruction> <>7__wrap1; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Transpiler>d__1(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; break; } if (<>7__wrap1.MoveNext()) { CodeInstruction current = <>7__wrap1.Current; if (current.opcode == OpCodes.Ldc_I4_5) { <>2__current = new CodeInstruction(OpCodes.Ldc_I4_6, (object)null); <>1__state = 1; return true; } <>2__current = current; <>1__state = 2; return true; } <>m__Finally1(); <>7__wrap1 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <Transpiler>d__1 <Transpiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <Transpiler>d__ = this; } else { <Transpiler>d__ = new <Transpiler>d__1(0); } <Transpiler>d__.instructions = <>3__instructions; return <Transpiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } private static MethodBase TargetMethod() { return typeof(SaveManager).GetMethod("LoadAllSaveSlotMetaForMainMenu", BindingFlags.Instance | BindingFlags.Public).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic); } [IteratorStateMachine(typeof(<Transpiler>d__1))] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Transpiler>d__1(-2) { <>3__instructions = instructions }; } } } namespace NKVDebugMod.Features.SaveSlotsManager.Configuration { internal static class SaveManagerConfiguration { private static ConfigEntry<KeyboardShortcut>? _quickLoad; private static ConfigEntry<KeyboardShortcut>? _quickSave; private static ConfigEntry<KeyboardShortcut>? _openManager; private static ConfigEntry<bool>? _saveOnPosition; public static bool SaveOnPosition { get { if (_saveOnPosition == null) { return false; } return _saveOnPosition.Value; } } public static event Action? OnOpenManagerInvoked; public static event Action? OnQuickloadInvoked; public static event Action? OnQuickSaveInvoked; internal static void Init() { //IL_000f: 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_004d: Unknown result type (might be due to invalid IL or missing references) _openManager = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Save Manager", "Open save manager", SaveManagerConstants.OpenManagerConfigDefault, (ConfigDescription)null); _quickLoad = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Save Manager", "Quick load", SaveManagerConstants.QuickLoadConfigDefault, (ConfigDescription)null); _quickSave = NKVDebugMod.ModConfig.Bind<KeyboardShortcut>("Save Manager", "Quick save", SaveManagerConstants.QuickSaveConfigDefault, (ConfigDescription)null); _saveOnPosition = NKVDebugMod.ModConfig.Bind<bool>("Save Manager", "Save on current position", false, (ConfigDescription)null); if ((Object)(object)SaveSlotsManager.Instance != (Object)null) { KeybindManager.Add((MonoBehaviour)(object)SaveSlotsManager.Instance, (Action)delegate { SaveManagerConfiguration.OnOpenManagerInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _openManager.Value)); KeybindManager.Add((MonoBehaviour)(object)SaveSlotsManager.Instance, (Action)delegate { SaveManagerConfiguration.OnQuickloadInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _quickLoad.Value)); KeybindManager.Add((MonoBehaviour)(object)SaveSlotsManager.Instance, (Action)delegate { SaveManagerConfiguration.OnQuickSaveInvoked?.Invoke(); }, (Func<KeyboardShortcut>)(() => _quickSave.Value)); } } } internal static class SaveManagerConstants { public const string CONFIG_SECTION_NAME = "Save Manager"; public const string OPEN_MANAGER_CONFIG_NAME = "Open save manager"; public static KeyboardShortcut OpenManagerConfigDefault = new KeyboardShortcut((KeyCode)110, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const string QUICK_SAVE_CONFIG_NAME = "Quick save"; public static KeyboardShortcut QuickSaveConfigDefault = new KeyboardShortcut((KeyCode)286, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const string QUICK_LOAD_CONFIG_NAME = "Quick load"; public static KeyboardShortcut QuickLoadConfigDefault = new KeyboardShortcut((KeyCode)290, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }); public const string SAVE_CURRENT_POSITION_CONFIG_NAME = "Save on current position"; public const bool SAVE_CURRENT_POSITION_CONFIG_DEFAULT = false; } } namespace NKVDebugMod.Features.MonsterInspector { internal class MonsterInspector : MonoBehaviour { private MonsterInspectorUI? _inspectorWindow; private Dictionary<string, MonsterBase> _monstersCache = new Dictionary<string, MonsterBase>(); private MonsterBase? _selectedMonster; internal static MonsterInspector? Instance { get; set; } public MonsterBase? SelectedMonster { get { return _selectedMonster; } set { try { if ((Object)(object)_selectedMonster == (Object)(object)value) { return; } _selectedMonster = value; if (_inspectorWindow == null) { return; } _inspectorWindow.SelectedMonsterData = CreateMonsterData(value); if ((Object)(object)SelectedMonster == (Object)null) { _inspectorWindow.SetMonsterStates(Array.Empty<MonsterInspectorUI.MonsterStateDescriptor>()); return; } _inspectorWindow.SetMonsterStates(SelectedMonster.fsm._stateMapping.getAllStates.Select((MappingEntry<States> state) => new MonsterInspectorUI.MonsterStateDescriptor(((Object)state.stateBehavior).name, state.state))); } catch (Exception ex) { Log.Exception(ex); } } } private void Awake() { try { Instance = this; _inspectorWindow = new MonsterInspectorUI(); _inspectorWindow.OnStateSelected += HandleMonsterStateSelected; _inspectorWindow.OnNextMonsterClick += HandleNextMonsterSelection; _inspectorWindow.OnPrevMonsterClick += HandlePrevMonsterSelection; _inspectorWindow.OnSelectClosestMonsterClick += HandleClosestMonsterSelection; } catch (Exception ex) { Log.Exception(ex); } } public void Hook() { MonsterInspectorConfiguration.OnToggleMonsterInspectorInvoked += ToggleUI; MonsterInspectorPatches.OnRegisterPostifx += HandleMonsterRegister; MonsterInspectorPatches.OnUnregisterPostifx += HandleMonsterUnregister; } private void HandleMonsterStateSelected(States state) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)SelectedMonster != (Object)null) { SelectedMonster.ChangeStateIfValid(state); } } private void HandleClosestMonsterSelection() { if (SingletonBehaviour<MonsterManager>.IsAvailable()) { SelectedMonster = SingletonBehaviour<MonsterManager>.Instance.ClosetMonster; } } private void HandlePrevMonsterSelection() { if ((Object)(object)SelectedMonster == (Object)null) { SelectedMonster = _monstersCache.Values.Last(); return; } List<string> list = _monstersCache.Keys.ToList(); int num = list.IndexOf(ObjectUtils.ObjectPath(((Component)SelectedMonster).gameObject)); if (num == 0) { SelectedMonster = _monstersCache.Values.Last(); } else { SelectedMonster = _monstersCache[list[num - 1]]; } } private void HandleNextMonsterSelection() { if ((Object)(object)SelectedMonster == (Object)null) { SelectedMonster = _monstersCache.Values.First(); return; } List<string> list = _monstersCache.Keys.ToList(); int num = list.IndexOf(ObjectUtils.ObjectPath(((Component)SelectedMonster).gameObject)); if (num == list.Count - 1) { SelectedMonster = _monstersCache.Values.First(); } else { SelectedMonster = _monstersCache[list[num + 1]]; } } private void HandleMonsterRegister(MonsterManager manager, MonsterBase monster) { MonstersListChanged(manager); } private void HandleMonsterUnregister(MonsterManager manager, MonsterBase monster) { MonstersListChanged(manager); } private void MonstersListChanged(MonsterManager manager) { _monstersCache.Clear(); foreach (MonsterBase value in manager.monsterDict.Values) { _monstersCache.TryAdd(ObjectUtils.ObjectPath(((Component)value).gameObject), value); } if ((Object)(object)SelectedMonster != (Object)null && _monstersCache.ContainsKey(ObjectUtils.ObjectPath(((Component)SelectedMonster).gameObject))) { SelectedMonster = null; } } private void ToggleUI() { if (_inspectorWindow != null) { _inspectorWindow.IsInspectorEnabled = !_inspectorWindow.IsInspectorEnabled; } } private ModMonsterData? CreateMonsterData(MonsterBase? monster) { if ((Object)(object)monster == (Object)null) { return null; } return new ModMonsterData(monster) { Name = ((Object)monster).name, Path = ObjectUtils.ObjectPath(((Component)monster).gameObject) }; } private void OnGUI() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0061: Unknown result type (might be due to invalid IL or missing references) _inspectorWindow?.Draw(); MonsterInspectorUI? inspectorWindow = _inspectorWindow; if (inspectorWindow == null || !inspectorWindow.IsInspectorEnabled) { return; } foreach (MonsterBase value in _monstersCache.Values) { Collider2D myCollider = ((Actor)value).myCollider; Color color = (((Object)(object)SelectedMonster == (Object)(object)value) ? Color.green : Color.red); HitboxDrawer.DrawCollider2D(myCollider, color); } } private void OnDestroy() { MonsterInspectorConfiguration.OnToggleMonsterInspectorInvoked -= ToggleUI; MonsterInspectorPatches.OnRegisterPostifx -= HandleMonsterRegister; MonsterInspectorPatches.OnUnregisterPostifx -= HandleMonsterUnregister; } } internal static class MonsterInspectorFeature { private static GameObject _inspector; public static void Ini