- Added ability to cycle through "pages" with lists/arrays and with search results. Also reduced default array display limit to 20 elements, since we can now just cycle through pages.
- Some backend restructuring / cleanups
This commit is contained in:
sinaioutlander
2020-08-13 00:06:39 +10:00
parent 13c2d6b92d
commit a2677e2321
30 changed files with 944 additions and 724 deletions

View File

@ -9,9 +9,9 @@ using UnityEngine.SceneManagement;
namespace Explorer
{
public class GameObjectWindow : WindowManager.UIWindow
public class GameObjectWindow : UIWindow
{
public override Il2CppSystem.String Name { get => "GameObject Inspector"; set => Name = value; }
public override string Name { get => "GameObject Inspector"; set => Name = value; }
public GameObject m_object;

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnhollowerBaseLib;
namespace Explorer
{
public class FieldInfoHolder : MemberInfoHolder
{
public FieldInfo fieldInfo;
public object m_value;
public FieldInfoHolder(Type _type, FieldInfo _fieldInfo)
{
classType = _type;
fieldInfo = _fieldInfo;
}
public override void UpdateValue(object obj)
{
m_value = fieldInfo.GetValue(fieldInfo.IsStatic ? null : obj);
}
public override void Draw(ReflectionWindow window)
{
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, ref this.arrayOffset, this.fieldInfo, window.m_rect, window.m_object, SetValue);
}
public override void SetValue(object obj)
{
if (fieldInfo.FieldType.IsEnum)
{
if (System.Enum.Parse(fieldInfo.FieldType, m_value.ToString()) is object enumValue && enumValue != null)
{
m_value = enumValue;
}
}
else if (fieldInfo.FieldType.IsPrimitive)
{
if (fieldInfo.FieldType == typeof(float))
{
if (float.TryParse(m_value.ToString(), out float f))
{
m_value = f;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a float!");
}
}
else if (fieldInfo.FieldType == typeof(double))
{
if (double.TryParse(m_value.ToString(), out double d))
{
m_value = d;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a double!");
}
}
else if (fieldInfo.FieldType != typeof(bool))
{
if (int.TryParse(m_value.ToString(), out int i))
{
m_value = i;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to an integer! type: " + fieldInfo.FieldType);
}
}
}
fieldInfo.SetValue(fieldInfo.IsStatic ? null : obj, m_value);
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Explorer
{
public abstract class MemberInfoHolder
{
public Type classType;
public bool IsExpanded = false;
public int arrayOffset = 0;
public abstract void Draw(ReflectionWindow window);
public abstract void UpdateValue(object obj);
public abstract void SetValue(object obj);
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnhollowerBaseLib;
namespace Explorer
{
public class PropertyInfoHolder : MemberInfoHolder
{
public PropertyInfo propInfo;
public object m_value;
public PropertyInfoHolder(Type _type, PropertyInfo _propInfo)
{
classType = _type;
propInfo = _propInfo;
}
public override void Draw(ReflectionWindow window)
{
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, ref this.arrayOffset, this.propInfo, window.m_rect, window.m_object, SetValue);
}
public override void UpdateValue(object obj)
{
try
{
if (obj is Il2CppSystem.Object ilObject)
{
var declaringType = this.propInfo.DeclaringType;
if (declaringType == typeof(Il2CppObjectBase))
{
m_value = ilObject.Pointer;
}
else
{
var cast = CppExplorer.Il2CppCast(obj, declaringType);
m_value = this.propInfo.GetValue(cast, null);
}
}
else
{
m_value = this.propInfo.GetValue(obj, null);
}
}
catch (Exception e)
{
MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name);
MelonLogger.Log(e.GetType() + ", " + e.Message);
var inner = e.InnerException;
while (inner != null)
{
MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message);
inner = inner.InnerException;
}
m_value = null;
}
}
public override void SetValue(object obj)
{
try
{
if (propInfo.PropertyType.IsEnum)
{
if (System.Enum.Parse(propInfo.PropertyType, m_value.ToString()) is object enumValue && enumValue != null)
{
m_value = enumValue;
}
}
else if (propInfo.PropertyType.IsPrimitive)
{
if (propInfo.PropertyType == typeof(float))
{
if (float.TryParse(m_value.ToString(), out float f))
{
m_value = f;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a float!");
}
}
else if (propInfo.PropertyType == typeof(double))
{
if (double.TryParse(m_value.ToString(), out double d))
{
m_value = d;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a double!");
}
}
else if (propInfo.PropertyType != typeof(bool))
{
if (int.TryParse(m_value.ToString(), out int i))
{
m_value = i;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to an integer! type: " + propInfo.PropertyType);
}
}
}
var declaring = propInfo.DeclaringType;
var cast = CppExplorer.Il2CppCast(obj, declaring);
propInfo.SetValue(propInfo.GetAccessors()[0].IsStatic ? null : cast, m_value, null);
}
catch
{
//MelonLogger.Log("Exception trying to set property " + this.propInfo.Name);
}
}
}
}

View File

@ -10,9 +10,9 @@ using UnityEngine;
namespace Explorer
{
public class ReflectionWindow : WindowManager.UIWindow
public class ReflectionWindow : UIWindow
{
public override Il2CppSystem.String Name { get => "Object Reflection"; set => Name = value; }
public override string Name { get => "Object Reflection"; set => Name = value; }
public Type m_objectType;
public object m_object;
@ -351,204 +351,5 @@ namespace Explorer
}
}
}
/* *********************
* PROPERTYINFO HOLDER
*/
public class PropertyInfoHolder
{
public Type classType;
public PropertyInfo propInfo;
public object m_value;
public bool IsExpanded;
public PropertyInfoHolder(Type _type, PropertyInfo _propInfo)
{
classType = _type;
propInfo = _propInfo;
}
public void Draw(ReflectionWindow window)
{
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.propInfo, window.m_rect, window.m_object, SetValue);
}
public void UpdateValue(object obj)
{
try
{
if (obj is Il2CppSystem.Object ilObject)
{
var declaringType = this.propInfo.DeclaringType;
if (declaringType == typeof(Il2CppObjectBase))
{
m_value = ilObject.Pointer;
}
else
{
var cast = CppExplorer.Il2CppCast(obj, declaringType);
m_value = this.propInfo.GetValue(cast, null);
}
}
else
{
m_value = this.propInfo.GetValue(obj, null);
}
}
catch (Exception e)
{
MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name);
MelonLogger.Log(e.GetType() + ", " + e.Message);
var inner = e.InnerException;
while (inner != null)
{
MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message);
inner = inner.InnerException;
}
m_value = null;
}
}
public void SetValue(object obj)
{
try
{
if (propInfo.PropertyType.IsEnum)
{
if (System.Enum.Parse(propInfo.PropertyType, m_value.ToString()) is object enumValue && enumValue != null)
{
m_value = enumValue;
}
}
else if (propInfo.PropertyType.IsPrimitive)
{
if (propInfo.PropertyType == typeof(float))
{
if (float.TryParse(m_value.ToString(), out float f))
{
m_value = f;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a float!");
}
}
else if (propInfo.PropertyType == typeof(double))
{
if (double.TryParse(m_value.ToString(), out double d))
{
m_value = d;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a double!");
}
}
else if (propInfo.PropertyType != typeof(bool))
{
if (int.TryParse(m_value.ToString(), out int i))
{
m_value = i;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to an integer! type: " + propInfo.PropertyType);
}
}
}
var declaring = propInfo.DeclaringType;
var cast = CppExplorer.Il2CppCast(obj, declaring);
propInfo.SetValue(propInfo.GetAccessors()[0].IsStatic ? null : cast, m_value, null);
}
catch
{
//MelonLogger.Log("Exception trying to set property " + this.propInfo.Name);
}
}
}
/* *********************
* FIELDINFO HOLDER
*/
public class FieldInfoHolder
{
public Type classType;
public FieldInfo fieldInfo;
public object m_value;
public bool IsExpanded;
public FieldInfoHolder(Type _type, FieldInfo _fieldInfo)
{
classType = _type;
fieldInfo = _fieldInfo;
}
public void UpdateValue(object obj)
{
m_value = fieldInfo.GetValue(fieldInfo.IsStatic ? null : obj);
}
public void Draw(ReflectionWindow window)
{
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.fieldInfo, window.m_rect, window.m_object, SetValue);
}
public void SetValue(object obj)
{
if (fieldInfo.FieldType.IsEnum)
{
if (System.Enum.Parse(fieldInfo.FieldType, m_value.ToString()) is object enumValue && enumValue != null)
{
m_value = enumValue;
}
}
else if (fieldInfo.FieldType.IsPrimitive)
{
if (fieldInfo.FieldType == typeof(float))
{
if (float.TryParse(m_value.ToString(), out float f))
{
m_value = f;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a float!");
}
}
else if (fieldInfo.FieldType == typeof(double))
{
if (double.TryParse(m_value.ToString(), out double d))
{
m_value = d;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to a double!");
}
}
else if (fieldInfo.FieldType != typeof(bool))
{
if (int.TryParse(m_value.ToString(), out int i))
{
m_value = i;
}
else
{
MelonLogger.LogWarning("Cannot parse " + m_value.ToString() + " to an integer! type: " + fieldInfo.FieldType);
}
}
}
fieldInfo.SetValue(fieldInfo.IsStatic ? null : obj, m_value);
}
}
}
}

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Harmony;
using MelonLoader;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace Explorer
{
public abstract class UIWindow
{
public abstract string Name { get; set; }
public object Target;
public int windowID;
public Rect m_rect = new Rect(0, 0, 550, 700);
public Vector2 scroll = Vector2.zero;
public static UIWindow CreateWindow<T>(object target) where T : UIWindow
{
//var component = (UIWindow)AddToGameObject<T>(Instance.gameObject);
var window = Activator.CreateInstance<T>();
window.Target = target;
window.windowID = WindowManager.NextWindowID();
window.m_rect = WindowManager.GetNewWindowRect();
WindowManager.Windows.Add(window);
window.Init();
return window;
}
public void DestroyWindow()
{
try
{
WindowManager.Windows.Remove(this);
}
catch (Exception e)
{
MelonLogger.Log("Exception removing Window from WindowManager.Windows list!");
MelonLogger.Log($"{e.GetType()} : {e.Message}\r\n{e.StackTrace}");
}
//Destroy(this);
}
public abstract void Init();
public abstract void WindowFunction(int windowID);
public abstract void Update();
public void OnGUI()
{
if (CppExplorer.ShowMenu)
{
var origSkin = GUI.skin;
GUI.skin = UIStyles.WindowSkin;
m_rect = GUI.Window(windowID, m_rect, (GUI.WindowFunction)WindowFunction, Name);
GUI.skin = origSkin;
}
}
public void Header()
{
GUI.DragWindow(new Rect(0, 0, m_rect.width - 90, 20));
if (GUI.Button(new Rect(m_rect.width - 90, 2, 80, 20), "<color=red><b>X</b></color>"))
{
DestroyWindow();
return;
}
}
}
}