diff --git a/README.md b/README.md index 997232a..7dd78ba 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ CppExplorer has two main inspector modes: GameObject Inspector, and Re * Allows you to inspect Properties, Fields and basic Methods, as well as set primitive values and evaluate primitive methods. * Can search and filter members for the ones you are interested in. -[![](https://i.imgur.com/eFVTQdh.png)](https://i.imgur.com/eFVTQdh.png) +[![](https://i.imgur.com/iq92m0l.png)](https://i.imgur.com/iq92m0l.png) ### Object Search diff --git a/src/CachedObjects/CacheList.cs b/src/CachedObjects/CacheList.cs index a9ba442..4b28132 100644 --- a/src/CachedObjects/CacheList.cs +++ b/src/CachedObjects/CacheList.cs @@ -8,7 +8,7 @@ using UnityEngine; namespace Explorer { - public partial class CacheList : CacheObjectBase + public class CacheList : CacheObjectBase { public bool IsExpanded { get; set; } public int ArrayOffset { get; set; } @@ -61,7 +61,7 @@ namespace Explorer { if (m_enumerable == null && Value != null) { - m_enumerable = Value as IEnumerable ?? CastValueFromList(); + m_enumerable = Value as IEnumerable ?? GetEnumerableFromIl2CppList(); } return m_enumerable; } @@ -101,7 +101,7 @@ namespace Explorer return m_itemProperty; } - private IEnumerable CastValueFromList() + private IEnumerable GetEnumerableFromIl2CppList() { if (Value == null) return null; @@ -111,11 +111,11 @@ namespace Explorer } else { - return CastFromIList(); + return ConvertIListToMono(); } } - private IList CastFromIList() + private IList ConvertIListToMono() { try { @@ -136,7 +136,7 @@ namespace Explorer } catch (Exception e) { - MelonLogger.Log("Exception casting IList to Array: " + e.GetType() + ", " + e.Message); + MelonLogger.Log("Exception converting Il2Cpp IList to Mono IList: " + e.GetType() + ", " + e.Message); return null; } } @@ -186,13 +186,12 @@ namespace Explorer { base.UpdateValue(); - if (Value == null) + if (Value == null || Enumerable == null) { return; } - var enumerator = Enumerable?.GetEnumerator(); - + var enumerator = Enumerable.GetEnumerator(); if (enumerator == null) { return; @@ -214,6 +213,7 @@ namespace Explorer list.Add(cached); } + m_cachedEntries = list.ToArray(); } diff --git a/src/CachedObjects/CacheObjectBase.cs b/src/CachedObjects/CacheObjectBase.cs index 85c4081..a773a33 100644 --- a/src/CachedObjects/CacheObjectBase.cs +++ b/src/CachedObjects/CacheObjectBase.cs @@ -19,7 +19,20 @@ namespace Explorer public MemberInfo MemberInfo { get; set; } public Type DeclaringType { get; set; } public object DeclaringInstance { get; set; } - public string FullName => $"{MemberInfo.DeclaringType.Name}.{MemberInfo.Name}"; + + public string RichTextName + { + get + { + if (m_richTextName == null) + { + GetRichTextName(); + } + return m_richTextName; + } + } + private string m_richTextName; + public string ReflectionException; public bool CanWrite @@ -156,45 +169,7 @@ namespace Explorer return holder; } - public const float MAX_LABEL_WIDTH = 400f; - - public static void ClampLabelWidth(Rect window, ref float labelWidth) - { - float min = window.width * 0.37f; - if (min > MAX_LABEL_WIDTH) min = MAX_LABEL_WIDTH; - - labelWidth = Mathf.Clamp(labelWidth, min, MAX_LABEL_WIDTH); - } - - public void Draw(Rect window, float labelWidth = 215f) - { - if (labelWidth > 0) - { - ClampLabelWidth(window, ref labelWidth); - } - - if (MemberInfo != null) - { - GUILayout.Label("" + FullName + "", new GUILayoutOption[] { GUILayout.Width(labelWidth) }); - } - else - { - GUILayout.Space(labelWidth); - } - - if (!string.IsNullOrEmpty(ReflectionException)) - { - GUILayout.Label("Reflection failed! (" + ReflectionException + ")", null); - } - else if (Value == null && MemberInfo?.MemberType != MemberTypes.Method) - { - GUILayout.Label("null (" + ValueType + ")", null); - } - else - { - DrawValue(window, window.width - labelWidth - 90); - } - } + // ======== Updating and Setting Value (memberinfo only) ========= public virtual void UpdateValue() { @@ -245,5 +220,79 @@ namespace Explorer MelonLogger.LogWarning($"Error setting value: {e.GetType()}, {e.Message}"); } } + + // ========= Gui Draw ========== + + public const float MAX_LABEL_WIDTH = 400f; + + public static void ClampLabelWidth(Rect window, ref float labelWidth) + { + float min = window.width * 0.37f; + if (min > MAX_LABEL_WIDTH) min = MAX_LABEL_WIDTH; + + labelWidth = Mathf.Clamp(labelWidth, min, MAX_LABEL_WIDTH); + } + + public void Draw(Rect window, float labelWidth = 215f) + { + if (labelWidth > 0) + { + ClampLabelWidth(window, ref labelWidth); + } + + if (MemberInfo != null) + { + + + GUILayout.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) }); + } + else + { + GUILayout.Space(labelWidth); + } + + if (!string.IsNullOrEmpty(ReflectionException)) + { + GUILayout.Label("Reflection failed! (" + ReflectionException + ")", null); + } + else if (Value == null && MemberInfo?.MemberType != MemberTypes.Method) + { + GUILayout.Label("null (" + ValueType + ")", null); + } + else + { + DrawValue(window, window.width - labelWidth - 90); + } + } + + private void GetRichTextName() + { + string memberColor = ""; + switch (MemberInfo.MemberType) + { + case MemberTypes.Field: + memberColor = "#c266ff"; break; + case MemberTypes.Property: + memberColor = "#72a6a6"; break; + case MemberTypes.Method: + memberColor = "#ff8000"; break; + }; + + m_richTextName = $"{MemberInfo.DeclaringType.Name}.{MemberInfo.Name}"; + + if (MemberInfo is MethodInfo mi) + { + m_richTextName += "("; + var _params = ""; + foreach (var param in mi.GetParameters()) + { + if (_params != "") _params += ", "; + + _params += $"{param.Name}"; + } + m_richTextName += _params; + m_richTextName += ")"; + } + } } } diff --git a/src/CachedObjects/CachePrimitive.cs b/src/CachedObjects/CachePrimitive.cs index b18384b..b28e6a6 100644 --- a/src/CachedObjects/CachePrimitive.cs +++ b/src/CachedObjects/CachePrimitive.cs @@ -113,7 +113,7 @@ namespace Explorer b = GUILayout.Toggle(b, label, null); if (b != (bool)Value) { - SetValue(m_valueToString); + SetValueFromInput(b.ToString()); } } else @@ -142,7 +142,7 @@ namespace Explorer { if (GUILayout.Button("Apply", new GUILayoutOption[] { GUILayout.Width(60) })) { - SetValue(m_valueToString); + SetValueFromInput(m_valueToString); } } @@ -150,7 +150,7 @@ namespace Explorer } } - public void SetValue(string value) + public void SetValueFromInput(string value) { if (MemberInfo == null) { diff --git a/src/CppExplorer.cs b/src/CppExplorer.cs index 77f9f9b..33f5e6f 100644 --- a/src/CppExplorer.cs +++ b/src/CppExplorer.cs @@ -12,7 +12,7 @@ namespace Explorer public class CppExplorer : MelonMod { public const string GUID = "com.sinai.cppexplorer"; - public const string VERSION = "1.4.7"; + public const string VERSION = "1.5.0"; public const string AUTHOR = "Sinai"; public const string NAME = "CppExplorer" diff --git a/src/Windows/ReflectionWindow.cs b/src/Windows/ReflectionWindow.cs index ce81ed9..272ba44 100644 --- a/src/Windows/ReflectionWindow.cs +++ b/src/Windows/ReflectionWindow.cs @@ -96,9 +96,9 @@ namespace Explorer if (m_search == "" || holder.MemberInfo == null) return true; - return holder.FullName - .ToLower() - .Contains(m_search.ToLower()); + var name = holder.MemberInfo.DeclaringType.Name + "." + holder.MemberInfo.Name; + + return name.ToLower().Contains(m_search.ToLower()); } private void CacheMembers(Type[] types) @@ -140,25 +140,38 @@ 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; + if (member is MethodInfo mi) + { + name += " ("; + foreach (var param in mi.GetParameters()) + { + name += param.ParameterType.Name + ", "; + } + name += ")"; + } + if (names.Contains(name)) + { + continue; + } + try { - var name = member.DeclaringType.Name + "." + member.Name; - if (names.Contains(name)) continue; - names.Add(name); - var cached = CacheObjectBase.GetCacheObject(null, member, target); if (cached != null) { + names.Add(name); list.Add(cached); cached.ReflectionException = exception; } } catch (Exception e) { - MelonLogger.LogWarning($"Exception caching member {declaringType.Name}.{member.Name}!"); + MelonLogger.LogWarning($"Exception caching member {name}!"); MelonLogger.Log(e.ToString()); } }