mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 22:27:45 +08:00
1.5.0
This commit is contained in:
parent
d8688193d5
commit
916bdea59b
@ -66,7 +66,7 @@ CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Re
|
|||||||
* Allows you to inspect Properties, Fields and basic Methods, as well as set primitive values and evaluate primitive methods.
|
* 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.
|
* Can search and filter members for the ones you are interested in.
|
||||||
|
|
||||||
[](https://i.imgur.com/eFVTQdh.png)
|
[](https://i.imgur.com/iq92m0l.png)
|
||||||
|
|
||||||
### Object Search
|
### Object Search
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public partial class CacheList : CacheObjectBase
|
public class CacheList : CacheObjectBase
|
||||||
{
|
{
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public int ArrayOffset { get; set; }
|
public int ArrayOffset { get; set; }
|
||||||
@ -61,7 +61,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (m_enumerable == null && Value != null)
|
if (m_enumerable == null && Value != null)
|
||||||
{
|
{
|
||||||
m_enumerable = Value as IEnumerable ?? CastValueFromList();
|
m_enumerable = Value as IEnumerable ?? GetEnumerableFromIl2CppList();
|
||||||
}
|
}
|
||||||
return m_enumerable;
|
return m_enumerable;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ namespace Explorer
|
|||||||
return m_itemProperty;
|
return m_itemProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable CastValueFromList()
|
private IEnumerable GetEnumerableFromIl2CppList()
|
||||||
{
|
{
|
||||||
if (Value == null) return null;
|
if (Value == null) return null;
|
||||||
|
|
||||||
@ -111,11 +111,11 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return CastFromIList();
|
return ConvertIListToMono();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IList CastFromIList()
|
private IList ConvertIListToMono()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,13 +186,12 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
if (Value == null)
|
if (Value == null || Enumerable == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var enumerator = Enumerable?.GetEnumerator();
|
var enumerator = Enumerable.GetEnumerator();
|
||||||
|
|
||||||
if (enumerator == null)
|
if (enumerator == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -214,6 +213,7 @@ namespace Explorer
|
|||||||
|
|
||||||
list.Add(cached);
|
list.Add(cached);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cachedEntries = list.ToArray();
|
m_cachedEntries = list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,20 @@ namespace Explorer
|
|||||||
public MemberInfo MemberInfo { get; set; }
|
public MemberInfo MemberInfo { get; set; }
|
||||||
public Type DeclaringType { get; set; }
|
public Type DeclaringType { get; set; }
|
||||||
public object DeclaringInstance { 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 string ReflectionException;
|
||||||
|
|
||||||
public bool CanWrite
|
public bool CanWrite
|
||||||
@ -156,45 +169,7 @@ namespace Explorer
|
|||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public const float MAX_LABEL_WIDTH = 400f;
|
// ======== Updating and Setting Value (memberinfo only) =========
|
||||||
|
|
||||||
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("<color=cyan>" + FullName + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GUILayout.Space(labelWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(ReflectionException))
|
|
||||||
{
|
|
||||||
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
|
||||||
}
|
|
||||||
else if (Value == null && MemberInfo?.MemberType != MemberTypes.Method)
|
|
||||||
{
|
|
||||||
GUILayout.Label("<i>null (" + ValueType + ")</i>", null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawValue(window, window.width - labelWidth - 90);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void UpdateValue()
|
public virtual void UpdateValue()
|
||||||
{
|
{
|
||||||
@ -245,5 +220,79 @@ namespace Explorer
|
|||||||
MelonLogger.LogWarning($"Error setting value: {e.GetType()}, {e.Message}");
|
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("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
||||||
|
}
|
||||||
|
else if (Value == null && MemberInfo?.MemberType != MemberTypes.Method)
|
||||||
|
{
|
||||||
|
GUILayout.Label("<i>null (" + ValueType + ")</i>", 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 = $"<color=#2df7b2>{MemberInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemberInfo.Name}</color>";
|
||||||
|
|
||||||
|
if (MemberInfo is MethodInfo mi)
|
||||||
|
{
|
||||||
|
m_richTextName += "(";
|
||||||
|
var _params = "";
|
||||||
|
foreach (var param in mi.GetParameters())
|
||||||
|
{
|
||||||
|
if (_params != "") _params += ", ";
|
||||||
|
|
||||||
|
_params += $"<color=#a6e9e9>{param.Name}</color>";
|
||||||
|
}
|
||||||
|
m_richTextName += _params;
|
||||||
|
m_richTextName += ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ namespace Explorer
|
|||||||
b = GUILayout.Toggle(b, label, null);
|
b = GUILayout.Toggle(b, label, null);
|
||||||
if (b != (bool)Value)
|
if (b != (bool)Value)
|
||||||
{
|
{
|
||||||
SetValue(m_valueToString);
|
SetValueFromInput(b.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -142,7 +142,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
|
if (GUILayout.Button("<color=#00FF00>Apply</color>", 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)
|
if (MemberInfo == null)
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
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 AUTHOR = "Sinai";
|
||||||
|
|
||||||
public const string NAME = "CppExplorer"
|
public const string NAME = "CppExplorer"
|
||||||
|
@ -96,9 +96,9 @@ namespace Explorer
|
|||||||
|
|
||||||
if (m_search == "" || holder.MemberInfo == null) return true;
|
if (m_search == "" || holder.MemberInfo == null) return true;
|
||||||
|
|
||||||
return holder.FullName
|
var name = holder.MemberInfo.DeclaringType.Name + "." + holder.MemberInfo.Name;
|
||||||
.ToLower()
|
|
||||||
.Contains(m_search.ToLower());
|
return name.ToLower().Contains(m_search.ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheMembers(Type[] types)
|
private void CacheMembers(Type[] types)
|
||||||
@ -140,25 +140,38 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property || member.MemberType == MemberTypes.Method)
|
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_"))
|
if (member.Name.Contains("Il2CppType") || member.Name.StartsWith("get_") || member.Name.StartsWith("set_"))
|
||||||
continue;
|
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
|
try
|
||||||
{
|
{
|
||||||
var name = member.DeclaringType.Name + "." + member.Name;
|
|
||||||
if (names.Contains(name)) continue;
|
|
||||||
names.Add(name);
|
|
||||||
|
|
||||||
var cached = CacheObjectBase.GetCacheObject(null, member, target);
|
var cached = CacheObjectBase.GetCacheObject(null, member, target);
|
||||||
if (cached != null)
|
if (cached != null)
|
||||||
{
|
{
|
||||||
|
names.Add(name);
|
||||||
list.Add(cached);
|
list.Add(cached);
|
||||||
cached.ReflectionException = exception;
|
cached.ReflectionException = exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MelonLogger.LogWarning($"Exception caching member {declaringType.Name}.{member.Name}!");
|
MelonLogger.LogWarning($"Exception caching member {name}!");
|
||||||
MelonLogger.Log(e.ToString());
|
MelonLogger.Log(e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user