Revert "Revert "1.31""

This reverts commit e58cf45e07.
This commit is contained in:
sinaioutlander 2020-08-12 18:26:13 +10:00
parent e58cf45e07
commit 2f3bb80eeb
19 changed files with 606 additions and 461 deletions

View File

@ -16,7 +16,7 @@ namespace Explorer
public const string ID = "com.sinai.cppexplorer";
public const string NAME = "IL2CPP Runtime Explorer";
public const string VERSION = "1.3.0";
public const string VERSION = "1.3.1";
public const string AUTHOR = "Sinai";
// fields

View File

@ -112,7 +112,6 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ILBehaviour.cs" />
<Compile Include="CppExplorer.cs" />
<Compile Include="MainMenu\Pages\ConsolePage.cs" />
<Compile Include="MainMenu\Pages\Console\REPL.cs" />

View File

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using MelonLoader;
using UnhollowerRuntimeLib;
namespace Explorer
{
//public class ILBehaviour : MonoBehaviour
//{
// public ILBehaviour(IntPtr intPtr) : base(intPtr) { }
// public static T AddToGameObject<T>(GameObject _go) where T : ILBehaviour
// {
// Il2CppSystem.Type ilType = UnhollowerRuntimeLib.Il2CppType.Of<T>();
// if (ilType == null)
// {
// MelonLogger.Log("Error - could not get MB as ilType");
// return null;
// }
// var obj = typeof(T)
// .GetConstructor(new Type[] { typeof(IntPtr) })
// .Invoke(new object[] { _go.AddComponent(UnhollowerRuntimeLib.Il2CppType.Of<T>()).Pointer });
// return (T)obj;
// }
//}
}

View File

@ -93,9 +93,13 @@ namespace Explorer
return;
}
try
{
m_objectType = type;
GetFields(m_object);
GetProperties(m_object);
}
catch { }
UpdateValues();
}
@ -292,8 +296,20 @@ namespace Explorer
foreach (var type in types)
{
foreach (var pi in type.GetProperties(At.flags))
PropertyInfo[] propInfos = new PropertyInfo[0];
try
{
propInfos = type.GetProperties(At.flags);
}
catch (TypeLoadException)
{
MelonLogger.Log($"Couldn't get Properties for Type '{type.Name}', it may not support Il2Cpp Reflection at the moment.");
}
foreach (var pi in propInfos)
{
// this member causes a crash when inspected, so just skipping it for now.
if (pi.Name == "Il2CppType")
{
continue;
@ -346,6 +362,7 @@ namespace Explorer
public Type classType;
public PropertyInfo propInfo;
public object m_value;
public bool IsExpanded;
public PropertyInfoHolder(Type _type, PropertyInfo _propInfo)
{
@ -355,14 +372,7 @@ namespace Explorer
public void Draw(ReflectionWindow window)
{
if (propInfo.CanWrite)
{
UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object, SetValue);
}
else
{
UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object);
}
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.propInfo, window.m_rect, window.m_object, SetValue);
}
public void UpdateValue(object obj)
@ -389,15 +399,15 @@ namespace Explorer
}
catch (Exception e)
{
//MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name);
//MelonLogger.Log(e.GetType() + ", " + e.Message);
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;
//}
var inner = e.InnerException;
while (inner != null)
{
MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message);
inner = inner.InnerException;
}
m_value = null;
}
@ -473,6 +483,7 @@ namespace Explorer
public Type classType;
public FieldInfo fieldInfo;
public object m_value;
public bool IsExpanded;
public FieldInfoHolder(Type _type, FieldInfo _fieldInfo)
{
@ -487,16 +498,7 @@ namespace Explorer
public void Draw(ReflectionWindow window)
{
bool canSet = !(fieldInfo.IsLiteral && !fieldInfo.IsInitOnly);
if (canSet)
{
UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object, SetValue);
}
else
{
UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object);
}
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.fieldInfo, window.m_rect, window.m_object, SetValue);
}
public void SetValue(object obj)

View File

@ -36,17 +36,17 @@ namespace Explorer
return MB.FindAll<T>();
}
[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")]
public static object runCoroutine(IEnumerator i)
{
return MB.RunCoroutine(i);
}
//[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")]
//public static object runCoroutine(IEnumerator i)
//{
// return MB.RunCoroutine(i);
//}
[Documentation("endCoroutine(co) - ends a Unity coroutine.")]
public static void endCoroutine(Coroutine c)
{
MB.EndCoroutine(c);
}
//[Documentation("endCoroutine(co) - ends a Unity coroutine.")]
//public static void endCoroutine(Coroutine c)
//{
// MB.EndCoroutine(c);
//}
////[Documentation("type<T>() - obtain type info about a type T. Provides some Reflection helpers.")]
////public static TypeHelper type<T>()

View File

@ -21,14 +21,14 @@ namespace Explorer
return FindObjectsOfType<T>();
}
public object RunCoroutine(IEnumerator enumerator)
{
return MelonCoroutines.Start(enumerator);
}
//public object RunCoroutine(IEnumerator enumerator)
//{
// return MelonCoroutines.Start(enumerator);
//}
public void EndCoroutine(Coroutine c)
{
StopCoroutine(c);
}
//public void EndCoroutine(Coroutine c)
//{
// StopCoroutine(c);
//}
}
}

View File

@ -20,12 +20,13 @@ namespace Explorer
// gameobject list
private Transform m_currentTransform;
private List<GameObject> m_objectList = new List<GameObject>();
private List<GameObjectCache> m_objectList = new List<GameObjectCache>();
private float m_timeOfLastUpdate = -1f;
// search bar
private bool m_searching = false;
private string m_searchInput = "";
private List<GameObject> m_searchResults = new List<GameObject>();
private List<GameObjectCache> m_searchResults = new List<GameObjectCache>();
// ------------ Init and Update ------------ //
@ -40,17 +41,24 @@ namespace Explorer
m_currentTransform = null;
CancelSearch();
}
public override void Update()
{
if (Time.time - m_timeOfLastUpdate < 1f)
{
return;
}
m_timeOfLastUpdate = Time.time;
var start = Time.realtimeSinceStartup;
if (!m_searching)
{
m_objectList = new List<GameObject>();
m_objectList = new List<GameObjectCache>();
if (m_currentTransform)
{
var noChildren = new List<GameObject>();
var endAppend = new List<GameObjectCache>();
for (int i = 0; i < m_currentTransform.childCount; i++)
{
var child = m_currentTransform.GetChild(i);
@ -58,13 +66,13 @@ namespace Explorer
if (child)
{
if (child.childCount > 0)
m_objectList.Add(child.gameObject);
m_objectList.Add(new GameObjectCache(child.gameObject));
else
noChildren.Add(child.gameObject);
endAppend.Add(new GameObjectCache(child.gameObject));
}
}
m_objectList.AddRange(noChildren);
noChildren = null;
m_objectList.AddRange(endAppend);
endAppend = null;
}
else
{
@ -74,11 +82,11 @@ namespace Explorer
// add objects with children first
foreach (var obj in rootObjects.Where(x => x.transform.childCount > 0))
{
m_objectList.Add(obj);
m_objectList.Add(new GameObjectCache(obj));
}
foreach (var obj in rootObjects.Where(x => x.transform.childCount == 0))
{
m_objectList.Add(obj);
m_objectList.Add(new GameObjectCache(obj));
}
}
}
@ -161,10 +169,13 @@ namespace Explorer
if (m_objectList.Count > 0)
{
var start = Time.realtimeSinceStartup;
foreach (var obj in m_objectList)
{
UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
//UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170);
}
var diff = Time.realtimeSinceStartup - start;
}
else
{
@ -184,7 +195,8 @@ namespace Explorer
{
foreach (var obj in m_searchResults)
{
UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
//UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170);
}
}
else
@ -232,19 +244,54 @@ namespace Explorer
m_searching = false;
}
public List<GameObject> SearchSceneObjects(string _search)
public List<GameObjectCache> SearchSceneObjects(string _search)
{
var matches = new List<GameObject>();
var matches = new List<GameObjectCache>();
foreach (var obj in Resources.FindObjectsOfTypeAll<GameObject>())
{
if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene)
{
matches.Add(obj);
matches.Add(new GameObjectCache(obj));
}
}
return matches;
}
public class GameObjectCache
{
public GameObject RefGameObject;
public string Label;
public Color EnabledColor;
public int ChildCount;
public GameObjectCache(GameObject obj)
{
RefGameObject = obj;
ChildCount = obj.transform.childCount;
Label = (ChildCount > 0) ? "[" + obj.transform.childCount + " children] " : "";
Label += obj.name;
bool enabled = obj.activeSelf;
int childCount = obj.transform.childCount;
if (enabled)
{
if (childCount > 0)
{
EnabledColor = Color.green;
}
else
{
EnabledColor = UIStyles.LightGreen;
}
}
else
{
EnabledColor = Color.red;
}
}
}
}
}

View File

@ -91,7 +91,8 @@ namespace Explorer
{
var obj = m_searchResults[i];
UIStyles.DrawValue(ref obj, _temprect);
bool _ = false;
UIStyles.DrawValue(ref obj, _temprect, ref _);
}
}
else
@ -262,7 +263,6 @@ namespace Explorer
{
var findType = CppExplorer.GetType(_type);
type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName);
MelonLogger.Log("Got type: " + type.AssemblyQualifiedName);
}
catch (Exception e)
{

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using Il2CppSystem.Collections;
using Il2CppSystem.Reflection;
//using Il2CppSystem.Reflection;
using MelonLoader;
using UnhollowerBaseLib;
using UnityEngine;
@ -15,6 +15,8 @@ namespace Explorer
{
public class UIStyles
{
public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
public static GUISkin WindowSkin
{
get
@ -115,42 +117,48 @@ namespace Explorer
// helper for drawing a styled button for a GameObject or Transform
public static void GameobjButton(GameObject obj, Action<GameObject> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
{
if (obj == null)
bool children = obj.transform.childCount > 0;
string label = children ? "[" + obj.transform.childCount + " children] " : "";
label += obj.name;
bool enabled = obj.activeSelf;
int childCount = obj.transform.childCount;
Color color;
if (enabled)
{
if (childCount > 0)
{
color = Color.green;
}
else
{
color = LightGreen;
}
}
else
{
color = Color.red;
}
FastGameobjButton(obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width);
}
public static void FastGameobjButton(GameObject obj, Color activeColor, string label, bool enabled, Action<GameObject> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
{
if (!obj)
{
GUILayout.Label("<i><color=red>null</color></i>", null);
return;
}
bool enabled = obj.activeSelf;
bool children = obj.transform.childCount > 0;
// ------ toggle active button ------
GUILayout.BeginHorizontal(null);
GUI.skin.button.alignment = TextAnchor.UpperLeft;
// ------ build name ------
string label = children ? "[" + obj.transform.childCount + " children] " : "";
label += obj.name;
// ------ Color -------
if (enabled)
{
if (children)
{
GUI.color = Color.green;
}
else
{
GUI.color = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
}
}
else
{
GUI.color = Color.red;
}
// ------ toggle active button ------
GUI.color = activeColor;
enabled = GUILayout.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
if (obj.activeSelf != enabled)
@ -188,21 +196,34 @@ namespace Explorer
GUILayout.EndHorizontal();
}
public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
public static void DrawMember(ref object value, ref bool isExpanded, MemberInfo memberInfo, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
{
GUILayout.Label("<color=cyan>" + memberName + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
GUILayout.Label("<color=cyan>" + memberInfo.Name + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet);
string valueType = "";
bool canWrite = true;
if (memberInfo is FieldInfo fi)
{
valueType = fi.FieldType.Name;
canWrite = !(fi.IsLiteral && !fi.IsInitOnly);
}
else if (memberInfo is PropertyInfo pi)
{
valueType = pi.PropertyType.Name;
canWrite = pi.CanWrite;
}
public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
DrawValue(ref value, rect, ref isExpanded, valueType, (canWrite ? setTarget : null), (canWrite ? setAction : null), autoSet);
}
public static void DrawValue(ref object value, Rect rect, ref bool isExpanded, string nullValueType = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
{
if (value == null)
{
GUILayout.Label("<i>null (" + nullValueType + ")</i>", null);
return;
}
else
{
var valueType = value.GetType();
if (valueType.IsPrimitive || value.GetType() == typeof(string))
{
@ -220,7 +241,7 @@ namespace Explorer
go = (value as GameObject);
}
UIStyles.GameobjButton(go, null, false, rect.width - 250);
GameobjButton(go, null, false, rect.width - 250);
}
else if (valueType.IsEnum)
{
@ -258,14 +279,31 @@ namespace Explorer
int count = enumerable.Cast<object>().Count();
if (!isExpanded)
{
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
isExpanded = true;
}
}
else
{
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
isExpanded = false;
}
}
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
string btnLabel = "<color=yellow>[" + count + "] " + valueType + "</color>";
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) }))
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 260) }))
{
WindowManager.InspectObject(value, out bool _);
}
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
if (isExpanded)
{
var enumerator = enumerable.GetEnumerator();
if (enumerator != null)
{
@ -315,6 +353,7 @@ namespace Explorer
}
}
}
}
else
{
var label = value.ToString();
@ -356,7 +395,25 @@ namespace Explorer
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
}
}
}
//public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
//{
// GUILayout.Label("<color=cyan>" + memberName + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
// DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet);
//}
//public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
//{
// if (value == null)
// {
// GUILayout.Label("<i>null (" + nullValueType + ")</i>", null);
// }
// else
// {
// }
//}
// Helper for drawing primitive values (with Apply button)

View File

@ -16,7 +16,7 @@ namespace Explorer
public const string ID = "com.sinai.cppexplorer";
public const string NAME = "IL2CPP Runtime Explorer";
public const string VERSION = "1.3.0";
public const string VERSION = "1.3.1";
public const string AUTHOR = "Sinai";
// fields

View File

@ -104,7 +104,6 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ILBehaviour.cs" />
<Compile Include="CppExplorer.cs" />
<Compile Include="MainMenu\Pages\ConsolePage.cs" />
<Compile Include="MainMenu\Pages\Console\REPL.cs" />

View File

@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using MelonLoader;
using UnhollowerRuntimeLib;
namespace Explorer
{
//public class ILBehaviour : MonoBehaviour
//{
// public ILBehaviour(IntPtr intPtr) : base(intPtr) { }
// public static T AddToGameObject<T>(GameObject _go) where T : ILBehaviour
// {
// Il2CppSystem.Type ilType = UnhollowerRuntimeLib.Il2CppType.Of<T>();
// if (ilType == null)
// {
// MelonLogger.Log("Error - could not get MB as ilType");
// return null;
// }
// var obj = typeof(T)
// .GetConstructor(new Type[] { typeof(IntPtr) })
// .Invoke(new object[] { _go.AddComponent(UnhollowerRuntimeLib.Il2CppType.Of<T>()).Pointer });
// return (T)obj;
// }
//}
}

View File

@ -93,9 +93,13 @@ namespace Explorer
return;
}
try
{
m_objectType = type;
GetFields(m_object);
GetProperties(m_object);
}
catch { }
UpdateValues();
}
@ -292,8 +296,20 @@ namespace Explorer
foreach (var type in types)
{
foreach (var pi in type.GetProperties(At.flags))
PropertyInfo[] propInfos = new PropertyInfo[0];
try
{
propInfos = type.GetProperties(At.flags);
}
catch (TypeLoadException)
{
MelonLogger.Log($"Couldn't get Properties for Type '{type.Name}', it may not support Il2Cpp Reflection at the moment.");
}
foreach (var pi in propInfos)
{
// this member causes a crash when inspected, so just skipping it for now.
if (pi.Name == "Il2CppType")
{
continue;
@ -346,6 +362,7 @@ namespace Explorer
public Type classType;
public PropertyInfo propInfo;
public object m_value;
public bool IsExpanded;
public PropertyInfoHolder(Type _type, PropertyInfo _propInfo)
{
@ -355,14 +372,7 @@ namespace Explorer
public void Draw(ReflectionWindow window)
{
if (propInfo.CanWrite)
{
UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object, SetValue);
}
else
{
UIStyles.DrawMember(ref m_value, propInfo.PropertyType.Name, propInfo.Name, window.m_rect, window.m_object);
}
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.propInfo, window.m_rect, window.m_object, SetValue);
}
public void UpdateValue(object obj)
@ -389,15 +399,15 @@ namespace Explorer
}
catch (Exception e)
{
//MelonLogger.Log("Exception on PropertyInfoHolder.UpdateValue, Name: " + this.propInfo.Name);
//MelonLogger.Log(e.GetType() + ", " + e.Message);
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;
//}
var inner = e.InnerException;
while (inner != null)
{
MelonLogger.Log("inner: " + inner.GetType() + ", " + inner.Message);
inner = inner.InnerException;
}
m_value = null;
}
@ -473,6 +483,7 @@ namespace Explorer
public Type classType;
public FieldInfo fieldInfo;
public object m_value;
public bool IsExpanded;
public FieldInfoHolder(Type _type, FieldInfo _fieldInfo)
{
@ -487,16 +498,7 @@ namespace Explorer
public void Draw(ReflectionWindow window)
{
bool canSet = !(fieldInfo.IsLiteral && !fieldInfo.IsInitOnly);
if (canSet)
{
UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object, SetValue);
}
else
{
UIStyles.DrawMember(ref m_value, fieldInfo.FieldType.Name, fieldInfo.Name, window.m_rect, window.m_object);
}
UIStyles.DrawMember(ref m_value, ref this.IsExpanded, this.fieldInfo, window.m_rect, window.m_object, SetValue);
}
public void SetValue(object obj)

View File

@ -36,17 +36,17 @@ namespace Explorer
return MB.FindAll<T>();
}
[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")]
public static object runCoroutine(IEnumerator i)
{
return MB.RunCoroutine(i);
}
//[Documentation("runCoroutine(enumerator) - runs an IEnumerator as a Unity coroutine.")]
//public static object runCoroutine(IEnumerator i)
//{
// return MB.RunCoroutine(i);
//}
[Documentation("endCoroutine(co) - ends a Unity coroutine.")]
public static void endCoroutine(Coroutine c)
{
MB.EndCoroutine(c);
}
//[Documentation("endCoroutine(co) - ends a Unity coroutine.")]
//public static void endCoroutine(Coroutine c)
//{
// MB.EndCoroutine(c);
//}
////[Documentation("type<T>() - obtain type info about a type T. Provides some Reflection helpers.")]
////public static TypeHelper type<T>()

View File

@ -21,14 +21,14 @@ namespace Explorer
return FindObjectsOfType<T>();
}
public object RunCoroutine(IEnumerator enumerator)
{
return MelonCoroutines.Start(enumerator);
}
//public object RunCoroutine(IEnumerator enumerator)
//{
// return MelonCoroutines.Start(enumerator);
//}
public void EndCoroutine(Coroutine c)
{
StopCoroutine(c);
}
//public void EndCoroutine(Coroutine c)
//{
// StopCoroutine(c);
//}
}
}

View File

@ -20,12 +20,13 @@ namespace Explorer
// gameobject list
private Transform m_currentTransform;
private List<GameObject> m_objectList = new List<GameObject>();
private List<GameObjectCache> m_objectList = new List<GameObjectCache>();
private float m_timeOfLastUpdate = -1f;
// search bar
private bool m_searching = false;
private string m_searchInput = "";
private List<GameObject> m_searchResults = new List<GameObject>();
private List<GameObjectCache> m_searchResults = new List<GameObjectCache>();
// ------------ Init and Update ------------ //
@ -40,17 +41,24 @@ namespace Explorer
m_currentTransform = null;
CancelSearch();
}
public override void Update()
{
if (Time.time - m_timeOfLastUpdate < 1f)
{
return;
}
m_timeOfLastUpdate = Time.time;
var start = Time.realtimeSinceStartup;
if (!m_searching)
{
m_objectList = new List<GameObject>();
m_objectList = new List<GameObjectCache>();
if (m_currentTransform)
{
var noChildren = new List<GameObject>();
var endAppend = new List<GameObjectCache>();
for (int i = 0; i < m_currentTransform.childCount; i++)
{
var child = m_currentTransform.GetChild(i);
@ -58,13 +66,13 @@ namespace Explorer
if (child)
{
if (child.childCount > 0)
m_objectList.Add(child.gameObject);
m_objectList.Add(new GameObjectCache(child.gameObject));
else
noChildren.Add(child.gameObject);
endAppend.Add(new GameObjectCache(child.gameObject));
}
}
m_objectList.AddRange(noChildren);
noChildren = null;
m_objectList.AddRange(endAppend);
endAppend = null;
}
else
{
@ -74,11 +82,11 @@ namespace Explorer
// add objects with children first
foreach (var obj in rootObjects.Where(x => x.transform.childCount > 0))
{
m_objectList.Add(obj);
m_objectList.Add(new GameObjectCache(obj));
}
foreach (var obj in rootObjects.Where(x => x.transform.childCount == 0))
{
m_objectList.Add(obj);
m_objectList.Add(new GameObjectCache(obj));
}
}
}
@ -120,7 +128,8 @@ namespace Explorer
m_currentScene = scenes[index].name;
}
}
GUILayout.Label("<color=cyan>" + m_currentScene + "</color>", null);
GUILayout.Label("<color=cyan>" + m_currentScene + "</color>", null); //new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.EndHorizontal();
// ----- GameObject Search -----
@ -160,10 +169,13 @@ namespace Explorer
if (m_objectList.Count > 0)
{
var start = Time.realtimeSinceStartup;
foreach (var obj in m_objectList)
{
UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
//UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170);
}
var diff = Time.realtimeSinceStartup - start;
}
else
{
@ -183,7 +195,8 @@ namespace Explorer
{
foreach (var obj in m_searchResults)
{
UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
//UIStyles.GameobjButton(obj, SetTransformTarget, true, MainMenu.MainRect.width - 170);
UIStyles.FastGameobjButton(obj.RefGameObject, obj.EnabledColor, obj.Label, obj.RefGameObject.activeSelf, SetTransformTarget, true, MainMenu.MainRect.width - 170);
}
}
else
@ -231,19 +244,54 @@ namespace Explorer
m_searching = false;
}
public List<GameObject> SearchSceneObjects(string _search)
public List<GameObjectCache> SearchSceneObjects(string _search)
{
var matches = new List<GameObject>();
var matches = new List<GameObjectCache>();
foreach (var obj in Resources.FindObjectsOfTypeAll<GameObject>())
{
if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene)
{
matches.Add(obj);
matches.Add(new GameObjectCache(obj));
}
}
return matches;
}
public class GameObjectCache
{
public GameObject RefGameObject;
public string Label;
public Color EnabledColor;
public int ChildCount;
public GameObjectCache(GameObject obj)
{
RefGameObject = obj;
ChildCount = obj.transform.childCount;
Label = (ChildCount > 0) ? "[" + obj.transform.childCount + " children] " : "";
Label += obj.name;
bool enabled = obj.activeSelf;
int childCount = obj.transform.childCount;
if (enabled)
{
if (childCount > 0)
{
EnabledColor = Color.green;
}
else
{
EnabledColor = UIStyles.LightGreen;
}
}
else
{
EnabledColor = Color.red;
}
}
}
}
}

View File

@ -91,7 +91,8 @@ namespace Explorer
{
var obj = m_searchResults[i];
UIStyles.DrawValue(ref obj, _temprect);
bool _ = false;
UIStyles.DrawValue(ref obj, _temprect, ref _);
}
}
else
@ -262,7 +263,6 @@ namespace Explorer
{
var findType = CppExplorer.GetType(_type);
type = Il2CppSystem.Type.GetType(findType.AssemblyQualifiedName);
MelonLogger.Log("Got type: " + type.AssemblyQualifiedName);
}
catch (Exception e)
{

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Reflection;
using System.Text;
using Il2CppSystem.Collections;
using Il2CppSystem.Reflection;
//using Il2CppSystem.Reflection;
using MelonLoader;
using UnhollowerBaseLib;
using UnityEngine;
@ -15,6 +15,8 @@ namespace Explorer
{
public class UIStyles
{
public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
public static GUISkin WindowSkin
{
get
@ -115,42 +117,48 @@ namespace Explorer
// helper for drawing a styled button for a GameObject or Transform
public static void GameobjButton(GameObject obj, Action<GameObject> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
{
if (obj == null)
bool children = obj.transform.childCount > 0;
string label = children ? "[" + obj.transform.childCount + " children] " : "";
label += obj.name;
bool enabled = obj.activeSelf;
int childCount = obj.transform.childCount;
Color color;
if (enabled)
{
if (childCount > 0)
{
color = Color.green;
}
else
{
color = LightGreen;
}
}
else
{
color = Color.red;
}
FastGameobjButton(obj, color, label, obj.activeSelf, specialInspectMethod, showSmallInspectBtn, width);
}
public static void FastGameobjButton(GameObject obj, Color activeColor, string label, bool enabled, Action<GameObject> specialInspectMethod = null, bool showSmallInspectBtn = true, float width = 380)
{
if (!obj)
{
GUILayout.Label("<i><color=red>null</color></i>", null);
return;
}
bool enabled = obj.activeSelf;
bool children = obj.transform.childCount > 0;
// ------ toggle active button ------
GUILayout.BeginHorizontal(null);
GUI.skin.button.alignment = TextAnchor.UpperLeft;
// ------ build name ------
string label = children ? "[" + obj.transform.childCount + " children] " : "";
label += obj.name;
// ------ Color -------
if (enabled)
{
if (children)
{
GUI.color = Color.green;
}
else
{
GUI.color = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
}
}
else
{
GUI.color = Color.red;
}
// ------ toggle active button ------
GUI.color = activeColor;
enabled = GUILayout.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
if (obj.activeSelf != enabled)
@ -188,21 +196,34 @@ namespace Explorer
GUILayout.EndHorizontal();
}
public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
public static void DrawMember(ref object value, ref bool isExpanded, MemberInfo memberInfo, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
{
GUILayout.Label("<color=cyan>" + memberName + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
GUILayout.Label("<color=cyan>" + memberInfo.Name + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet);
string valueType = "";
bool canWrite = true;
if (memberInfo is FieldInfo fi)
{
valueType = fi.FieldType.Name;
canWrite = !(fi.IsLiteral && !fi.IsInitOnly);
}
else if (memberInfo is PropertyInfo pi)
{
valueType = pi.PropertyType.Name;
canWrite = pi.CanWrite;
}
public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
DrawValue(ref value, rect, ref isExpanded, valueType, (canWrite ? setTarget : null), (canWrite ? setAction : null), autoSet);
}
public static void DrawValue(ref object value, Rect rect, ref bool isExpanded, string nullValueType = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
{
if (value == null)
{
GUILayout.Label("<i>null (" + nullValueType + ")</i>", null);
return;
}
else
{
var valueType = value.GetType();
if (valueType.IsPrimitive || value.GetType() == typeof(string))
{
@ -220,7 +241,7 @@ namespace Explorer
go = (value as GameObject);
}
UIStyles.GameobjButton(go, null, false, rect.width - 250);
GameobjButton(go, null, false, rect.width - 250);
}
else if (valueType.IsEnum)
{
@ -258,14 +279,31 @@ namespace Explorer
int count = enumerable.Cast<object>().Count();
if (!isExpanded)
{
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
isExpanded = true;
}
}
else
{
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
isExpanded = false;
}
}
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
string btnLabel = "<color=yellow>[" + count + "] " + valueType + "</color>";
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 230) }))
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(rect.width - 260) }))
{
WindowManager.InspectObject(value, out bool _);
}
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
if (isExpanded)
{
var enumerator = enumerable.GetEnumerator();
if (enumerator != null)
{
@ -315,6 +353,7 @@ namespace Explorer
}
}
}
}
else
{
var label = value.ToString();
@ -356,7 +395,25 @@ namespace Explorer
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
}
}
}
//public static void DrawMember(ref object value, string valueType, string memberName, Rect rect, object setTarget = null, Action<object> setAction = null, float labelWidth = 180, bool autoSet = false)
//{
// GUILayout.Label("<color=cyan>" + memberName + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
// DrawValue(ref value, rect, valueType, memberName, setTarget, setAction, autoSet);
//}
//public static void DrawValue(ref object value, Rect rect, string nullValueType = null, string memberName = null, object setTarget = null, Action<object> setAction = null, bool autoSet = false)
//{
// if (value == null)
// {
// GUILayout.Label("<i>null (" + nullValueType + ")</i>", null);
// }
// else
// {
// }
//}
// Helper for drawing primitive values (with Apply button)

View File

@ -142,11 +142,11 @@ namespace Explorer
// ============= Resize Window Helper ============
static readonly GUIContent gcDrag = new GUIContent("<->");
//static readonly GUIContent gcDrag = new GUIContent("<->");
private static bool isResizing = false;
private static Rect m_currentResize;
private static int m_currentWindow;
//private static bool isResizing = false;
//private static Rect m_currentResize;
//private static int m_currentWindow;
public static Rect ResizeWindow(Rect _rect, int ID)
{