diff --git a/src/Config/ConfigManager.cs b/src/Config/ConfigManager.cs index ad8eb6c..479286c 100644 --- a/src/Config/ConfigManager.cs +++ b/src/Config/ConfigManager.cs @@ -16,17 +16,17 @@ namespace UnityExplorer.Config // Actual UE Settings public static ConfigElement Master_Toggle; - public static ConfigElement Target_Display; - public static ConfigElement Main_Navbar_Anchor; - public static ConfigElement Force_Unlock_Mouse; - public static ConfigElement Force_Unlock_Toggle; - public static ConfigElement Aggressive_Mouse_Unlock; - public static ConfigElement Disable_EventSystem_Override; - public static ConfigElement Default_Output_Path; - public static ConfigElement Log_Unity_Debug; public static ConfigElement Hide_On_Startup; public static ConfigElement Startup_Delay_Time; + public static ConfigElement Disable_EventSystem_Override; + public static ConfigElement Target_Display; + public static ConfigElement Force_Unlock_Mouse; + public static ConfigElement Force_Unlock_Toggle; + public static ConfigElement Default_Output_Path; + public static ConfigElement DnSpy_Path; + public static ConfigElement Log_Unity_Debug; public static ConfigElement Reflection_Signature_Blacklist; + public static ConfigElement Main_Navbar_Anchor; public static ConfigElement World_MouseInspect_Keybind; public static ConfigElement UI_MouseInspect_Keybind; @@ -85,23 +85,15 @@ namespace UnityExplorer.Config "Should UnityExplorer be hidden on startup?", false); + Startup_Delay_Time = new ConfigElement("Startup Delay Time", + "The delay on startup before the UI is created.", + 1f); + Target_Display = new ConfigElement("Target Display", "The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " + "Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.", 0); - Main_Navbar_Anchor = new ConfigElement("Main Navbar Anchor", - "The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.", - UIManager.VerticalAnchor.Top); - - World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind", - "Optional keybind to being a World-mode Mouse Inspect.", - KeyCode.None); - - UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind", - "Optional keybind to begin a UI-mode Mouse Inspect.", - KeyCode.None); - Force_Unlock_Mouse = new ConfigElement("Force Unlock Mouse", "Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.", true); @@ -116,17 +108,29 @@ namespace UnityExplorer.Config false); Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value; - Log_Unity_Debug = new ConfigElement("Log Unity Debug", - "Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?", - false); - Default_Output_Path = new ConfigElement("Default Output Path", "The default output path when exporting things from UnityExplorer.", Path.Combine(ExplorerCore.ExplorerFolder, "Output")); - Startup_Delay_Time = new ConfigElement("Startup Delay Time", - "The delay on startup before the UI is created.", - 1f); + DnSpy_Path = new ConfigElement("dnSpy Path", + "The full path to dnSpy.exe (64-bit).", + @"C:/Program Files/dnspy/dnSpy.exe"); + + Main_Navbar_Anchor = new ConfigElement("Main Navbar Anchor", + "The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.", + UIManager.VerticalAnchor.Top); + + Log_Unity_Debug = new ConfigElement("Log Unity Debug", + "Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?", + false); + + World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind", + "Optional keybind to being a World-mode Mouse Inspect.", + KeyCode.None); + + UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind", + "Optional keybind to begin a UI-mode Mouse Inspect.", + KeyCode.None); Reflection_Signature_Blacklist = new ConfigElement("Member Signature Blacklist", "Use this to blacklist certain member signatures if they are known to cause a crash or other issues.\r\n" + diff --git a/src/Inspectors/ReflectionInspector.cs b/src/Inspectors/ReflectionInspector.cs index de5329b..4876d5d 100644 --- a/src/Inspectors/ReflectionInspector.cs +++ b/src/Inspectors/ReflectionInspector.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; @@ -8,6 +9,8 @@ using UnityEngine; using UnityEngine.UI; using UnityExplorer.CacheObject; using UnityExplorer.CacheObject.Views; +using UnityExplorer.Config; +using UnityExplorer.UI; using UnityExplorer.UI.Panels; using UnityExplorer.UI.Widgets; using UniverseLib; @@ -33,7 +36,6 @@ namespace UnityExplorer.Inspectors public class ReflectionInspector : InspectorBase, ICellPoolDataSource, ICacheObjectController { public CacheObjectBase ParentCacheObject { get; set; } - //public Type TargetType { get; private set; } public bool StaticOnly { get; internal set; } public bool CanWrite => true; @@ -73,6 +75,8 @@ namespace UnityExplorer.Inspectors Text assemblyText; Toggle autoUpdateToggle; + ButtonRef dnSpyButton; + ButtonRef makeGenericButton; GenericConstructorWidget genericConstructor; @@ -155,9 +159,15 @@ namespace UnityExplorer.Inspectors string asmText; if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location)) + { asmText = $"{TargetType.Assembly.GetName().Name} (in memory)"; + dnSpyButton.GameObject.SetActive(false); + } else + { asmText = Path.GetFileName(TargetType.Assembly.Location); + dnSpyButton.GameObject.SetActive(true); + } assemblyText.text = $"Assembly: {asmText}"; // Unity object helper widget @@ -350,6 +360,25 @@ namespace UnityExplorer.Inspectors ClipboardPanel.Copy(this.Target ?? this.TargetType); } + void OnDnSpyButtonClicked() + { + string path = ConfigManager.DnSpy_Path.Value; + if (File.Exists(path) && path.EndsWith("dnspy.exe", StringComparison.OrdinalIgnoreCase)) + { + Type type = TargetType; + // if constructed generic type, use the generic type definition + if (type.IsGenericType && !type.IsGenericTypeDefinition) + type = type.GetGenericTypeDefinition(); + + string args = $"\"{type.Assembly.Location}\" --select T:{type.FullName}"; + Process.Start(path, args); + } + else + { + Notification.ShowMessage($"Please set a valid dnSpy path in UnityExplorer Settings."); + } + } + void OnMakeGenericClicked() { ContentRoot.SetActive(false); @@ -425,10 +454,21 @@ namespace UnityExplorer.Inspectors UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0); copyButton.OnClick += OnCopyClicked; - assemblyText = UIFactory.CreateLabel(UIRoot, "AssemblyLabel", "not set", TextAnchor.MiddleLeft); + // Assembly row + + GameObject asmRow = UIFactory.CreateHorizontalGroup(UIRoot, "AssemblyRow", false, false, true, true, 5, default, new(1, 1, 1, 0)); + UIFactory.SetLayoutElement(asmRow, flexibleWidth: 9999, minHeight: 25); + + assemblyText = UIFactory.CreateLabel(asmRow, "AssemblyLabel", "not set", TextAnchor.MiddleLeft); UIFactory.SetLayoutElement(assemblyText.gameObject, minHeight: 25, flexibleWidth: 9999); - ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "MemberHolder", false, false, true, true, 5, new Vector4(2, 2, 2, 2), + dnSpyButton = UIFactory.CreateButton(asmRow, "DnSpyButton", "View in dnSpy"); + UIFactory.SetLayoutElement(dnSpyButton.GameObject, minWidth: 120, minHeight: 25); + dnSpyButton.OnClick += OnDnSpyButtonClicked; + + // Content + + ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "ContentRoot", false, false, true, true, 5, new Vector4(2, 2, 2, 2), new Color(0.12f, 0.12f, 0.12f)); UIFactory.SetLayoutElement(ContentRoot, flexibleWidth: 9999, flexibleHeight: 9999); diff --git a/src/UI/Notification.cs b/src/UI/Notification.cs index e57da58..94d00b0 100644 --- a/src/UI/Notification.cs +++ b/src/UI/Notification.cs @@ -39,7 +39,6 @@ namespace UnityExplorer.UI private static void ConstructUI() { - popupLabel = UIFactory.CreateLabel(UIManager.UIRoot, "ClipboardNotification", "", TextAnchor.MiddleCenter); popupLabel.rectTransform.sizeDelta = new(500, 100); popupLabel.gameObject.AddComponent();