Compare commits

..

4 Commits
3.0.1 ... 3.0.2

12 changed files with 265 additions and 203 deletions

View File

@ -25,8 +25,8 @@
| Mod Loader | IL2CPP | Mono | | Mod Loader | IL2CPP | Mono |
| ----------- | ------ | ---- | | ----------- | ------ | ---- |
| [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.MelonLoader.Mono.zip) | | [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.MelonLoader.Mono.zip) |
| [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/Explorer/releases/latest/download/Explorer.BepInEx.Mono.zip) | | [BepInEx](https://github.com/BepInEx/BepInEx) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Il2Cpp.zip) | ✔️ [link](https://github.com/sinai-dev/UnityExplorer/releases/latest/download/UnityExplorer.BepInEx.Mono.zip) |
<b>IL2CPP Issues:</b> <b>IL2CPP Issues:</b>
* Some methods may still fail with a `MissingMethodException`, please let me know if you experience this (with full debug log please). * Some methods may still fail with a `MissingMethodException`, please let me know if you experience this (with full debug log please).

View File

@ -8,13 +8,14 @@ using UnityExplorer.Inspectors;
using System.IO; using System.IO;
using UnityExplorer.Unstrip; using UnityExplorer.Unstrip;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityExplorer.Helpers;
namespace UnityExplorer namespace UnityExplorer
{ {
public class ExplorerCore public class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "3.0.1"; public const string VERSION = "3.0.2";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";
public const string EXPLORER_FOLDER = @"Mods\UnityExplorer"; public const string EXPLORER_FOLDER = @"Mods\UnityExplorer";
@ -41,6 +42,10 @@ namespace UnityExplorer
Instance = this; Instance = this;
#if CPP
ReflectionHelpers.TryLoadGameModules();
#endif
if (!Directory.Exists(EXPLORER_FOLDER)) if (!Directory.Exists(EXPLORER_FOLDER))
Directory.CreateDirectory(EXPLORER_FOLDER); Directory.CreateDirectory(EXPLORER_FOLDER);

View File

@ -105,21 +105,19 @@ namespace UnityExplorer.Helpers
return getType; return getType;
} }
private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>(); private static readonly Dictionary<Type, IntPtr> CppClassPointers = new Dictionary<Type, IntPtr>();
public static object Il2CppCast(this object obj, Type castTo) public static object Il2CppCast(this object obj, Type castTo)
{ {
if (!(obj is Il2CppSystem.Object ilObj)) if (!(obj is Il2CppSystem.Object ilObj))
{
return obj; return obj;
}
if (!Il2CppTypeNotNull(castTo, out IntPtr castToPtr)) if (!Il2CppTypeNotNull(castTo, out IntPtr castToPtr))
return obj; return obj;
IntPtr classPtr = il2cpp_object_get_class(ilObj.Pointer); IntPtr castFromPtr = il2cpp_object_get_class(ilObj.Pointer);
if (!il2cpp_class_is_assignable_from(castToPtr, classPtr)) if (!il2cpp_class_is_assignable_from(castToPtr, castFromPtr))
return obj; return obj;
if (RuntimeSpecificsStore.IsInjected(castToPtr)) if (RuntimeSpecificsStore.IsInjected(castToPtr))
@ -128,24 +126,21 @@ namespace UnityExplorer.Helpers
return Activator.CreateInstance(castTo, ilObj.Pointer); return Activator.CreateInstance(castTo, ilObj.Pointer);
} }
public static bool Il2CppTypeNotNull(Type type) public static bool Il2CppTypeNotNull(Type type) => Il2CppTypeNotNull(type, out _);
{
return Il2CppTypeNotNull(type, out _);
}
public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr) public static bool Il2CppTypeNotNull(Type type, out IntPtr il2cppPtr)
{ {
if (!ClassPointers.ContainsKey(type)) if (!CppClassPointers.ContainsKey(type))
{ {
il2cppPtr = (IntPtr)typeof(Il2CppClassPointerStore<>) il2cppPtr = (IntPtr)typeof(Il2CppClassPointerStore<>)
.MakeGenericType(new Type[] { type }) .MakeGenericType(new Type[] { type })
.GetField("NativeClassPtr", BF.Public | BF.Static) .GetField("NativeClassPtr", BF.Public | BF.Static)
.GetValue(null); .GetValue(null);
ClassPointers.Add(type, il2cppPtr); CppClassPointers.Add(type, il2cppPtr);
} }
else else
il2cppPtr = ClassPointers[type]; il2cppPtr = CppClassPointers[type];
return il2cppPtr != IntPtr.Zero; return il2cppPtr != IntPtr.Zero;
} }
@ -181,31 +176,42 @@ namespace UnityExplorer.Helpers
} }
} }
#if CPP
internal static void TryLoadGameModules()
{
LoadModule("Assembly-CSharp");
LoadModule("Assembly-CSharp-firstpass");
}
public static bool LoadModule(string module) public static bool LoadModule(string module)
{ {
#if CPP
#if ML #if ML
string path = $@"MelonLoader\Managed\{module}.dll"; var path = $@"MelonLoader\Managed\{module}.dll";
#else #else
var path = $@"BepInEx\unhollowed\{module}.dll"; var path = $@"BepInEx\unhollowed\{module}.dll";
#endif #endif
if (!File.Exists(path))
{ return LoadModuleInternal(path);
}
internal static bool LoadModuleInternal(string fullPath)
{
if (!File.Exists(fullPath))
return false; return false;
}
try try
{ {
Assembly.Load(File.ReadAllBytes(path)); Assembly.Load(File.ReadAllBytes(fullPath));
return true; return true;
} }
catch (Exception e) catch (Exception e)
{ {
ExplorerCore.Log(e.GetType() + ", " + e.Message); Console.WriteLine(e.GetType() + ", " + e.Message);
} }
#endif
return false; return false;
} }
#endif
public static bool IsEnumerable(Type t) public static bool IsEnumerable(Type t)
{ {

View File

@ -12,8 +12,17 @@ namespace UnityExplorer.Input
{ {
private static IHandleInput m_inputModule; private static IHandleInput m_inputModule;
public static Vector3 MousePosition => m_inputModule.MousePosition;
public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
public static bool GetKey(KeyCode key) => m_inputModule.GetKey(key);
public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
public static void Init() public static void Init()
{ {
#if CPP
if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null)) if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null))
{ {
m_inputModule = new InputSystem(); m_inputModule = new InputSystem();
@ -22,6 +31,7 @@ namespace UnityExplorer.Input
{ {
m_inputModule = new LegacyInput(); m_inputModule = new LegacyInput();
} }
#endif
if (m_inputModule == null) if (m_inputModule == null)
{ {
@ -29,13 +39,5 @@ namespace UnityExplorer.Input
m_inputModule = new NoInput(); m_inputModule = new NoInput();
} }
} }
public static Vector3 MousePosition => m_inputModule.MousePosition;
public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
public static bool GetKey(KeyCode key) => m_inputModule.GetKey(key);
public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
} }
} }

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Reflection; using System.Reflection;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.Helpers; using UnityExplorer.Helpers;
using UnityEngine;
namespace UnityExplorer.Inspectors.Reflection namespace UnityExplorer.Inspectors.Reflection
{ {
@ -14,7 +15,7 @@ namespace UnityExplorer.Inspectors.Reflection
public override Type FallbackType => (MemInfo as FieldInfo).FieldType; public override Type FallbackType => (MemInfo as FieldInfo).FieldType;
public CacheField(FieldInfo fieldInfo, object declaringInstance) : base(fieldInfo, declaringInstance) public CacheField(FieldInfo fieldInfo, object declaringInstance, GameObject parent) : base(fieldInfo, declaringInstance, parent)
{ {
CreateIValue(null, fieldInfo.FieldType); CreateIValue(null, fieldInfo.FieldType);
} }

View File

@ -43,11 +43,12 @@ namespace UnityExplorer.Inspectors.Reflection
public string RichTextName => m_richTextName ?? GetRichTextName(); public string RichTextName => m_richTextName ?? GetRichTextName();
private string m_richTextName; private string m_richTextName;
public CacheMember(MemberInfo memberInfo, object declaringInstance) public CacheMember(MemberInfo memberInfo, object declaringInstance, GameObject parentContent)
{ {
MemInfo = memberInfo; MemInfo = memberInfo;
DeclaringType = memberInfo.DeclaringType; DeclaringType = memberInfo.DeclaringType;
DeclaringInstance = declaringInstance; DeclaringInstance = declaringInstance;
this.m_parentContent = parentContent;
#if CPP #if CPP
if (DeclaringInstance != null) if (DeclaringInstance != null)
DeclaringInstance = DeclaringInstance.Il2CppCast(DeclaringType); DeclaringInstance = DeclaringInstance.Il2CppCast(DeclaringType);

View File

@ -26,7 +26,7 @@ namespace UnityExplorer.Inspectors.Reflection
public string[] m_genericArgInput = new string[0]; public string[] m_genericArgInput = new string[0];
public CacheMethod(MethodInfo methodInfo, object declaringInstance) : base(methodInfo, declaringInstance) public CacheMethod(MethodInfo methodInfo, object declaringInstance, GameObject parent) : base(methodInfo, declaringInstance, parent)
{ {
GenericArgs = methodInfo.GetGenericArguments(); GenericArgs = methodInfo.GetGenericArguments();

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Reflection; using System.Reflection;
using UnityExplorer.UI; using UnityExplorer.UI;
using UnityExplorer.Helpers; using UnityExplorer.Helpers;
using UnityEngine;
namespace UnityExplorer.Inspectors.Reflection namespace UnityExplorer.Inspectors.Reflection
{ {
@ -14,7 +15,7 @@ namespace UnityExplorer.Inspectors.Reflection
public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic; public override bool IsStatic => (MemInfo as PropertyInfo).GetAccessors(true)[0].IsStatic;
public CacheProperty(PropertyInfo propertyInfo, object declaringInstance) : base(propertyInfo, declaringInstance) public CacheProperty(PropertyInfo propertyInfo, object declaringInstance, GameObject parent) : base(propertyInfo, declaringInstance, parent)
{ {
this.m_arguments = propertyInfo.GetIndexParameters(); this.m_arguments = propertyInfo.GetIndexParameters();
this.m_argumentInput = new string[m_arguments.Length]; this.m_argumentInput = new string[m_arguments.Length];

View File

@ -45,19 +45,95 @@ namespace UnityExplorer.Inspectors.Reflection
public void ConstructInstanceHelpers() public void ConstructInstanceHelpers()
{ {
if (!typeof(Component).IsAssignableFrom(m_targetType) && !typeof(UnityEngine.Object).IsAssignableFrom(m_targetType))
return;
var rowObj = UIFactory.CreateHorizontalGroup(Content, new Color(0.1f, 0.1f, 0.1f));
var rowGroup = rowObj.GetComponent<HorizontalLayoutGroup>();
rowGroup.childForceExpandWidth = true;
rowGroup.childControlWidth = true;
rowGroup.spacing = 5;
rowGroup.padding.top = 2;
rowGroup.padding.bottom = 2;
rowGroup.padding.right = 2;
rowGroup.padding.left = 2;
var rowLayout = rowObj.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleWidth = 5000;
if (typeof(Component).IsAssignableFrom(m_targetType))
{
ConstructCompHelper(rowObj);
}
ConstructUObjHelper(rowObj);
// WIP // WIP
//if (m_targetType == typeof(Texture2D)) //if (m_targetType == typeof(Texture2D))
// ConstructTextureHelper(); // ConstructTextureHelper();
}
// todo other helpers internal void ConstructCompHelper(GameObject rowObj)
{
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 90;
labelLayout.minHeight = 25;
labelLayout.flexibleWidth = 0;
var labelText = labelObj.GetComponent<Text>();
labelText.text = "GameObject:";
//if (typeof(Component).IsAssignableFrom(m_targetType)) #if MONO
//{ var comp = Target as Component;
//} #else
//else if (typeof(UnityEngine.Object).IsAssignableFrom(m_targetType)) var comp = (Target as Il2CppSystem.Object).TryCast<Component>();
//{ #endif
//}
var goBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.5f, 0.2f));
var goBtnLayout = goBtnObj.AddComponent<LayoutElement>();
goBtnLayout.minHeight = 25;
goBtnLayout.minWidth = 200;
goBtnLayout.flexibleWidth = 0;
var text = goBtnObj.GetComponentInChildren<Text>();
text.text = comp.name;
var btn = goBtnObj.GetComponent<Button>();
btn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(comp.gameObject); });
}
internal void ConstructUObjHelper(GameObject rowObj)
{
var labelObj = UIFactory.CreateLabel(rowObj, TextAnchor.MiddleLeft);
var labelLayout = labelObj.AddComponent<LayoutElement>();
labelLayout.minWidth = 60;
labelLayout.minHeight = 25;
labelLayout.flexibleWidth = 0;
var labelText = labelObj.GetComponent<Text>();
labelText.text = "Name:";
#if MONO
var uObj = Target as UnityEngine.Object;
#else
var uObj = (Target as Il2CppSystem.Object).TryCast<UnityEngine.Object>();
#endif
var inputObj = UIFactory.CreateInputField(rowObj, 14, 3, 1);
var inputLayout = inputObj.AddComponent<LayoutElement>();
inputLayout.minHeight = 25;
inputLayout.flexibleWidth = 2000;
var inputField = inputObj.GetComponent<InputField>();
inputField.readOnly = true;
inputField.text = uObj.name;
//var goBtnObj = UIFactory.CreateButton(rowObj, new Color(0.2f, 0.5f, 0.2f));
//var goBtnLayout = goBtnObj.AddComponent<LayoutElement>();
//goBtnLayout.minHeight = 25;
//goBtnLayout.minWidth = 200;
//goBtnLayout.flexibleWidth = 0;
//var text = goBtnObj.GetComponentInChildren<Text>();
//text.text = comp.name;
//var btn = goBtnObj.GetComponent<Button>();
//btn.onClick.AddListener(() => { InspectorManager.Instance.Inspect(comp.gameObject); });
} }
//internal bool showingTextureHelper; //internal bool showingTextureHelper;

View File

@ -34,7 +34,7 @@ namespace UnityExplorer.Inspectors
} }
// Blacklists // Blacklists
private static readonly HashSet<string> s_typeAndMemberBlacklist = new HashSet<string> private static readonly HashSet<string> bl_typeAndMember = new HashSet<string>
{ {
#if CPP #if CPP
// these cause a crash in IL2CPP // these cause a crash in IL2CPP
@ -45,14 +45,14 @@ namespace UnityExplorer.Inspectors
"Texture2D.SetPixelDataImpl", "Texture2D.SetPixelDataImpl",
#endif #endif
}; };
private static readonly HashSet<string> s_methodStartsWithBlacklist = new HashSet<string> private static readonly HashSet<string> bl_memberNameStartsWith = new HashSet<string>
{ {
// these are redundant // these are redundant
"get_", "get_",
"set_", "set_",
}; };
#endregion #endregion
#region INSTANCE #region INSTANCE
@ -132,24 +132,99 @@ namespace UnityExplorer.Inspectors
RefreshDisplay(); RefreshDisplay();
} }
private void OnMemberFilterClicked(MemberTypes type, Button button) internal bool IsBlacklisted(string sig) => bl_typeAndMember.Any(it => sig.Contains(it));
internal bool IsBlacklisted(MethodInfo method) => bl_memberNameStartsWith.Any(it => method.Name.StartsWith(it));
internal string GetSig(MemberInfo member) => $"{member.DeclaringType.Name}.{member.Name}";
internal string AppendArgsToSig(ParameterInfo[] args)
{ {
if (m_lastActiveMemButton) string ret = " (";
foreach (var param in args)
ret += $"{param.ParameterType.Name} {param.Name}, ";
ret += ")";
return ret;
}
public void CacheMembers(Type type)
{
var list = new List<CacheMember>();
var cachedSigs = new HashSet<string>();
var types = ReflectionHelpers.GetAllBaseTypes(type);
var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
if (this is InstanceInspector)
flags |= BindingFlags.Instance;
foreach (var declaringType in types)
{ {
var lastColors = m_lastActiveMemButton.colors; var target = Target;
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f); #if CPP
m_lastActiveMemButton.colors = lastColors; target = target.Il2CppCast(declaringType);
#endif
IEnumerable<MemberInfo> infos = declaringType.GetMethods(flags);
infos = infos.Concat(declaringType.GetProperties(flags));
infos = infos.Concat(declaringType.GetFields(flags));
foreach (var member in infos)
{
try
{
//ExplorerCore.Log($"Trying to cache member {sig}...");
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
var sig = GetSig(member);
var mi = member as MethodInfo;
var pi = member as PropertyInfo;
var fi = member as FieldInfo;
if (IsBlacklisted(sig) || (mi != null && IsBlacklisted(mi)))
continue;
var args = mi?.GetParameters() ?? pi?.GetIndexParameters();
if (args != null)
{
if (!CacheMember.CanProcessArgs(args))
continue;
sig += AppendArgsToSig(args);
}
if (cachedSigs.Contains(sig))
continue;
cachedSigs.Add(sig);
if (mi != null)
list.Add(new CacheMethod(mi, target, m_scrollContent));
else if (pi != null)
list.Add(new CacheProperty(pi, target, m_scrollContent));
else
list.Add(new CacheField(fi, target, m_scrollContent));
}
catch (Exception e)
{
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
ExplorerCore.Log(e.ToString());
}
}
} }
m_memberFilter = type; var typeList = types.ToList();
m_lastActiveMemButton = button;
var colors = m_lastActiveMemButton.colors; var sorted = new List<CacheMember>();
colors.normalColor = new Color(0.2f, 0.6f, 0.2f); sorted.AddRange(list.Where(it => it is CacheMethod)
m_lastActiveMemButton.colors = colors; .OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheProperty)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheField)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
FilterMembers(null, true); m_allMembers = sorted.ToArray();
m_sliderScroller.m_slider.value = 1f;
} }
public override void Update() public override void Update()
@ -178,6 +253,26 @@ namespace UnityExplorer.Inspectors
} }
} }
private void OnMemberFilterClicked(MemberTypes type, Button button)
{
if (m_lastActiveMemButton)
{
var lastColors = m_lastActiveMemButton.colors;
lastColors.normalColor = new Color(0.2f, 0.2f, 0.2f);
m_lastActiveMemButton.colors = lastColors;
}
m_memberFilter = type;
m_lastActiveMemButton = button;
var colors = m_lastActiveMemButton.colors;
colors.normalColor = new Color(0.2f, 0.6f, 0.2f);
m_lastActiveMemButton.colors = colors;
FilterMembers(null, true);
m_sliderScroller.m_slider.value = 1f;
}
public void FilterMembers(string nameFilter = null, bool force = false) public void FilterMembers(string nameFilter = null, bool force = false)
{ {
int lastCount = m_membersFiltered.Count; int lastCount = m_membersFiltered.Count;
@ -200,7 +295,7 @@ namespace UnityExplorer.Inspectors
} }
// name filter // name filter
if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter)) if (!string.IsNullOrEmpty(nameFilter) && !mem.NameForFiltering.Contains(nameFilter))
continue; continue;
m_membersFiltered.Add(mem); m_membersFiltered.Add(mem);
@ -266,137 +361,6 @@ namespace UnityExplorer.Inspectors
} }
} }
public void CacheMembers(Type type)
{
var list = new List<CacheMember>();
var cachedSigs = new HashSet<string>();
var types = ReflectionHelpers.GetAllBaseTypes(type);
foreach (var declaringType in types)
{
MemberInfo[] infos;
try
{
infos = declaringType.GetMembers(ReflectionHelpers.CommonFlags);
}
catch
{
ExplorerCore.Log($"Exception getting members for type: {declaringType.FullName}");
continue;
}
var target = Target;
#if CPP
try
{
target = target.Il2CppCast(declaringType);
}
catch //(Exception e)
{
//ExplorerCore.LogWarning("Excepting casting " + target.GetType().FullName + " to " + declaringType.FullName);
}
#endif
foreach (var member in infos)
{
try
{
// make sure member type is Field, Method or Property (4 / 8 / 16)
int m = (int)member.MemberType;
if (m < 4 || m > 16)
continue;
//ExplorerCore.Log($"Trying to cache member {sig}...");
//ExplorerCore.Log(member.DeclaringType.FullName + "." + member.Name);
var pi = member as PropertyInfo;
var mi = member as MethodInfo;
if (this is StaticInspector)
{
if (member is FieldInfo fi && !fi.IsStatic) continue;
else if (pi != null && !pi.GetAccessors(true)[0].IsStatic) continue;
else if (mi != null && !mi.IsStatic) continue;
}
// check blacklisted members
var sig = $"{member.DeclaringType.Name}.{member.Name}";
if (s_typeAndMemberBlacklist.Any(it => sig.Contains(it)))
continue;
if (s_methodStartsWithBlacklist.Any(it => member.Name.StartsWith(it)))
continue;
if (mi != null)
AppendParams(mi.GetParameters());
else if (pi != null)
AppendParams(pi.GetIndexParameters());
void AppendParams(ParameterInfo[] _args)
{
sig += " (";
foreach (var param in _args)
sig += $"{param.ParameterType.Name} {param.Name}, ";
sig += ")";
}
if (cachedSigs.Contains(sig))
continue;
try
{
CacheMember cached;
if (mi != null && CacheMember.CanProcessArgs(mi.GetParameters()))
cached = new CacheMethod(mi, target);
else if (pi != null && CacheMember.CanProcessArgs(pi.GetIndexParameters()))
cached = new CacheProperty(pi, target);
else if (member is FieldInfo fi)
cached = new CacheField(fi, target);
else
continue;
cached.m_parentContent = m_scrollContent;
if (cached != null)
{
cachedSigs.Add(sig);
list.Add(cached);
}
}
catch (Exception e)
{
ExplorerCore.LogWarning($"Exception caching member {sig}!");
ExplorerCore.Log(e.ToString());
}
}
catch (Exception e)
{
ExplorerCore.LogWarning($"Exception caching member {member.DeclaringType.FullName}.{member.Name}!");
ExplorerCore.Log(e.ToString());
}
}
}
var typeList = types.ToList();
var sorted = new List<CacheMember>();
sorted.AddRange(list.Where(it => it is CacheMethod)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheProperty)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
sorted.AddRange(list.Where(it => it is CacheField)
.OrderBy(it => typeList.IndexOf(it.DeclaringType))
.ThenBy(it => it.NameForFiltering));
m_allMembers = sorted.ToArray();
// ExplorerCore.Log("Cached " + m_allMembers.Length + " members");
}
#region UI CONSTRUCTION #region UI CONSTRUCTION
internal void ConstructUI() internal void ConstructUI()
@ -578,7 +542,7 @@ namespace UnityExplorer.Inspectors
internal void ConstructOptionsArea() internal void ConstructOptionsArea()
{ {
var optionsRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1,1,1,0)); var optionsRowObj = UIFactory.CreateHorizontalGroup(Content, new Color(1, 1, 1, 0));
var optionsLayout = optionsRowObj.AddComponent<LayoutElement>(); var optionsLayout = optionsRowObj.AddComponent<LayoutElement>();
optionsLayout.minHeight = 25; optionsLayout.minHeight = 25;
var optionsGroup = optionsRowObj.GetComponent<HorizontalLayoutGroup>(); var optionsGroup = optionsRowObj.GetComponent<HorizontalLayoutGroup>();
@ -617,7 +581,7 @@ namespace UnityExplorer.Inspectors
internal void ConstructMemberList() internal void ConstructMemberList()
{ {
var scrollobj = UIFactory.CreateScrollView(Content, out m_scrollContent, out m_sliderScroller, new Color(0.08f, 0.08f, 0.08f)); var scrollobj = UIFactory.CreateScrollView(Content, out m_scrollContent, out m_sliderScroller, new Color(0.05f, 0.05f, 0.05f));
m_scrollContentRect = m_scrollContent.GetComponent<RectTransform>(); m_scrollContentRect = m_scrollContent.GetComponent<RectTransform>();

View File

@ -77,11 +77,6 @@ namespace UnityExplorer.UI
catch { } catch { }
// Setup Harmony Patches // Setup Harmony Patches
TryPatch(typeof(EventSystem),
"current",
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_EventSystem_set_current))),
true);
TryPatch(typeof(Cursor), TryPatch(typeof(Cursor),
"lockState", "lockState",
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_lockState))), new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_lockState))),
@ -91,6 +86,17 @@ namespace UnityExplorer.UI
"visible", "visible",
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_visible))), new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_visible))),
true); true);
#if BIE
#if CPP
// temporarily disabling this patch in BepInEx il2cpp as it's causing a crash in some games.
return;
#endif
#endif
TryPatch(typeof(EventSystem),
"current",
new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_EventSystem_set_current))),
true);
} }
catch (Exception e) catch (Exception e)
{ {
@ -120,10 +126,10 @@ namespace UnityExplorer.UI
harmony.Patch(prop.GetGetMethod(), postfix: patch); harmony.Patch(prop.GetGetMethod(), postfix: patch);
} }
} }
catch // (Exception e) catch (Exception e)
{ {
//string suf = setter ? "set_" : "get_"; string suf = setter ? "set_" : "get_";
//ExplorerCore.Log($"Unable to patch {type.Name}.{suf}{property}: {e.Message}"); ExplorerCore.Log($"Unable to patch {type.Name}.{suf}{property}: {e.Message}");
} }
} }

View File

@ -42,10 +42,10 @@ namespace UnityExplorer.UI
public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null) public static string ParseFullSyntax(Type type, bool includeNamespace, MemberInfo memberInfo = null)
{ {
string ret = "";
if (type == null) if (type == null)
return "????????????"; throw new ArgumentNullException("type");
string ret = "";
if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter)) if (type.IsGenericParameter || (type.HasElementType && type.GetElementType().IsGenericParameter))
{ {