* 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:
sinaioutlander 2020-09-06 16:55:39 +10:00
parent 9a059c1056
commit e13f198815
8 changed files with 127 additions and 95 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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