diff --git a/src/CachedObjects/CacheEnum.cs b/src/CachedObjects/CacheEnum.cs
index 00f3d09..9bcd5ba 100644
--- a/src/CachedObjects/CacheEnum.cs
+++ b/src/CachedObjects/CacheEnum.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Reflection;
using MelonLoader;
using UnityEngine;
@@ -15,8 +16,23 @@ namespace Explorer
public override void Init()
{
- EnumType = Value.GetType();
- EnumNames = Enum.GetNames(EnumType);
+ try
+ {
+ EnumType = Value.GetType();
+ }
+ catch
+ {
+ EnumType = (MemInfo as FieldInfo)?.FieldType ?? (MemInfo as PropertyInfo).PropertyType;
+ }
+
+ if (EnumType != null)
+ {
+ EnumNames = Enum.GetNames(EnumType);
+ }
+ else
+ {
+ ReflectionException = "Unknown, could not get Enum names.";
+ }
}
public override void DrawValue(Rect window, float width)
diff --git a/src/CachedObjects/CacheList.cs b/src/CachedObjects/CacheList.cs
index 4b28132..88d17e4 100644
--- a/src/CachedObjects/CacheList.cs
+++ b/src/CachedObjects/CacheList.cs
@@ -145,16 +145,16 @@ namespace Explorer
{
if (m_entryType == null)
{
- if (this.MemberInfo != null)
+ if (this.MemInfo != null)
{
Type memberType = null;
- switch (this.MemberInfo.MemberType)
+ switch (this.MemInfo.MemberType)
{
case MemberTypes.Field:
- memberType = (MemberInfo as FieldInfo).FieldType;
+ memberType = (MemInfo as FieldInfo).FieldType;
break;
case MemberTypes.Property:
- memberType = (MemberInfo as PropertyInfo).PropertyType;
+ memberType = (MemInfo as PropertyInfo).PropertyType;
break;
}
@@ -201,17 +201,47 @@ namespace Explorer
while (enumerator.MoveNext())
{
var obj = enumerator.Current;
- var type = ReflectionHelpers.GetActualType(obj);
- if (obj is Il2CppSystem.Object iObj)
+ if (obj != null && ReflectionHelpers.GetActualType(obj) is Type t)
{
- obj = iObj.Il2CppCast(type);
+ if (obj is Il2CppSystem.Object iObj)
+ {
+ try
+ {
+ var cast = iObj.Il2CppCast(t);
+ if (cast != null)
+ {
+ obj = cast;
+ }
+ }
+ catch { }
+ }
+
+ if (GetCacheObject(obj, t) is CacheObjectBase cached)
+ {
+ list.Add(cached);
+ }
+ else
+ {
+ list.Add(null);
+ }
+ }
+ else
+ {
+ list.Add(null);
}
- var cached = GetCacheObject(obj, null, null, type);
- cached.UpdateValue();
+ //var type = ReflectionHelpers.GetActualType(obj);
- list.Add(cached);
+ //if (obj is Il2CppSystem.Object iObj)
+ //{
+ // obj = iObj.Il2CppCast(type);
+ //}
+
+ //var cached = GetCacheObject(obj, null, null, type);
+ //cached.UpdateValue();
+
+ //list.Add(cached);
}
m_cachedEntries = list.ToArray();
@@ -310,16 +340,18 @@ namespace Explorer
GUILayout.Space(whitespace);
- if (entry.Value == null)
+ if (entry == null || entry.Value == null)
{
- GUILayout.Label(i + " (null)", null);
+ GUILayout.Label($"[{i}] (null)", null);
}
else
{
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
- entry.DrawValue(window, window.width - (whitespace + 85));
+
+ entry.DrawValue(window, window.width - (whitespace + 85));
}
+
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
diff --git a/src/CachedObjects/CacheMethod.cs b/src/CachedObjects/CacheMethod.cs
index 6aad655..2e580ee 100644
--- a/src/CachedObjects/CacheMethod.cs
+++ b/src/CachedObjects/CacheMethod.cs
@@ -24,7 +24,7 @@ namespace Explorer
{
if (m_hasParams == null)
{
- m_hasParams = (MemberInfo as MethodInfo).GetParameters().Length > 0;
+ m_hasParams = (MemInfo as MethodInfo).GetParameters().Length > 0;
}
return (bool)m_hasParams;
}
@@ -55,7 +55,7 @@ namespace Explorer
{
base.Init();
- var mi = MemberInfo as MethodInfo;
+ var mi = MemInfo as MethodInfo;
m_arguments = mi.GetParameters();
m_argumentInput = new string[m_arguments.Length];
@@ -136,12 +136,12 @@ namespace Explorer
}
else
{
- GUILayout.Label($"null ({ValueType})", null);
+ GUILayout.Label($"null ({ValueTypeName})", null);
}
}
else
{
- GUILayout.Label($"Not yet evaluated ({ValueType})", null);
+ GUILayout.Label($"Not yet evaluated ({ValueTypeName})", null);
}
GUILayout.EndHorizontal();
@@ -150,7 +150,7 @@ namespace Explorer
private void Evaluate()
{
- var mi = MemberInfo as MethodInfo;
+ var mi = MemInfo as MethodInfo;
object ret = null;
diff --git a/src/CachedObjects/CacheObjectBase.cs b/src/CachedObjects/CacheObjectBase.cs
index a773a33..81bba82 100644
--- a/src/CachedObjects/CacheObjectBase.cs
+++ b/src/CachedObjects/CacheObjectBase.cs
@@ -13,67 +13,70 @@ namespace Explorer
public abstract class CacheObjectBase
{
public object Value;
- public string ValueType;
+ public string ValueTypeName;
- // Reflection window only
- public MemberInfo MemberInfo { get; set; }
+ // Reflection Inspector only
+ public MemberInfo MemInfo { get; set; }
public Type DeclaringType { get; set; }
public object DeclaringInstance { get; set; }
-
- public string RichTextName
- {
- get
- {
- if (m_richTextName == null)
- {
- GetRichTextName();
- }
- return m_richTextName;
- }
- }
- private string m_richTextName;
+ public string ReflectionException { get; set; }
- public string ReflectionException;
+ public int PropertyIndex { get; private set; }
+ private string m_propertyIndexInput = "0";
+
+ public string RichTextName => m_richTextName ?? GetRichTextName();
+ private string m_richTextName;
public bool CanWrite
{
get
{
- if (MemberInfo is FieldInfo fi)
- {
+ if (MemInfo is FieldInfo fi)
return !(fi.IsLiteral && !fi.IsInitOnly);
- }
- else if (MemberInfo is PropertyInfo pi)
- {
+ else if (MemInfo is PropertyInfo pi)
return pi.CanWrite;
- }
else
- {
return false;
- }
}
}
- // methods
+ // ===== Abstract/Virtual Methods ===== //
+
public virtual void Init() { }
+
public abstract void DrawValue(Rect window, float width);
+ // ===== Static Methods ===== //
+
+ ///
+ /// Get CacheObject from only an object instance
+ /// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (obj, null, null)
public static CacheObjectBase GetCacheObject(object obj)
{
return GetCacheObject(obj, null, null);
}
///
- /// Gets the CacheObject subclass for an object or MemberInfo
- ///
- /// The current value (can be null if memberInfo is not null)
- /// The MemberInfo (can be null if obj is not null)
- /// If MemberInfo is not null, the declaring class instance. Can be null if static.
- ///
+ /// Get CacheObject from an object instance and provide the value type
+ /// Calls GetCacheObjectImpl directly
+ public static CacheObjectBase GetCacheObject(object obj, Type valueType)
+ {
+ return GetCacheObjectImpl(obj, null, null, valueType);
+ }
+
+ ///
+ /// Get CacheObject from only a MemberInfo and declaring instance
+ /// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (null, memberInfo, declaringInstance)
+ public static CacheObjectBase GetCacheObject(MemberInfo memberInfo, object declaringInstance)
+ {
+ return GetCacheObject(null, memberInfo, declaringInstance);
+ }
+
+ ///
+ /// Get CacheObject from either an object or MemberInfo, and don't provide the type.
+ /// This gets the type and then calls GetCacheObjectImpl
public static CacheObjectBase GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance)
{
- //var type = ReflectionHelpers.GetActualType(obj) ?? (memberInfo as FieldInfo)?.FieldType ?? (memberInfo as PropertyInfo)?.PropertyType;
-
Type type = null;
if (obj != null)
@@ -101,18 +104,13 @@ namespace Explorer
return null;
}
- return GetCacheObject(obj, memberInfo, declaringInstance, type);
+ return GetCacheObjectImpl(obj, memberInfo, declaringInstance, type);
}
///
- /// Gets the CacheObject subclass for an object or MemberInfo
+ /// Actual GetCacheObject implementation (private)
///
- /// The current value (can be null if memberInfo is not null)
- /// The MemberInfo (can be null if obj is not null)
- /// If MemberInfo is not null, the declaring class instance. Can be null if static.
- /// The type of the object or MemberInfo value.
- ///
- public static CacheObjectBase GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance, Type valueType)
+ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberInfo, object declaringInstance, Type valueType)
{
CacheObjectBase holder;
@@ -153,11 +151,11 @@ namespace Explorer
}
holder.Value = obj;
- holder.ValueType = valueType.FullName;
+ holder.ValueTypeName = valueType.FullName;
if (memberInfo != null)
{
- holder.MemberInfo = memberInfo;
+ holder.MemInfo = memberInfo;
holder.DeclaringType = memberInfo.DeclaringType;
holder.DeclaringInstance = declaringInstance;
@@ -169,30 +167,40 @@ namespace Explorer
return holder;
}
- // ======== Updating and Setting Value (memberinfo only) =========
+ // ======== Instance Methods =========
public virtual void UpdateValue()
{
- if (MemberInfo == null || !string.IsNullOrEmpty(ReflectionException))
+ if (MemInfo == null || !string.IsNullOrEmpty(ReflectionException))
{
return;
}
try
{
- if (MemberInfo.MemberType == MemberTypes.Field)
+ if (MemInfo.MemberType == MemberTypes.Field)
{
- var fi = MemberInfo as FieldInfo;
+ var fi = MemInfo as FieldInfo;
Value = fi.GetValue(fi.IsStatic ? null : DeclaringInstance);
}
- else if (MemberInfo.MemberType == MemberTypes.Property)
+ else if (MemInfo.MemberType == MemberTypes.Property)
{
- var pi = MemberInfo as PropertyInfo;
+ var pi = MemInfo as PropertyInfo;
bool isStatic = pi.GetAccessors()[0].IsStatic;
var target = isStatic ? null : DeclaringInstance;
- Value = pi.GetValue(target, null);
+
+ if (pi.GetIndexParameters().Length > 0)
+ {
+ var indexes = new object[] { PropertyIndex };
+ Value = pi.GetValue(target, indexes);
+ }
+ else
+ {
+ Value = pi.GetValue(target, null);
+ }
}
- //ReflectionException = null;
+
+ ReflectionException = null;
}
catch (Exception e)
{
@@ -204,15 +212,24 @@ namespace Explorer
{
try
{
- if (MemberInfo.MemberType == MemberTypes.Field)
+ if (MemInfo.MemberType == MemberTypes.Field)
{
- var fi = MemberInfo as FieldInfo;
+ var fi = MemInfo as FieldInfo;
fi.SetValue(fi.IsStatic ? null : DeclaringInstance, Value);
}
- else if (MemberInfo.MemberType == MemberTypes.Property)
+ else if (MemInfo.MemberType == MemberTypes.Property)
{
- var pi = MemberInfo as PropertyInfo;
- pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value);
+ var pi = MemInfo as PropertyInfo;
+
+ if (pi.GetIndexParameters().Length > 0)
+ {
+ var indexes = new object[] { PropertyIndex };
+ pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value, indexes);
+ }
+ else
+ {
+ pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value);
+ }
}
}
catch (Exception e)
@@ -221,7 +238,7 @@ namespace Explorer
}
}
- // ========= Gui Draw ==========
+ // ========= Instance Gui Draw ==========
public const float MAX_LABEL_WIDTH = 400f;
@@ -240,11 +257,15 @@ namespace Explorer
ClampLabelWidth(window, ref labelWidth);
}
- if (MemberInfo != null)
+ if (MemInfo != null)
{
+ var name = RichTextName;
+ if (MemInfo is PropertyInfo pi && pi.GetIndexParameters().Length > 0)
+ {
+ name += $"[{PropertyIndex}]";
+ }
-
- GUILayout.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
+ GUILayout.Label(name, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
}
else
{
@@ -255,20 +276,44 @@ namespace Explorer
{
GUILayout.Label("Reflection failed! (" + ReflectionException + ")", null);
}
- else if (Value == null && MemberInfo?.MemberType != MemberTypes.Method)
+ else if (Value == null && MemInfo?.MemberType != MemberTypes.Method)
{
- GUILayout.Label("null (" + ValueType + ")", null);
+ GUILayout.Label("null (" + ValueTypeName + ")", null);
}
else
{
+ if (MemInfo is PropertyInfo pi && pi.GetIndexParameters().Length > 0)
+ {
+ GUILayout.Label("index:", new GUILayoutOption[] { GUILayout.Width(50) });
+
+ m_propertyIndexInput = GUILayout.TextField(m_propertyIndexInput, new GUILayoutOption[] { GUILayout.Width(100) });
+ if (GUILayout.Button("Set", new GUILayoutOption[] { GUILayout.Width(60) }))
+ {
+ if (int.TryParse(m_propertyIndexInput, out int i))
+ {
+ PropertyIndex = i;
+ UpdateValue();
+ }
+ else
+ {
+ MelonLogger.Log($"Could not parse '{m_propertyIndexInput}' to an int!");
+ }
+ }
+
+ // new line and space
+ GUILayout.EndHorizontal();
+ GUILayout.BeginHorizontal(null);
+ GUILayout.Space(labelWidth);
+ }
+
DrawValue(window, window.width - labelWidth - 90);
}
}
- private void GetRichTextName()
+ private string GetRichTextName()
{
string memberColor = "";
- switch (MemberInfo.MemberType)
+ switch (MemInfo.MemberType)
{
case MemberTypes.Field:
memberColor = "#c266ff"; break;
@@ -278,9 +323,9 @@ namespace Explorer
memberColor = "#ff8000"; break;
};
- m_richTextName = $"{MemberInfo.DeclaringType.Name}.{MemberInfo.Name}";
+ m_richTextName = $"{MemInfo.DeclaringType.Name}.{MemInfo.Name}";
- if (MemberInfo is MethodInfo mi)
+ if (MemInfo is MethodInfo mi)
{
m_richTextName += "(";
var _params = "";
@@ -293,6 +338,8 @@ namespace Explorer
m_richTextName += _params;
m_richTextName += ")";
}
+
+ return m_richTextName;
}
}
}
diff --git a/src/CachedObjects/CacheOther.cs b/src/CachedObjects/CacheOther.cs
index a4d5044..b77981b 100644
--- a/src/CachedObjects/CacheOther.cs
+++ b/src/CachedObjects/CacheOther.cs
@@ -12,33 +12,25 @@ namespace Explorer
public class CacheOther : CacheObjectBase
{
private MethodInfo m_toStringMethod;
- private bool m_triedToGetMethod;
public MethodInfo ToStringMethod
{
get
{
- if (m_toStringMethod == null && !m_triedToGetMethod)
+ if (m_toStringMethod == null)
{
- if (Value == null) return null;
-
- m_triedToGetMethod = true;
-
try
{
- var methods = ReflectionHelpers.GetActualType(Value)
- .GetMethods(ReflectionHelpers.CommonFlags)
- .Where(x => x.Name == "ToString")
- .GetEnumerator();
+ m_toStringMethod = ReflectionHelpers.GetActualType(Value).GetMethod("ToString", new Type[0])
+ ?? typeof(object).GetMethod("ToString", new Type[0]);
- while (methods.MoveNext())
- {
- // just get the first (top-most level) method, then break.
- m_toStringMethod = methods.Current;
- break;
- }
+ // test invoke
+ m_toStringMethod.Invoke(Value, null);
+ }
+ catch
+ {
+ m_toStringMethod = typeof(object).GetMethod("ToString", new Type[0]);
}
- catch { }
}
return m_toStringMethod;
}
@@ -48,9 +40,9 @@ namespace Explorer
{
string label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
- if (!label.Contains(ValueType))
+ if (!label.Contains(ValueTypeName))
{
- label += $" ({ValueType})";
+ label += $" ({ValueTypeName})";
}
if (Value is UnityEngine.Object unityObj && !label.Contains(unityObj.name))
{
@@ -58,7 +50,7 @@ namespace Explorer
}
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
- if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.MaxWidth(width + 40) }))
+ if (GUILayout.Button("" + label + "", new GUILayoutOption[] { GUILayout.Width(width) }))
{
WindowManager.InspectObject(Value, out bool _);
}
diff --git a/src/CachedObjects/CachePrimitive.cs b/src/CachedObjects/CachePrimitive.cs
index b28e6a6..4789209 100644
--- a/src/CachedObjects/CachePrimitive.cs
+++ b/src/CachedObjects/CachePrimitive.cs
@@ -152,7 +152,7 @@ namespace Explorer
public void SetValueFromInput(string value)
{
- if (MemberInfo == null)
+ if (MemInfo == null)
{
MelonLogger.Log("Trying to SetValue but the MemberInfo is null!");
return;
diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs
index 33f5e6f..0ca6742 100644
--- a/src/CppExplorer.cs
+++ b/src/CppExplorer.cs
@@ -133,7 +133,7 @@ namespace Explorer
// value that we set back to when we close the menu or disable force-unlock.
[HarmonyPatch(typeof(Cursor), nameof(Cursor.lockState), MethodType.Setter)]
- public class Cursor_lockState
+ public class Cursor_set_lockState
{
[HarmonyPrefix]
public static void Prefix(ref CursorLockMode value)
@@ -170,19 +170,6 @@ namespace Explorer
// Make it appear as though UnlockMouse is disabled to the rest of the application.
- [HarmonyPatch(typeof(Cursor), nameof(Cursor.visible), MethodType.Getter)]
- public class Cursor_get_visible
- {
- [HarmonyPostfix]
- public static void Postfix(ref bool __result)
- {
- if (ShouldForceMouse)
- {
- __result = m_lastVisibleState;
- }
- }
- }
-
[HarmonyPatch(typeof(Cursor), nameof(Cursor.lockState), MethodType.Getter)]
public class Cursor_get_lockState
{
@@ -195,5 +182,18 @@ namespace Explorer
}
}
}
+
+ [HarmonyPatch(typeof(Cursor), nameof(Cursor.visible), MethodType.Getter)]
+ public class Cursor_get_visible
+ {
+ [HarmonyPostfix]
+ public static void Postfix(ref bool __result)
+ {
+ if (ShouldForceMouse)
+ {
+ __result = m_lastVisibleState;
+ }
+ }
+ }
}
}
diff --git a/src/CppExplorer.csproj b/src/CppExplorer.csproj
index d8784ad..cc1ea50 100644
--- a/src/CppExplorer.csproj
+++ b/src/CppExplorer.csproj
@@ -60,7 +60,9 @@
..\..\..\..\..\Steam\steamapps\common\Hellpoint\MelonLoader\Managed\UnhollowerBaseLib.dll
False
+
+
..\..\..\Steam\steamapps\common\Hellpoint\MelonLoader\Managed\UnityEngine.dll
False
@@ -89,7 +91,9 @@
..\..\..\Steam\steamapps\common\Hellpoint\MelonLoader\Managed\UnityEngine.UI.dll
False
+
+
..\..\..\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.dll
False
@@ -118,6 +122,7 @@
..\..\..\Steam\steamapps\common\VRChat\MelonLoader\Managed\UnityEngine.UI.dll
False
+
diff --git a/src/Helpers/ReflectionHelpers.cs b/src/Helpers/ReflectionHelpers.cs
index 2318e08..b61bb24 100644
--- a/src/Helpers/ReflectionHelpers.cs
+++ b/src/Helpers/ReflectionHelpers.cs
@@ -8,6 +8,7 @@ using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using UnityEngine;
using BF = System.Reflection.BindingFlags;
+using MelonLoader;
namespace Explorer
{
@@ -27,8 +28,9 @@ namespace Explorer
{
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo)) return obj;
- var generic = m_tryCastMethodInfo.MakeGenericMethod(castTo);
- return generic.Invoke(obj, null);
+ return m_tryCastMethodInfo
+ .MakeGenericMethod(castTo)
+ .Invoke(obj, null);
}
public static string ExceptionToString(Exception e)
@@ -81,9 +83,10 @@ namespace Explorer
{
if (t.IsGenericType)
{
- return t.GetGenericTypeDefinition() is Type typeDef
- && (typeDef.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.List<>))
- || typeDef.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.IList<>)));
+ var generic = t.GetGenericTypeDefinition();
+
+ return generic.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.List<>))
+ || generic.IsAssignableFrom(typeof(Il2CppSystem.Collections.Generic.IList<>));
}
else
{
@@ -115,58 +118,36 @@ namespace Explorer
return null;
}
- public static Type GetActualType(object m_object)
+ public static Type GetActualType(object obj)
{
- if (m_object == null) return null;
+ if (obj == null) return null;
- if (m_object is Il2CppSystem.Object ilObject)
+ if (obj is Il2CppSystem.Object ilObject)
{
- var iltype = ilObject.GetIl2CppType();
- if (Type.GetType(iltype.AssemblyQualifiedName) is Type type)
+ var ilTypeName = ilObject.GetIl2CppType().AssemblyQualifiedName;
+
+ if (Type.GetType(ilTypeName) is Type t && !t.FullName.Contains("System.RuntimeType"))
{
- return type;
- }
- else
- {
- return ilObject.GetType();
+ return t;
}
+
+ return ilObject.GetType();
}
- else
- {
- return m_object.GetType();
- }
+
+ return obj.GetType();
}
- public static Type[] GetAllBaseTypes(object m_object)
+ public static Type[] GetAllBaseTypes(object obj)
{
var list = new List();
- if (m_object is Il2CppSystem.Object ilObject)
- {
- var ilType = ilObject.GetIl2CppType();
- if (Type.GetType(ilType.AssemblyQualifiedName) is Type ilTypeToManaged)
- {
- list.Add(ilTypeToManaged);
+ var type = GetActualType(obj);
+ list.Add(type);
- while (ilType.BaseType != null)
- {
- ilType = ilType.BaseType;
- if (Type.GetType(ilType.AssemblyQualifiedName) is Type ilBaseTypeToManaged)
- {
- list.Add(ilBaseTypeToManaged);
- }
- }
- }
- }
- else
+ while (type.BaseType != null)
{
- var type = m_object.GetType();
+ type = type.BaseType;
list.Add(type);
- while (type.BaseType != null)
- {
- type = type.BaseType;
- list.Add(type);
- }
}
return list.ToArray();
diff --git a/src/Helpers/UIStyles.cs b/src/Helpers/UIStyles.cs
index c02c91d..5ee9fef 100644
--- a/src/Helpers/UIStyles.cs
+++ b/src/Helpers/UIStyles.cs
@@ -33,12 +33,14 @@ namespace Explorer
}
}
- public static void HorizontalLine(Color color)
+ public static void HorizontalLine(Color _color, bool small = false)
{
- var c = GUI.color;
- GUI.color = color;
- GUILayout.Box(GUIContent.none, HorizontalBar, null);
- GUI.color = c;
+ var orig = GUI.color;
+
+ GUI.color = _color;
+ GUILayout.Box(GUIContent.none, !small ? HorizontalBar : HorizontalBarSmall, null);
+
+ GUI.color = orig;
}
private static GUISkin _customSkin;
@@ -46,8 +48,6 @@ namespace Explorer
public static Texture2D m_nofocusTex;
public static Texture2D m_focusTex;
- private static GUIStyle _horizBarStyle;
-
private static GUIStyle HorizontalBar
{
get
@@ -63,6 +63,24 @@ namespace Explorer
return _horizBarStyle;
}
}
+ private static GUIStyle _horizBarStyle;
+
+ private static GUIStyle HorizontalBarSmall
+ {
+ get
+ {
+ if (_horizBarSmallStyle == null)
+ {
+ _horizBarSmallStyle = new GUIStyle();
+ _horizBarSmallStyle.normal.background = Texture2D.whiteTexture;
+ _horizBarSmallStyle.margin = new RectOffset(0, 0, 2, 2);
+ _horizBarSmallStyle.fixedHeight = 1;
+ }
+
+ return _horizBarSmallStyle;
+ }
+ }
+ private static GUIStyle _horizBarSmallStyle;
private static GUISkin CreateWindowSkin()
{
diff --git a/src/Windows/ReflectionWindow.cs b/src/Windows/ReflectionWindow.cs
index 272ba44..fca607b 100644
--- a/src/Windows/ReflectionWindow.cs
+++ b/src/Windows/ReflectionWindow.cs
@@ -13,10 +13,10 @@ namespace Explorer
public class ReflectionWindow : UIWindow
{
public override string Title => WindowManager.TabView
- ? $"[R] {ObjectType.Name}"
- : $"Reflection Inspector ({ObjectType.Name})";
+ ? $"[R] {TargetType.Name}"
+ : $"Reflection Inspector ({TargetType.Name})";
- public Type ObjectType;
+ public Type TargetType;
private CacheObjectBase[] m_allCachedMembers;
private CacheObjectBase[] m_cachedMembersFiltered;
@@ -35,16 +35,11 @@ namespace Explorer
public override void Init()
{
var type = ReflectionHelpers.GetActualType(Target);
- if (type == null)
- {
- MelonLogger.Log($"Could not get underlying type for object! Type: {Target?.GetType().AssemblyQualifiedName}, Value ToString: {Target?.ToString()}");
- DestroyWindow();
- return;
- }
- ObjectType = type;
+ TargetType = type;
var types = ReflectionHelpers.GetAllBaseTypes(Target);
+
CacheMembers(types);
if (Target is Il2CppSystem.Object ilObject)
@@ -90,13 +85,13 @@ namespace Explorer
private bool ShouldProcessMember(CacheObjectBase holder)
{
- if (m_filter != MemberTypes.All && m_filter != holder.MemberInfo?.MemberType) return false;
+ if (m_filter != MemberTypes.All && m_filter != holder.MemInfo?.MemberType) return false;
if (!string.IsNullOrEmpty(holder.ReflectionException) && m_hideFailedReflection) return false;
- if (m_search == "" || holder.MemberInfo == null) return true;
+ if (m_search == "" || holder.MemInfo == null) return true;
- var name = holder.MemberInfo.DeclaringType.Name + "." + holder.MemberInfo.Name;
+ var name = holder.MemInfo.DeclaringType.Name + "." + holder.MemInfo.Name;
return name.ToLower().Contains(m_search.ToLower());
}
@@ -118,7 +113,7 @@ namespace Explorer
}
catch
{
- MelonLogger.Log("Exception getting members for type: " + declaringType.Name);
+ MelonLogger.Log($"Exception getting members for type: {declaringType.FullName}");
continue;
}
@@ -140,11 +135,14 @@ namespace Explorer
{
if (member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property || member.MemberType == MemberTypes.Method)
{
- // ignore these
- if (member.Name.Contains("Il2CppType") || member.Name.StartsWith("get_") || member.Name.StartsWith("set_"))
- continue;
+ var name = $"{member.DeclaringType.Name}.{member.Name}";
+
+ // blacklist (should probably make a proper implementation)
+ if (name == "Type.DeclaringMethod" || member.Name.Contains("Il2CppType") || member.Name.StartsWith("get_") || member.Name.StartsWith("set_"))
+ {
+ continue;
+ }
- var name = member.DeclaringType.Name + "." + member.Name;
if (member is MethodInfo mi)
{
name += " (";
@@ -161,7 +159,7 @@ namespace Explorer
try
{
- var cached = CacheObjectBase.GetCacheObject(null, member, target);
+ var cached = CacheObjectBase.GetCacheObject(member, target);
if (cached != null)
{
names.Add(name);
@@ -198,7 +196,7 @@ namespace Explorer
}
GUILayout.BeginHorizontal(null);
- GUILayout.Label("Type: " + ObjectType.FullName + "", new GUILayoutOption[] { GUILayout.Width(245f) });
+ GUILayout.Label("Type: " + TargetType.FullName + "", new GUILayoutOption[] { GUILayout.Width(245f) });
if (m_uObj)
{
GUILayout.Label("Name: " + m_uObj.name, null);
@@ -298,11 +296,10 @@ namespace Explorer
GUILayout.BeginVertical(GUI.skin.box, null);
- int index = 0;
var members = this.m_cachedMembersFiltered;
- int offsetIndex = (m_pageOffset * m_limitPerPage) + index;
+ int start = m_pageOffset * m_limitPerPage;
- if (offsetIndex >= count)
+ if (start >= count)
{
int maxOffset = (int)Mathf.Ceil((float)(m_cachedMembersFiltered.Length / (decimal)m_limitPerPage)) - 1;
if (m_pageOffset > maxOffset)
@@ -311,21 +308,25 @@ namespace Explorer
}
}
- for (int j = offsetIndex; (j < offsetIndex + m_limitPerPage && j < members.Length); j++)
+ for (int j = start; (j < start + m_limitPerPage && j < members.Length); j++)
{
var holder = members[j];
GUILayout.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
-
- try
- {
+ try
+ {
holder.Draw(rect, 180f);
+ }
+ catch
+ {
+ GUILayout.EndHorizontal();
+ continue;
}
- catch { }
-
GUILayout.EndHorizontal();
- index++;
+ // if not last element
+ if (!(j == (start + m_limitPerPage - 1) || j == (members.Length - 1)))
+ UIStyles.HorizontalLine(new Color(0.07f, 0.07f, 0.07f), true);
}
GUILayout.EndVertical();
diff --git a/src/Windows/WindowManager.cs b/src/Windows/WindowManager.cs
index 3ec7a57..29fc7e0 100644
--- a/src/Windows/WindowManager.cs
+++ b/src/Windows/WindowManager.cs
@@ -86,61 +86,6 @@ namespace Explorer
// ========= Public Helpers =========
- public static bool IsMouseInWindow
- {
- get
- {
- if (!CppExplorer.ShowMenu)
- {
- return false;
- }
-
- foreach (var window in Windows)
- {
- if (RectContainsMouse(window.m_rect))
- {
- return true;
- }
- }
- return RectContainsMouse(MainMenu.MainRect);
- }
- }
-
- private static bool RectContainsMouse(Rect rect)
- {
- return rect.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y));
- }
-
- public static int NextWindowID()
- {
- return CurrentWindowID++;
- }
-
- public static Rect GetNewWindowRect()
- {
- return GetNewWindowRect(ref m_lastWindowRect);
- }
-
- public static Rect GetNewWindowRect(ref Rect lastRect)
- {
- Rect rect = new Rect(0, 0, 550, 700);
-
- var mainrect = MainMenu.MainRect;
- if (mainrect.x <= (Screen.width - mainrect.width - 100))
- {
- rect = new Rect(mainrect.x + mainrect.width + 20, mainrect.y, rect.width, rect.height);
- }
-
- if (lastRect.x == rect.x)
- {
- rect = new Rect(rect.x + 25, rect.y + 25, rect.width, rect.height);
- }
-
- lastRect = rect;
-
- return rect;
- }
-
public static UIWindow InspectObject(object obj, out bool createdNew)
{
createdNew = false;
@@ -206,5 +151,62 @@ namespace Explorer
return new_window;
}
+
+ // === Misc Helpers ===
+
+ public static bool IsMouseInWindow
+ {
+ get
+ {
+ if (!CppExplorer.ShowMenu)
+ {
+ return false;
+ }
+
+ foreach (var window in Windows)
+ {
+ if (RectContainsMouse(window.m_rect))
+ {
+ return true;
+ }
+ }
+ return RectContainsMouse(MainMenu.MainRect);
+ }
+ }
+
+ private static bool RectContainsMouse(Rect rect)
+ {
+ return rect.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y));
+ }
+
+ public static int NextWindowID()
+ {
+ return CurrentWindowID++;
+ }
+
+ public static Rect GetNewWindowRect()
+ {
+ return GetNewWindowRect(ref m_lastWindowRect);
+ }
+
+ public static Rect GetNewWindowRect(ref Rect lastRect)
+ {
+ Rect rect = new Rect(0, 0, 550, 700);
+
+ var mainrect = MainMenu.MainRect;
+ if (mainrect.x <= (Screen.width - mainrect.width - 100))
+ {
+ rect = new Rect(mainrect.x + mainrect.width + 20, mainrect.y, rect.width, rect.height);
+ }
+
+ if (lastRect.x == rect.x)
+ {
+ rect = new Rect(rect.x + 25, rect.y + 25, rect.width, rect.height);
+ }
+
+ lastRect = rect;
+
+ return rect;
+ }
}
}