mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-14 15:46:36 +08:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
9a059c1056 | |||
ffb6cad8c2 | |||
d0a4863139 | |||
bb8837d58c |
@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Explorer.CachedObjects;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer.CachedObjects
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public class CacheColor : CacheObjectBase
|
public class CacheColor : CacheObjectBase
|
||||||
{
|
{
|
||||||
@ -80,6 +80,7 @@ namespace Explorer.CachedObjects
|
|||||||
&& float.TryParse(a, out float fA))
|
&& float.TryParse(a, out float fA))
|
||||||
{
|
{
|
||||||
Value = new Color(fR, fB, fG, fA);
|
Value = new Color(fR, fB, fG, fA);
|
||||||
|
SetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class CachePrimitive : CacheObjectBase
|
public class CachePrimitive : CacheObjectBase
|
||||||
{
|
{
|
||||||
public enum PrimitiveTypes
|
public enum Types
|
||||||
{
|
{
|
||||||
Bool,
|
Bool,
|
||||||
Double,
|
Double,
|
||||||
@ -20,20 +20,9 @@ namespace Explorer
|
|||||||
|
|
||||||
private string m_valueToString;
|
private string m_valueToString;
|
||||||
|
|
||||||
public PrimitiveTypes PrimitiveType;
|
public Types PrimitiveType;
|
||||||
|
|
||||||
public MethodInfo ParseMethod
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_parseMethod == null)
|
|
||||||
{
|
|
||||||
m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) });
|
|
||||||
}
|
|
||||||
return m_parseMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
||||||
private MethodInfo m_parseMethod;
|
private MethodInfo m_parseMethod;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@ -41,58 +30,39 @@ namespace Explorer
|
|||||||
if (Value == null)
|
if (Value == null)
|
||||||
{
|
{
|
||||||
// this must mean it is a string. No other primitive type should be nullable.
|
// this must mean it is a string. No other primitive type should be nullable.
|
||||||
PrimitiveType = PrimitiveTypes.String;
|
PrimitiveType = Types.String;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_valueToString = Value.ToString();
|
m_valueToString = Value.ToString();
|
||||||
var type = Value.GetType();
|
|
||||||
|
|
||||||
|
var type = Value.GetType();
|
||||||
if (type == typeof(bool))
|
if (type == typeof(bool))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Bool;
|
PrimitiveType = Types.Bool;
|
||||||
}
|
}
|
||||||
else if (type == typeof(double))
|
else if (type == typeof(double))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Double;
|
PrimitiveType = Types.Double;
|
||||||
}
|
}
|
||||||
else if (type == typeof(float))
|
else if (type == typeof(float))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Float;
|
PrimitiveType = Types.Float;
|
||||||
}
|
|
||||||
else if (IsInteger(type))
|
|
||||||
{
|
|
||||||
PrimitiveType = PrimitiveTypes.Int;
|
|
||||||
}
|
}
|
||||||
else if (type == typeof(char))
|
else if (type == typeof(char))
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.Char;
|
PrimitiveType = Types.Char;
|
||||||
|
}
|
||||||
|
else if (typeof(int).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
PrimitiveType = Types.Int;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimitiveType = PrimitiveTypes.String;
|
PrimitiveType = Types.String;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsInteger(Type type)
|
|
||||||
{
|
|
||||||
// For our purposes, all types of int can be treated the same, including IntPtr.
|
|
||||||
return _integerTypes.Contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly HashSet<Type> _integerTypes = new HashSet<Type>
|
|
||||||
{
|
|
||||||
typeof(int),
|
|
||||||
typeof(uint),
|
|
||||||
typeof(short),
|
|
||||||
typeof(ushort),
|
|
||||||
typeof(long),
|
|
||||||
typeof(ulong),
|
|
||||||
typeof(byte),
|
|
||||||
typeof(sbyte),
|
|
||||||
typeof(IntPtr)
|
|
||||||
};
|
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
@ -102,11 +72,10 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
{
|
{
|
||||||
if (PrimitiveType == PrimitiveTypes.Bool)
|
if (PrimitiveType == Types.Bool)
|
||||||
{
|
{
|
||||||
var b = (bool)Value;
|
var b = (bool)Value;
|
||||||
var color = $"<color={(b ? "lime>" : "red>")}";
|
var label = $"<color={(b ? "lime" : "red")}>{b}</color>";
|
||||||
var label = $"{color}{b}</color>";
|
|
||||||
|
|
||||||
if (CanWrite)
|
if (CanWrite)
|
||||||
{
|
{
|
||||||
@ -150,7 +119,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetValueFromInput(string value)
|
public void SetValueFromInput(string valueString)
|
||||||
{
|
{
|
||||||
if (MemInfo == null)
|
if (MemInfo == null)
|
||||||
{
|
{
|
||||||
@ -158,16 +127,15 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PrimitiveType == PrimitiveTypes.String)
|
if (PrimitiveType == Types.String)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = valueString;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var val = ParseMethod.Invoke(null, new object[] { value });
|
Value = ParseMethod.Invoke(null, new object[] { valueString });
|
||||||
Value = val;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -9,8 +9,6 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class CacheQuaternion : CacheObjectBase
|
public class CacheQuaternion : CacheObjectBase
|
||||||
{
|
{
|
||||||
private Vector3 EulerAngle = Vector3.zero;
|
|
||||||
|
|
||||||
private string x = "0";
|
private string x = "0";
|
||||||
private string y = "0";
|
private string y = "0";
|
||||||
private string z = "0";
|
private string z = "0";
|
||||||
@ -19,11 +17,11 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
EulerAngle = ((Quaternion)Value).eulerAngles;
|
var euler = ((Quaternion)Value).eulerAngles;
|
||||||
|
|
||||||
x = EulerAngle.x.ToString();
|
x = euler.x.ToString();
|
||||||
y = EulerAngle.y.ToString();
|
y = euler.y.ToString();
|
||||||
z = EulerAngle.z.ToString();
|
z = euler.z.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
|
@ -5,7 +5,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer.CachedObjects
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public class CacheRect : CacheObjectBase
|
public class CacheRect : CacheObjectBase
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
public const string VERSION = "1.5.6";
|
public const string VERSION = "1.5.7";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
|
|
||||||
public const string NAME = "CppExplorer"
|
public const string NAME = "CppExplorer"
|
||||||
|
@ -14,7 +14,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class ConsolePage : WindowPage
|
public class ConsolePage : WindowPage
|
||||||
{
|
{
|
||||||
public override string Name { get => "C# Console"; set => base.Name = value; }
|
public override string Name { get => "C# Console"; }
|
||||||
|
|
||||||
private ScriptEvaluator _evaluator;
|
private ScriptEvaluator _evaluator;
|
||||||
private readonly StringBuilder _sb = new StringBuilder();
|
private readonly StringBuilder _sb = new StringBuilder();
|
||||||
|
@ -12,14 +12,14 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public static ScenePage Instance;
|
public static ScenePage Instance;
|
||||||
|
|
||||||
public override string Name { get => "Scene Explorer"; set => base.Name = value; }
|
public override string Name { get => "Scene Explorer"; }
|
||||||
|
|
||||||
public PageHelper Pages = new PageHelper();
|
public PageHelper Pages = new PageHelper();
|
||||||
|
|
||||||
private float m_timeOfLastUpdate = -1f;
|
private float m_timeOfLastUpdate = -1f;
|
||||||
private static int PASSIVE_UPDATE_INTERVAL = 1;
|
private const int PASSIVE_UPDATE_INTERVAL = 1;
|
||||||
|
|
||||||
private static bool m_getRootObjectsFailed = false;
|
private static bool m_getRootObjectsFailed;
|
||||||
|
|
||||||
// ----- Holders for GUI elements ----- //
|
// ----- Holders for GUI elements ----- //
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ namespace Explorer
|
|||||||
if (m_searching)
|
if (m_searching)
|
||||||
CancelSearch();
|
CancelSearch();
|
||||||
|
|
||||||
Update_Impl();
|
Update_Impl(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TraverseUp()
|
public void TraverseUp()
|
||||||
@ -90,11 +90,12 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
var matches = new List<GameObjectCache>();
|
var matches = new List<GameObjectCache>();
|
||||||
|
|
||||||
foreach (var obj in Resources.FindObjectsOfTypeAll<GameObject>())
|
foreach (var obj in Resources.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
|
||||||
{
|
{
|
||||||
if (obj.name.ToLower().Contains(_search.ToLower()) && obj.scene.name == m_currentScene)
|
var go = obj.TryCast<GameObject>();
|
||||||
|
if (go.name.ToLower().Contains(_search.ToLower()) && go.scene.name == m_currentScene)
|
||||||
{
|
{
|
||||||
matches.Add(new GameObjectCache(obj));
|
matches.Add(new GameObjectCache(go));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,9 +112,9 @@ namespace Explorer
|
|||||||
Update_Impl();
|
Update_Impl();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update_Impl()
|
private void Update_Impl(bool manual = false)
|
||||||
{
|
{
|
||||||
var allTransforms = new List<Transform>();
|
List<Transform> allTransforms = new List<Transform>();
|
||||||
|
|
||||||
// get current list of all transforms (either scene root or our current transform children)
|
// get current list of all transforms (either scene root or our current transform children)
|
||||||
if (m_currentTransform)
|
if (m_currentTransform)
|
||||||
@ -125,28 +126,26 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!m_getRootObjectsFailed)
|
if (!manual && m_getRootObjectsFailed) return;
|
||||||
|
|
||||||
|
if (!manual)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var list = SceneManager.GetActiveScene().GetRootGameObjects().ToArray();
|
var scene = SceneManager.GetSceneByName(m_currentScene);
|
||||||
|
|
||||||
foreach (var obj in list)
|
allTransforms.AddRange(scene.GetRootGameObjects()
|
||||||
{
|
.Select(it => it.transform));
|
||||||
allTransforms.Add(obj.transform);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
m_getRootObjectsFailed = true;
|
m_getRootObjectsFailed = true;
|
||||||
PASSIVE_UPDATE_INTERVAL = 2;
|
allTransforms.AddRange(GetRootObjectsManual_Impl());
|
||||||
|
|
||||||
allTransforms = GetRootObjectsManual_Impl();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
allTransforms = GetRootObjectsManual_Impl();
|
allTransforms.AddRange(GetRootObjectsManual_Impl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,13 +165,30 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Transform> GetRootObjectsManual_Impl()
|
private IEnumerable<Transform> GetRootObjectsManual_Impl()
|
||||||
{
|
{
|
||||||
var allTransforms = Resources.FindObjectsOfTypeAll<Transform>()
|
try
|
||||||
.Where(x => x.parent == null && x.gameObject.scene.name == m_currentScene)
|
{
|
||||||
.ToList();
|
var array = Resources.FindObjectsOfTypeAll(ReflectionHelpers.TransformType);
|
||||||
|
|
||||||
return allTransforms;
|
var list = new List<Transform>();
|
||||||
|
foreach (var obj in array)
|
||||||
|
{
|
||||||
|
var transform = obj.TryCast<Transform>();
|
||||||
|
if (transform.parent == null && transform.gameObject.scene.name == m_currentScene)
|
||||||
|
{
|
||||||
|
list.Add(transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MelonLogger.Log("Exception getting root scene objects (manual): "
|
||||||
|
+ e.GetType() + ", " + e.Message + "\r\n"
|
||||||
|
+ e.StackTrace);
|
||||||
|
return new Transform[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------- GUI Draw Function --------- //
|
// --------- GUI Draw Function --------- //
|
||||||
@ -274,7 +290,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Left, ref this.scroll);
|
Pages.TurnPage(Turn.Left, ref this.scroll);
|
||||||
|
|
||||||
Update_Impl();
|
Update_Impl(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pages.CurrentPageLabel();
|
Pages.CurrentPageLabel();
|
||||||
@ -283,7 +299,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
Pages.TurnPage(Turn.Right, ref this.scroll);
|
Pages.TurnPage(Turn.Right, ref this.scroll);
|
||||||
|
|
||||||
Update_Impl();
|
Update_Impl(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,6 +329,14 @@ namespace Explorer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUILayout.Label("Scene Root GameObjects:", null);
|
GUILayout.Label("Scene Root GameObjects:", null);
|
||||||
|
|
||||||
|
if (m_getRootObjectsFailed)
|
||||||
|
{
|
||||||
|
if (GUILayout.Button("Update Root Object List (auto-update failed!)", null))
|
||||||
|
{
|
||||||
|
Update_Impl(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_objectList.Count > 0)
|
if (m_objectList.Count > 0)
|
||||||
|
@ -13,7 +13,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public static SearchPage Instance;
|
public static SearchPage Instance;
|
||||||
|
|
||||||
public override string Name { get => "Object Search"; set => base.Name = value; }
|
public override string Name { get => "Object Search"; }
|
||||||
|
|
||||||
private string m_searchInput = "";
|
private string m_searchInput = "";
|
||||||
private string m_typeInput = "";
|
private string m_typeInput = "";
|
||||||
@ -318,7 +318,8 @@ namespace Explorer
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchType == ReflectionHelpers.ComponentType && ReflectionHelpers.TransformType.IsAssignableFrom(obj.GetIl2CppType()))
|
if (searchType.FullName == ReflectionHelpers.ComponentType.FullName
|
||||||
|
&& ReflectionHelpers.TransformType.IsAssignableFrom(obj.GetIl2CppType()))
|
||||||
{
|
{
|
||||||
// Transforms shouldn't really be counted as Components, skip them.
|
// Transforms shouldn't really be counted as Components, skip them.
|
||||||
// They're more akin to GameObjects.
|
// They're more akin to GameObjects.
|
||||||
|
@ -9,7 +9,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public abstract class WindowPage
|
public abstract class WindowPage
|
||||||
{
|
{
|
||||||
public virtual string Name { get; set; }
|
public virtual string Name { get; }
|
||||||
|
|
||||||
public Vector2 scroll = Vector2.zero;
|
public Vector2 scroll = Vector2.zero;
|
||||||
|
|
||||||
|
@ -128,28 +128,22 @@ namespace Explorer
|
|||||||
m_object.transform.localScale = m_frozenScale;
|
m_object.transform.localScale = m_frozenScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = new List<Transform>();
|
// update child objects
|
||||||
|
var childList = new List<Transform>();
|
||||||
for (int i = 0; i < m_object.transform.childCount; i++)
|
for (int i = 0; i < m_object.transform.childCount; i++)
|
||||||
{
|
{
|
||||||
list.Add(m_object.transform.GetChild(i));
|
childList.Add(m_object.transform.GetChild(i));
|
||||||
}
|
}
|
||||||
list.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
childList.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
||||||
m_children = list.ToArray();
|
m_children = childList.ToArray();
|
||||||
|
|
||||||
ChildPages.ItemCount = m_children.Length;
|
ChildPages.ItemCount = m_children.Length;
|
||||||
|
|
||||||
var list2 = new List<Component>();
|
// update components
|
||||||
foreach (var comp in m_object.GetComponents(ReflectionHelpers.ComponentType))
|
var compList = new Il2CppSystem.Collections.Generic.List<Component>();
|
||||||
{
|
m_object.GetComponentsInternal(ReflectionHelpers.ComponentType, true, false, true, false, compList);
|
||||||
var ilType = comp.GetIl2CppType();
|
|
||||||
if (ilType == ReflectionHelpers.TransformType)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
list2.Add(comp);
|
m_components = compList.ToArray();
|
||||||
}
|
|
||||||
m_components = list2.ToArray();
|
|
||||||
|
|
||||||
CompPages.ItemCount = m_components.Length;
|
CompPages.ItemCount = m_components.Length;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Init() { }
|
public override void Init() { }
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
while (TargetTabID >= WindowManager.Windows.Count)
|
while (TargetTabID >= WindowManager.Windows.Count)
|
||||||
|
@ -109,7 +109,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if (!equals && iObj is Il2CppSystem.Object iCurrent && window.Target is Il2CppSystem.Object iTarget)
|
if (!equals && iObj is Il2CppSystem.Object iCurrent && window.Target is Il2CppSystem.Object iTarget)
|
||||||
{
|
{
|
||||||
if (iCurrent.GetIl2CppType() != iTarget.GetIl2CppType())
|
if (iCurrent.GetIl2CppType().FullName != iTarget.GetIl2CppType().FullName)
|
||||||
{
|
{
|
||||||
if (iCurrent is Transform transform)
|
if (iCurrent is Transform transform)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user