mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-01-08 10:13:25 +08:00
1.5.8
* Fixed a bug where the Page Helper would not update the total page count after changing the limit per page * Cleaned up the "Find Instances" helper, it will now filter out all types in the `System`, `Mono`, `Il2CppSystem` and `Iced` namespaces. * Improved the Find Instances helper so that it will avoid exceptions and get more results. * Enums now display their value type name * Changed the Scroll View unstrip so that it is less hard-coded for different unity versions and more dynamic.
This commit is contained in:
parent
9a059c1056
commit
e13f198815
@ -14,6 +14,7 @@ namespace Explorer
|
||||
{
|
||||
public object Value;
|
||||
public string ValueTypeName;
|
||||
public Type ValueType;
|
||||
|
||||
// Reflection Inspector only
|
||||
public MemberInfo MemInfo { get; set; }
|
||||
@ -79,11 +80,7 @@ namespace Explorer
|
||||
{
|
||||
Type type = null;
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
type = ReflectionHelpers.GetActualType(obj);
|
||||
}
|
||||
else if (memberInfo != null)
|
||||
if (memberInfo != null)
|
||||
{
|
||||
if (memberInfo is FieldInfo fi)
|
||||
{
|
||||
@ -98,6 +95,10 @@ namespace Explorer
|
||||
type = mi.ReturnType;
|
||||
}
|
||||
}
|
||||
else if (obj != null)
|
||||
{
|
||||
type = ReflectionHelpers.GetActualType(obj);
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
@ -167,6 +168,7 @@ namespace Explorer
|
||||
}
|
||||
|
||||
holder.Value = obj;
|
||||
holder.ValueType = valueType;
|
||||
holder.ValueTypeName = valueType.FullName;
|
||||
|
||||
if (memberInfo != null)
|
||||
|
@ -51,7 +51,7 @@ namespace Explorer
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Label(Value.ToString(), null);// + "<color=yellow><i> (" + ValueType + ")</i></color>", null);
|
||||
GUILayout.Label(Value.ToString() + "<color=yellow><i> (" + ValueType + ")</i></color>", null);
|
||||
}
|
||||
|
||||
public void SetEnum(ref object value, int change)
|
||||
|
@ -8,58 +8,34 @@ namespace Explorer
|
||||
{
|
||||
public class CachePrimitive : CacheObjectBase
|
||||
{
|
||||
public enum Types
|
||||
{
|
||||
Bool,
|
||||
Double,
|
||||
Float,
|
||||
Int,
|
||||
String,
|
||||
Char
|
||||
}
|
||||
private bool m_isBool;
|
||||
private bool m_isString;
|
||||
|
||||
private string m_valueToString;
|
||||
|
||||
public Types PrimitiveType;
|
||||
|
||||
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
|
||||
private MethodInfo m_parseMethod;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
if (Value == null)
|
||||
if (ValueType == null)
|
||||
{
|
||||
// this must mean it is a string. No other primitive type should be nullable.
|
||||
PrimitiveType = Types.String;
|
||||
return;
|
||||
ValueType = Value?.GetType();
|
||||
|
||||
// has to be a string at this point
|
||||
if (ValueType == null)
|
||||
{
|
||||
ValueType = typeof(string);
|
||||
}
|
||||
}
|
||||
|
||||
m_valueToString = Value.ToString();
|
||||
|
||||
var type = Value.GetType();
|
||||
if (type == typeof(bool))
|
||||
if (ValueType == typeof(string))
|
||||
{
|
||||
PrimitiveType = Types.Bool;
|
||||
m_isString = true;
|
||||
}
|
||||
else if (type == typeof(double))
|
||||
else if (ValueType == typeof(bool))
|
||||
{
|
||||
PrimitiveType = Types.Double;
|
||||
}
|
||||
else if (type == typeof(float))
|
||||
{
|
||||
PrimitiveType = Types.Float;
|
||||
}
|
||||
else if (type == typeof(char))
|
||||
{
|
||||
PrimitiveType = Types.Char;
|
||||
}
|
||||
else if (typeof(int).IsAssignableFrom(type))
|
||||
{
|
||||
PrimitiveType = Types.Int;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrimitiveType = Types.String;
|
||||
m_isBool = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +48,7 @@ namespace Explorer
|
||||
|
||||
public override void DrawValue(Rect window, float width)
|
||||
{
|
||||
if (PrimitiveType == Types.Bool)
|
||||
if (m_isBool)
|
||||
{
|
||||
var b = (bool)Value;
|
||||
var label = $"<color={(b ? "lime" : "red")}>{b}</color>";
|
||||
@ -92,7 +68,8 @@ namespace Explorer
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayout.Label("<color=yellow><i>" + PrimitiveType + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
// using ValueType.Name instead of ValueTypeName, because we only want the short name.
|
||||
GUILayout.Label("<color=yellow><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||
|
||||
int dynSize = 25 + (m_valueToString.Length * 15);
|
||||
var maxwidth = window.width - 300f;
|
||||
@ -127,7 +104,7 @@ namespace Explorer
|
||||
return;
|
||||
}
|
||||
|
||||
if (PrimitiveType == Types.String)
|
||||
if (m_isString)
|
||||
{
|
||||
Value = valueString;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace Explorer
|
||||
public class CppExplorer : MelonMod
|
||||
{
|
||||
public const string GUID = "com.sinai.cppexplorer";
|
||||
public const string VERSION = "1.5.7";
|
||||
public const string VERSION = "1.5.8";
|
||||
public const string AUTHOR = "Sinai";
|
||||
|
||||
public const string NAME = "CppExplorer"
|
||||
|
@ -16,7 +16,18 @@ namespace Explorer
|
||||
public class PageHelper
|
||||
{
|
||||
public int PageOffset { get; set; }
|
||||
public int ItemsPerPage { get; set; } = 20;
|
||||
|
||||
public int ItemsPerPage
|
||||
{
|
||||
get => m_itemsPerPage;
|
||||
set
|
||||
{
|
||||
m_itemsPerPage = value;
|
||||
CalculateMaxOffset();
|
||||
}
|
||||
}
|
||||
private int m_itemsPerPage = 20;
|
||||
|
||||
public int ItemCount
|
||||
{
|
||||
get => m_count;
|
||||
|
@ -21,8 +21,6 @@ namespace Explorer
|
||||
|
||||
private static bool m_getRootObjectsFailed;
|
||||
|
||||
// ----- Holders for GUI elements ----- //
|
||||
|
||||
private static string m_currentScene = "";
|
||||
|
||||
// gameobject list
|
||||
@ -34,8 +32,6 @@ namespace Explorer
|
||||
private string m_searchInput = "";
|
||||
private List<GameObjectCache> m_searchResults = new List<GameObjectCache>();
|
||||
|
||||
// ------------ Init and Update ------------ //
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
Instance = this;
|
||||
@ -126,9 +122,7 @@ namespace Explorer
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!manual && m_getRootObjectsFailed) return;
|
||||
|
||||
if (!manual)
|
||||
if (!m_getRootObjectsFailed)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -139,12 +133,19 @@ namespace Explorer
|
||||
}
|
||||
catch
|
||||
{
|
||||
MelonLogger.Log("Exception getting root scene objects, falling back to backup method...");
|
||||
|
||||
m_getRootObjectsFailed = true;
|
||||
allTransforms.AddRange(GetRootObjectsManual_Impl());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!manual)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
allTransforms.AddRange(GetRootObjectsManual_Impl());
|
||||
}
|
||||
}
|
||||
|
@ -137,14 +137,11 @@ namespace Explorer
|
||||
|
||||
if (m_searchResults.Count > 0)
|
||||
{
|
||||
//int offset = m_pageOffset * this.m_limit;
|
||||
//if (offset >= count) m_pageOffset = 0;
|
||||
int offset = Pages.CalculateOffsetIndex();
|
||||
|
||||
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
|
||||
{
|
||||
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
|
||||
//m_searchResults[i].DrawValue(MainMenu.MainRect);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -377,33 +374,67 @@ namespace Explorer
|
||||
|
||||
// ====== other ========
|
||||
|
||||
private static bool FilterName(string name)
|
||||
{
|
||||
// Don't really want these instances.
|
||||
return !name.StartsWith("Mono")
|
||||
&& !name.StartsWith("System")
|
||||
&& !name.StartsWith("Il2CppSystem")
|
||||
&& !name.StartsWith("Iced");
|
||||
}
|
||||
|
||||
// credit: ManlyMarco (RuntimeUnityEditor)
|
||||
public static IEnumerable<object> GetInstanceClassScanner()
|
||||
{
|
||||
var query = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Where(x => !x.FullName.StartsWith("Mono"))
|
||||
.SelectMany(GetTypesSafe)
|
||||
.Where(t => t.IsClass && !t.IsAbstract && !t.ContainsGenericParameters);
|
||||
|
||||
var flags = BindingFlags.Public | BindingFlags.Static;
|
||||
var flatFlags = flags | BindingFlags.FlattenHierarchy;
|
||||
|
||||
foreach (var type in query)
|
||||
{
|
||||
object obj = null;
|
||||
try
|
||||
{
|
||||
obj = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)?.GetValue(null, null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
var pi = type.GetProperty("Instance", flags);
|
||||
|
||||
if (pi == null)
|
||||
{
|
||||
obj = type.GetField("Instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)?.GetValue(null);
|
||||
pi = type.GetProperty("Instance", flatFlags);
|
||||
}
|
||||
catch
|
||||
|
||||
if (pi != null)
|
||||
{
|
||||
obj = pi.GetValue(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fi = type.GetField("Instance", flags);
|
||||
|
||||
if (fi == null)
|
||||
{
|
||||
fi = type.GetField("Instance", flatFlags);
|
||||
}
|
||||
|
||||
if (fi != null)
|
||||
{
|
||||
obj = fi.GetValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj != null && !obj.ToString().StartsWith("Mono"))
|
||||
catch { }
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
var t = ReflectionHelpers.GetActualType(obj);
|
||||
|
||||
if (!FilterName(t.FullName) || ReflectionHelpers.IsArray(t) || ReflectionHelpers.IsList(t))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return obj;
|
||||
}
|
||||
}
|
||||
|
@ -24,13 +24,23 @@ namespace Explorer
|
||||
{
|
||||
get
|
||||
{
|
||||
#if Release_2019
|
||||
return GUI.scrollViewStates;
|
||||
#else
|
||||
return GUI.s_ScrollViewStates;
|
||||
#endif
|
||||
if (m_scrollViewStatesInfo == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_scrollViewStatesInfo = typeof(GUI).GetProperty("scrollViewStates");
|
||||
if (m_scrollViewStatesInfo == null) throw new Exception();
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_scrollViewStatesInfo = typeof(GUI).GetProperty("s_scrollViewStates");
|
||||
}
|
||||
}
|
||||
|
||||
return (GenericStack)m_scrollViewStatesInfo?.GetValue(null, null);
|
||||
}
|
||||
}
|
||||
private static PropertyInfo m_scrollViewStatesInfo;
|
||||
|
||||
// ======= public methods ======= //
|
||||
|
||||
@ -49,24 +59,6 @@ namespace Explorer
|
||||
return last;
|
||||
}
|
||||
|
||||
public static float HorizontalScrollbar(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||
{
|
||||
return Scroller_Impl(position, value, size, leftValue, rightValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "leftbutton"),
|
||||
GUI.skin.GetStyle(style.name + "rightbutton"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static float VerticalScrollbar(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style)
|
||||
{
|
||||
return Scroller_Impl(position, value, size, topValue, bottomValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "upbutton"),
|
||||
GUI.skin.GetStyle(style.name + "downbutton"),
|
||||
false);
|
||||
}
|
||||
|
||||
// Fix for BeginScrollView.
|
||||
|
||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||
@ -221,7 +213,7 @@ namespace Explorer
|
||||
}
|
||||
if (flag2 && horizontalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.x = HorizontalScrollbar(
|
||||
scrollPosition.x = HorizBar_Impl(
|
||||
new Rect(
|
||||
position.x,
|
||||
position.yMax - horizontalScrollbar.fixedHeight,
|
||||
@ -243,7 +235,7 @@ namespace Explorer
|
||||
}
|
||||
if (flag && verticalScrollbar != GUIStyle.none)
|
||||
{
|
||||
scrollPosition.y = VerticalScrollbar(
|
||||
scrollPosition.y = VertBar_Impl(
|
||||
new Rect(
|
||||
screenRect.xMax + (float)verticalScrollbar.margin.left,
|
||||
screenRect.y,
|
||||
@ -279,6 +271,24 @@ namespace Explorer
|
||||
return scrollPosition;
|
||||
}
|
||||
|
||||
public static float HorizBar_Impl(Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style)
|
||||
{
|
||||
return Scroller_Impl(position, value, size, leftValue, rightValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "leftbutton"),
|
||||
GUI.skin.GetStyle(style.name + "rightbutton"),
|
||||
true);
|
||||
}
|
||||
|
||||
public static float VertBar_Impl(Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style)
|
||||
{
|
||||
return Scroller_Impl(position, value, size, topValue, bottomValue, style,
|
||||
GUI.skin.GetStyle(style.name + "thumb"),
|
||||
GUI.skin.GetStyle(style.name + "upbutton"),
|
||||
GUI.skin.GetStyle(style.name + "downbutton"),
|
||||
false);
|
||||
}
|
||||
|
||||
private static void EndScrollView_Impl(bool handleScrollWheel)
|
||||
{
|
||||
GUIUtility.CheckOnGUI();
|
||||
@ -337,7 +347,7 @@ namespace Explorer
|
||||
rect2 = new Rect(position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight);
|
||||
}
|
||||
|
||||
value = Slider(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID);
|
||||
value = Slider_Impl(position2, value, size, leftValue, rightValue, slider, thumb, horiz, controlID);
|
||||
|
||||
bool flag = Event.current.type == EventType.MouseUp;
|
||||
if (ScrollerRepeatButton_Impl(controlID, rect, leftButton))
|
||||
@ -363,7 +373,7 @@ namespace Explorer
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float Slider(Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
||||
public static float Slider_Impl(Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
|
||||
{
|
||||
if (id == 0)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user