Compare commits

..

20 Commits
4.5.4 ... 4.5.9

Author SHA1 Message Date
b8c4be473f Fix disposed TextWriter bug, bump version 2022-03-06 00:21:48 +11:00
b6966f8836 Bump UniverseLib, bump version 2022-03-05 07:32:32 +11:00
ad8c5293a0 Add keybinds for Mouse Inspect, small cleanup 2022-03-04 00:20:04 +11:00
a7165c849c Bump UniverseLib, cleanup, bump version 2022-03-04 00:09:19 +11:00
79f2514109 Fix issue with partially unloaded scenes(?) 2022-03-03 03:22:17 +11:00
4e76eca73a Use new melonloader logging method 2022-02-24 19:26:16 +11:00
2f0876466c bump mod loader versions 2022-02-24 19:26:01 +11:00
fdefc3d567 Include runtime context in "initialized" log. 2022-02-21 01:46:13 +11:00
64193ff1b0 Use a patch instead of manual check on every property 2022-02-21 01:45:46 +11:00
a90292f47f Prevent Unity crashing on PropertyInfo evaluation
Unity crashes from checking Canvas.renderingDisplaySize on a Canvas set to WorldSpace with no worldCamera set.
2022-02-19 17:50:10 +11:00
d0bccae50c Update TypeCompleter.cs 2022-02-11 19:39:11 +11:00
bdf08f014f Use ReflectionUtility.AllTypes for type autocompleter, bump UniverseLib 2022-02-11 19:37:17 +11:00
df8522963e Use reflection for AllTypes until it's public 2022-02-07 22:12:18 +11:00
f6d0acab7b Bump version 2022-02-07 00:45:19 +11:00
d4fbc89158 Use ReflectionUtility.AllTypes when doing class search to include static classes 2022-02-06 04:50:52 +11:00
9e49f09a79 Bump UniverseLib, fix C# Console issues, add Stop helper 2022-02-04 20:34:05 +11:00
b9a3ab7439 Fix CSConsole not re-selecting properly after Escape is pressed 2022-02-04 18:07:34 +11:00
03661cdd0b Bump UniverseLib 2022-02-03 23:51:38 +11:00
10f2b7e849 Bump UniverseLib and fix changes to CreatePanel 2022-02-03 23:33:45 +11:00
4602f07c34 Add NuGet config 2022-02-01 18:20:01 +11:00
35 changed files with 323 additions and 180 deletions

Binary file not shown.

View File

@ -18,6 +18,8 @@ using UniverseLib.UI;
using UniverseLib; using UniverseLib;
using UniverseLib.UI.Models; using UniverseLib.UI.Models;
using UniverseLib.Utility; using UniverseLib.Utility;
using HarmonyLib;
using UniverseLib.Runtime;
namespace UnityExplorer.CSConsole namespace UnityExplorer.CSConsole
{ {
@ -60,6 +62,8 @@ namespace UnityExplorer.CSConsole
public static void Init() public static void Init()
{ {
InitEventSystemPropertyHandlers();
// Make sure console is supported on this platform // Make sure console is supported on this platform
try try
{ {
@ -383,30 +387,77 @@ namespace UnityExplorer.CSConsole
RuntimeHelper.StartCoroutine(SetCaretCoroutine(caretPosition)); RuntimeHelper.StartCoroutine(SetCaretCoroutine(caretPosition));
} }
internal static PropertyInfo SelectionGuardProperty => selectionGuardPropInfo ?? GetSelectionGuardPropInfo(); static void InitEventSystemPropertyHandlers()
private static PropertyInfo GetSelectionGuardPropInfo()
{ {
selectionGuardPropInfo = typeof(EventSystem).GetProperty("m_SelectionGuard"); try
if (selectionGuardPropInfo == null) {
selectionGuardPropInfo = typeof(EventSystem).GetProperty("m_selectionGuard"); foreach (var member in typeof(EventSystem).GetMembers(AccessTools.all))
return selectionGuardPropInfo; {
if (member.Name == "m_CurrentSelected")
{
Type backingType;
if (member.MemberType == MemberTypes.Property)
backingType = (member as PropertyInfo).PropertyType;
else
backingType = (member as FieldInfo).FieldType;
usingEventSystemDictionaryMembers = ReflectionUtility.IsDictionary(backingType);
break;
}
}
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Exception checking EventSystem property backing type: {ex}");
}
} }
private static PropertyInfo selectionGuardPropInfo; static bool usingEventSystemDictionaryMembers;
static readonly AmbiguousMemberHandler<EventSystem, GameObject> m_CurrentSelected_Handler_Normal = new("m_CurrentSelected", "m_currentSelected");
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, GameObject>> m_CurrentSelected_Handler_Dictionary = new("m_CurrentSelected", "m_currentSelected");
static readonly AmbiguousMemberHandler<EventSystem, bool> m_SelectionGuard_Handler_Normal = new("m_SelectionGuard", "m_selectionGuard");
static readonly AmbiguousMemberHandler<EventSystem, Dictionary<int, bool>> m_SelectionGuard_Handler_Dictionary = new("m_SelectionGuard", "m_selectionGuard");
static void SetCurrentSelectedGameObject(EventSystem instance, GameObject value)
{
instance.SetSelectedGameObject(value);
if (usingEventSystemDictionaryMembers)
m_CurrentSelected_Handler_Dictionary.GetValue(instance)[0] = value;
else
m_CurrentSelected_Handler_Normal.SetValue(instance, value);
}
static void SetSelectionGuard(EventSystem instance, bool value)
{
if (usingEventSystemDictionaryMembers)
m_SelectionGuard_Handler_Dictionary.GetValue(instance)[0] = value;
else
m_SelectionGuard_Handler_Normal.SetValue(instance, value);
}
private static IEnumerator SetCaretCoroutine(int caretPosition) private static IEnumerator SetCaretCoroutine(int caretPosition)
{ {
var color = Input.Component.selectionColor; var color = Input.Component.selectionColor;
color.a = 0f; color.a = 0f;
Input.Component.selectionColor = color; Input.Component.selectionColor = color;
try { EventSystem.current.SetSelectedGameObject(null, null); } catch { }
yield return null;
try { SelectionGuardProperty.SetValue(EventSystem.current, false, null); } catch { } try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, null); }
try { EventSystem.current.SetSelectedGameObject(Input.UIRoot, null); } catch { } catch (Exception ex) { ExplorerCore.Log($"Failed removing selected object: {ex}"); }
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
try { SetSelectionGuard(CursorUnlocker.CurrentEventSystem, false); }
catch (Exception ex) { ExplorerCore.Log($"Failed setting selection guard: {ex}"); }
try { SetCurrentSelectedGameObject(CursorUnlocker.CurrentEventSystem, Input.GameObject); }
catch (Exception ex) { ExplorerCore.Log($"Failed setting selected gameobject: {ex}"); }
yield return null; // ~~~~~~~ YIELD FRAME ~~~~~~~~~
Input.Component.Select(); Input.Component.Select();
yield return null;
Input.Component.caretPosition = caretPosition; Input.Component.caretPosition = caretPosition;
Input.Component.selectionFocusPosition = caretPosition; Input.Component.selectionFocusPosition = caretPosition;
@ -665,7 +716,8 @@ var x = 5;
* Log(obj); - prints a message to the console log * Log(obj); - prints a message to the console log
* Inspect(obj); - inspect the object with the Inspector * Inspect(obj); - inspect the object with the Inspector
* Inspect(someType); - inspect a Type with static reflection * Inspect(someType); - inspect a Type with static reflection
* Start(enumerator); - starts the IEnumerator as a Coroutine * Start(enumerator); - Coroutine, starts the IEnumerator as a Coroutine, and returns the Coroutine.
* Stop(coroutine); - stop the Coroutine ONLY if it was started with Start(ienumerator).
* Copy(obj); - copies the object to the UnityExplorer Clipboard * Copy(obj); - copies the object to the UnityExplorer Clipboard
* Paste(); - System.Object, the contents of the Clipboard. * Paste(); - System.Object, the contents of the Clipboard.
* GetUsing(); - prints the current using directives to the console log * GetUsing(); - prints the current using directives to the console log

View File

@ -51,13 +51,8 @@ namespace UnityExplorer.CSConsole
ReferenceAssembly(asm); ReferenceAssembly(asm);
} }
private static CompilerContext context;
private static CompilerContext BuildContext(TextWriter tw) private static CompilerContext BuildContext(TextWriter tw)
{ {
if (context != null)
return context;
_reportPrinter = new StreamReportPrinter(tw); _reportPrinter = new StreamReportPrinter(tw);
var settings = new CompilerSettings var settings = new CompilerSettings
@ -70,7 +65,7 @@ namespace UnityExplorer.CSConsole
EnhancedWarnings = false EnhancedWarnings = false
}; };
return context = new CompilerContext(settings, _reportPrinter); return new CompilerContext(settings, _reportPrinter);
} }
private static void ImportAppdomainAssemblies(Action<Assembly> import) private static void ImportAppdomainAssemblies(Action<Assembly> import)

View File

@ -29,9 +29,12 @@ namespace UnityExplorer.CSConsole
public static void Inspect(Type type) public static void Inspect(Type type)
=> InspectorManager.Inspect(type); => InspectorManager.Inspect(type);
public static void Start(IEnumerator ienumerator) public static Coroutine Start(IEnumerator ienumerator)
=> RuntimeHelper.StartCoroutine(ienumerator); => RuntimeHelper.StartCoroutine(ienumerator);
public static void Stop(Coroutine coro)
=> RuntimeHelper.StopCoroutine(coro);
public static void Copy(object obj) public static void Copy(object obj)
=> ClipboardPanel.Copy(obj); => ClipboardPanel.Copy(obj);

View File

@ -21,7 +21,7 @@ namespace UnityExplorer.CacheObject
{ {
public abstract Type DeclaringType { get; } public abstract Type DeclaringType { get; }
public string NameForFiltering { get; protected set; } public string NameForFiltering { get; protected set; }
public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ?? (m_declaringInstance = Owner.Target.TryCast(DeclaringType))); public object DeclaringInstance => IsStatic ? null : (m_declaringInstance ??= Owner.Target.TryCast(DeclaringType));
private object m_declaringInstance; private object m_declaringInstance;
public abstract bool IsStatic { get; } public abstract bool IsStatic { get; }
@ -94,8 +94,8 @@ namespace UnityExplorer.CacheObject
base.SetValueState(cell, args); base.SetValueState(cell, args);
} }
private static readonly Color evalEnabledColor = new Color(0.15f, 0.25f, 0.15f); private static readonly Color evalEnabledColor = new(0.15f, 0.25f, 0.15f);
private static readonly Color evalDisabledColor = new Color(0.15f, 0.15f, 0.15f); private static readonly Color evalDisabledColor = new(0.15f, 0.15f, 0.15f);
protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell) protected override bool TryAutoEvaluateIfUnitialized(CacheObjectCell objectcell)
{ {
@ -242,7 +242,7 @@ namespace UnityExplorer.CacheObject
var sig = GetSig(member); var sig = GetSig(member);
//ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})"); // ExplorerCore.Log($"Trying to cache member {sig}... ({member.MemberType})");
CacheMember cached; CacheMember cached;
Type returnType; Type returnType;

View File

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using UnityEngine;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using UnityExplorer.Runtime;
namespace UnityExplorer.CacheObject namespace UnityExplorer.CacheObject
{ {

View File

@ -32,6 +32,8 @@ namespace UnityExplorer.Config
public static ConfigElement<bool> Hide_On_Startup; public static ConfigElement<bool> Hide_On_Startup;
public static ConfigElement<float> Startup_Delay_Time; public static ConfigElement<float> Startup_Delay_Time;
public static ConfigElement<string> Reflection_Signature_Blacklist; public static ConfigElement<string> Reflection_Signature_Blacklist;
public static ConfigElement<KeyCode> World_MouseInspect_Keybind;
public static ConfigElement<KeyCode> UI_MouseInspect_Keybind;
// internal configs // internal configs
internal static InternalConfigHandler InternalHandler { get; private set; } internal static InternalConfigHandler InternalHandler { get; private set; }
@ -93,13 +95,18 @@ namespace UnityExplorer.Config
"Should UnityExplorer be hidden on startup?", "Should UnityExplorer be hidden on startup?",
false); 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);
Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse", Force_Unlock_Mouse = new ConfigElement<bool>("Force Unlock Mouse",
"Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.", "Force the Cursor to be unlocked (visible) when the UnityExplorer menu is open.",
true); true);
Force_Unlock_Mouse.OnValueChanged += (bool value) => Force_Unlock_Mouse.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value;
{
UniverseLib.Config.ConfigManager.Force_Unlock_Mouse = value;
};
Force_Unlock_Toggle = new ConfigElement<KeyCode>("Force Unlock Toggle Key", Force_Unlock_Toggle = new ConfigElement<KeyCode>("Force Unlock Toggle Key",
"The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.", "The keybind to toggle the 'Force Unlock Mouse' setting. Only usable when UnityExplorer is open.",
@ -108,10 +115,7 @@ namespace UnityExplorer.Config
Disable_EventSystem_Override = new ConfigElement<bool>("Disable EventSystem override", Disable_EventSystem_Override = new ConfigElement<bool>("Disable EventSystem override",
"If enabled, UnityExplorer will not override the EventSystem from the game.\n<b>May require restart to take effect.</b>", "If enabled, UnityExplorer will not override the EventSystem from the game.\n<b>May require restart to take effect.</b>",
false); false);
Disable_EventSystem_Override.OnValueChanged += (bool value) => Disable_EventSystem_Override.OnValueChanged += (bool value) => UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
{
UniverseLib.Config.ConfigManager.Disable_EventSystem_Override = value;
};
Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug", Log_Unity_Debug = new ConfigElement<bool>("Log Unity Debug",
"Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?", "Should UnityEngine.Debug.Log messages be printed to UnityExplorer's log?",

View File

@ -11,13 +11,14 @@ using UnityExplorer.UI.Panels;
using UnityExplorer.Runtime; using UnityExplorer.Runtime;
using UniverseLib.Input; using UniverseLib.Input;
using UniverseLib.UI; using UniverseLib.UI;
using System.Reflection;
namespace UnityExplorer namespace UnityExplorer
{ {
public static class ExplorerCore public static class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "4.5.4"; public const string VERSION = "4.5.9";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";
@ -45,6 +46,7 @@ namespace UnityExplorer
ConfigManager.Init(Loader.ConfigHandler); ConfigManager.Init(Loader.ConfigHandler);
UERuntimeHelper.Init(); UERuntimeHelper.Init();
ExplorerBehaviour.Setup(); ExplorerBehaviour.Setup();
UnityCrashPrevention.Init();
UniverseLib.Universe.Init(ConfigManager.Startup_Delay_Time.Value, LateInit, Log, new() UniverseLib.Universe.Init(ConfigManager.Startup_Delay_Time.Value, LateInit, Log, new()
{ {
@ -67,7 +69,7 @@ namespace UnityExplorer
UIManager.InitUI(); UIManager.InitUI();
Log($"{NAME} {VERSION} initialized."); Log($"{NAME} {VERSION} initialized for {UniverseLib.Universe.Context}.");
//InspectorManager.Inspect(typeof(Tests.TestClass)); //InspectorManager.Inspect(typeof(Tests.TestClass));
} }

View File

@ -18,7 +18,7 @@ namespace UnityExplorer
{ {
public static class InspectorManager public static class InspectorManager
{ {
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>(); public static readonly List<InspectorBase> Inspectors = new();
public static InspectorBase ActiveInspector { get; private set; } public static InspectorBase ActiveInspector { get; private set; }
private static InspectorBase lastActiveInspector; private static InspectorBase lastActiveInspector;
@ -94,17 +94,17 @@ namespace UnityExplorer
} }
private static void CreateInspector<T>(object target, bool staticReflection = false, private static void CreateInspector<T>(object target, bool staticReflection = false,
CacheObjectBase sourceCache = null) where T : InspectorBase CacheObjectBase parentObject = null) where T : InspectorBase
{ {
var inspector = Pool<T>.Borrow(); var inspector = Pool<T>.Borrow();
Inspectors.Add(inspector); Inspectors.Add(inspector);
inspector.Target = target; inspector.Target = target;
if (sourceCache != null && sourceCache.CanWrite) if (parentObject != null && parentObject.CanWrite)
{ {
// only set parent cache object if we are inspecting a struct, otherwise there is no point. // only set parent cache object if we are inspecting a struct, otherwise there is no point.
if (target.GetType().IsValueType && inspector is ReflectionInspector ri) if (target.GetType().IsValueType && inspector is ReflectionInspector ri)
ri.ParentCacheObject = sourceCache; ri.ParentCacheObject = parentObject;
} }
UIManager.SetPanelActive(UIManager.Panels.Inspector, true); UIManager.SetPanelActive(UIManager.Panels.Inspector, true);

View File

@ -13,6 +13,7 @@ using UnityExplorer.UI.Panels;
using UniverseLib; using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
using UniverseLib.Utility; using UniverseLib.Utility;
using UnityExplorer.Config;
namespace UnityExplorer.Inspectors namespace UnityExplorer.Inspectors
{ {
@ -22,9 +23,9 @@ namespace UnityExplorer.Inspectors
UI UI
} }
public class InspectUnderMouse : UIPanel public class MouseInspector : UIPanel
{ {
public static InspectUnderMouse Instance { get; private set; } public static MouseInspector Instance { get; private set; }
private readonly WorldInspector worldInspector; private readonly WorldInspector worldInspector;
private readonly UiInspector uiInspector; private readonly UiInspector uiInspector;
@ -58,7 +59,7 @@ namespace UnityExplorer.Inspectors
internal Text objPathLabel; internal Text objPathLabel;
internal Text mousePosLabel; internal Text mousePosLabel;
public InspectUnderMouse() public MouseInspector()
{ {
Instance = this; Instance = this;
worldInspector = new WorldInspector(); worldInspector = new WorldInspector();
@ -116,6 +117,26 @@ namespace UnityExplorer.Inspectors
private static float timeOfLastRaycast; private static float timeOfLastRaycast;
public bool TryUpdate()
{
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None)
{
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
Instance.StartInspect(MouseInspectMode.World);
}
if (ConfigManager.World_MouseInspect_Keybind.Value != KeyCode.None)
{
if (InputManager.GetKeyDown(ConfigManager.World_MouseInspect_Keybind.Value))
Instance.StartInspect(MouseInspectMode.World);
}
if (Inspecting)
UpdateInspect();
return Inspecting;
}
public void UpdateInspect() public void UpdateInspect()
{ {
if (InputManager.GetKeyDown(KeyCode.Escape)) if (InputManager.GetKeyDown(KeyCode.Escape))
@ -177,10 +198,10 @@ namespace UnityExplorer.Inspectors
public override void ConstructPanelContent() public override void ConstructPanelContent()
{ {
// hide title bar // hide title bar
this.titleBar.SetActive(false); this.TitleBar.SetActive(false);
this.UIRoot.transform.SetParent(UIManager.UIRoot.transform, false); this.UIRoot.transform.SetParent(UIManager.UIRoot.transform, false);
var inspectContent = UIFactory.CreateVerticalGroup(this.uiRoot, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2)); var inspectContent = UIFactory.CreateVerticalGroup(this.uiContent, "InspectContent", true, true, true, true, 3, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(inspectContent, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(inspectContent, flexibleWidth: 9999, flexibleHeight: 9999);
// Title text // Title text

View File

@ -26,7 +26,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
public override void OnBeginMouseInspect() public override void OnBeginMouseInspect()
{ {
SetupUIRaycast(); SetupUIRaycast();
InspectUnderMouse.Instance.objPathLabel.text = ""; MouseInspector.Instance.objPathLabel.text = "";
} }
public override void ClearHitData() public override void ClearHitData()
@ -70,9 +70,9 @@ namespace UnityExplorer.Inspectors.MouseInspectors
} }
if (currentHitObjects.Any()) if (currentHitObjects.Any())
InspectUnderMouse.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}"; MouseInspector.Instance.objNameLabel.text = $"Click to view UI Objects under mouse: {currentHitObjects.Count}";
else else
InspectUnderMouse.Instance.objNameLabel.text = $"No UI objects under mouse."; MouseInspector.Instance.objNameLabel.text = $"No UI objects under mouse.";
} }
private static void SetupUIRaycast() private static void SetupUIRaycast()

View File

@ -41,7 +41,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
if (!MainCamera) if (!MainCamera)
{ {
ExplorerCore.LogWarning("No Main Camera was found, unable to inspect world!"); ExplorerCore.LogWarning("No Main Camera was found, unable to inspect world!");
InspectUnderMouse.Instance.StopInspect(); MouseInspector.Instance.StopInspect();
return; return;
} }
@ -51,7 +51,7 @@ namespace UnityExplorer.Inspectors.MouseInspectors
if (hit.transform) if (hit.transform)
OnHitGameObject(hit.transform.gameObject); OnHitGameObject(hit.transform.gameObject);
else if (lastHitObject) else if (lastHitObject)
InspectUnderMouse.Instance.ClearHitData(); MouseInspector.Instance.ClearHitData();
} }
internal void OnHitGameObject(GameObject obj) internal void OnHitGameObject(GameObject obj)
@ -59,8 +59,8 @@ namespace UnityExplorer.Inspectors.MouseInspectors
if (obj != lastHitObject) if (obj != lastHitObject)
{ {
lastHitObject = obj; lastHitObject = obj;
InspectUnderMouse.Instance.objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>"; MouseInspector.Instance.objNameLabel.text = $"<b>Click to Inspect:</b> <color=cyan>{obj.name}</color>";
InspectUnderMouse.Instance.objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}"; MouseInspector.Instance.objPathLabel.text = $"Path: {obj.transform.GetTransformPath(true)}";
} }
} }

View File

@ -31,9 +31,9 @@ namespace UnityExplorer
public ConfigHandler ConfigHandler => _configHandler; public ConfigHandler ConfigHandler => _configHandler;
public MelonLoaderConfigHandler _configHandler; public MelonLoaderConfigHandler _configHandler;
public Action<object> OnLogMessage => MelonLogger.Msg; public Action<object> OnLogMessage => LoggerInstance.Msg;
public Action<object> OnLogWarning => MelonLogger.Warning; public Action<object> OnLogWarning => LoggerInstance.Warning;
public Action<object> OnLogError => MelonLogger.Error; public Action<object> OnLogError => LoggerInstance.Error;
public override void OnApplicationStart() public override void OnApplicationStart()
{ {

View File

@ -99,7 +99,13 @@ namespace UnityExplorer.ObjectExplorer
nameInputRow.SetActive(context == SearchContext.UnityObject); nameInputRow.SetActive(context == SearchContext.UnityObject);
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object); if (context == SearchContext.Class)
typeAutocompleter.AllTypes = true;
else
{
typeAutocompleter.BaseType = context == SearchContext.UnityObject ? typeof(UnityEngine.Object) : typeof(object);
typeAutocompleter.AllTypes = false;
}
typeAutocompleter.CacheTypes(); typeAutocompleter.CacheTypes();
} }

View File

@ -27,7 +27,7 @@ namespace UnityExplorer.ObjectExplorer
Parent = parent; Parent = parent;
SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged; SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged;
SceneHandler.OnLoadedScenesChanged += SceneHandler_OnLoadedScenesChanged; SceneHandler.OnLoadedScenesUpdated += SceneHandler_OnLoadedScenesUpdated;
} }
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
@ -87,7 +87,7 @@ namespace UnityExplorer.ObjectExplorer
Tree.JumpAndExpandToTransform(transform); Tree.JumpAndExpandToTransform(transform);
} }
private void OnDropdownChanged(int value) private void OnSceneSelectionDropdownChanged(int value)
{ {
if (value < 0 || SceneHandler.LoadedScenes.Count <= value) if (value < 0 || SceneHandler.LoadedScenes.Count <= value)
return; return;
@ -101,7 +101,7 @@ namespace UnityExplorer.ObjectExplorer
private void SceneHandler_OnInspectedSceneChanged(Scene scene) private void SceneHandler_OnInspectedSceneChanged(Scene scene)
{ {
if (!sceneToDropdownOption.ContainsKey(scene)) if (!sceneToDropdownOption.ContainsKey(scene))
PopulateSceneDropdown(); PopulateSceneDropdown(SceneHandler.LoadedScenes);
if (sceneToDropdownOption.ContainsKey(scene)) if (sceneToDropdownOption.ContainsKey(scene))
{ {
@ -122,17 +122,17 @@ namespace UnityExplorer.ObjectExplorer
refreshRow.SetActive(!scene.IsValid()); refreshRow.SetActive(!scene.IsValid());
} }
private void SceneHandler_OnLoadedScenesChanged(List<Scene> loadedScenes) private void SceneHandler_OnLoadedScenesUpdated(List<Scene> loadedScenes)
{ {
PopulateSceneDropdown(); PopulateSceneDropdown(loadedScenes);
} }
private void PopulateSceneDropdown() private void PopulateSceneDropdown(List<Scene> loadedScenes)
{ {
sceneToDropdownOption.Clear(); sceneToDropdownOption.Clear();
sceneDropdown.options.Clear(); sceneDropdown.options.Clear();
foreach (var scene in SceneHandler.LoadedScenes) foreach (var scene in loadedScenes)
{ {
if (sceneToDropdownOption.ContainsKey(scene)) if (sceneToDropdownOption.ContainsKey(scene))
continue; continue;
@ -198,11 +198,11 @@ namespace UnityExplorer.ObjectExplorer
var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15); var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15);
UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0); UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnDropdownChanged); var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnSceneSelectionDropdownChanged);
UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
SceneHandler.Update(); SceneHandler.Update();
PopulateSceneDropdown(); PopulateSceneDropdown(SceneHandler.LoadedScenes);
sceneDropdown.captionText.text = sceneToDropdownOption.First().Value.text; sceneDropdown.captionText.text = sceneToDropdownOption.First().Value.text;
// Filter row // Filter row

View File

@ -17,7 +17,7 @@ namespace UnityExplorer.ObjectExplorer
get => selectedScene; get => selectedScene;
internal set internal set
{ {
if (selectedScene != null && selectedScene == value) if (selectedScene.HasValue && selectedScene == value)
return; return;
selectedScene = value; selectedScene = value;
OnInspectedSceneChanged?.Invoke((Scene)selectedScene); OnInspectedSceneChanged?.Invoke((Scene)selectedScene);
@ -30,7 +30,7 @@ namespace UnityExplorer.ObjectExplorer
/// <summary>All currently loaded Scenes.</summary> /// <summary>All currently loaded Scenes.</summary>
public static List<Scene> LoadedScenes { get; private set; } = new(); public static List<Scene> LoadedScenes { get; private set; } = new();
private static HashSet<Scene> previousLoadedScenes; //private static HashSet<Scene> previousLoadedScenes;
/// <summary>The names of all scenes in the build settings, if they could be retrieved.</summary> /// <summary>The names of all scenes in the build settings, if they could be retrieved.</summary>
public static List<string> AllSceneNames { get; private set; } = new(); public static List<string> AllSceneNames { get; private set; } = new();
@ -39,7 +39,7 @@ namespace UnityExplorer.ObjectExplorer
public static event Action<Scene> OnInspectedSceneChanged; public static event Action<Scene> OnInspectedSceneChanged;
/// <summary>Invoked whenever the list of currently loaded Scenes changes. The argument contains all loaded scenes after the change.</summary> /// <summary>Invoked whenever the list of currently loaded Scenes changes. The argument contains all loaded scenes after the change.</summary>
public static event Action<List<Scene>> OnLoadedScenesChanged; public static event Action<List<Scene>> OnLoadedScenesUpdated;
/// <summary>Generally will be 2, unless DontDestroyExists == false, then this will be 1.</summary> /// <summary>Generally will be 2, unless DontDestroyExists == false, then this will be 1.</summary>
internal static int DefaultSceneCount => 1 + (DontDestroyExists ? 1 : 0); internal static int DefaultSceneCount => 1 + (DontDestroyExists ? 1 : 0);
@ -84,23 +84,20 @@ namespace UnityExplorer.ObjectExplorer
internal static void Update() internal static void Update()
{ {
// check if the loaded scenes changed. always confirm DontDestroy / HideAndDontSave // Inspected scene will exist if it's DontDestroyOnLoad or HideAndDontSave
int confirmedCount = DefaultSceneCount; bool inspectedExists =
bool inspectedExists = (SelectedScene.HasValue && SelectedScene.Value.handle == -12) SelectedScene.HasValue
|| (SelectedScene.HasValue && SelectedScene.Value.handle == -1); && ((DontDestroyExists && SelectedScene.Value.handle == -12)
|| SelectedScene.Value.handle == -1);
LoadedScenes.Clear(); LoadedScenes.Clear();
for (int i = 0; i < SceneManager.sceneCount; i++) for (int i = 0; i < SceneManager.sceneCount; i++)
{ {
Scene scene = SceneManager.GetSceneAt(i); Scene scene = SceneManager.GetSceneAt(i);
if (scene == default || !scene.isLoaded) if (scene == default || !scene.isLoaded || !scene.IsValid())
continue; continue;
// If no changes yet, ensure the previous list contained the scene
if (previousLoadedScenes != null && previousLoadedScenes.Contains(scene))
confirmedCount++;
// If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one. // If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one.
if (!inspectedExists && scene == SelectedScene) if (!inspectedExists && scene == SelectedScene)
inspectedExists = true; inspectedExists = true;
@ -112,17 +109,12 @@ namespace UnityExplorer.ObjectExplorer
LoadedScenes.Add(new Scene { m_Handle = -12 }); LoadedScenes.Add(new Scene { m_Handle = -12 });
LoadedScenes.Add(new Scene { m_Handle = -1 }); LoadedScenes.Add(new Scene { m_Handle = -1 });
bool anyChange = confirmedCount != LoadedScenes.Count;
previousLoadedScenes = new HashSet<Scene>(LoadedScenes);
// Default to first scene if none selected or previous selection no longer exists. // Default to first scene if none selected or previous selection no longer exists.
if (!inspectedExists) if (!inspectedExists)
SelectedScene = LoadedScenes.First(); SelectedScene = LoadedScenes.First();
// Notify on the list changing at all // Notify on the list changing at all
if (anyChange) OnLoadedScenesUpdated?.Invoke(LoadedScenes);
OnLoadedScenesChanged?.Invoke(LoadedScenes);
// Finally, update the root objects list. // Finally, update the root objects list.
if (SelectedScene != null && ((Scene)SelectedScene).IsValid()) if (SelectedScene != null && ((Scene)SelectedScene).IsValid())

View File

@ -1,5 +1,4 @@
#if MONO #if MONO
using System;
using UnityEngine; using UnityEngine;
namespace UnityExplorer.Runtime namespace UnityExplorer.Runtime

View File

@ -0,0 +1,38 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityExplorer.CacheObject;
namespace UnityExplorer.Runtime
{
internal static class UnityCrashPrevention
{
internal static void Init()
{
try
{
ExplorerCore.Harmony.PatchAll(typeof(UnityCrashPrevention));
ExplorerCore.Log("Initialized UnityCrashPrevention.");
}
catch //(Exception ex)
{
//ExplorerCore.Log($"Exception setting up Canvas crash prevention patch: {ex}");
}
}
// In Unity 2020 they introduced "Canvas.renderingDisplaySize".
// If you try to get the value on a Canvas which has a renderMode value of WorldSpace and no worldCamera set,
// the game will Crash (I think from Unity trying to read from null ptr).
[HarmonyPatch(typeof(Canvas), "renderingDisplaySize", MethodType.Getter)]
[HarmonyPrefix]
internal static void Prefix_Canvas_renderingDisplaySize(Canvas __instance)
{
if (__instance.renderMode == RenderMode.WorldSpace && !__instance.worldCamera)
throw new InvalidOperationException(
"Canvas is set to RenderMode.WorldSpace but not worldCamera is set, cannot get renderingDisplaySize.");
}
}
}

View File

@ -146,22 +146,22 @@ namespace UnityExplorer.Tests
} }
#if CPP #if CPP
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> IL2CPP_Dict;
public static Il2CppSystem.Collections.Generic.HashSet<string> IL2CPP_HashSet;
public static Il2CppSystem.Collections.Generic.List<string> IL2CPP_ListString; public static Il2CppSystem.Collections.Generic.List<string> IL2CPP_ListString;
public static Il2CppSystem.Collections.Hashtable IL2CPP_HashTable;
public static List<Il2CppSystem.Object> IL2CPP_listOfBoxedObjects; public static List<Il2CppSystem.Object> IL2CPP_listOfBoxedObjects;
public static Il2CppStructArray<int> IL2CPP_structArray; public static Il2CppStructArray<int> IL2CPP_structArray;
public static Il2CppReferenceArray<Il2CppSystem.Object> IL2CPP_ReferenceArray; public static Il2CppReferenceArray<Il2CppSystem.Object> IL2CPP_ReferenceArray;
public static Il2CppSystem.Collections.IDictionary IL2CPP_IDict; public static Il2CppSystem.Collections.IDictionary IL2CPP_IDict;
public static Il2CppSystem.Collections.IList IL2CPP_IList; public static Il2CppSystem.Collections.IList IL2CPP_IList;
public static Dictionary<Il2CppSystem.String, Il2CppSystem.Object> CppBoxedDict; public static Dictionary<Il2CppSystem.Object, Il2CppSystem.Object> IL2CPP_BoxedDict;
public static Il2CppSystem.Collections.Generic.HashSet<string> IL2CPP_HashSet; public static Il2CppSystem.Object IL2CPP_BoxedInt;
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> IL2CPP_Dict; public static Il2CppSystem.Int32 IL2CPP_Int;
public static Il2CppSystem.Collections.Hashtable IL2CPP_HashTable; public static Il2CppSystem.Decimal IL2CPP_Decimal;
public static Il2CppSystem.Object cppBoxedInt; public static Il2CppSystem.Object IL2CPP_DecimalBoxed;
public static Il2CppSystem.Int32 cppInt; public static Il2CppSystem.Object IL2CPP_Vector3Boxed;
public static Il2CppSystem.Decimal cppDecimal;
public static Il2CppSystem.Object cppDecimalBoxed;
public static Il2CppSystem.Object cppVector3Boxed;
public static string IL2CPP_systemString = "Test"; public static string IL2CPP_systemString = "Test";
public static Il2CppSystem.Object IL2CPP_objectString = "string boxed as cpp object"; public static Il2CppSystem.Object IL2CPP_objectString = "string boxed as cpp object";
public static Il2CppSystem.String IL2CPP_il2cppString = "string boxed as cpp string"; public static Il2CppSystem.String IL2CPP_il2cppString = "string boxed as cpp string";
@ -175,6 +175,11 @@ namespace UnityExplorer.Tests
IL2CPP_Dict.Add("key2", "value2"); IL2CPP_Dict.Add("key2", "value2");
IL2CPP_Dict.Add("key3", "value3"); IL2CPP_Dict.Add("key3", "value3");
ExplorerCore.Log($"IL2CPP 6: Il2Cpp HashSet of strings");
IL2CPP_HashSet = new Il2CppSystem.Collections.Generic.HashSet<string>();
IL2CPP_HashSet.Add("one");
IL2CPP_HashSet.Add("two");
ExplorerCore.Log($"IL2CPP 2: Il2Cpp Hashtable"); ExplorerCore.Log($"IL2CPP 2: Il2Cpp Hashtable");
IL2CPP_HashTable = new Il2CppSystem.Collections.Hashtable(); IL2CPP_HashTable = new Il2CppSystem.Collections.Hashtable();
IL2CPP_HashTable.Add("key1", "value1"); IL2CPP_HashTable.Add("key1", "value1");
@ -197,17 +202,13 @@ namespace UnityExplorer.Tests
IL2CPP_ListString.Add("hello,"); IL2CPP_ListString.Add("hello,");
IL2CPP_ListString.Add("world!"); IL2CPP_ListString.Add("world!");
ExplorerCore.Log($"IL2CPP 6: Il2Cpp HashSet of strings");
IL2CPP_HashSet = new Il2CppSystem.Collections.Generic.HashSet<string>();
IL2CPP_HashSet.Add("one");
IL2CPP_HashSet.Add("two");
ExplorerCore.Log($"IL2CPP 7: Dictionary of Il2Cpp String and Il2Cpp Object"); ExplorerCore.Log($"IL2CPP 7: Dictionary of Il2Cpp String and Il2Cpp Object");
CppBoxedDict = new Dictionary<Il2CppSystem.String, Il2CppSystem.Object>(); IL2CPP_BoxedDict = new();
CppBoxedDict.Add("1", new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject()); IL2CPP_BoxedDict[(Il2CppSystem.String)"one"] = new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject();
CppBoxedDict.Add("2", new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject()); IL2CPP_BoxedDict[(Il2CppSystem.String)"two"] = new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject();
CppBoxedDict.Add("3", new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject()); IL2CPP_BoxedDict[(Il2CppSystem.String)"three"] = new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject();
CppBoxedDict.Add("4", new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject()); IL2CPP_BoxedDict[(Il2CppSystem.String)"four"] = new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject();
ExplorerCore.Log($"IL2CPP 8: List of boxed Il2Cpp Objects"); ExplorerCore.Log($"IL2CPP 8: List of boxed Il2Cpp Objects");
IL2CPP_listOfBoxedObjects = new List<Il2CppSystem.Object>(); IL2CPP_listOfBoxedObjects = new List<Il2CppSystem.Object>();
@ -248,11 +249,11 @@ namespace UnityExplorer.Tests
IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up"; IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up";
ExplorerCore.Log($"IL2CPP 11: Misc il2cpp members"); ExplorerCore.Log($"IL2CPP 11: Misc il2cpp members");
cppBoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject(); IL2CPP_BoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
cppInt = new Il2CppSystem.Int32 { m_value = 420 }; IL2CPP_Int = new Il2CppSystem.Int32 { m_value = 420 };
cppDecimal = new Il2CppSystem.Decimal(1f); IL2CPP_Decimal = new Il2CppSystem.Decimal(1f);
cppDecimalBoxed = new Il2CppSystem.Decimal(1f).BoxIl2CppObject(); IL2CPP_DecimalBoxed = new Il2CppSystem.Decimal(1f).BoxIl2CppObject();
cppVector3Boxed = Vector3.down.BoxIl2CppObject(); IL2CPP_Vector3Boxed = Vector3.down.BoxIl2CppObject();
ExplorerCore.Log($"Finished Init_Il2Cpp"); ExplorerCore.Log($"Finished Init_Il2Cpp");
} }

View File

@ -75,7 +75,7 @@ namespace UnityExplorer.UI.Panels
{ {
// Tools Row // Tools Row
var toolsRow = UIFactory.CreateHorizontalGroup(this.uiRoot, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5), var toolsRow = UIFactory.CreateHorizontalGroup(this.uiContent, "ToggleRow", false, false, true, true, 5, new Vector4(8, 8, 10, 5),
default, TextAnchor.MiddleLeft); default, TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(toolsRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); UIFactory.SetLayoutElement(toolsRow, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
@ -124,7 +124,7 @@ namespace UnityExplorer.UI.Panels
// Console Input // Console Input
var inputArea = UIFactory.CreateUIObject("InputGroup", uiRoot); var inputArea = UIFactory.CreateUIObject("InputGroup", uiContent);
UIFactory.SetLayoutElement(inputArea, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(inputArea, flexibleWidth: 9999, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(inputArea, false, true, true, true); UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(inputArea, false, true, true, true);
inputArea.AddComponent<Image>().color = Color.white; inputArea.AddComponent<Image>().color = Color.white;

View File

@ -89,7 +89,7 @@ namespace UnityExplorer.UI.Panels
// Actual panel content // Actual panel content
var firstRow = UIFactory.CreateHorizontalGroup(UIRoot, "FirstRow", false, false, true, true, 5, new(2,2,2,2), new(1,1,1,0)); var firstRow = UIFactory.CreateHorizontalGroup(uiContent, "FirstRow", false, false, true, true, 5, new(2,2,2,2), new(1,1,1,0));
UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 999); UIFactory.SetLayoutElement(firstRow, minHeight: 25, flexibleWidth: 999);
// Title for "Current Paste:" // Title for "Current Paste:"
@ -102,7 +102,7 @@ namespace UnityExplorer.UI.Panels
clearButton.OnClick += () => Copy(null); clearButton.OnClick += () => Copy(null);
// Current Paste info row // Current Paste info row
var currentPasteHolder = UIFactory.CreateHorizontalGroup(UIRoot, "SecondRow", false, false, true, true, 0, var currentPasteHolder = UIFactory.CreateHorizontalGroup(uiContent, "SecondRow", false, false, true, true, 0,
new(2, 2, 2, 2), childAlignment: TextAnchor.UpperCenter); new(2, 2, 2, 2), childAlignment: TextAnchor.UpperCenter);
// Actual current paste info label // Actual current paste info label

View File

@ -83,7 +83,7 @@ namespace UnityExplorer.UI.Panels
{ {
// ~~~~~~~~~ Active hooks scroll pool // ~~~~~~~~~ Active hooks scroll pool
currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiRoot); currentHooksPanel = UIFactory.CreateUIObject("CurrentHooksPanel", this.uiContent);
UIFactory.SetLayoutElement(currentHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutElement(currentHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(currentHooksPanel, true, true, true, true); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(currentHooksPanel, true, true, true, true);
@ -109,7 +109,7 @@ namespace UnityExplorer.UI.Panels
// ~~~~~~~~~ Add hooks panel // ~~~~~~~~~ Add hooks panel
addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiRoot); addHooksPanel = UIFactory.CreateUIObject("AddHooksPanel", this.uiContent);
UIFactory.SetLayoutElement(addHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutElement(addHooksPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(addHooksPanel, true, true, true, true); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(addHooksPanel, true, true, true, true);
@ -136,7 +136,7 @@ namespace UnityExplorer.UI.Panels
// ~~~~~~~~~ Hook source editor panel // ~~~~~~~~~ Hook source editor panel
editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiRoot); editorPanel = UIFactory.CreateUIObject("HookSourceEditor", this.uiContent);
UIFactory.SetLayoutElement(editorPanel, flexibleHeight: 9999, flexibleWidth: 9999); UIFactory.SetLayoutElement(editorPanel, flexibleHeight: 9999, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(editorPanel, true, true, true, true); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(editorPanel, true, true, true, true);

View File

@ -54,12 +54,12 @@ namespace UnityExplorer.UI.Panels
public override void ConstructPanelContent() public override void ConstructPanelContent()
{ {
var closeHolder = this.titleBar.transform.Find("CloseHolder").gameObject; var closeHolder = this.TitleBar.transform.Find("CloseHolder").gameObject;
// Inspect under mouse dropdown on title bar // Inspect under mouse dropdown on title bar
var mouseDropdown = UIFactory.CreateDropdown(closeHolder, "MouseInspectDropdown", out MouseInspectDropdown, "Mouse Inspect", 14, var mouseDropdown = UIFactory.CreateDropdown(closeHolder, "MouseInspectDropdown", out MouseInspectDropdown, "Mouse Inspect", 14,
InspectUnderMouse.OnDropdownSelect); MouseInspector.OnDropdownSelect);
UIFactory.SetLayoutElement(mouseDropdown, minHeight: 25, minWidth: 140); UIFactory.SetLayoutElement(mouseDropdown, minHeight: 25, minWidth: 140);
MouseInspectDropdown.options.Add(new Dropdown.OptionData("Mouse Inspect")); MouseInspectDropdown.options.Add(new Dropdown.OptionData("Mouse Inspect"));
MouseInspectDropdown.options.Add(new Dropdown.OptionData("World")); MouseInspectDropdown.options.Add(new Dropdown.OptionData("World"));
@ -76,14 +76,14 @@ namespace UnityExplorer.UI.Panels
// this.UIRoot.GetComponent<Mask>().enabled = false; // this.UIRoot.GetComponent<Mask>().enabled = false;
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, true, true, true, true, 4, padLeft: 5, padRight: 5); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, true, true, true, true, 4, padLeft: 5, padRight: 5);
this.NavbarHolder = UIFactory.CreateGridGroup(this.uiRoot, "Navbar", new Vector2(200, 22), new Vector2(4, 4), this.NavbarHolder = UIFactory.CreateGridGroup(this.uiContent, "Navbar", new Vector2(200, 22), new Vector2(4, 4),
new Color(0.05f, 0.05f, 0.05f)); new Color(0.05f, 0.05f, 0.05f));
//UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999); //UIFactory.SetLayoutElement(NavbarHolder, flexibleWidth: 9999, minHeight: 0, preferredHeight: 0, flexibleHeight: 9999);
NavbarHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize; NavbarHolder.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize;
this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiRoot, "ContentHolder", true, true, true, true, 0, default, this.ContentHolder = UIFactory.CreateVerticalGroup(this.uiContent, "ContentHolder", true, true, true, true, 0, default,
new Color(0.1f, 0.1f, 0.1f)); new Color(0.1f, 0.1f, 0.1f));
UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999); UIFactory.SetLayoutElement(ContentHolder, flexibleHeight: 9999);
ContentRect = ContentHolder.GetComponent<RectTransform>(); ContentRect = ContentHolder.GetComponent<RectTransform>();

View File

@ -161,13 +161,13 @@ namespace UnityExplorer.UI.Panels
{ {
// Log scroll pool // Log scroll pool
logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.uiRoot, "Logs", out GameObject scrollObj, logScrollPool = UIFactory.CreateScrollPool<ConsoleLogCell>(this.uiContent, "Logs", out GameObject scrollObj,
out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f)); out GameObject scrollContent, new Color(0.03f, 0.03f, 0.03f));
UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999); UIFactory.SetLayoutElement(scrollObj, flexibleWidth: 9999, flexibleHeight: 9999);
// Buttons and toggles // Buttons and toggles
var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiRoot); var optionsRow = UIFactory.CreateUIObject("OptionsRow", this.uiContent);
UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999); UIFactory.SetLayoutElement(optionsRow, minHeight: 25, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(optionsRow, false, false, true, true, 5, 2, 2, 2, 2); UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(optionsRow, false, false, true, true, 5, 2, 2, 2, 2);

View File

@ -99,17 +99,17 @@ namespace UnityExplorer.UI.Panels
public override void ConstructPanelContent() public override void ConstructPanelContent()
{ {
// Tab bar // Tab bar
var tabGroup = UIFactory.CreateHorizontalGroup(uiRoot, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2)); var tabGroup = UIFactory.CreateHorizontalGroup(uiContent, "TabBar", true, true, true, true, 2, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(tabGroup, minHeight: 25, flexibleHeight: 0); UIFactory.SetLayoutElement(tabGroup, minHeight: 25, flexibleHeight: 0);
// Scene Explorer // Scene Explorer
SceneExplorer = new SceneExplorer(this); SceneExplorer = new SceneExplorer(this);
SceneExplorer.ConstructUI(uiRoot); SceneExplorer.ConstructUI(uiContent);
tabPages.Add(SceneExplorer); tabPages.Add(SceneExplorer);
// Object search // Object search
ObjectSearch = new ObjectSearch(this); ObjectSearch = new ObjectSearch(this);
ObjectSearch.ConstructUI(uiRoot); ObjectSearch.ConstructUI(uiContent);
tabPages.Add(ObjectSearch); tabPages.Add(ObjectSearch);
// set up tabs // set up tabs

View File

@ -71,13 +71,13 @@ namespace UnityExplorer.UI.Panels
{ {
// Save button // Save button
var saveBtn = UIFactory.CreateButton(this.uiRoot, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f)); var saveBtn = UIFactory.CreateButton(this.uiContent, "Save", "Save Options", new Color(0.2f, 0.3f, 0.2f));
UIFactory.SetLayoutElement(saveBtn.Component.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0); UIFactory.SetLayoutElement(saveBtn.Component.gameObject, flexibleWidth: 9999, minHeight: 30, flexibleHeight: 0);
saveBtn.OnClick += ConfigManager.Handler.SaveConfig; saveBtn.OnClick += ConfigManager.Handler.SaveConfig;
// Config entries // Config entries
var scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(this.uiRoot, "ConfigEntries", out GameObject scrollObj, var scrollPool = UIFactory.CreateScrollPool<ConfigEntryCell>(this.uiContent, "ConfigEntries", out GameObject scrollObj,
out GameObject scrollContent); out GameObject scrollContent);
scrollPool.Initialize(this); scrollPool.Initialize(this);

View File

@ -87,13 +87,14 @@ namespace UnityExplorer.UI.Panels
public virtual bool CanDragAndResize => true; public virtual bool CanDragAndResize => true;
public virtual bool NavButtonWanted => true; public virtual bool NavButtonWanted => true;
public ButtonRef NavButton; public ButtonRef NavButton { get; internal set; }
public PanelDragger Dragger; public PanelDragger Dragger { get; internal set; }
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
protected GameObject uiRoot; protected GameObject uiRoot;
public RectTransform Rect; protected GameObject uiContent;
public GameObject titleBar; public RectTransform Rect { get; private set; }
public GameObject TitleBar { get; private set; }
public virtual void OnFinishResize(RectTransform panel) public virtual void OnFinishResize(RectTransform panel)
{ {
@ -247,29 +248,28 @@ namespace UnityExplorer.UI.Panels
} }
// create core canvas // create core canvas
uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder); uiRoot = UIFactory.CreatePanel(Name, UIManager.PanelHolder, out uiContent);
Rect = this.uiRoot.GetComponent<RectTransform>(); Rect = this.uiRoot.GetComponent<RectTransform>();
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft); //UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiRoot, false, false, true, true, 0, 2, 2, 2, 2, TextAnchor.UpperLeft);
int id = this.uiRoot.transform.GetInstanceID(); int id = this.uiRoot.transform.GetInstanceID();
transformToPanelDict.Add(id, this); transformToPanelDict.Add(id, this);
//content = panelContent; UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.uiContent, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
//UIFactory.SetLayoutGroup<VerticalLayoutGroup>(this.content, false, false, true, true, 2, 2, 2, 2, 2, TextAnchor.UpperLeft);
// Title bar // Title bar
titleBar = UIFactory.CreateHorizontalGroup(uiRoot, "TitleBar", false, true, true, true, 2, TitleBar = UIFactory.CreateHorizontalGroup(uiContent, "TitleBar", false, true, true, true, 2,
new Vector4(2, 2, 2, 2), new Color(0.06f, 0.06f, 0.06f)); new Vector4(2, 2, 2, 2), new Color(0.06f, 0.06f, 0.06f));
UIFactory.SetLayoutElement(titleBar, minHeight: 25, flexibleHeight: 0); UIFactory.SetLayoutElement(TitleBar, minHeight: 25, flexibleHeight: 0);
// Title text // Title text
var titleTxt = UIFactory.CreateLabel(titleBar, "TitleBar", Name, TextAnchor.MiddleLeft); var titleTxt = UIFactory.CreateLabel(TitleBar, "TitleBar", Name, TextAnchor.MiddleLeft);
UIFactory.SetLayoutElement(titleTxt.gameObject, minWidth: 250, minHeight: 25, flexibleHeight: 0); UIFactory.SetLayoutElement(titleTxt.gameObject, minWidth: 250, minHeight: 25, flexibleHeight: 0);
// close button // close button
var closeHolder = UIFactory.CreateUIObject("CloseHolder", titleBar); var closeHolder = UIFactory.CreateUIObject("CloseHolder", TitleBar);
UIFactory.SetLayoutElement(closeHolder, minHeight: 25, flexibleHeight: 0, minWidth: 30, flexibleWidth: 9999); UIFactory.SetLayoutElement(closeHolder, minHeight: 25, flexibleHeight: 0, minWidth: 30, flexibleWidth: 9999);
UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(closeHolder, false, false, true, true, 3, childAlignment: TextAnchor.MiddleRight); UIFactory.SetLayoutGroup<HorizontalLayoutGroup>(closeHolder, false, false, true, true, 3, childAlignment: TextAnchor.MiddleRight);
var closeBtn = UIFactory.CreateButton(closeHolder, "CloseButton", "—"); var closeBtn = UIFactory.CreateButton(closeHolder, "CloseButton", "—");
@ -283,11 +283,11 @@ namespace UnityExplorer.UI.Panels
}; };
if (!CanDragAndResize) if (!CanDragAndResize)
titleBar.SetActive(false); TitleBar.SetActive(false);
// Panel dragger // Panel dragger
Dragger = new PanelDragger(titleBar.GetComponent<RectTransform>(), Rect, this); Dragger = new PanelDragger(TitleBar.GetComponent<RectTransform>(), Rect, this);
Dragger.OnFinishResize += OnFinishResize; Dragger.OnFinishResize += OnFinishResize;
Dragger.OnFinishDrag += OnFinishDrag; Dragger.OnFinishDrag += OnFinishDrag;

View File

@ -61,7 +61,7 @@ namespace UnityExplorer.UI.Panels
{ {
dataHandler = new ButtonListHandler<GameObject, ButtonCell>(buttonScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked); dataHandler = new ButtonListHandler<GameObject, ButtonCell>(buttonScrollPool, GetEntries, SetCell, ShouldDisplayCell, OnCellClicked);
buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiRoot, "ResultsList", out GameObject scrollObj, buttonScrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "ResultsList", out GameObject scrollObj,
out GameObject scrollContent); out GameObject scrollContent);
buttonScrollPool.Initialize(dataHandler); buttonScrollPool.Initialize(dataHandler);

View File

@ -73,7 +73,7 @@ namespace UnityExplorer.UI
return; return;
UniversalUI.SetUIActive(ExplorerCore.GUID, value); UniversalUI.SetUIActive(ExplorerCore.GUID, value);
UniversalUI.SetUIActive(InspectUnderMouse.UIBaseGUID, value); UniversalUI.SetUIActive(MouseInspector.UIBaseGUID, value);
} }
} }
@ -106,7 +106,7 @@ namespace UnityExplorer.UI
UIPanels.Add(Panels.ConsoleLog, new LogPanel()); UIPanels.Add(Panels.ConsoleLog, new LogPanel());
UIPanels.Add(Panels.Options, new OptionsPanel()); UIPanels.Add(Panels.Options, new OptionsPanel());
UIPanels.Add(Panels.UIInspectorResults, new UiInspectorResultsPanel()); UIPanels.Add(Panels.UIInspectorResults, new UiInspectorResultsPanel());
UIPanels.Add(Panels.MouseInspector, new InspectUnderMouse()); UIPanels.Add(Panels.MouseInspector, new MouseInspector());
foreach (var panel in UIPanels.Values) foreach (var panel in UIPanels.Values)
panel.ConstructUI(); panel.ConstructUI();
@ -135,12 +135,9 @@ namespace UnityExplorer.UI
if (!UIRoot) if (!UIRoot)
return; return;
// if doing Mouse Inspect, update that and return. // If we are doing a Mouse Inspect, we don't need to update anything else.
if (InspectUnderMouse.Inspecting) if (MouseInspector.Instance.TryUpdate())
{
InspectUnderMouse.Instance.UpdateInspect();
return; return;
}
// Update Notification modal // Update Notification modal
Notification.Update(); Notification.Update();

View File

@ -305,13 +305,13 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
{ {
dataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked); dataHandler = new ButtonListHandler<Suggestion, ButtonCell>(scrollPool, GetEntries, SetCell, ShouldDisplay, OnCellClicked);
scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiRoot, "AutoCompleter", out GameObject scrollObj, scrollPool = UIFactory.CreateScrollPool<ButtonCell>(this.uiContent, "AutoCompleter", out GameObject scrollObj,
out GameObject scrollContent); out GameObject scrollContent);
scrollPool.Initialize(dataHandler); scrollPool.Initialize(dataHandler);
UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999); UIFactory.SetLayoutElement(scrollObj, flexibleHeight: 9999);
UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false); UIFactory.SetLayoutGroup<VerticalLayoutGroup>(scrollContent, true, false, true, false);
navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiRoot, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2)); navigationTipRow = UIFactory.CreateHorizontalGroup(this.uiContent, "BottomRow", true, true, true, true, 0, new Vector4(2, 2, 2, 2));
UIFactory.SetLayoutElement(navigationTipRow, minHeight: 20, flexibleWidth: 9999); UIFactory.SetLayoutElement(navigationTipRow, minHeight: 20, flexibleWidth: 9999);
UIFactory.CreateLabel(navigationTipRow, "HelpText", "Up/Down to select, Enter to use, Esc to close", UIFactory.CreateLabel(navigationTipRow, "HelpText", "Up/Down to select, Enter to use, Esc to close",
TextAnchor.MiddleLeft, Color.grey, false, 13); TextAnchor.MiddleLeft, Color.grey, false, 13);

View File

@ -1,4 +1,5 @@
using System; using HarmonyLib;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using UniverseLib; using UniverseLib;
using UniverseLib.UI; using UniverseLib.UI;
@ -25,6 +26,8 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public Type BaseType { get; set; } public Type BaseType { get; set; }
public Type[] GenericConstraints { get; set; } public Type[] GenericConstraints { get; set; }
public bool AllTypes { get; set; }
private readonly bool allowAbstract; private readonly bool allowAbstract;
private readonly bool allowEnum; private readonly bool allowEnum;
@ -58,7 +61,14 @@ namespace UnityExplorer.UI.Widgets.AutoComplete
public void CacheTypes() public void CacheTypes()
{ {
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowEnum, false); if (!AllTypes)
allowedTypes = ReflectionUtility.GetImplementationsOf(BaseType, allowAbstract, allowEnum, false);
else
{
allowedTypes = new();
foreach (var entry in ReflectionUtility.AllTypes)
allowedTypes.Add(entry.Value);
}
} }
public void OnSuggestionClicked(Suggestion suggestion) public void OnSuggestionClicked(Suggestion suggestion)

View File

@ -175,13 +175,13 @@
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UniverseLib.Mono"> <Reference Include="UniverseLib.Mono">
<HintPath>packages\UniverseLib.1.2.2\lib\net35\UniverseLib.Mono.dll</HintPath> <HintPath>packages\UniverseLib.1.2.11\lib\net35\UniverseLib.Mono.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<!-- Il2Cpp refs --> <!-- Il2Cpp refs -->
<ItemGroup Condition="'$(IsCpp)'=='true'"> <ItemGroup Condition="'$(IsCpp)'=='true'">
<Reference Include="UniverseLib.IL2CPP"> <Reference Include="UniverseLib.IL2CPP">
<HintPath>packages\UniverseLib.1.2.2\lib\net472\UniverseLib.IL2CPP.dll</HintPath> <HintPath>packages\UniverseLib.1.2.11\lib\net472\UniverseLib.IL2CPP.dll</HintPath>
</Reference> </Reference>
<Reference Include="UnhollowerBaseLib, Version=0.4.22.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="UnhollowerBaseLib, Version=0.4.22.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\Il2CppAssemblyUnhollower.BaseLib.0.4.22\lib\net472\UnhollowerBaseLib.dll</HintPath> <HintPath>packages\Il2CppAssemblyUnhollower.BaseLib.0.4.22\lib\net472\UnhollowerBaseLib.dll</HintPath>
@ -246,7 +246,7 @@
<Compile Include="Inspectors\GameObjectWidgets\ComponentCell.cs" /> <Compile Include="Inspectors\GameObjectWidgets\ComponentCell.cs" />
<Compile Include="Inspectors\GameObjectWidgets\ComponentList.cs" /> <Compile Include="Inspectors\GameObjectWidgets\ComponentList.cs" />
<Compile Include="Inspectors\GameObjectWidgets\GameObjectControls.cs" /> <Compile Include="Inspectors\GameObjectWidgets\GameObjectControls.cs" />
<Compile Include="Inspectors\InspectUnderMouse.cs" /> <Compile Include="Inspectors\MouseInspector.cs" />
<Compile Include="CSConsole\ConsoleController.cs" /> <Compile Include="CSConsole\ConsoleController.cs" />
<Compile Include="CacheObject\CacheField.cs" /> <Compile Include="CacheObject\CacheField.cs" />
<Compile Include="CacheObject\CacheKeyValuePair.cs" /> <Compile Include="CacheObject\CacheKeyValuePair.cs" />
@ -259,6 +259,7 @@
<Compile Include="CacheObject\Views\CacheListEntryCell.cs" /> <Compile Include="CacheObject\Views\CacheListEntryCell.cs" />
<Compile Include="CacheObject\Views\CacheMemberCell.cs" /> <Compile Include="CacheObject\Views\CacheMemberCell.cs" />
<Compile Include="CacheObject\Views\CacheObjectCell.cs" /> <Compile Include="CacheObject\Views\CacheObjectCell.cs" />
<Compile Include="Runtime\UnityCrashPrevention.cs" />
<Compile Include="UI\DisplayManager.cs" /> <Compile Include="UI\DisplayManager.cs" />
<Compile Include="UI\Notification.cs" /> <Compile Include="UI\Notification.cs" />
<Compile Include="UI\Panels\ClipboardPanel.cs" /> <Compile Include="UI\Panels\ClipboardPanel.cs" />
@ -324,6 +325,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ILRepack.targets" /> <None Include="ILRepack.targets" />
<None Include="nuget.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

19
src/nuget.config Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="dependencyVersion" value="Lowest" />
</config>
<packageRestore>
<!-- Allow NuGet to download missing packages -->
<add key="enabled" value="True" />
<!-- Automatically check for missing packages during build in Visual Studio -->
<add key="automatic" value="True" />
</packageRestore>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="BepInEx" value="https://nuget.bepinex.dev/v3/index.json" />
</packageSources>
</configuration>

View File

@ -6,6 +6,6 @@
<package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" /> <package id="ILRepack.Lib.MSBuild.Task" version="2.0.18.2" targetFramework="net35" />
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" /> <package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
<package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" /> <package id="Samboy063.Tomlet" version="3.1.3" targetFramework="net472" />
<package id="UniverseLib" version="1.2.2" targetFramework="net35" /> <package id="UniverseLib" version="1.2.11" targetFramework="net35" />
<package id="UniverseLib.Analyzers" version="1.0.3" targetFramework="net35" developmentDependency="true" /> <package id="UniverseLib.Analyzers" version="1.0.3" targetFramework="net35" developmentDependency="true" />
</packages> </packages>