mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-15 15:57:52 +08:00
Enum parse support, start work on CSConsole, cleanup
This commit is contained in:
@ -1,76 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Mono.CSharp;
|
||||
|
||||
// Thanks to ManlyMarco for most of this
|
||||
|
||||
namespace UnityExplorer.Core.CSharp
|
||||
{
|
||||
public class ScriptEvaluator : Evaluator, IDisposable
|
||||
{
|
||||
private static readonly HashSet<string> StdLib = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase)
|
||||
{
|
||||
"mscorlib", "System.Core", "System", "System.Xml"
|
||||
};
|
||||
|
||||
internal static TextWriter _textWriter;
|
||||
internal static StreamReportPrinter _reportPrinter;
|
||||
|
||||
public ScriptEvaluator(TextWriter tw) : base(BuildContext(tw))
|
||||
{
|
||||
_textWriter = tw;
|
||||
|
||||
ImportAppdomainAssemblies(ReferenceAssembly);
|
||||
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
|
||||
_textWriter.Dispose();
|
||||
}
|
||||
|
||||
private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
|
||||
{
|
||||
string name = args.LoadedAssembly.GetName().Name;
|
||||
|
||||
if (StdLib.Contains(name))
|
||||
return;
|
||||
|
||||
ReferenceAssembly(args.LoadedAssembly);
|
||||
}
|
||||
|
||||
private static CompilerContext BuildContext(TextWriter tw)
|
||||
{
|
||||
_reportPrinter = new StreamReportPrinter(tw);
|
||||
|
||||
var settings = new CompilerSettings
|
||||
{
|
||||
Version = LanguageVersion.Experimental,
|
||||
GenerateDebugInfo = false,
|
||||
StdLib = true,
|
||||
Target = Target.Library,
|
||||
WarningLevel = 0,
|
||||
EnhancedWarnings = false
|
||||
};
|
||||
|
||||
return new CompilerContext(settings, _reportPrinter);
|
||||
}
|
||||
|
||||
private static void ImportAppdomainAssemblies(Action<Assembly> import)
|
||||
{
|
||||
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
string name = assembly.GetName().Name;
|
||||
if (StdLib.Contains(name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
import(assembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using Mono.CSharp;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityExplorer.Core.Runtime;
|
||||
|
||||
namespace UnityExplorer.Core.CSharp
|
||||
{
|
||||
public class ScriptInteraction : InteractiveBase
|
||||
{
|
||||
public static void Log(object message)
|
||||
{
|
||||
ExplorerCore.Log(message);
|
||||
}
|
||||
|
||||
public static void StartCoroutine(IEnumerator ienumerator)
|
||||
{
|
||||
RuntimeProvider.Instance.StartCoroutine(ienumerator);
|
||||
}
|
||||
|
||||
//public static void AddUsing(string directive)
|
||||
//{
|
||||
// CSharpConsole.Instance.AddUsing(directive);
|
||||
//}
|
||||
|
||||
//public static void GetUsing()
|
||||
//{
|
||||
// ExplorerCore.Log(CSharpConsole.Instance.Evaluator.GetUsing());
|
||||
//}
|
||||
|
||||
//public static void Reset()
|
||||
//{
|
||||
// CSharpConsole.Instance.ResetConsole();
|
||||
//}
|
||||
|
||||
//public static object CurrentTarget()
|
||||
//{
|
||||
// return InspectorManager.Instance?.m_activeInspector?.Target;
|
||||
//}
|
||||
|
||||
//public static object[] AllTargets()
|
||||
//{
|
||||
// int count = InspectorManager.Instance?.m_currentInspectors.Count ?? 0;
|
||||
// object[] ret = new object[count];
|
||||
// for (int i = 0; i < count; i++)
|
||||
// {
|
||||
// ret[i] = InspectorManager.Instance?.m_currentInspectors[i].Target;
|
||||
// }
|
||||
// return ret;
|
||||
//}
|
||||
|
||||
//public static void Inspect(object obj)
|
||||
//{
|
||||
// InspectorManager.Instance.Inspect(obj);
|
||||
//}
|
||||
|
||||
//public static void Inspect(Type type)
|
||||
//{
|
||||
// InspectorManager.Instance.Inspect(type);
|
||||
//}
|
||||
}
|
||||
}
|
151
src/Core/InspectorManager.cs
Normal file
151
src/Core/InspectorManager.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.UI;
|
||||
using UnityExplorer.UI.CacheObject;
|
||||
using UnityExplorer.UI.Inspectors;
|
||||
using UnityExplorer.UI.ObjectPool;
|
||||
using UnityExplorer.UI.Panels;
|
||||
|
||||
namespace UnityExplorer
|
||||
{
|
||||
public static class InspectorManager
|
||||
{
|
||||
public static readonly List<InspectorBase> Inspectors = new List<InspectorBase>();
|
||||
|
||||
public static InspectorBase ActiveInspector { get; private set; }
|
||||
private static InspectorBase lastActiveInspector;
|
||||
|
||||
public static float PanelWidth;
|
||||
|
||||
public static void Inspect(object obj, CacheObjectBase sourceCache = null)
|
||||
{
|
||||
if (obj.IsNullOrDestroyed())
|
||||
return;
|
||||
|
||||
obj = obj.TryCast();
|
||||
|
||||
if (TryFocusActiveInspector(obj))
|
||||
return;
|
||||
|
||||
if (obj is GameObject)
|
||||
CreateInspector<GameObjectInspector>(obj);
|
||||
else
|
||||
CreateInspector<ReflectionInspector>(obj, false, sourceCache);
|
||||
}
|
||||
|
||||
private static bool TryFocusActiveInspector(object target)
|
||||
{
|
||||
foreach (var inspector in Inspectors)
|
||||
{
|
||||
if (inspector.Target.ReferenceEqual(target))
|
||||
{
|
||||
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
|
||||
SetInspectorActive(inspector);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Inspect(Type type)
|
||||
{
|
||||
CreateInspector<ReflectionInspector>(type, true);
|
||||
}
|
||||
|
||||
public static void SetInspectorActive(InspectorBase inspector)
|
||||
{
|
||||
UnsetActiveInspector();
|
||||
|
||||
ActiveInspector = inspector;
|
||||
inspector.OnSetActive();
|
||||
}
|
||||
|
||||
public static void UnsetActiveInspector()
|
||||
{
|
||||
if (ActiveInspector != null)
|
||||
{
|
||||
lastActiveInspector = ActiveInspector;
|
||||
ActiveInspector.OnSetInactive();
|
||||
ActiveInspector = null;
|
||||
}
|
||||
}
|
||||
private static void CreateInspector<T>(object target, bool staticReflection = false, CacheObjectBase sourceCache = null) where T : InspectorBase
|
||||
{
|
||||
var inspector = Pool<T>.Borrow();
|
||||
Inspectors.Add(inspector);
|
||||
inspector.Target = target;
|
||||
|
||||
if (sourceCache != null && sourceCache.CanWrite)
|
||||
{
|
||||
// only set parent cache object if we are inspecting a struct, otherwise there is no point.
|
||||
if (target.GetType().IsValueType && inspector is ReflectionInspector ri)
|
||||
ri.ParentCacheObject = sourceCache;
|
||||
}
|
||||
|
||||
UIManager.SetPanelActive(UIManager.Panels.Inspector, true);
|
||||
inspector.UIRoot.transform.SetParent(InspectorPanel.Instance.ContentHolder.transform, false);
|
||||
|
||||
if (inspector is ReflectionInspector reflectInspector)
|
||||
reflectInspector.StaticOnly = staticReflection;
|
||||
|
||||
inspector.OnBorrowedFromPool(target);
|
||||
SetInspectorActive(inspector);
|
||||
}
|
||||
|
||||
internal static void ReleaseInspector<T>(T inspector) where T : InspectorBase
|
||||
{
|
||||
if (lastActiveInspector == inspector)
|
||||
lastActiveInspector = null;
|
||||
|
||||
bool wasActive = ActiveInspector == inspector;
|
||||
int wasIdx = Inspectors.IndexOf(inspector);
|
||||
|
||||
Inspectors.Remove(inspector);
|
||||
inspector.OnReturnToPool();
|
||||
Pool<T>.Return(inspector);
|
||||
|
||||
if (wasActive)
|
||||
{
|
||||
ActiveInspector = null;
|
||||
// Try focus another inspector, or close the window.
|
||||
if (lastActiveInspector != null)
|
||||
{
|
||||
SetInspectorActive(lastActiveInspector);
|
||||
lastActiveInspector = null;
|
||||
}
|
||||
else if (Inspectors.Any())
|
||||
{
|
||||
int newIdx = Math.Min(Inspectors.Count - 1, Math.Max(0, wasIdx - 1));
|
||||
SetInspectorActive(Inspectors[newIdx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIManager.SetPanelActive(UIManager.Panels.Inspector, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Update()
|
||||
{
|
||||
for (int i = Inspectors.Count - 1; i >= 0; i--)
|
||||
Inspectors[i].Update();
|
||||
}
|
||||
|
||||
internal static void OnPanelResized(float width)
|
||||
{
|
||||
PanelWidth = width;
|
||||
|
||||
foreach (var obj in Inspectors)
|
||||
{
|
||||
if (obj is ReflectionInspector inspector)
|
||||
{
|
||||
inspector.SetLayouts();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
public enum ChildFilter
|
||||
{
|
||||
Any,
|
||||
RootObject,
|
||||
HasParent
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
public enum SceneFilter
|
||||
{
|
||||
Any,
|
||||
ActivelyLoaded,
|
||||
DontDestroyOnLoad,
|
||||
HideAndDontSave,
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
public enum SearchContext
|
||||
{
|
||||
UnityObject,
|
||||
GameObject,
|
||||
//Component,
|
||||
//Custom,
|
||||
Singleton,
|
||||
StaticClass
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityExplorer.Core.Runtime;
|
||||
|
||||
namespace UnityExplorer.Core.Search
|
||||
{
|
||||
public static class SearchProvider
|
||||
{
|
||||
|
||||
private static bool Filter(Scene scene, SceneFilter filter)
|
||||
{
|
||||
switch (filter)
|
||||
{
|
||||
case SceneFilter.Any:
|
||||
return true;
|
||||
case SceneFilter.DontDestroyOnLoad:
|
||||
return scene == SceneHandler.DontDestroyScene;
|
||||
case SceneFilter.HideAndDontSave:
|
||||
return scene == SceneHandler.AssetScene;
|
||||
case SceneFilter.ActivelyLoaded:
|
||||
return scene != SceneHandler.DontDestroyScene && scene != SceneHandler.AssetScene;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<object> UnityObjectSearch(string input, string customTypeInput, SearchContext context,
|
||||
ChildFilter childFilter, SceneFilter sceneFilter)
|
||||
{
|
||||
var results = new List<object>();
|
||||
|
||||
Type searchType;
|
||||
switch (context)
|
||||
{
|
||||
case SearchContext.GameObject:
|
||||
searchType = typeof(GameObject);
|
||||
break;
|
||||
|
||||
case SearchContext.UnityObject:
|
||||
default:
|
||||
|
||||
if (!string.IsNullOrEmpty(customTypeInput))
|
||||
{
|
||||
if (ReflectionUtility.GetTypeByName(customTypeInput) is Type customType)
|
||||
{
|
||||
if (typeof(UnityEngine.Object).IsAssignableFrom(customType))
|
||||
{
|
||||
searchType = customType;
|
||||
break;
|
||||
}
|
||||
else
|
||||
ExplorerCore.LogWarning($"Custom type '{customType.FullName}' is not assignable from UnityEngine.Object!");
|
||||
}
|
||||
else
|
||||
ExplorerCore.LogWarning($"Could not find any type by name '{customTypeInput}'!");
|
||||
}
|
||||
|
||||
searchType = typeof(UnityEngine.Object);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (searchType == null)
|
||||
return results;
|
||||
|
||||
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(searchType);
|
||||
|
||||
// perform filter comparers
|
||||
|
||||
string nameFilter = null;
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input;
|
||||
|
||||
bool canGetGameObject = context == SearchContext.GameObject || typeof(Component).IsAssignableFrom(searchType);
|
||||
|
||||
foreach (var obj in allObjects)
|
||||
{
|
||||
// name check
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !obj.name.ContainsIgnoreCase(nameFilter))
|
||||
continue;
|
||||
|
||||
if (canGetGameObject)
|
||||
{
|
||||
var go = context == SearchContext.GameObject
|
||||
? obj.TryCast<GameObject>()
|
||||
: obj.TryCast<Component>().gameObject;
|
||||
|
||||
if (go)
|
||||
{
|
||||
// scene check
|
||||
if (sceneFilter != SceneFilter.Any)
|
||||
{
|
||||
if (!Filter(go.scene, sceneFilter))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (childFilter != ChildFilter.Any)
|
||||
{
|
||||
if (!go)
|
||||
continue;
|
||||
|
||||
// root object check (no parent)
|
||||
if (childFilter == ChildFilter.HasParent && !go.transform.parent)
|
||||
continue;
|
||||
else if (childFilter == ChildFilter.RootObject && go.transform.parent)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.Add(obj);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<object> StaticClassSearch(string input)
|
||||
{
|
||||
var list = new List<object>();
|
||||
|
||||
var nameFilter = "";
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input;
|
||||
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var type in asm.TryGetTypes().Where(it => it.IsSealed && it.IsAbstract))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
|
||||
continue;
|
||||
|
||||
list.Add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
internal static string[] instanceNames = new string[]
|
||||
{
|
||||
"m_instance",
|
||||
"m_Instance",
|
||||
"s_instance",
|
||||
"s_Instance",
|
||||
"_instance",
|
||||
"_Instance",
|
||||
"instance",
|
||||
"Instance",
|
||||
"<Instance>k__BackingField",
|
||||
"<instance>k__BackingField",
|
||||
};
|
||||
|
||||
internal static List<object> SingletonSearch(string input)
|
||||
{
|
||||
var instances = new List<object>();
|
||||
|
||||
var nameFilter = "";
|
||||
if (!string.IsNullOrEmpty(input))
|
||||
nameFilter = input;
|
||||
|
||||
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
|
||||
|
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
// Search all non-static, non-enum classes.
|
||||
foreach (var type in asm.TryGetTypes().Where(it => !(it.IsSealed && it.IsAbstract) && !it.IsEnum))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(nameFilter) && !type.FullName.ContainsIgnoreCase(nameFilter))
|
||||
continue;
|
||||
|
||||
ReflectionUtility.FindSingleton(instanceNames, type, flags, instances);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
return instances;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.UI.IValues;
|
||||
using System.Reflection;
|
||||
#if CPP
|
||||
using UnhollowerRuntimeLib;
|
||||
using UnhollowerBaseLib;
|
||||
@ -11,8 +13,69 @@ using UnhollowerBaseLib;
|
||||
|
||||
namespace UnityExplorer.Tests
|
||||
{
|
||||
public struct TestValueStruct
|
||||
{
|
||||
public const object TestIgnoreThis = null;
|
||||
public const string TestIgnoreButValid = "";
|
||||
|
||||
public string aString;
|
||||
public int anInt;
|
||||
public float aFloat;
|
||||
public bool aBool;
|
||||
public Vector3 AVector3;
|
||||
public Vector4 aVector4;
|
||||
public DateTime aDateTime;
|
||||
public Color32 aColor32;
|
||||
public CameraClearFlags clearFlags;
|
||||
}
|
||||
|
||||
public enum TestEnum : long
|
||||
{
|
||||
Neg50 = -50,
|
||||
Neg1 = -1,
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
Pos49 = 49,
|
||||
Implicit50,
|
||||
Also50 = 50,
|
||||
AlsoAlso50 = 50,
|
||||
};
|
||||
public enum TestEnum2 : ulong
|
||||
{
|
||||
Min = ulong.MinValue,
|
||||
Max = ulong.MaxValue
|
||||
}
|
||||
[Flags]
|
||||
public enum TestFlags : int
|
||||
{
|
||||
All = -1,
|
||||
Zero = 0,
|
||||
Ok = 1,
|
||||
Two = 2,
|
||||
Three = 4,
|
||||
Four = 8,
|
||||
Five = 16,
|
||||
Six = 32,
|
||||
Seven = 64,
|
||||
Thirteen = Six | Seven,
|
||||
Fifteen = Four | Five | Six,
|
||||
}
|
||||
|
||||
public static class TestClass
|
||||
{
|
||||
public static void ATestMethod(string s, float f, Vector3 vector, DateTime date, Quaternion quater, bool b, CameraClearFlags enumvalue)
|
||||
{
|
||||
ExplorerCore.Log($"{s}, {f}, {vector.ToString()}, {date}, {quater.eulerAngles.ToString()}, {b}, {enumvalue}");
|
||||
}
|
||||
|
||||
public static TestValueStruct AATestStruct;
|
||||
|
||||
public static TestEnum AATestEnumOne = TestEnum.Neg50;
|
||||
public static TestEnum2 AATestEnumTwo = TestEnum2.Max;
|
||||
public static TestFlags AATestFlags = TestFlags.Thirteen;
|
||||
public static BindingFlags AATestbinding;
|
||||
public static HideFlags AAHideFlags;
|
||||
|
||||
public static List<int> AWritableList = new List<int> { 1, 2, 3, 4, 5 };
|
||||
public static Dictionary<string, int> AWritableDict = new Dictionary<string, int> { { "one", 1 }, { "two", 2 } };
|
||||
|
||||
@ -67,6 +130,9 @@ namespace UnityExplorer.Tests
|
||||
|
||||
public const int ConstantInt = 5;
|
||||
|
||||
public static Color AColor = Color.magenta;
|
||||
public static Color32 AColor32 = Color.red;
|
||||
|
||||
public static byte[] ByteArray = new byte[16];
|
||||
public static string LongString = new string('#', 10000);
|
||||
public static List<string> BigList = new List<string>(10000);
|
||||
@ -123,7 +189,6 @@ namespace UnityExplorer.Tests
|
||||
}
|
||||
|
||||
#if CPP
|
||||
public static List<Il2CppSystem.Object> TestWritableBoxedList;
|
||||
|
||||
public static string testStringOne = "Test";
|
||||
public static Il2CppSystem.Object testStringTwo = "string boxed as cpp object";
|
||||
@ -141,6 +206,21 @@ namespace UnityExplorer.Tests
|
||||
public static Il2CppSystem.Object cppDecimalBoxed;
|
||||
public static Il2CppSystem.Object cppVector3Boxed;
|
||||
|
||||
public static Il2CppSystem.Object RandomBoxedColor
|
||||
{
|
||||
get
|
||||
{
|
||||
int ran = UnityEngine.Random.Range(0, 3);
|
||||
switch (ran)
|
||||
{
|
||||
case 1: return new Color32().BoxIl2CppObject();
|
||||
case 2: return Color.magenta.BoxIl2CppObject();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Il2CppSystem.Collections.Hashtable cppHashset;
|
||||
|
||||
public static Dictionary<Il2CppSystem.String, Il2CppSystem.Object> CppBoxedDict;
|
||||
@ -167,6 +247,7 @@ namespace UnityExplorer.Tests
|
||||
CppBoxedList = new List<Il2CppSystem.Object>();
|
||||
CppBoxedList.Add((Il2CppSystem.String)"boxedString");
|
||||
CppBoxedList.Add(new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject());
|
||||
CppBoxedList.Add(Color.red.BoxIl2CppObject());
|
||||
|
||||
try
|
||||
{
|
||||
@ -205,12 +286,6 @@ namespace UnityExplorer.Tests
|
||||
cppBoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
|
||||
cppInt = new Il2CppSystem.Int32 { m_value = 420 };
|
||||
|
||||
TestWritableBoxedList = new List<Il2CppSystem.Object>();
|
||||
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject());
|
||||
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject());
|
||||
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject());
|
||||
TestWritableBoxedList.Add(new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject());
|
||||
|
||||
cppHashset = new Il2CppSystem.Collections.Hashtable();
|
||||
cppHashset.Add("key1", "itemOne");
|
||||
cppHashset.Add("key2", "itemTwo");
|
||||
|
@ -23,7 +23,7 @@ namespace UnityExplorer
|
||||
{
|
||||
if (string.IsNullOrEmpty(type.FullName))
|
||||
return false;
|
||||
return type.IsPrimitive || nonPrimitiveTypes.Contains(type) || customTypes.ContainsKey(type.FullName);
|
||||
return type.IsPrimitive || type.IsEnum || nonPrimitiveTypes.Contains(type) || customTypes.ContainsKey(type.FullName);
|
||||
}
|
||||
|
||||
public static bool TryParse(string input, Type type, out object obj, out Exception parseException)
|
||||
@ -40,6 +40,20 @@ namespace UnityExplorer
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
try
|
||||
{
|
||||
obj = Enum.Parse(type, input);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
parseException = ex.GetInnerMostException();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (customTypes.ContainsKey(type.FullName))
|
||||
@ -63,6 +77,12 @@ namespace UnityExplorer
|
||||
return false;
|
||||
}
|
||||
|
||||
private static readonly HashSet<Type> nonFormattedTypes = new HashSet<Type>
|
||||
{
|
||||
typeof(IntPtr),
|
||||
typeof(UIntPtr),
|
||||
};
|
||||
|
||||
public static string ToStringForInput(object obj, Type type)
|
||||
{
|
||||
if (type == null || obj == null)
|
||||
@ -71,6 +91,13 @@ namespace UnityExplorer
|
||||
if (type == typeof(string))
|
||||
return obj as string;
|
||||
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return Enum.IsDefined(type, obj)
|
||||
? Enum.GetName(type, obj)
|
||||
: obj.ToString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (customTypes.ContainsKey(type.FullName))
|
||||
@ -79,10 +106,8 @@ namespace UnityExplorer
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj is IntPtr ptr)
|
||||
return ptr.ToString();
|
||||
else if (obj is UIntPtr uPtr)
|
||||
return uPtr.ToString();
|
||||
if (nonFormattedTypes.Contains(type))
|
||||
return obj.ToString();
|
||||
else
|
||||
return ReflectionUtility.GetMethodInfo(type, "ToString", new Type[] { typeof(IFormatProvider) })
|
||||
.Invoke(obj, new object[] { en_US })
|
||||
@ -104,8 +129,15 @@ namespace UnityExplorer
|
||||
{
|
||||
try
|
||||
{
|
||||
var instance = Activator.CreateInstance(type);
|
||||
typeInputExamples.Add(type.AssemblyQualifiedName, ToStringForInput(instance, type));
|
||||
if (type.IsEnum)
|
||||
{
|
||||
typeInputExamples.Add(type.AssemblyQualifiedName, Enum.GetNames(type).First());
|
||||
}
|
||||
else
|
||||
{
|
||||
var instance = Activator.CreateInstance(type);
|
||||
typeInputExamples.Add(type.AssemblyQualifiedName, ToStringForInput(instance, type));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -231,6 +231,18 @@ namespace UnityExplorer
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string GetMemberInfoColor(MemberTypes type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MemberTypes.Method: return METHOD_INSTANCE;
|
||||
case MemberTypes.Property: return PROP_INSTANCE;
|
||||
case MemberTypes.Field: return FIELD_INSTANCE;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string GetMemberInfoColor(MemberInfo memberInfo, out bool isStatic)
|
||||
{
|
||||
isStatic = false;
|
||||
|
Reference in New Issue
Block a user