mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-16 22:27:45 +08:00
1.6.2
* Fix for a crash that can occur when inspecting unsupported Dictionaries * Added a scroll bar to the REPL console input area, fixes the issue of the code just being cut off when it goes too long.
This commit is contained in:
parent
72d31eaa64
commit
56d1507aff
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using UnhollowerBaseLib;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -130,6 +131,13 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
|
// first make sure we won't run into a TypeInitializationException.
|
||||||
|
if (!EnsureDictionaryIsSupported())
|
||||||
|
{
|
||||||
|
ReflectionException = "Dictionary Type not supported with Reflection!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
@ -160,6 +168,86 @@ namespace Explorer
|
|||||||
m_cachedValues = values.ToArray();
|
m_cachedValues = values.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool EnsureDictionaryIsSupported()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//var ilTypes = new List<Il2CppSystem.Type>();
|
||||||
|
var monoTypes = new Type[] { TypeOfKeys, TypeOfValues };
|
||||||
|
|
||||||
|
foreach (var type in monoTypes)
|
||||||
|
{
|
||||||
|
var generic = typeof(Il2CppClassPointerStore<>).MakeGenericType(type);
|
||||||
|
if (generic == null) return false;
|
||||||
|
|
||||||
|
var genericPtr = (IntPtr)generic.GetField("NativeClassPtr").GetValue(null);
|
||||||
|
if (genericPtr == null) return false;
|
||||||
|
|
||||||
|
var classPtr = IL2CPP.il2cpp_class_get_type(genericPtr);
|
||||||
|
if (classPtr == null) return false;
|
||||||
|
|
||||||
|
var internalType = Il2CppSystem.Type.internal_from_handle(classPtr);
|
||||||
|
if (internalType == null) return false;
|
||||||
|
|
||||||
|
//ilTypes.Add(internalType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should be fine if we got this far, but I'll leave the rest below commented out just in case.
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Got both generic types, continuing...");
|
||||||
|
|
||||||
|
//var dictIlClass = IL2CPP.GetIl2CppClass("mscorlib.dll", "System.Collections.Generic", "Dictionary`2");
|
||||||
|
//if (dictIlClass == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Got base dictionary Il2Cpp type");
|
||||||
|
|
||||||
|
//var ilClassFromType = IL2CPP.il2cpp_class_get_type(dictIlClass);
|
||||||
|
//if (ilClassFromType == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("got IntPtr from base dictionary type");
|
||||||
|
|
||||||
|
//var internalHandle = Il2CppSystem.Type.internal_from_handle(ilClassFromType);
|
||||||
|
//if (internalHandle == null) return;
|
||||||
|
|
||||||
|
//var generic = internalHandle.MakeGenericType(new Il2CppReferenceArray<Il2CppSystem.Type>(new Il2CppSystem.Type[]
|
||||||
|
//{
|
||||||
|
// ilTypes[0], ilTypes[1]
|
||||||
|
//}));
|
||||||
|
//if (generic == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Made generic handle for our entry types");
|
||||||
|
|
||||||
|
//var nativeClassPtr = generic.TypeHandle.value;
|
||||||
|
//if (nativeClassPtr == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Got the actual nativeClassPtr for the handle");
|
||||||
|
|
||||||
|
//var dictType = typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).MakeGenericType(TypeOfKeys, TypeOfValues);
|
||||||
|
//if (dictType == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Made the generic type for the dictionary");
|
||||||
|
|
||||||
|
//var pointerStoreType = typeof(Il2CppClassPointerStore<>).MakeGenericType(dictType);
|
||||||
|
//if (pointerStoreType == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Made the generic PointerStoreType for our dict");
|
||||||
|
|
||||||
|
//var ptrToSet = IL2CPP.il2cpp_class_from_type(nativeClassPtr);
|
||||||
|
//if (ptrToSet == null) return;
|
||||||
|
|
||||||
|
//MelonLogger.Log("Got class from nativeClassPtr, setting value...");
|
||||||
|
|
||||||
|
//pointerStoreType.GetField("NativeClassPtr").SetValue(null, ptrToSet);
|
||||||
|
|
||||||
|
//MelonLogger.Log("Ok");
|
||||||
|
}
|
||||||
|
|
||||||
// ============= GUI Draw =============
|
// ============= GUI Draw =============
|
||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
|
@ -19,6 +19,8 @@ namespace Explorer
|
|||||||
private ScriptEvaluator _evaluator;
|
private ScriptEvaluator _evaluator;
|
||||||
private readonly StringBuilder _sb = new StringBuilder();
|
private readonly StringBuilder _sb = new StringBuilder();
|
||||||
|
|
||||||
|
private Vector2 inputAreaScroll;
|
||||||
|
|
||||||
private string MethodInput = "";
|
private string MethodInput = "";
|
||||||
private string UsingInput = "";
|
private string UsingInput = "";
|
||||||
|
|
||||||
@ -124,7 +126,12 @@ MelonLogger.Log(""hello world"");";
|
|||||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||||
|
|
||||||
GUILayout.Label("Enter code here as though it is a method body:", null);
|
GUILayout.Label("Enter code here as though it is a method body:", null);
|
||||||
MethodInput = GUILayout.TextArea(MethodInput, new GUILayoutOption[] { GUILayout.Height(250) });
|
|
||||||
|
inputAreaScroll = GUIUnstrip.BeginScrollView(inputAreaScroll, new GUILayoutOption[] { GUILayout.Height(250) });
|
||||||
|
|
||||||
|
MethodInput = GUILayout.TextArea(MethodInput, new GUILayoutOption[] { GUILayout.ExpandHeight(true) });
|
||||||
|
|
||||||
|
GUIUnstrip.EndScrollView();
|
||||||
|
|
||||||
if (GUILayout.Button("<color=cyan><b>Execute</b></color>", null))
|
if (GUILayout.Button("<color=cyan><b>Execute</b></color>", null))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user