diff --git a/src/Console/Lexer/KeywordMatch.cs b/src/Console/Lexer/KeywordMatch.cs index abf247f..b944526 100644 --- a/src/Console/Lexer/KeywordMatch.cs +++ b/src/Console/Lexer/KeywordMatch.cs @@ -17,8 +17,8 @@ namespace UnityExplorer.Console.Lexer public override bool IsImplicitMatch(CSharpLexer lexer) { - if (!char.IsWhiteSpace(lexer.Previous) || - lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End)) + if (!char.IsWhiteSpace(lexer.Previous) && + !lexer.IsSpecialSymbol(lexer.Previous, DelimiterType.End)) { return false; } diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index 241f56b..b28b4df 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -23,10 +23,10 @@ namespace UnityExplorer public static bool ShowMenu { - get => m_showMenu; + get => s_showMenu; set => SetShowMenu(value); } - public static bool m_showMenu; + public static bool s_showMenu; private static bool s_doneUIInit; private static float s_timeSinceStartup; @@ -100,13 +100,13 @@ namespace UnityExplorer #if CPP try { - Application.add_logMessageReceived(new Action(LogCallback)); + Application.add_logMessageReceived(new Action(OnUnityLog)); SceneManager.add_sceneLoaded(new Action((Scene a, LoadSceneMode b) => { OnSceneLoaded(); })); SceneManager.add_activeSceneChanged(new Action((Scene a, Scene b) => { OnSceneLoaded(); })); } catch { } #else - Application.logMessageReceived += LogCallback; + Application.logMessageReceived += OnUnityLog; SceneManager.sceneLoaded += (Scene a, LoadSceneMode b) => { OnSceneLoaded(); }; SceneManager.activeSceneChanged += (Scene a, Scene b) => { OnSceneLoaded(); }; #endif @@ -119,7 +119,7 @@ namespace UnityExplorer private static void SetShowMenu(bool show) { - m_showMenu = show; + s_showMenu = show; if (UIManager.CanvasRoot) { @@ -134,7 +134,7 @@ namespace UnityExplorer ForceUnlockCursor.UpdateCursorControl(); } - private void LogCallback(string message, string stackTrace, LogType type) + private void OnUnityLog(string message, string stackTrace, LogType type) { if (!DebugConsole.LogUnity) return; diff --git a/src/ExplorerMelonMod.cs b/src/ExplorerMelonMod.cs index 5cb48ad..9525009 100644 --- a/src/ExplorerMelonMod.cs +++ b/src/ExplorerMelonMod.cs @@ -1,6 +1,6 @@ #if ML +using System; using MelonLoader; -using UnityExplorer.UI.Modules; namespace UnityExplorer { diff --git a/src/Helpers/ReflectionHelpers.cs b/src/Helpers/ReflectionHelpers.cs index bf38c66..104b4ac 100644 --- a/src/Helpers/ReflectionHelpers.cs +++ b/src/Helpers/ReflectionHelpers.cs @@ -83,7 +83,14 @@ namespace UnityExplorer.Helpers if (type.Namespace.StartsWith("System.") || type.Namespace.StartsWith("Il2CppSystem.")) return ilObject.GetType(); - var getType = Type.GetType(ilObject.GetIl2CppType().AssemblyQualifiedName); + var il2cppType = ilObject.GetIl2CppType(); + + // check if type is injected + IntPtr classPtr = il2cpp_object_get_class(ilObject.Pointer); + if (RuntimeSpecificsStore.IsInjected(classPtr)) + return GetTypeByName(il2cppType.FullName); + + var getType = Type.GetType(il2cppType.AssemblyQualifiedName); if (getType != null) return getType; diff --git a/src/Inspectors/InspectorBase.cs b/src/Inspectors/InspectorBase.cs index 27f1340..7f35ffb 100644 --- a/src/Inspectors/InspectorBase.cs +++ b/src/Inspectors/InspectorBase.cs @@ -123,6 +123,7 @@ namespace UnityExplorer.Inspectors tabGroupObj.AddComponent(); var targetButtonObj = UIFactory.CreateButton(tabGroupObj); + targetButtonObj.AddComponent(); var targetButtonLayout = targetButtonObj.AddComponent(); targetButtonLayout.minWidth = 165; targetButtonLayout.flexibleWidth = 0; diff --git a/src/Inspectors/InspectorManager.cs b/src/Inspectors/InspectorManager.cs index 2b86ce2..6c680a4 100644 --- a/src/Inspectors/InspectorManager.cs +++ b/src/Inspectors/InspectorManager.cs @@ -105,14 +105,14 @@ namespace UnityExplorer.Inspectors public void SetInspectorTab(InspectorBase inspector) { + MainMenu.Instance.SetPage(HomePage.Instance); + if (m_activeInspector == inspector) return; UnsetInspectorTab(); - MainMenu.Instance.SetPage(HomePage.Instance); m_activeInspector = inspector; - inspector.SetActive(); Color activeColor = new Color(0, 0.25f, 0, 1); diff --git a/src/Inspectors/Reflection/CacheObject/CacheMember.cs b/src/Inspectors/Reflection/CacheObject/CacheMember.cs index fbb9543..512320d 100644 --- a/src/Inspectors/Reflection/CacheObject/CacheMember.cs +++ b/src/Inspectors/Reflection/CacheObject/CacheMember.cs @@ -31,6 +31,9 @@ namespace UnityExplorer.Inspectors.Reflection public string RichTextName => m_richTextName ?? GetRichTextName(); private string m_richTextName; + public string NameForFiltering => m_nameForFilter ?? (m_nameForFilter = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}".ToLower()); + private string m_nameForFilter; + public override bool CanWrite => m_canWrite ?? GetCanWrite(); private bool? m_canWrite; diff --git a/src/Inspectors/Reflection/ReflectionInspector.cs b/src/Inspectors/Reflection/ReflectionInspector.cs index fc8dbc8..a7da3f0 100644 --- a/src/Inspectors/Reflection/ReflectionInspector.cs +++ b/src/Inspectors/Reflection/ReflectionInspector.cs @@ -83,6 +83,8 @@ namespace UnityExplorer.Inspectors set => m_content = value; } + internal Text m_nameFilterText; + internal PageHandler m_pageHandler; internal SliderScrollbar m_sliderScroller; internal GameObject m_scrollContent; @@ -100,13 +102,13 @@ namespace UnityExplorer.Inspectors else m_targetType = ReflectionHelpers.GetActualType(target); - m_targetTypeShortName = m_targetType.Name; + m_targetTypeShortName = UISyntaxHighlight.ParseFullSyntax(m_targetType, false); ConstructUI(); CacheMembers(m_targetType); - RefreshDisplay(); + FilterMembers(); } // Methods @@ -123,6 +125,19 @@ namespace UnityExplorer.Inspectors ActiveInstance = null; } + public override void Destroy() + { + base.Destroy(); + + if (this.Content) + GameObject.Destroy(this.Content); + } + + private void OnPageTurned() + { + RefreshDisplay(); + } + public override void Update() { base.Update(); @@ -148,24 +163,30 @@ namespace UnityExplorer.Inspectors } } - public override void Destroy() + public void FilterMembers(string nameFilter = null) { - base.Destroy(); + var list = new List(); - if (this.Content) - GameObject.Destroy(this.Content); - } + nameFilter = nameFilter?.ToLower() ?? m_nameFilterText.text.ToLower(); - private void OnPageTurned() - { - RefreshDisplay(); + foreach (var mem in m_allMembers) + { + // name filter + if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter)) + continue; + + list.Add(mem); + } + + if (m_membersFiltered == null || m_membersFiltered.Length != list.Count) + { + m_membersFiltered = list.ToArray(); + RefreshDisplay(); + } } public void RefreshDisplay() { - // temp because not doing filtering yet - m_membersFiltered = m_allMembers; - var members = m_membersFiltered; m_pageHandler.ListCount = members.Length; @@ -360,65 +381,99 @@ namespace UnityExplorer.Inspectors ConstructTopArea(); - ConstructFilterArea(); - ConstructMemberList(); } internal void ConstructTopArea() { - var typeRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0)); - var typeRowGroup = typeRowObj.GetComponent(); - typeRowGroup.childForceExpandWidth = true; - typeRowGroup.childForceExpandHeight = true; - typeRowGroup.childControlHeight = true; - typeRowGroup.childControlWidth = true; - var typeRowLayout = typeRowObj.AddComponent(); - typeRowLayout.minHeight = 25; - typeRowLayout.flexibleHeight = 0; - typeRowLayout.minWidth = 200; - typeRowLayout.flexibleWidth = 5000; + var topGroupObj = UIFactory.CreateVerticalGroup(Content, new Color(0.1f, 0.1f, 0.1f)); + var topGroup = topGroupObj.GetComponent(); + topGroup.childForceExpandWidth = true; + topGroup.childForceExpandHeight = true; + topGroup.childControlWidth = true; + topGroup.childControlHeight = true; + topGroup.spacing = 8; + topGroup.padding.left = 4; + topGroup.padding.right = 4; - var typeLabel = UIFactory.CreateLabel(typeRowObj, TextAnchor.MiddleLeft); + var nameRowObj = UIFactory.CreateHorizontalGroup(topGroupObj, new Color(1, 1, 1, 0)); + var nameRow = nameRowObj.GetComponent(); + nameRow.childForceExpandWidth = true; + nameRow.childForceExpandHeight = true; + nameRow.childControlHeight = true; + nameRow.childControlWidth = true; + nameRow.padding.top = 2; + var nameRowLayout = nameRowObj.AddComponent(); + nameRowLayout.minHeight = 25; + nameRowLayout.flexibleHeight = 0; + nameRowLayout.minWidth = 200; + nameRowLayout.flexibleWidth = 5000; + + var typeLabel = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleLeft); var typeLabelText = typeLabel.GetComponent(); typeLabelText.text = "Type:"; typeLabelText.horizontalOverflow = HorizontalWrapMode.Overflow; var typeLabelTextLayout = typeLabel.AddComponent(); - typeLabelTextLayout.minWidth = 60; + typeLabelTextLayout.minWidth = 40; typeLabelTextLayout.flexibleWidth = 0; typeLabelTextLayout.minHeight = 25; - var typeLabelInputObj = UIFactory.CreateInputField(typeRowObj); - var typeLabelInput = typeLabelInputObj.GetComponent(); - typeLabelInput.readOnly = true; - var typeLabelLayout = typeLabelInputObj.AddComponent(); - typeLabelLayout.minWidth = 150; - typeLabelLayout.flexibleWidth = 5000; - - typeLabelInput.text = UISyntaxHighlight.ParseFullSyntax(m_targetType, true); + var typeDisplayObj = UIFactory.CreateLabel(nameRowObj, TextAnchor.MiddleLeft); + var typeDisplayText = typeDisplayObj.GetComponent(); + typeDisplayText.text = UISyntaxHighlight.ParseFullSyntax(m_targetType, true); + var typeDisplayLayout = typeDisplayObj.AddComponent(); + typeDisplayLayout.minHeight = 25; + typeDisplayLayout.flexibleWidth = 5000; // Helper tools - if (this is InstanceInspector instanceInspector) + if (this is InstanceInspector) { - instanceInspector.ConstructInstanceHelpers(Content); + (this as InstanceInspector).ConstructInstanceHelpers(topGroupObj); } - } - internal void ConstructFilterArea() - { - var filterAreaObj = UIFactory.CreateVerticalGroup(Content, new Color(0.1f, 0.1f, 0.1f)); + // Filters + + var filterAreaObj = UIFactory.CreateVerticalGroup(topGroupObj, new Color(1,1,1,0)); var filterLayout = filterAreaObj.AddComponent(); - filterLayout.minHeight = 25; + filterLayout.minHeight = 60; var filterGroup = filterAreaObj.GetComponent(); filterGroup.childForceExpandWidth = true; filterGroup.childForceExpandHeight = false; filterGroup.childControlWidth = true; filterGroup.childControlHeight = true; + filterGroup.spacing = 4; // name filter + var nameFilterRowObj = UIFactory.CreateHorizontalGroup(filterAreaObj, new Color(1, 1, 1, 0)); + var nameFilterGroup = nameFilterRowObj.GetComponent(); + nameFilterGroup.childForceExpandHeight = false; + nameFilterGroup.childForceExpandWidth = false; + nameFilterGroup.childControlWidth = true; + nameFilterGroup.childControlHeight = true; + nameFilterGroup.spacing = 5; + var nameFilterLayout = nameFilterRowObj.AddComponent(); + nameFilterLayout.minHeight = 25; + nameFilterLayout.flexibleHeight = 0; + nameFilterLayout.flexibleWidth = 5000; + var nameLabelObj = UIFactory.CreateLabel(nameFilterRowObj, TextAnchor.MiddleLeft); + var nameLabelLayout = nameLabelObj.AddComponent(); + nameLabelLayout.minWidth = 130; + nameLabelLayout.minHeight = 25; + nameLabelLayout.flexibleWidth = 0; + var nameLabelText = nameLabelObj.GetComponent(); + nameLabelText.text = "Name contains:"; + + var nameInputObj = UIFactory.CreateInputField(nameFilterRowObj, 14, (int)TextAnchor.MiddleLeft, (int)HorizontalWrapMode.Overflow); + var nameInputLayout = nameInputObj.AddComponent(); + nameInputLayout.flexibleWidth = 5000; + nameInputLayout.minWidth = 100; + nameInputLayout.minHeight = 25; + var nameInput = nameInputObj.GetComponent(); + nameInput.onValueChanged.AddListener(new Action((string val) => { FilterMembers(val); })); + m_nameFilterText = nameInput.textComponent; // membertype filter @@ -426,9 +481,9 @@ namespace UnityExplorer.Inspectors // Instance filters - if (this is InstanceInspector instanceInspector) + if (this is InstanceInspector) { - instanceInspector.ConstructInstanceFilters(filterAreaObj); + (this as InstanceInspector).ConstructInstanceFilters(filterAreaObj); } } diff --git a/src/Inspectors/SceneExplorer.cs b/src/Inspectors/SceneExplorer.cs index 6a8e466..aabd203 100644 --- a/src/Inspectors/SceneExplorer.cs +++ b/src/Inspectors/SceneExplorer.cs @@ -33,6 +33,7 @@ namespace UnityExplorer.Inspectors private int m_lastCount; private Dropdown m_sceneDropdown; + private Text m_sceneDropdownText; private Text m_scenePathText; private GameObject m_mainInspectBtn; private GameObject m_backButtonObj; @@ -135,9 +136,9 @@ namespace UnityExplorer.Inspectors m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene }); } - if (!names.Contains(m_sceneDropdown.itemText.text)) + if (!names.Contains(m_sceneDropdownText.text)) { - m_sceneDropdown.transform.Find("Label").GetComponent().text = names[0]; + m_sceneDropdownText.text = names[0]; SetTargetScene(handles[0]); } } @@ -317,6 +318,8 @@ namespace UnityExplorer.Inspectors dropdownLayout.minWidth = 320; dropdownLayout.flexibleWidth = 2; + m_sceneDropdownText = m_sceneDropdown.transform.Find("Label").GetComponent(); + #if CPP m_sceneDropdown.onValueChanged.AddListener(new Action((int val) => { SetSceneFromDropdown(val); })); #else