Skip to content
This repository was archived by the owner on May 9, 2023. It is now read-only.

Commit a1fab0c

Browse files
committed
Add support for opening inspected Type in dnSpy
1 parent 4599747 commit a1fab0c

File tree

3 files changed

+70
-27
lines changed

3 files changed

+70
-27
lines changed

src/Config/ConfigManager.cs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ public static class ConfigManager
1616

1717
// Actual UE Settings
1818
public static ConfigElement<KeyCode> Master_Toggle;
19+
public static ConfigElement<bool> Hide_On_Startup;
20+
public static ConfigElement<float> Startup_Delay_Time;
21+
public static ConfigElement<bool> Disable_EventSystem_Override;
1922
public static ConfigElement<int> Target_Display;
20-
public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor;
2123
public static ConfigElement<bool> Force_Unlock_Mouse;
2224
public static ConfigElement<KeyCode> Force_Unlock_Toggle;
23-
public static ConfigElement<bool> Aggressive_Mouse_Unlock;
24-
public static ConfigElement<bool> Disable_EventSystem_Override;
2525
public static ConfigElement<string> Default_Output_Path;
26+
public static ConfigElement<string> DnSpy_Path;
2627
public static ConfigElement<bool> Log_Unity_Debug;
27-
public static ConfigElement<bool> Hide_On_Startup;
28-
public static ConfigElement<float> Startup_Delay_Time;
2928
public static ConfigElement<string> Reflection_Signature_Blacklist;
29+
public static ConfigElement<UIManager.VerticalAnchor> Main_Navbar_Anchor;
3030
public static ConfigElement<KeyCode> World_MouseInspect_Keybind;
3131
public static ConfigElement<KeyCode> UI_MouseInspect_Keybind;
3232

@@ -85,23 +85,15 @@ private static void CreateConfigElements()
8585
"Should UnityExplorer be hidden on startup?",
8686
false);
8787

88+
Startup_Delay_Time = new ConfigElement<float>("Startup Delay Time",
89+
"The delay on startup before the UI is created.",
90+
1f);
91+
8892
Target_Display = new ConfigElement<int>("Target Display",
8993
"The monitor index for UnityExplorer to use, if you have multiple. 0 is the default display, 1 is secondary, etc. " +
9094
"Restart recommended when changing this setting. Make sure your extra monitors are the same resolution as your primary monitor.",
9195
0);
9296

93-
Main_Navbar_Anchor = new ConfigElement<UIManager.VerticalAnchor>("Main Navbar Anchor",
94-
"The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.",
95-
UIManager.VerticalAnchor.Top);
96-
97-
World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind",
98-
"Optional keybind to being a World-mode Mouse Inspect.",
99-
KeyCode.None);
100-
101-
UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind",
102-
"Optional keybind to begin a UI-mode Mouse Inspect.",
103-
KeyCode.None);
104-
10597
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",
10698
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
10799
true);
@@ -116,17 +108,29 @@ private static void CreateConfigElements()
116108
false);
117109
Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
118110

111+
Default_Output_Path = new ConfigElement<string>("Default Output Path",
112+
"The default output path when exporting things from UnityExplorer.",
113+
Path.Combine(ExplorerCore.ExplorerFolder, "Output"));
114+
115+
DnSpy_Path = new ConfigElement<string>("dnSpy Path",
116+
"The full path to dnSpy.exe (64-bit).",
117+
@"C:/Program Files/dnspy/dnSpy.exe");
118+
119+
Main_Navbar_Anchor = new ConfigElement<UIManager.VerticalAnchor>("Main Navbar Anchor",
120+
"The vertical anchor of the main UnityExplorer Navbar, in case you want to move it.",
121+
UIManager.VerticalAnchor.Top);
122+
119123
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
120124
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",
121125
false);
122126

123-
Default_Output_Path = new ConfigElement<string>("Default Output Path",
124-
"The default output path when exporting things from UnityExplorer.",
125-
Path.Combine(ExplorerCore.ExplorerFolder, "Output"));
127+
World_MouseInspect_Keybind = new("World Mouse-Inspect Keybind",
128+
"Optional keybind to being a World-mode Mouse Inspect.",
129+
KeyCode.None);
126130

127-
Startup_Delay_Time = new ConfigElement<float>("Startup Delay Time",
128-
"The delay on startup before the UI is created.",
129-
1f);
131+
UI_MouseInspect_Keybind = new("UI Mouse-Inspect Keybind",
132+
"Optional keybind to begin a UI-mode Mouse Inspect.",
133+
KeyCode.None);
130134

131135
Reflection_Signature_Blacklist = new ConfigElement<string>("Member Signature Blacklist",
132136
"Use this to blacklist certain member signatures if they are known to cause a crash or other issues.\r\n" +

src/Inspectors/ReflectionInspector.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Diagnostics;
45
using System.IO;
56
using System.Reflection;
67
using System.Reflection.Emit;
78
using UnityEngine;
89
using UnityEngine.UI;
910
using UnityExplorer.CacheObject;
1011
using UnityExplorer.CacheObject.Views;
12+
using UnityExplorer.Config;
13+
using UnityExplorer.UI;
1114
using UnityExplorer.UI.Panels;
1215
using UnityExplorer.UI.Widgets;
1316
using UniverseLib;
@@ -33,7 +36,6 @@ public enum MemberFilter
3336
public class ReflectionInspector : InspectorBase, ICellPoolDataSource<CacheMemberCell>, ICacheObjectController
3437
{
3538
public CacheObjectBase ParentCacheObject { get; set; }
36-
//public Type TargetType { get; private set; }
3739
public bool StaticOnly { get; internal set; }
3840
public bool CanWrite => true;
3941

@@ -73,6 +75,8 @@ public class ReflectionInspector : InspectorBase, ICellPoolDataSource<CacheMembe
7375
Text assemblyText;
7476
Toggle autoUpdateToggle;
7577

78+
ButtonRef dnSpyButton;
79+
7680
ButtonRef makeGenericButton;
7781
GenericConstructorWidget genericConstructor;
7882

@@ -155,9 +159,15 @@ private void SetTarget(object target)
155159

156160
string asmText;
157161
if (TargetType.Assembly is AssemblyBuilder || string.IsNullOrEmpty(TargetType.Assembly.Location))
162+
{
158163
asmText = $"{TargetType.Assembly.GetName().Name} <color=grey><i>(in memory)</i></color>";
164+
dnSpyButton.GameObject.SetActive(false);
165+
}
159166
else
167+
{
160168
asmText = Path.GetFileName(TargetType.Assembly.Location);
169+
dnSpyButton.GameObject.SetActive(true);
170+
}
161171
assemblyText.text = $"<color=grey>Assembly:</color> {asmText}";
162172

163173
// Unity object helper widget
@@ -350,6 +360,25 @@ void OnCopyClicked()
350360
ClipboardPanel.Copy(this.Target ?? this.TargetType);
351361
}
352362

363+
void OnDnSpyButtonClicked()
364+
{
365+
string path = ConfigManager.DnSpy_Path.Value;
366+
if (File.Exists(path) && path.EndsWith("dnspy.exe", StringComparison.OrdinalIgnoreCase))
367+
{
368+
Type type = TargetType;
369+
// if constructed generic type, use the generic type definition
370+
if (type.IsGenericType && !type.IsGenericTypeDefinition)
371+
type = type.GetGenericTypeDefinition();
372+
373+
string args = $"\"{type.Assembly.Location}\" --select T:{type.FullName}";
374+
Process.Start(path, args);
375+
}
376+
else
377+
{
378+
Notification.ShowMessage($"Please set a valid dnSpy path in UnityExplorer Settings.");
379+
}
380+
}
381+
353382
void OnMakeGenericClicked()
354383
{
355384
ContentRoot.SetActive(false);
@@ -425,10 +454,21 @@ public override GameObject CreateContent(GameObject parent)
425454
UIFactory.SetLayoutElement(copyButton.Component.gameObject, minHeight: 25, minWidth: 120, flexibleWidth: 0);
426455
copyButton.OnClick += OnCopyClicked;
427456

428-
assemblyText = UIFactory.CreateLabel(UIRoot, "AssemblyLabel", "not set", TextAnchor.MiddleLeft);
457+
// Assembly row
458+
459+
GameObject asmRow = UIFactory.CreateHorizontalGroup(UIRoot, "AssemblyRow", false, false, true, true, 5, default, new(1, 1, 1, 0));
460+
UIFactory.SetLayoutElement(asmRow, flexibleWidth: 9999, minHeight: 25);
461+
462+
assemblyText = UIFactory.CreateLabel(asmRow, "AssemblyLabel", "not set", TextAnchor.MiddleLeft);
429463
UIFactory.SetLayoutElement(assemblyText.gameObject, minHeight: 25, flexibleWidth: 9999);
430464

431-
ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "MemberHolder", false, false, true, true, 5, new Vector4(2, 2, 2, 2),
465+
dnSpyButton = UIFactory.CreateButton(asmRow, "DnSpyButton", "View in dnSpy");
466+
UIFactory.SetLayoutElement(dnSpyButton.GameObject, minWidth: 120, minHeight: 25);
467+
dnSpyButton.OnClick += OnDnSpyButtonClicked;
468+
469+
// Content
470+
471+
ContentRoot = UIFactory.CreateVerticalGroup(UIRoot, "ContentRoot", false, false, true, true, 5, new Vector4(2, 2, 2, 2),
432472
new Color(0.12f, 0.12f, 0.12f));
433473
UIFactory.SetLayoutElement(ContentRoot, flexibleWidth: 9999, flexibleHeight: 9999);
434474

src/UI/Notification.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public static void Update()
3939

4040
private static void ConstructUI()
4141
{
42-
4342
popupLabel = UIFactory.CreateLabel(UIManager.UIRoot, "ClipboardNotification", "", TextAnchor.MiddleCenter);
4443
popupLabel.rectTransform.sizeDelta = new(500, 100);
4544
popupLabel.gameObject.AddComponent<Outline>();

0 commit comments

Comments
 (0)