diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs index f6861b9..7df55f4 100644 --- a/src/CppExplorer.cs +++ b/src/CppExplorer.cs @@ -15,7 +15,7 @@ namespace Explorer public const string ID = "com.sinai.cppexplorer"; public const string NAME = "IL2CPP Runtime Explorer"; - public const string VERSION = "1.0.0"; + public const string VERSION = "1.1.0"; public const string AUTHOR = "Sinai"; // fields diff --git a/src/Inspectors/ReflectionWindow.cs b/src/Inspectors/ReflectionWindow.cs index 1b3a31e..0d1ba66 100644 --- a/src/Inspectors/ReflectionWindow.cs +++ b/src/Inspectors/ReflectionWindow.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using MelonLoader; +using Mono.CSharp; using UnhollowerBaseLib; using UnityEngine; @@ -275,10 +276,11 @@ namespace Explorer public static bool IsList(Type t) { - return t.IsGenericType && t.GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>)); + return t.IsGenericType + && t.GetGenericTypeDefinition() is Type typeDef + && (typeDef.IsAssignableFrom(typeof(List<>)) || typeDef.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.List<>))); } - private void GetProperties(object m_object, List names = null) { if (names == null) @@ -292,6 +294,11 @@ namespace Explorer { foreach (var pi in type.GetProperties(At.flags)) { + if (pi.Name == "Il2CppType") + { + continue; + } + if (names.Contains(pi.Name)) { continue; @@ -382,15 +389,15 @@ namespace Explorer } catch (Exception e) { - MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); - MelonLogger.Log(e.GetType() + ", " + e.Message); + //MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name); + //MelonLogger.Log(e.GetType() + ", " + e.Message); - var inner = e.InnerException; - while (inner != null) - { - MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); - inner = inner.InnerException; - } + //var inner = e.InnerException; + //while (inner != null) + //{ + // MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message); + // inner = inner.InnerException; + //} m_value = null; } @@ -402,7 +409,7 @@ namespace Explorer { if (propInfo.PropertyType.IsEnum) { - if (Enum.Parse(propInfo.PropertyType, m_value.ToString()) is object enumValue && enumValue != null) + if (System.Enum.Parse(propInfo.PropertyType, m_value.ToString()) is object enumValue && enumValue != null) { m_value = enumValue; } @@ -451,7 +458,7 @@ namespace Explorer } catch { - MelonLogger.Log("Exception trying to set property " + this.propInfo.Name); + //MelonLogger.Log("Exception trying to set property " + this.propInfo.Name); } } } @@ -496,7 +503,7 @@ namespace Explorer { if (fieldInfo.FieldType.IsEnum) { - if (Enum.Parse(fieldInfo.FieldType, m_value.ToString()) is object enumValue && enumValue != null) + if (System.Enum.Parse(fieldInfo.FieldType, m_value.ToString()) is object enumValue && enumValue != null) { m_value = enumValue; } diff --git a/src/UIStyles.cs b/src/UIStyles.cs index 72f04d1..a605092 100644 --- a/src/UIStyles.cs +++ b/src/UIStyles.cs @@ -2,7 +2,12 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; +using Il2CppSystem.Collections; +using Il2CppSystem.Reflection; +using MelonLoader; +using UnhollowerBaseLib; using UnityEngine; using Object = UnityEngine.Object; @@ -234,50 +239,79 @@ namespace Explorer } GUILayout.Label(value.ToString(), null); - } - else if (valueType.IsArray || ReflectionWindow.IsList(valueType)) + else if (value is System.Collections.IEnumerable || ReflectionWindow.IsList(valueType)) { - object[] m_array; - if (valueType.IsArray) + System.Collections.IEnumerable enumerable; + + if (value is System.Collections.IEnumerable isEnumerable) { - m_array = (value as Array).Cast().ToArray(); + enumerable = isEnumerable; } else { - m_array = (value as IEnumerable).Cast().ToArray(); + var listValueType = value.GetType().GetGenericArguments()[0]; + var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType }); + var method = listType.GetMethod("ToArray"); + enumerable = (System.Collections.IEnumerable)method.Invoke(value, new object[0]); } + int count = enumerable.Cast().Count(); + GUI.skin.button.alignment = TextAnchor.MiddleLeft; - if (GUILayout.Button("[" + m_array.Length + "] " + valueType + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) + string btnLabel = "[" + count + "] " + valueType + ""; + if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) })) { WindowManager.InspectObject(value, out bool _); } GUI.skin.button.alignment = TextAnchor.MiddleCenter; - for (int i = 0; i < m_array.Length; i++) + var enumerator = enumerable.GetEnumerator(); + if (enumerator != null) { - var obj = m_array[i]; - - // collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry - GUILayout.EndHorizontal(); - GUILayout.BeginHorizontal(null); - GUILayout.Space(190); - - if (i > CppExplorer.ArrayLimit) + int i = 0; + while (enumerator.MoveNext()) { - GUILayout.Label($"{m_array.Length - CppExplorer.ArrayLimit} results omitted, array is too long!", null); - break; - } + var obj = enumerator.Current; - if (obj == null) - { - GUILayout.Label("null", null); - } - else - { - var type = obj.GetType(); - DrawMember(ref obj, type.ToString(), i.ToString(), rect, setTarget, setAction, 25, true); + //collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(null); + GUILayout.Space(190); + + if (i > CppExplorer.ArrayLimit) + { + GUILayout.Label($"{count - CppExplorer.ArrayLimit} results omitted, array is too long!", null); + break; + } + + if (obj == null) + { + GUILayout.Label("null", null); + } + else + { + var type = obj.GetType(); + var lbl = i + ": " + obj.ToString() + ""; + + if (type.IsPrimitive || typeof(string).IsAssignableFrom(type)) + { + GUILayout.Label(lbl, null); + } + else + { + GUI.skin.button.alignment = TextAnchor.MiddleLeft; + if (GUILayout.Button(lbl, null)) + { + WindowManager.InspectObject(obj, out _); + } + GUI.skin.button.alignment = TextAnchor.MiddleCenter; + } + //var type = obj.GetType(); + //DrawMember(ref obj, type.ToString(), i.ToString(), rect, setTarget, setAction, 25, true); + } + + i++; } } } @@ -289,6 +323,30 @@ namespace Explorer { label = (value as Object).name; } + else if (value is Vector4 vec4) + { + label = vec4.ToString(); + } + else if (value is Vector3 vec3) + { + label = vec3.ToString(); + } + else if (value is Vector2 vec2) + { + label = vec2.ToString(); + } + else if (value is Rect rec) + { + label = rec.ToString(); + } + else if (value is Matrix4x4 matrix) + { + label = matrix.ToString(); + } + else if (value is Color col) + { + label = col.ToString(); + } GUI.skin.button.alignment = TextAnchor.MiddleLeft; if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) }))