mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-27 02:22:33 +08:00
Fix strings boxed as Il2CppSystem.Objects
This commit is contained in:
@ -154,21 +154,24 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
/// <returns>The object, as the type (or a normal C# object) if successful or the input value if not.</returns>
|
/// <returns>The object, as the type (or a normal C# object) if successful or the input value if not.</returns>
|
||||||
public static object Il2CppCast(object obj, Type castTo)
|
public static object Il2CppCast(object obj, Type castTo)
|
||||||
{
|
{
|
||||||
if (!(obj is Il2CppSystem.Object ilObj))
|
if (!(obj is Il2CppSystem.Object cppObj))
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
if (!Il2CppTypeNotNull(castTo, out IntPtr castToPtr))
|
if (!Il2CppTypeNotNull(castTo, out IntPtr castToPtr))
|
||||||
return obj;
|
return obj;
|
||||||
|
|
||||||
IntPtr castFromPtr = il2cpp_object_get_class(ilObj.Pointer);
|
IntPtr castFromPtr = il2cpp_object_get_class(cppObj.Pointer);
|
||||||
|
|
||||||
if (!il2cpp_class_is_assignable_from(castToPtr, castFromPtr))
|
if (!il2cpp_class_is_assignable_from(castToPtr, castFromPtr))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (RuntimeSpecificsStore.IsInjected(castToPtr))
|
if (RuntimeSpecificsStore.IsInjected(castToPtr))
|
||||||
return UnhollowerBaseLib.Runtime.ClassInjectorBase.GetMonoObjectFromIl2CppPointer(ilObj.Pointer);
|
return UnhollowerBaseLib.Runtime.ClassInjectorBase.GetMonoObjectFromIl2CppPointer(cppObj.Pointer);
|
||||||
|
|
||||||
return Activator.CreateInstance(castTo, ilObj.Pointer);
|
if (castTo == typeof(string))
|
||||||
|
return cppObj.ToString();
|
||||||
|
|
||||||
|
return Activator.CreateInstance(castTo, cppObj.Pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -319,6 +322,14 @@ namespace UnityExplorer.Core.Runtime.Il2Cpp
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void BoxStringToType(ref object value, Type castTo)
|
||||||
|
{
|
||||||
|
if (castTo == typeof(Il2CppSystem.String))
|
||||||
|
value = (Il2CppSystem.String)(value as string);
|
||||||
|
else
|
||||||
|
value = (Il2CppSystem.Object)(value as string);
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~ not used ~~~~~~~~~~~~
|
// ~~~~~~~~~~ not used ~~~~~~~~~~~~
|
||||||
|
|
||||||
// cached il2cpp unbox methods
|
// cached il2cpp unbox methods
|
||||||
|
@ -27,6 +27,9 @@ namespace UnityExplorer.Core.Runtime.Mono
|
|||||||
|
|
||||||
public override string ProcessTypeNameInString(Type type, string theString, ref string typeName)
|
public override string ProcessTypeNameInString(Type type, string theString, ref string typeName)
|
||||||
=> theString;
|
=> theString;
|
||||||
|
|
||||||
|
// not necessary
|
||||||
|
public override void BoxStringToType(ref object _string, Type castTo) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,5 +25,7 @@ namespace UnityExplorer.Core.Runtime
|
|||||||
public abstract string ProcessTypeNameInString(Type type, string theString, ref string typeName);
|
public abstract string ProcessTypeNameInString(Type type, string theString, ref string typeName);
|
||||||
|
|
||||||
public abstract bool LoadModule(string module);
|
public abstract bool LoadModule(string module);
|
||||||
|
|
||||||
|
public abstract void BoxStringToType(ref object _string, Type castTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,14 @@ using System.Text;
|
|||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
{
|
{
|
||||||
#if CPP
|
|
||||||
public static class TestClass
|
public static class TestClass
|
||||||
{
|
{
|
||||||
|
#if CPP
|
||||||
|
public static string testStringOne = "Test";
|
||||||
|
public static Il2CppSystem.Object testStringTwo = "string boxed as cpp object";
|
||||||
|
public static Il2CppSystem.String testStringThree = "string boxed as cpp string";
|
||||||
|
public static string nullString = null;
|
||||||
|
|
||||||
public static Il2CppSystem.Collections.Hashtable testHashset;
|
public static Il2CppSystem.Collections.Hashtable testHashset;
|
||||||
|
|
||||||
static TestClass()
|
static TestClass()
|
||||||
@ -17,6 +22,6 @@ namespace UnityExplorer
|
|||||||
testHashset.Add("key2", "itemTwo");
|
testHashset.Add("key2", "itemTwo");
|
||||||
testHashset.Add("key3", "itemThree");
|
testHashset.Add("key3", "itemThree");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using UnityExplorer.Core.Config;
|
|||||||
using UnityExplorer.Core.Input;
|
using UnityExplorer.Core.Input;
|
||||||
using UnityExplorer.Core.Runtime;
|
using UnityExplorer.Core.Runtime;
|
||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
|
using UnityExplorer.UI.Inspectors;
|
||||||
using UnityExplorer.UI.Main;
|
using UnityExplorer.UI.Main;
|
||||||
|
|
||||||
namespace UnityExplorer
|
namespace UnityExplorer
|
||||||
@ -12,7 +13,7 @@ namespace UnityExplorer
|
|||||||
public class ExplorerCore
|
public class ExplorerCore
|
||||||
{
|
{
|
||||||
public const string NAME = "UnityExplorer";
|
public const string NAME = "UnityExplorer";
|
||||||
public const string VERSION = "3.3.5";
|
public const string VERSION = "3.3.6";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.unityexplorer";
|
public const string GUID = "com.sinai.unityexplorer";
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using UnityExplorer.Core.Unity;
|
|||||||
using UnityExplorer.UI;
|
using UnityExplorer.UI;
|
||||||
using UnityExplorer.UI.Utility;
|
using UnityExplorer.UI.Utility;
|
||||||
using UnityExplorer.UI.CacheObject;
|
using UnityExplorer.UI.CacheObject;
|
||||||
|
using UnityExplorer.Core.Runtime;
|
||||||
|
|
||||||
namespace UnityExplorer.UI.InteractiveValues
|
namespace UnityExplorer.UI.InteractiveValues
|
||||||
{
|
{
|
||||||
@ -27,8 +28,8 @@ namespace UnityExplorer.UI.InteractiveValues
|
|||||||
// strings boxed as Il2CppSystem.Objects can behave weirdly.
|
// strings boxed as Il2CppSystem.Objects can behave weirdly.
|
||||||
// GetActualType will find they are a string, but if its boxed
|
// GetActualType will find they are a string, but if its boxed
|
||||||
// then we need to unbox it like this...
|
// then we need to unbox it like this...
|
||||||
if (!(Value is string))
|
if (!(Value is string) && Value is Il2CppSystem.Object cppobj)
|
||||||
Value = ((Il2CppSystem.Object)Value).ToString();
|
Value = cppobj.ToString();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base.OnValueUpdated();
|
base.OnValueUpdated();
|
||||||
@ -96,10 +97,18 @@ namespace UnityExplorer.UI.InteractiveValues
|
|||||||
m_labelLayout.flexibleWidth = 0;
|
m_labelLayout.flexibleWidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnApplyClicked()
|
internal void SetValueFromInput()
|
||||||
{
|
{
|
||||||
Value = m_valueInput.text;
|
Value = m_valueInput.text;
|
||||||
|
|
||||||
|
if (!typeof(string).IsAssignableFrom(Owner.FallbackType))
|
||||||
|
ReflectionProvider.Instance.BoxStringToType(ref Value, Owner.FallbackType);
|
||||||
|
|
||||||
Owner.SetValue();
|
Owner.SetValue();
|
||||||
|
|
||||||
|
// revert back to string now
|
||||||
|
OnValueUpdated();
|
||||||
|
|
||||||
RefreshUIForValue();
|
RefreshUIForValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +179,7 @@ namespace UnityExplorer.UI.InteractiveValues
|
|||||||
|
|
||||||
if (Owner.CanWrite)
|
if (Owner.CanWrite)
|
||||||
{
|
{
|
||||||
var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", OnApplyClicked, new Color(0.2f, 0.2f, 0.2f));
|
var apply = UIFactory.CreateButton(groupObj, "ApplyButton", "Apply", SetValueFromInput, new Color(0.2f, 0.2f, 0.2f));
|
||||||
UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
|
UIFactory.SetLayoutElement(apply.gameObject, minWidth: 50, minHeight: 25, flexibleWidth: 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user