mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-14 23:56:36 +08:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
a927b5ed21 | |||
642c97812c | |||
e43d3579de |
@ -33,7 +33,7 @@ Requires [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) to be ins
|
|||||||
* Simply browse through the scene, search for objects, etc, most of it is pretty self-explanatory.
|
* Simply browse through the scene, search for objects, etc, most of it is pretty self-explanatory.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
[](img.png)
|
[](overview.png)
|
||||||
|
|
||||||
<i>An overview of the different CppExplorer menus.</i>
|
<i>An overview of the different CppExplorer menus.</i>
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 524 KiB After Width: | Height: | Size: 523 KiB |
@ -44,12 +44,9 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== Abstract/Virtual Methods ===== //
|
|
||||||
|
|
||||||
public virtual void Init() { }
|
public virtual void Init() { }
|
||||||
public abstract void DrawValue(Rect window, float width);
|
|
||||||
|
|
||||||
// ===== Static Methods ===== //
|
public abstract void DrawValue(Rect window, float width);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get CacheObject from only an object instance
|
/// Get CacheObject from only an object instance
|
||||||
@ -205,11 +202,8 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
holder.m_argumentInput = new string[holder.m_arguments.Length];
|
holder.m_argumentInput = new string[holder.m_arguments.Length];
|
||||||
|
|
||||||
if (!holder.HasParameters)
|
holder.UpdateValue();
|
||||||
{
|
|
||||||
holder.UpdateValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.Init();
|
holder.Init();
|
||||||
|
|
||||||
@ -229,7 +223,18 @@ namespace Explorer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======== Instance Methods =========
|
public float CalcWhitespace(Rect window)
|
||||||
|
{
|
||||||
|
if (!(this is IExpandHeight)) return 0f;
|
||||||
|
|
||||||
|
float whitespace = (this as IExpandHeight).WhiteSpace;
|
||||||
|
if (whitespace > 0)
|
||||||
|
{
|
||||||
|
ClampLabelWidth(window, ref whitespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return whitespace;
|
||||||
|
}
|
||||||
|
|
||||||
public object[] ParseArguments()
|
public object[] ParseArguments()
|
||||||
{
|
{
|
||||||
@ -247,16 +252,20 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parsedArgs.Add(type.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(null, new object[] { input }));
|
parsedArgs.Add(type.GetMethod("Parse", new Type[] { typeof(string) })
|
||||||
|
.Invoke(null, new object[] { input }));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
//MelonLogger.Log($"Unable to parse '{input}' to type '{type.Name}'");
|
if (m_arguments[i].HasDefaultValue)
|
||||||
|
{
|
||||||
// try add a null arg i guess
|
parsedArgs.Add(m_arguments[i].DefaultValue);
|
||||||
parsedArgs.Add(null);
|
}
|
||||||
|
else
|
||||||
//break;
|
{
|
||||||
|
// Try add a null arg I guess
|
||||||
|
parsedArgs.Add(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,6 +280,12 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasParameters && !m_isEvaluating)
|
||||||
|
{
|
||||||
|
// Need to enter parameters first
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (MemInfo.MemberType == MemberTypes.Field)
|
if (MemInfo.MemberType == MemberTypes.Field)
|
||||||
@ -332,7 +347,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========= Instance Gui Draw ==========
|
// ========= Gui Draw ==========
|
||||||
|
|
||||||
public const float MAX_LABEL_WIDTH = 400f;
|
public const float MAX_LABEL_WIDTH = 400f;
|
||||||
public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>";
|
public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>";
|
||||||
@ -375,10 +390,18 @@ namespace Explorer
|
|||||||
var input = m_argumentInput[i];
|
var input = m_argumentInput[i];
|
||||||
var type = m_arguments[i].ParameterType.Name;
|
var type = m_arguments[i].ParameterType.Name;
|
||||||
|
|
||||||
|
var label = "<color=#2df7b2>" + type + "</color> <color=#a6e9e9>" + name + "</color>";
|
||||||
|
if (m_arguments[i].HasDefaultValue)
|
||||||
|
{
|
||||||
|
label = $"<i>[{label} = {m_arguments[i].DefaultValue}]</i>";
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(30) });
|
|
||||||
|
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(20) });
|
||||||
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
||||||
GUILayout.Label("<color=#2df7b2>" + type + "</color> <color=cyan>" + name + "</color>", null);
|
GUILayout.Label(label, null);
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +461,11 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
||||||
}
|
}
|
||||||
else if (Value == null && MemInfo?.MemberType != MemberTypes.Method)
|
else if ((HasParameters || this is CacheMethod) && !m_evaluated)
|
||||||
|
{
|
||||||
|
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)", null);
|
||||||
|
}
|
||||||
|
else if (Value == null && !(this is CacheMethod))
|
||||||
{
|
{
|
||||||
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
|
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
|
||||||
}
|
}
|
||||||
@ -463,7 +490,7 @@ namespace Explorer
|
|||||||
|
|
||||||
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
|
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
|
||||||
|
|
||||||
if (m_arguments.Length > 0)
|
if (m_arguments.Length > 0 || this is CacheMethod)
|
||||||
{
|
{
|
||||||
m_richTextName += "(";
|
m_richTextName += "(";
|
||||||
var _params = "";
|
var _params = "";
|
||||||
|
@ -9,8 +9,6 @@ namespace Explorer
|
|||||||
interface IExpandHeight
|
interface IExpandHeight
|
||||||
{
|
{
|
||||||
bool IsExpanded { get; set; }
|
bool IsExpanded { get; set; }
|
||||||
|
float WhiteSpace { get; set; }
|
||||||
float WhiteSpace { get; set; }
|
|
||||||
float ButtonWidthOffset { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,7 +15,6 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 350f;
|
|
||||||
|
|
||||||
public PageHelper Pages = new PageHelper();
|
public PageHelper Pages = new PageHelper();
|
||||||
|
|
||||||
@ -126,6 +125,10 @@ namespace Explorer
|
|||||||
m_keysType = type.GetGenericArguments()[0];
|
m_keysType = type.GetGenericArguments()[0];
|
||||||
m_valuesType = type.GetGenericArguments()[1];
|
m_valuesType = type.GetGenericArguments()[1];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MelonLogger.Log("TODO? Dictionary is of type: " + Value.GetType().FullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,11 +206,7 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float whitespace = WhiteSpace;
|
var whitespace = CalcWhitespace(window);
|
||||||
if (whitespace > 0)
|
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = m_cachedKeys.Length;
|
int count = m_cachedKeys.Length;
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 290f;
|
|
||||||
|
|
||||||
public PageHelper Pages = new PageHelper();
|
public PageHelper Pages = new PageHelper();
|
||||||
|
|
||||||
@ -245,11 +244,7 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float whitespace = WhiteSpace;
|
var whitespace = CalcWhitespace(window);
|
||||||
if (whitespace > 0)
|
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = m_cachedEntries.Length;
|
int count = m_cachedEntries.Length;
|
||||||
|
|
||||||
|
@ -44,11 +44,9 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var parsedArgs = ParseArguments();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, parsedArgs.ToArray());
|
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments());
|
||||||
m_evaluated = true;
|
m_evaluated = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -16,7 +16,6 @@ namespace Explorer
|
|||||||
|
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 290f;
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
@ -59,11 +58,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
float whitespace = WhiteSpace;
|
var whitespace = CalcWhitespace(window);
|
||||||
if (whitespace > 0)
|
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Space(whitespace);
|
GUILayout.Space(whitespace);
|
||||||
|
@ -15,7 +15,6 @@ namespace Explorer
|
|||||||
|
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 290f;
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
@ -54,11 +53,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
float whitespace = WhiteSpace;
|
var whitespace = CalcWhitespace(window);
|
||||||
if (whitespace > 0)
|
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Space(whitespace);
|
GUILayout.Space(whitespace);
|
||||||
|
@ -16,7 +16,6 @@ namespace Explorer
|
|||||||
|
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 290f;
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
@ -56,11 +55,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
float whitespace = WhiteSpace;
|
var whitespace = CalcWhitespace(window);
|
||||||
if (whitespace > 0)
|
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Space(whitespace);
|
GUILayout.Space(whitespace);
|
||||||
|
@ -21,7 +21,6 @@ namespace Explorer
|
|||||||
|
|
||||||
public bool IsExpanded { get; set; }
|
public bool IsExpanded { get; set; }
|
||||||
public float WhiteSpace { get; set; } = 215f;
|
public float WhiteSpace { get; set; } = 215f;
|
||||||
public float ButtonWidthOffset { get; set; } = 290f;
|
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
@ -90,11 +89,8 @@ namespace Explorer
|
|||||||
if (CanWrite && IsExpanded)
|
if (CanWrite && IsExpanded)
|
||||||
{
|
{
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
float whitespace = WhiteSpace;
|
|
||||||
if (whitespace > 0)
|
var whitespace = CalcWhitespace(window);
|
||||||
{
|
|
||||||
ClampLabelWidth(window, ref whitespace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// always draw x and y
|
// always draw x and y
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
|
@ -13,7 +13,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string NAME = "CppExplorer";
|
public const string NAME = "CppExplorer";
|
||||||
public const string VERSION = "1.6.5";
|
public const string VERSION = "1.6.7";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
|
|
||||||
@ -44,7 +44,11 @@ namespace Explorer
|
|||||||
UpdateCursorControl();
|
UpdateCursorControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== MonoBehaviour methods ==========
|
private static void SetForceUnlock(bool unlock)
|
||||||
|
{
|
||||||
|
m_forceUnlock = unlock;
|
||||||
|
UpdateCursorControl();
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnApplicationStart()
|
public override void OnApplicationStart()
|
||||||
{
|
{
|
||||||
@ -60,9 +64,9 @@ namespace Explorer
|
|||||||
m_lastVisibleState = Cursor.visible;
|
m_lastVisibleState = Cursor.visible;
|
||||||
|
|
||||||
// Enable ShowMenu and ForceUnlockMouse
|
// Enable ShowMenu and ForceUnlockMouse
|
||||||
// (set m_showMenu to not call UpdateCursorState twice)
|
// (set m_showMenu directly to not call UpdateCursorState twice)
|
||||||
m_showMenu = true;
|
m_showMenu = true;
|
||||||
SetForceUnlock(true);
|
ForceUnlockMouse = true;
|
||||||
|
|
||||||
MelonLogger.Log($"CppExplorer {VERSION} initialized.");
|
MelonLogger.Log($"CppExplorer {VERSION} initialized.");
|
||||||
}
|
}
|
||||||
@ -104,14 +108,6 @@ namespace Explorer
|
|||||||
InspectUnderMouse.OnGUI();
|
InspectUnderMouse.OnGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========== Cursor control ===========
|
|
||||||
|
|
||||||
private static void SetForceUnlock(bool unlock)
|
|
||||||
{
|
|
||||||
m_forceUnlock = unlock;
|
|
||||||
UpdateCursorControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateCursorControl()
|
private static void UpdateCursorControl()
|
||||||
{
|
{
|
||||||
m_currentlySettingCursor = true;
|
m_currentlySettingCursor = true;
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Helpers\IExpandHeight.cs" />
|
<Compile Include="CachedObjects\IExpandHeight.cs" />
|
||||||
<Compile Include="CachedObjects\Struct\CacheColor.cs" />
|
<Compile Include="CachedObjects\Struct\CacheColor.cs" />
|
||||||
<Compile Include="CachedObjects\Object\CacheDictionary.cs" />
|
<Compile Include="CachedObjects\Object\CacheDictionary.cs" />
|
||||||
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
|
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
|
||||||
|
@ -14,21 +14,7 @@ namespace Explorer.Tests
|
|||||||
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
|
||||||
private static TestClass m_instance;
|
private static TestClass m_instance;
|
||||||
|
|
||||||
public string this[int index]
|
// Test indexed parameter
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return $"int indexer: {index}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string this[string stringIndex]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return $"string indexer: {stringIndex}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string this[int arg0, string arg1]
|
public string this[int arg0, string arg1]
|
||||||
{
|
{
|
||||||
@ -38,6 +24,8 @@ namespace Explorer.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test basic list
|
||||||
|
|
||||||
public static List<string> TestList = new List<string>
|
public static List<string> TestList = new List<string>
|
||||||
{
|
{
|
||||||
"1",
|
"1",
|
||||||
@ -46,29 +34,48 @@ namespace Explorer.Tests
|
|||||||
"etc..."
|
"etc..."
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Dictionary<int, List<string>> NestedDictionary = new Dictionary<int, List<string>>
|
// Test a nested dictionary
|
||||||
|
|
||||||
|
public static Dictionary<int, Dictionary<string, int>> NestedDictionary = new Dictionary<int, Dictionary<string, int>>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
123,
|
1,
|
||||||
new List<string>
|
new Dictionary<string, int>
|
||||||
{
|
{
|
||||||
"One",
|
{
|
||||||
"Two"
|
"Sub 1", 123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sub 2", 456
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
567,
|
2,
|
||||||
new List<string>
|
new Dictionary<string, int>
|
||||||
{
|
{
|
||||||
"One",
|
{
|
||||||
"Two"
|
"Sub 3", 789
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sub 4", 000
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Test a basic method
|
||||||
|
|
||||||
public static Color TestMethod(float r, float g, float b, float a)
|
public static Color TestMethod(float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
return new Color(r, g, b, a);
|
return new Color(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A method with default arguments
|
||||||
|
|
||||||
|
public static Vector3 TestDefaultArgs(float arg0, float arg1, float arg2 = 5.0f)
|
||||||
|
{
|
||||||
|
return new Vector3(arg0, arg1, arg2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,20 +28,26 @@ namespace Explorer
|
|||||||
public MemberTypes m_filter = MemberTypes.Property;
|
public MemberTypes m_filter = MemberTypes.Property;
|
||||||
private bool m_hideFailedReflection = false;
|
private bool m_hideFailedReflection = false;
|
||||||
|
|
||||||
// some extra caching
|
// some extra cast-caching
|
||||||
private UnityEngine.Object m_uObj;
|
private UnityEngine.Object m_uObj;
|
||||||
private Component m_component;
|
private Component m_component;
|
||||||
|
|
||||||
|
private static readonly HashSet<string> _memberBlacklist = new HashSet<string>
|
||||||
|
{
|
||||||
|
// Causes a crash
|
||||||
|
"Type.DeclaringMethod",
|
||||||
|
// Pointless (handled by Properties)
|
||||||
|
"get_",
|
||||||
|
"set_"
|
||||||
|
};
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
var type = ReflectionHelpers.GetActualType(Target);
|
TargetType = ReflectionHelpers.GetActualType(Target);
|
||||||
|
|
||||||
TargetType = type;
|
CacheMembers(ReflectionHelpers.GetAllBaseTypes(Target));
|
||||||
|
|
||||||
var types = ReflectionHelpers.GetAllBaseTypes(Target);
|
|
||||||
|
|
||||||
CacheMembers(types);
|
|
||||||
|
|
||||||
|
// cache the extra cast-caching
|
||||||
if (Target is Il2CppSystem.Object ilObject)
|
if (Target is Il2CppSystem.Object ilObject)
|
||||||
{
|
{
|
||||||
var unityObj = ilObject.TryCast<UnityEngine.Object>();
|
var unityObj = ilObject.TryCast<UnityEngine.Object>();
|
||||||
@ -56,13 +62,6 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_filter = MemberTypes.All;
|
|
||||||
m_autoUpdate = true;
|
|
||||||
Update();
|
|
||||||
|
|
||||||
m_autoUpdate = false;
|
|
||||||
m_filter = MemberTypes.Property;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
@ -99,28 +98,32 @@ namespace Explorer
|
|||||||
|
|
||||||
private bool ShouldProcessMember(CacheObjectBase holder)
|
private bool ShouldProcessMember(CacheObjectBase holder)
|
||||||
{
|
{
|
||||||
if (m_filter != MemberTypes.All && m_filter != holder.MemInfo?.MemberType) return false;
|
// check MemberTypes filter
|
||||||
|
if (m_filter != MemberTypes.All && m_filter != holder.MemInfo?.MemberType)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(holder.ReflectionException) && m_hideFailedReflection) return false;
|
// hide failed reflection
|
||||||
|
if (!string.IsNullOrEmpty(holder.ReflectionException) && m_hideFailedReflection)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (m_search == "" || holder.MemInfo == null) return true;
|
// see if we should do name search
|
||||||
|
if (m_search == "" || holder.MemInfo == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
var name = holder.MemInfo.DeclaringType.Name + "." + holder.MemInfo.Name;
|
// ok do name search
|
||||||
|
return (holder.MemInfo.DeclaringType.Name + "." + holder.MemInfo.Name)
|
||||||
return name.ToLower().Contains(m_search.ToLower());
|
.ToLower()
|
||||||
|
.Contains(m_search.ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CacheMembers(Type[] types)
|
private void CacheMembers(Type[] types)
|
||||||
{
|
{
|
||||||
var list = new List<CacheObjectBase>();
|
var list = new List<CacheObjectBase>();
|
||||||
|
var cachedSigs = new List<string>();
|
||||||
var names = new List<string>();
|
|
||||||
|
|
||||||
foreach (var declaringType in types)
|
foreach (var declaringType in types)
|
||||||
{
|
{
|
||||||
MemberInfo[] infos;
|
MemberInfo[] infos;
|
||||||
string exception = null;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
infos = declaringType.GetMembers(ReflectionHelpers.CommonFlags);
|
infos = declaringType.GetMembers(ReflectionHelpers.CommonFlags);
|
||||||
@ -132,6 +135,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
object target = Target;
|
object target = Target;
|
||||||
|
string exception = null;
|
||||||
|
|
||||||
if (target is Il2CppSystem.Object ilObject)
|
if (target is Il2CppSystem.Object ilObject)
|
||||||
{
|
{
|
||||||
@ -147,56 +151,56 @@ namespace Explorer
|
|||||||
|
|
||||||
foreach (var member in infos)
|
foreach (var member in infos)
|
||||||
{
|
{
|
||||||
if (member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property || member.MemberType == MemberTypes.Method)
|
// make sure member type is Field, Method of Property (4 / 8 / 16)
|
||||||
|
int m = (int)member.MemberType;
|
||||||
|
if (m < 4 || m > 16)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// check blacklisted members
|
||||||
|
if (_memberBlacklist.Any(it => member.Name.StartsWith(it)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// compare signature to already cached members
|
||||||
|
var signature = $"{member.DeclaringType.Name}.{member.Name}";
|
||||||
|
if (member is MethodInfo mi)
|
||||||
{
|
{
|
||||||
var name = $"{member.DeclaringType.Name}.{member.Name}";
|
AppendParams(mi.GetParameters());
|
||||||
|
}
|
||||||
|
else if (member is PropertyInfo pi)
|
||||||
|
{
|
||||||
|
AppendParams(pi.GetIndexParameters());
|
||||||
|
}
|
||||||
|
|
||||||
// blacklist (should probably make a proper implementation)
|
void AppendParams(ParameterInfo[] _args)
|
||||||
if (name == "Type.DeclaringMethod" || member.Name.StartsWith("get_") || member.Name.StartsWith("set_")) //|| member.Name.Contains("Il2CppType")
|
{
|
||||||
|
signature += " (";
|
||||||
|
foreach (var param in _args)
|
||||||
{
|
{
|
||||||
continue;
|
signature += $"{param.ParameterType.Name} {param.Name}, ";
|
||||||
}
|
}
|
||||||
|
signature += ")";
|
||||||
|
}
|
||||||
|
|
||||||
if (member is MethodInfo mi)
|
if (cachedSigs.Contains(signature))
|
||||||
{
|
{
|
||||||
name += " (";
|
continue;
|
||||||
foreach (var param in mi.GetParameters())
|
}
|
||||||
{
|
|
||||||
name += $"{param.ParameterType.Name} {param.Name}, ";
|
|
||||||
}
|
|
||||||
name += ")";
|
|
||||||
}
|
|
||||||
else if (member is PropertyInfo pi)
|
|
||||||
{
|
|
||||||
name += " (";
|
|
||||||
foreach (var param in pi.GetIndexParameters())
|
|
||||||
{
|
|
||||||
name += $"{param.ParameterType.Name} {param.Name}, ";
|
|
||||||
}
|
|
||||||
name += ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (names.Contains(name))
|
try
|
||||||
|
{
|
||||||
|
var cached = CacheObjectBase.GetCacheObject(member, target);
|
||||||
|
if (cached != null)
|
||||||
{
|
{
|
||||||
continue;
|
cachedSigs.Add(signature);
|
||||||
}
|
list.Add(cached);
|
||||||
|
cached.ReflectionException = exception;
|
||||||
try
|
|
||||||
{
|
|
||||||
var cached = CacheObjectBase.GetCacheObject(member, target);
|
|
||||||
if (cached != null)
|
|
||||||
{
|
|
||||||
names.Add(name);
|
|
||||||
list.Add(cached);
|
|
||||||
cached.ReflectionException = exception;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
MelonLogger.LogWarning($"Exception caching member {name}!");
|
|
||||||
MelonLogger.Log(e.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MelonLogger.LogWarning($"Exception caching member {signature}!");
|
||||||
|
MelonLogger.Log(e.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user