diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs index 8bf2a45..19e0003 100644 --- a/src/CppExplorer.cs +++ b/src/CppExplorer.cs @@ -6,6 +6,7 @@ using System.Text; using UnityEngine; using MelonLoader; using UnhollowerBaseLib; +using UnhollowerRuntimeLib; using Harmony; namespace Explorer @@ -16,7 +17,7 @@ namespace Explorer public const string ID = "com.sinai.cppexplorer"; public const string NAME = "IL2CPP Runtime Explorer"; - public const string VERSION = "1.3.1"; + public const string VERSION = "1.3.2"; public const string AUTHOR = "Sinai"; // fields @@ -31,6 +32,13 @@ namespace Explorer public static int ArrayLimit { get; set; } = 20; public bool MouseInspect { get; set; } = false; + // prop helpers + + public static Il2CppSystem.Type GameObjectType => Il2CppType.Of(); + public static Il2CppSystem.Type TransformType => Il2CppType.Of(); + public static Il2CppSystem.Type ObjectType => Il2CppType.Of(); + public static Il2CppSystem.Type ComponentType => Il2CppType.Of(); + public static string ActiveSceneName { get diff --git a/src/MainMenu/Pages/SearchPage.cs b/src/MainMenu/Pages/SearchPage.cs index 6976647..6129bde 100644 --- a/src/MainMenu/Pages/SearchPage.cs +++ b/src/MainMenu/Pages/SearchPage.cs @@ -22,6 +22,8 @@ namespace Explorer private string m_typeInput = ""; private int m_limit = 100; private int m_pageOffset = 0; + private List m_searchResults = new List(); + private Vector2 resultsScroll = Vector2.zero; public SceneFilter SceneMode = SceneFilter.Any; public TypeFilter TypeMode = TypeFilter.Object; @@ -42,9 +44,6 @@ namespace Explorer Custom } - private List m_searchResults = new List(); - private Vector2 resultsScroll = Vector2.zero; - public override void Init() { Instance = this; @@ -114,7 +113,7 @@ namespace Explorer int offset = m_pageOffset * CppExplorer.ArrayLimit; int preiterated = 0; - if (offset >= count) offset = 0; + if (offset >= count) m_pageOffset = 0; for (int i = 0; i < m_searchResults.Count; i++) { @@ -246,7 +245,110 @@ namespace Explorer } - // -------------- ACTUAL METHODS (not Gui draw) ----------------- // + // -------------- ACTUAL METHODS (not Gui draw) ----------------- // + + // ======= search functions ======= + + private void Search() + { + m_pageOffset = 0; + m_searchResults = FindAllObjectsOfType(m_searchInput, m_typeInput); + } + + private List FindAllObjectsOfType(string _search, string _type) + { + Il2CppSystem.Type type = null; + + if (TypeMode == TypeFilter.Custom) + { + try + { + var findType = CppExplorer.GetType(_type); + type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); + } + catch (Exception e) + { + MelonLogger.Log("Exception: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); + } + } + else if (TypeMode == TypeFilter.Object) + { + type = CppExplorer.ObjectType; + } + else if (TypeMode == TypeFilter.GameObject) + { + type = CppExplorer.GameObjectType; + } + else if (TypeMode == TypeFilter.Component) + { + type = CppExplorer.ComponentType; + } + + if (!CppExplorer.ObjectType.IsAssignableFrom(type)) + { + MelonLogger.LogError("Your Class Type must inherit from UnityEngine.Object! Leave blank to default to UnityEngine.Object"); + return new List(); + } + + var matches = new List(); + + var allObjectsOfType = Resources.FindObjectsOfTypeAll(type); + + foreach (var obj in allObjectsOfType) + { + if (_search != "" && !obj.name.ToLower().Contains(_search.ToLower())) + { + continue; + } + + if (SceneMode != SceneFilter.Any && !FilterScene(obj, this.SceneMode)) + { + continue; + } + + if (!matches.Contains(obj)) + { + matches.Add(obj); + } + } + + return matches; + } + + public static bool FilterScene(object obj, SceneFilter filter) + { + GameObject go; + if (obj is Il2CppSystem.Object ilObject) + { + go = ilObject.TryCast() ?? ilObject.TryCast().gameObject; + } + else + { + go = (obj as GameObject) ?? (obj as Component).gameObject; + } + + if (!go) + { + // object is not on a GameObject, cannot perform scene filter operation. + return false; + } + + if (filter == SceneFilter.None) + { + return string.IsNullOrEmpty(go.scene.name); + } + else if (filter == SceneFilter.This) + { + return go.scene.name == CppExplorer.ActiveSceneName; + } + else if (filter == SceneFilter.DontDestroy) + { + return go.scene.name == "DontDestroyOnLoad"; + } + return false; + } + + // ====== other ======== // credit: ManlyMarco (RuntimeUnityEditor) public static IEnumerable GetInstanceClassScanner() @@ -286,172 +388,5 @@ namespace Explorer catch (ReflectionTypeLoadException e) { return e.Types.Where(x => x != null); } catch { return Enumerable.Empty(); } } - - // ======= search functions ======= - - private void Search() - { - m_searchResults = FindAllObjectsOfType(m_searchInput, m_typeInput); - } - - private List FindAllObjectsOfType(string _search, string _type) - { - Il2CppSystem.Type type = null; - - if (TypeMode == TypeFilter.Custom) - { - try - { - var findType = CppExplorer.GetType(_type); - type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); - } - catch (Exception e) - { - MelonLogger.Log("Exception: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); - } - } - else if (TypeMode == TypeFilter.Object) - { - type = Il2CppType.Of(); - } - else if (TypeMode == TypeFilter.GameObject) - { - type = Il2CppType.Of(); - } - else if (TypeMode == TypeFilter.Component) - { - type = Il2CppType.Of(); - } - - if (!Il2CppType.Of().IsAssignableFrom(type)) - { - MelonLogger.LogError("Your Class Type must inherit from UnityEngine.Object! Leave blank to default to UnityEngine.Object"); - return new List(); - } - - var matches = new List(); - - foreach (var obj in Resources.FindObjectsOfTypeAll(type)) - { - if (_search != "" && !obj.name.ToLower().Contains(_search.ToLower())) - { - continue; - } - - if (SceneMode != SceneFilter.Any) - { - if (SceneMode == SceneFilter.None) - { - if (!NoSceneFilter(obj, obj.GetType())) - { - continue; - } - } - else - { - GameObject go; - - var objtype = obj.GetType(); - if (objtype == typeof(GameObject)) - { - go = obj as GameObject; - } - else if (typeof(Component).IsAssignableFrom(objtype)) - { - go = (obj as Component).gameObject; - } - else { continue; } - - if (!go) { continue; } - - if (SceneMode == SceneFilter.This) - { - if (go.scene.name != CppExplorer.ActiveSceneName || go.scene.name == "DontDestroyOnLoad") - { - continue; - } - } - else if (SceneMode == SceneFilter.DontDestroy) - { - if (go.scene.name != "DontDestroyOnLoad") - { - continue; - } - } - } - } - - if (!matches.Contains(obj)) - { - matches.Add(obj); - } - } - - return matches; - } - - public static bool ThisSceneFilter(object obj, Type type) - { - if (type == typeof(GameObject) || typeof(Component).IsAssignableFrom(type)) - { - var go = obj as GameObject ?? (obj as Component).gameObject; - - if (go != null && go.scene.name == CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad") - { - return true; - } - } - - return false; - } - - public static bool DontDestroyFilter(object obj, Type type) - { - if (type == typeof(GameObject) || typeof(Component).IsAssignableFrom(type)) - { - var go = obj as GameObject ?? (obj as Component).gameObject; - - if (go != null && go.scene.name == "DontDestroyOnLoad") - { - return true; - } - } - - return false; - } - - public static bool NoSceneFilter(object obj, Type type) - { - if (type == typeof(GameObject)) - { - var go = obj as GameObject; - - if (go.scene.name != CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad") - { - return true; - } - else - { - return false; - } - } - else if (typeof(Component).IsAssignableFrom(type)) - { - var go = (obj as Component).gameObject; - - if (go == null || (go.scene.name != CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad")) - { - return true; - } - else - { - return false; - } - } - else - { - return true; - } - } } } diff --git a/src/UIStyles.cs b/src/UIStyles.cs index 9f1795f..4e97484 100644 --- a/src/UIStyles.cs +++ b/src/UIStyles.cs @@ -225,20 +225,41 @@ namespace Explorer } var valueType = value.GetType(); + + Il2CppSystem.Type ilType = null; + if (value is Il2CppSystem.Object ilObject) + { + ilType = ilObject.GetIl2CppType(); + } + if (valueType.IsPrimitive || value.GetType() == typeof(string)) { DrawPrimitive(ref value, rect, setTarget, setAction); } - else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + //else if (valueType == typeof(GameObject) || typeof(Component).IsAssignableFrom(valueType)) + else if (ilType != null && ilType == CppExplorer.GameObjectType || CppExplorer.ComponentType.IsAssignableFrom(ilType)) { + //GameObject go; + //if (value.GetType() == typeof(Transform)) + //{ + // go = (value as Transform).gameObject; + //} + //else + //{ + // go = (value as GameObject); + //} + + //var go = (value as GameObject) ?? (value as Component).gameObject; + GameObject go; - if (value.GetType() == typeof(Transform)) + var ilObj = value as Il2CppSystem.Object; + if (ilType == CppExplorer.GameObjectType) { - go = (value as Transform).gameObject; + go = ilObj.TryCast(); } else { - go = (value as GameObject); + go = ilObj.TryCast().gameObject; } GameobjButton(go, null, false, rect.width - 250); diff --git a/src_2018/CppExplorer.cs b/src_2018/CppExplorer.cs index 4ca579c..d98b7b8 100644 --- a/src_2018/CppExplorer.cs +++ b/src_2018/CppExplorer.cs @@ -6,6 +6,7 @@ using System.Text; using UnityEngine; using MelonLoader; using UnhollowerBaseLib; +using UnhollowerRuntimeLib; using Harmony; namespace Explorer @@ -16,7 +17,7 @@ namespace Explorer public const string ID = "com.sinai.cppexplorer"; public const string NAME = "IL2CPP Runtime Explorer (Unity 2018)"; - public const string VERSION = "1.3.1"; + public const string VERSION = "1.3.2"; public const string AUTHOR = "Sinai"; // fields @@ -31,6 +32,13 @@ namespace Explorer public static int ArrayLimit { get; set; } = 20; public bool MouseInspect { get; set; } = false; + // prop helpers + + public static Il2CppSystem.Type GameObjectType => Il2CppType.Of(); + public static Il2CppSystem.Type TransformType => Il2CppType.Of(); + public static Il2CppSystem.Type ObjectType => Il2CppType.Of(); + public static Il2CppSystem.Type ComponentType => Il2CppType.Of(); + public static string ActiveSceneName { get diff --git a/src_2018/MainMenu/Pages/SearchPage.cs b/src_2018/MainMenu/Pages/SearchPage.cs index 9a632ca..3259bc6 100644 --- a/src_2018/MainMenu/Pages/SearchPage.cs +++ b/src_2018/MainMenu/Pages/SearchPage.cs @@ -22,6 +22,8 @@ namespace Explorer private string m_typeInput = ""; private int m_limit = 100; private int m_pageOffset = 0; + private List m_searchResults = new List(); + private Vector2 resultsScroll = Vector2.zero; public SceneFilter SceneMode = SceneFilter.Any; public TypeFilter TypeMode = TypeFilter.Object; @@ -42,9 +44,6 @@ namespace Explorer Custom } - private List m_searchResults = new List(); - private Vector2 resultsScroll = Vector2.zero; - public override void Init() { Instance = this; @@ -114,7 +113,7 @@ namespace Explorer int offset = m_pageOffset * CppExplorer.ArrayLimit; int preiterated = 0; - if (offset >= count) offset = 0; + if (offset >= count) m_pageOffset = 0; for (int i = 0; i < m_searchResults.Count; i++) { @@ -246,7 +245,110 @@ namespace Explorer } - // -------------- ACTUAL METHODS (not Gui draw) ----------------- // + // -------------- ACTUAL METHODS (not Gui draw) ----------------- // + + // ======= search functions ======= + + private void Search() + { + m_pageOffset = 0; + m_searchResults = FindAllObjectsOfType(m_searchInput, m_typeInput); + } + + private List FindAllObjectsOfType(string _search, string _type) + { + Il2CppSystem.Type type = null; + + if (TypeMode == TypeFilter.Custom) + { + try + { + var findType = CppExplorer.GetType(_type); + type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); + } + catch (Exception e) + { + MelonLogger.Log("Exception: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); + } + } + else if (TypeMode == TypeFilter.Object) + { + type = CppExplorer.ObjectType; + } + else if (TypeMode == TypeFilter.GameObject) + { + type = CppExplorer.GameObjectType; + } + else if (TypeMode == TypeFilter.Component) + { + type = CppExplorer.ComponentType; + } + + if (!CppExplorer.ObjectType.IsAssignableFrom(type)) + { + MelonLogger.LogError("Your Class Type must inherit from UnityEngine.Object! Leave blank to default to UnityEngine.Object"); + return new List(); + } + + var matches = new List(); + + var allObjectsOfType = Resources.FindObjectsOfTypeAll(type); + + foreach (var obj in allObjectsOfType) + { + if (_search != "" && !obj.name.ToLower().Contains(_search.ToLower())) + { + continue; + } + + if (SceneMode != SceneFilter.Any && !FilterScene(obj, this.SceneMode)) + { + continue; + } + + if (!matches.Contains(obj)) + { + matches.Add(obj); + } + } + + return matches; + } + + public static bool FilterScene(object obj, SceneFilter filter) + { + GameObject go; + if (obj is Il2CppSystem.Object ilObject) + { + go = ilObject.TryCast() ?? ilObject.TryCast().gameObject; + } + else + { + go = (obj as GameObject) ?? (obj as Component).gameObject; + } + + if (!go) + { + // object is not on a GameObject, cannot perform scene filter operation. + return false; + } + + if (filter == SceneFilter.None) + { + return string.IsNullOrEmpty(go.scene.name); + } + else if (filter == SceneFilter.This) + { + return go.scene.name == CppExplorer.ActiveSceneName; + } + else if (filter == SceneFilter.DontDestroy) + { + return go.scene.name == "DontDestroyOnLoad"; + } + return false; + } + + // ====== other ======== // credit: ManlyMarco (RuntimeUnityEditor) public static IEnumerable GetInstanceClassScanner() @@ -286,172 +388,5 @@ namespace Explorer catch (ReflectionTypeLoadException e) { return e.Types.Where(x => x != null); } catch { return Enumerable.Empty(); } } - - // ======= search functions ======= - - private void Search() - { - m_searchResults = FindAllObjectsOfType(m_searchInput, m_typeInput); - } - - private List FindAllObjectsOfType(string _search, string _type) - { - Il2CppSystem.Type type = null; - - if (TypeMode == TypeFilter.Custom) - { - try - { - var findType = CppExplorer.GetType(_type); - type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName); - } - catch (Exception e) - { - MelonLogger.Log("Exception: " + e.GetType() + ", " + e.Message + "\r\n" + e.StackTrace); - } - } - else if (TypeMode == TypeFilter.Object) - { - type = Il2CppType.Of(); - } - else if (TypeMode == TypeFilter.GameObject) - { - type = Il2CppType.Of(); - } - else if (TypeMode == TypeFilter.Component) - { - type = Il2CppType.Of(); - } - - if (!Il2CppType.Of().IsAssignableFrom(type)) - { - MelonLogger.LogError("Your Class Type must inherit from UnityEngine.Object! Leave blank to default to UnityEngine.Object"); - return new List(); - } - - var matches = new List(); - - foreach (var obj in Resources.FindObjectsOfTypeAll(type)) - { - if (_search != "" && !obj.name.ToLower().Contains(_search.ToLower())) - { - continue; - } - - if (SceneMode != SceneFilter.Any) - { - if (SceneMode == SceneFilter.None) - { - if (!NoSceneFilter(obj, obj.GetType())) - { - continue; - } - } - else - { - GameObject go; - - var objtype = obj.GetType(); - if (objtype == typeof(GameObject)) - { - go = obj as GameObject; - } - else if (typeof(Component).IsAssignableFrom(objtype)) - { - go = (obj as Component).gameObject; - } - else { continue; } - - if (!go) { continue; } - - if (SceneMode == SceneFilter.This) - { - if (go.scene.name != CppExplorer.ActiveSceneName || go.scene.name == "DontDestroyOnLoad") - { - continue; - } - } - else if (SceneMode == SceneFilter.DontDestroy) - { - if (go.scene.name != "DontDestroyOnLoad") - { - continue; - } - } - } - } - - if (!matches.Contains(obj)) - { - matches.Add(obj); - } - } - - return matches; - } - - public static bool ThisSceneFilter(object obj, Type type) - { - if (type == typeof(GameObject) || typeof(Component).IsAssignableFrom(type)) - { - var go = obj as GameObject ?? (obj as Component).gameObject; - - if (go != null && go.scene.name == CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad") - { - return true; - } - } - - return false; - } - - public static bool DontDestroyFilter(object obj, Type type) - { - if (type == typeof(GameObject) || typeof(Component).IsAssignableFrom(type)) - { - var go = obj as GameObject ?? (obj as Component).gameObject; - - if (go != null && go.scene.name == "DontDestroyOnLoad") - { - return true; - } - } - - return false; - } - - public static bool NoSceneFilter(object obj, Type type) - { - if (type == typeof(GameObject)) - { - var go = obj as GameObject; - - if (go.scene.name != CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad") - { - return true; - } - else - { - return false; - } - } - else if (typeof(Component).IsAssignableFrom(type)) - { - var go = (obj as Component).gameObject; - - if (go == null || (go.scene.name != CppExplorer.ActiveSceneName && go.scene.name != "DontDestroyOnLoad")) - { - return true; - } - else - { - return false; - } - } - else - { - return true; - } - } } } diff --git a/src_2018/UIStyles.cs b/src_2018/UIStyles.cs index 8c2ebef..568625f 100644 --- a/src_2018/UIStyles.cs +++ b/src_2018/UIStyles.cs @@ -225,20 +225,29 @@ namespace Explorer } var valueType = value.GetType(); + + Il2CppSystem.Type ilType = null; + if (value is Il2CppSystem.Object ilObject) + { + ilType = ilObject.GetIl2CppType(); + } + if (valueType.IsPrimitive || value.GetType() == typeof(string)) { DrawPrimitive(ref value, rect, setTarget, setAction); } - else if (valueType == typeof(GameObject) || valueType == typeof(Transform)) + //else if (valueType == typeof(GameObject) || typeof(Component).IsAssignableFrom(valueType)) + else if (ilType != null && ilType == CppExplorer.GameObjectType || CppExplorer.ComponentType.IsAssignableFrom(ilType)) { GameObject go; - if (value.GetType() == typeof(Transform)) + var ilObj = value as Il2CppSystem.Object; + if (ilType == CppExplorer.GameObjectType) { - go = (value as Transform).gameObject; + go = ilObj.TryCast(); } else { - go = (value as GameObject); + go = ilObj.TryCast().gameObject; } GameobjButton(go, null, false, rect.width - 250);