Compare commits

..

8 Commits
4.6.1 ... 4.6.2

Author SHA1 Message Date
4e3d3a2e5c Update README.md 2022-04-01 01:37:51 +11:00
7dbc8fd66e Merge branch 'master' of https://github.com/sinai-dev/UnityExplorer 2022-04-01 01:31:53 +11:00
892cefcc91 Bump version 2022-04-01 01:31:45 +11:00
a986b92963 Don't try to get UnityObjectWidget for static class inspection 2022-04-01 01:31:40 +11:00
8837119781 Merge pull request #132 from liesauer/master
Fix standalone reading config item type casting bug
2022-04-01 01:21:39 +11:00
7eda249ddb Fix standalone reading config item type casting bug 2022-03-31 21:07:06 +08:00
710b4ba74a Use switch expression instead of if/else block 2022-03-29 22:39:26 +11:00
4bee55fb25 Cleanups, remove redundancy 2022-03-29 22:36:17 +11:00
7 changed files with 64 additions and 83 deletions

View File

@ -45,7 +45,7 @@
The standalone release can be used with any injector or loader of your choice, but it requires you to load the dependencies manually.
1. Ensure the required libs are loaded - UniverseLib, HarmonyX and MonoMod
1. Ensure the required libs are loaded - UniverseLib, HarmonyX and MonoMod. Take them from the [`UnityExplorer.Editor`](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.Editor.zip) release if you need them.
2. For IL2CPP, load Il2CppAssemblyUnhollower and start an [Il2CppAssemblyUnhollower runtime](https://github.com/knah/Il2CppAssemblyUnhollower#required-external-setup)
2. Load the UnityExplorer DLL
3. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`

View File

@ -14,7 +14,7 @@ namespace UnityExplorer.CacheObject
{
public static class CacheMemberFactory
{
public static List<CacheMember> GetCacheMembers(object inspectorTarget, Type type, ReflectionInspector inspector)
public static List<CacheMember> GetCacheMembers(Type type, ReflectionInspector inspector)
{
//var list = new List<CacheMember>();
HashSet<string> cachedSigs = new();
@ -49,10 +49,6 @@ namespace UnityExplorer.CacheObject
foreach (var declaringType in types)
{
var target = inspectorTarget;
if (!inspector.StaticOnly)
target = target.TryCast(declaringType);
foreach (var prop in declaringType.GetProperties(flags))
if (prop.DeclaringType == declaringType)
TryCacheMember(prop, props, cachedSigs, declaringType, inspector);
@ -79,13 +75,9 @@ namespace UnityExplorer.CacheObject
return sorted;
}
static void TryCacheMember(
MemberInfo member,
IList list,
HashSet<string> cachedSigs,
Type declaringType,
ReflectionInspector inspector,
bool ignorePropertyMethodInfos = true)
static void TryCacheMember<T>(MemberInfo member, List<T> list, HashSet<string> cachedSigs,
Type declaringType, ReflectionInspector inspector, bool ignorePropertyMethodInfos = true)
where T : CacheMember
{
try
{
@ -94,7 +86,9 @@ namespace UnityExplorer.CacheObject
string sig = member switch
{
// method or constructor
MethodBase mb => mb.FullDescription(),
// property or field
PropertyInfo or FieldInfo => $"{member.DeclaringType.FullDescription()}.{member.Name}",
_ => throw new NotImplementedException(),
};
@ -164,32 +158,13 @@ namespace UnityExplorer.CacheObject
cached.SetFallbackType(returnType);
cached.SetInspectorOwner(inspector, member);
list.Add(cached);
list.Add((T)cached);
}
catch (Exception e)
{
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
ExplorerCore.Log(e.ToString());
ExplorerCore.Log(e);
}
}
//internal static string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}";
//
//internal static string GetArgumentString(ParameterInfo[] args)
//{
// var sb = new StringBuilder();
// sb.Append(' ');
// sb.Append('(');
// foreach (var param in args)
// {
// sb.Append(param.ParameterType.Name);
// sb.Append(' ');
// sb.Append(param.Name);
// sb.Append(',');
// sb.Append(' ');
// }
// sb.Append(')');
// return sb.ToString();
//}
}
}

View File

@ -1,10 +1,13 @@
using System.IO;
using System;
using System.IO;
using UnityEngine;
using UnityExplorer.CacheObject;
using UnityExplorer.Config;
using UnityExplorer.ObjectExplorer;
using UnityExplorer.Runtime;
using UnityExplorer.UI;
using UnityExplorer.UI.Panels;
using UniverseLib;
using UniverseLib.Input;
namespace UnityExplorer
@ -12,7 +15,7 @@ namespace UnityExplorer
public static class ExplorerCore
{
public const string NAME = "UnityExplorer";
public const string VERSION = "4.6.1";
public const string VERSION = "4.6.2";
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer";
@ -26,23 +29,20 @@ namespace UnityExplorer
public static void Init(IExplorerLoader loader)
{
if (Loader != null)
{
LogWarning("UnityExplorer is already loaded!");
return;
}
throw new Exception("UnityExplorer is already loaded.");
Loader = loader;
Log($"{NAME} {VERSION} initializing...");
if (!Directory.Exists(Loader.ExplorerFolder))
Directory.CreateDirectory(Loader.ExplorerFolder);
Directory.CreateDirectory(Loader.ExplorerFolder);
ConfigManager.Init(Loader.ConfigHandler);
UERuntimeHelper.Init();
ExplorerBehaviour.Setup();
UnityCrashPrevention.Init();
UniverseLib.Universe.Init(ConfigManager.Startup_Delay_Time.Value, LateInit, Log, new()
Universe.Init(ConfigManager.Startup_Delay_Time.Value, LateInit, Log, new()
{
Disable_EventSystem_Override = ConfigManager.Disable_EventSystem_Override.Value,
Force_Unlock_Mouse = ConfigManager.Force_Unlock_Mouse.Value,
@ -53,7 +53,7 @@ namespace UnityExplorer
// Do a delayed setup so that objects aren't destroyed instantly.
// This can happen for a multitude of reasons.
// Default delay is 1 second which is usually enough.
private static void LateInit()
static void LateInit()
{
Log($"Setting up late core features...");
@ -63,21 +63,18 @@ namespace UnityExplorer
UIManager.InitUI();
Log($"{NAME} {VERSION} initialized for {UniverseLib.Universe.Context}.");
Log($"{NAME} {VERSION} ({Universe.Context}) initialized.");
//InspectorManager.Inspect(typeof(Tests.TestClass));
}
/// <summary>
/// Should be called once per frame.
/// </summary>
public static void Update()
internal static void Update()
{
UIManager.Update();
// check master toggle
if (InputManager.GetKeyDown(ConfigManager.Master_Toggle.Value))
UIManager.ShowMenu = !UIManager.ShowMenu;
UIManager.Update();
}
#region LOGGING

View File

@ -160,11 +160,12 @@ namespace UnityExplorer.Inspectors
// Unity object helper widget
this.UnityWidget = UnityObjectWidget.GetUnityWidget(target, TargetType, this);
if (!StaticOnly)
this.UnityWidget = UnityObjectWidget.GetUnityWidget(target, TargetType, this);
// Get cache members
this.members = CacheMemberFactory.GetCacheMembers(Target, TargetType, this);
this.members = CacheMemberFactory.GetCacheMembers(TargetType, this);
// reset filters

View File

@ -73,7 +73,11 @@ namespace UnityExplorer.Loader.Standalone
return bool.Parse(value);
else if (elementType == typeof(int))
return int.Parse(value);
else
else if (elementType == typeof(float))
return float.Parse(value);
else if (elementType.IsEnum)
return Enum.Parse(elementType, value);
else
return value;
}

View File

@ -24,6 +24,8 @@ namespace UnityExplorer.Tests
#endif
}
#region MONO
public static object LiterallyAnything = null;
// Test enumerables
@ -90,12 +92,12 @@ namespace UnityExplorer.Tests
ExplorerCore.Log($"Test3 {typeof(T).FullName}");
}
public static void TestArgumentParse(string _string,
int integer,
Color color,
CameraClearFlags flags,
Vector3 vector,
Quaternion quaternion,
public static void TestArgumentParse(string _string,
int integer,
Color color,
CameraClearFlags flags,
Vector3 vector,
Quaternion quaternion,
object obj,
Type type,
GameObject go)
@ -145,6 +147,8 @@ namespace UnityExplorer.Tests
ExplorerCore.Log("Finished TestClass Init_Mono");
}
#endregion
#if CPP
public static Il2CppSystem.Collections.Generic.Dictionary<string, string> IL2CPP_Dict;
public static Il2CppSystem.Collections.Generic.HashSet<string> IL2CPP_HashSet;
@ -156,7 +160,7 @@ namespace UnityExplorer.Tests
public static Il2CppSystem.Collections.IDictionary IL2CPP_IDict;
public static Il2CppSystem.Collections.IList IL2CPP_IList;
public static Dictionary<Il2CppSystem.Object, Il2CppSystem.Object> IL2CPP_BoxedDict;
public static Il2CppSystem.Object IL2CPP_BoxedInt;
public static Il2CppSystem.Int32 IL2CPP_Int;
public static Il2CppSystem.Decimal IL2CPP_Decimal;
@ -185,31 +189,31 @@ namespace UnityExplorer.Tests
IL2CPP_HashTable.Add("key1", "value1");
IL2CPP_HashTable.Add("key2", "value2");
IL2CPP_HashTable.Add("key3", "value3");
ExplorerCore.Log($"IL2CPP 3: Il2Cpp IDictionary");
var dict2 = new Il2CppSystem.Collections.Generic.Dictionary<string, string>();
dict2.Add("key1", "value1");
IL2CPP_IDict = dict2.TryCast<Il2CppSystem.Collections.IDictionary>();
ExplorerCore.Log($"IL2CPP 4: Il2Cpp List of Il2Cpp Object");
var list = new Il2CppSystem.Collections.Generic.List<Il2CppSystem.Object>(5);
list.Add("one");
list.Add("two");
IL2CPP_IList = list.TryCast<Il2CppSystem.Collections.IList>();
ExplorerCore.Log($"IL2CPP 5: Il2Cpp List of strings");
IL2CPP_ListString = new Il2CppSystem.Collections.Generic.List<string>();
IL2CPP_ListString.Add("hello,");
IL2CPP_ListString.Add("world!");
ExplorerCore.Log($"IL2CPP 7: Dictionary of Il2Cpp String and Il2Cpp Object");
IL2CPP_BoxedDict = new();
IL2CPP_BoxedDict[(Il2CppSystem.String)"one"] = new Il2CppSystem.Int32 { m_value = 1 }.BoxIl2CppObject();
IL2CPP_BoxedDict[(Il2CppSystem.String)"two"] = new Il2CppSystem.Int32 { m_value = 2 }.BoxIl2CppObject();
IL2CPP_BoxedDict[(Il2CppSystem.String)"three"] = new Il2CppSystem.Int32 { m_value = 3 }.BoxIl2CppObject();
IL2CPP_BoxedDict[(Il2CppSystem.String)"four"] = new Il2CppSystem.Int32 { m_value = 4 }.BoxIl2CppObject();
ExplorerCore.Log($"IL2CPP 8: List of boxed Il2Cpp Objects");
IL2CPP_listOfBoxedObjects = new List<Il2CppSystem.Object>();
IL2CPP_listOfBoxedObjects.Add((Il2CppSystem.String)"boxedString");
@ -224,16 +228,16 @@ namespace UnityExplorer.Tests
var boxedEnum = Il2CppSystem.Enum.Parse(cppType, "Color");
IL2CPP_listOfBoxedObjects.Add(boxedEnum);
}
var structBox = Vector3.one.BoxIl2CppObject();
IL2CPP_listOfBoxedObjects.Add(structBox);
}
catch (Exception ex)
{
ExplorerCore.LogWarning($"Boxed enum test fail: {ex}");
}
ExplorerCore.Log($"IL2CPP 9: Il2Cpp struct array of ints");
IL2CPP_structArray = new UnhollowerBaseLib.Il2CppStructArray<int>(5);
IL2CPP_structArray[0] = 0;
@ -241,13 +245,13 @@ namespace UnityExplorer.Tests
IL2CPP_structArray[2] = 2;
IL2CPP_structArray[3] = 3;
IL2CPP_structArray[4] = 4;
ExplorerCore.Log($"IL2CPP 10: Il2Cpp reference array of boxed objects");
IL2CPP_ReferenceArray = new UnhollowerBaseLib.Il2CppReferenceArray<Il2CppSystem.Object>(3);
IL2CPP_ReferenceArray[0] = new Il2CppSystem.Int32 { m_value = 5 }.BoxIl2CppObject();
IL2CPP_ReferenceArray[1] = null;
IL2CPP_ReferenceArray[2] = (Il2CppSystem.String)"whats up";
ExplorerCore.Log($"IL2CPP 11: Misc il2cpp members");
IL2CPP_BoxedInt = new Il2CppSystem.Int32() { m_value = 5 }.BoxIl2CppObject();
IL2CPP_Int = new Il2CppSystem.Int32 { m_value = 420 };
@ -257,6 +261,7 @@ namespace UnityExplorer.Tests
ExplorerCore.Log($"Finished Init_Il2Cpp");
}
#endif
}
}

View File

@ -28,17 +28,16 @@ namespace UnityExplorer.UI.Widgets
if (!typeof(UnityEngine.Object).IsAssignableFrom(targetType))
return null;
UnityObjectWidget ret;
UnityObjectWidget widget = target switch
{
Texture2D => Pool<Texture2DWidget>.Borrow(),
AudioClip => Pool<AudioClipWidget>.Borrow(),
_ => Pool<UnityObjectWidget>.Borrow()
};
if (targetType == typeof(Texture2D))
ret = Pool<Texture2DWidget>.Borrow();
else if (targetType == typeof(AudioClip))
ret = Pool<AudioClipWidget>.Borrow();
else
ret = Pool<UnityObjectWidget>.Borrow();
widget.OnBorrowed(target, targetType, inspector);
ret.OnBorrowed(target, targetType, inspector);
return ret;
return widget;
}
public virtual void OnBorrowed(object target, Type targetType, ReflectionInspector inspector)
@ -52,7 +51,7 @@ namespace UnityExplorer.UI.Widgets
this.UIRoot.transform.SetSiblingIndex(inspector.UIRoot.transform.childCount - 2);
UnityObjectRef = (UnityEngine.Object)target.TryCast(typeof(UnityEngine.Object));
UnityObjectRef = target.TryCast<UnityEngine.Object>();
UIRoot.SetActive(true);
nameInput.Text = UnityObjectRef.name;