Compare commits

..

4 Commits
1.5.6 ... 1.5.7

Author SHA1 Message Date
9a059c1056 Update ScenePage.cs 2020-09-06 03:19:39 +10:00
ffb6cad8c2 1.5.7
* More fixes for failed unstripping, should fix most issues in Audica and other games
* If `GetRootSceneObjects` fails and we fall back to the manual implementation, the auto-update for root scene objects will be disabled. Instead, there will be a button to press to update the list.
* Transforms are now listed on the Components list in the GameObject inspector
* Various cleanups
2020-09-06 03:19:21 +10:00
d0a4863139 Update ScenePage.cs 2020-09-05 23:18:58 +10:00
bb8837d58c 1.5.6 hotfix
* Fix for setting CacheColor value
* Cleanup
2020-09-05 23:10:50 +10:00
13 changed files with 95 additions and 109 deletions

View File

@ -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;

View File

@ -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();
} }
} }
} }

View File

@ -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)
{ {

View File

@ -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)

View File

@ -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
{ {

View File

@ -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"

View File

@ -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();

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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;
} }

View File

@ -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)

View File

@ -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)
{ {