Cleanups and refactorings, and some small UI fixes

This commit is contained in:
sinaioutlander 2020-09-29 05:40:06 +10:00
parent f1406d016f
commit dab7ecd441
21 changed files with 553 additions and 635 deletions

View File

@ -0,0 +1,169 @@
using System;
using System.Reflection;
using UnityEngine;
namespace Explorer
{
public static class CacheFactory
{
public static CacheObjectBase GetTypeAndCacheObject(object obj)
=> GetTypeAndCacheObject(obj, null, null);
public static CacheObjectBase GetTypeAndCacheObject(MemberInfo memberInfo, object declarer)
=> GetTypeAndCacheObject(null, memberInfo, declarer);
public static CacheObjectBase GetTypeAndCacheObject(object obj, MemberInfo memberInfo, object declarer)
{
Type type = null;
if (memberInfo != null)
{
if (memberInfo is FieldInfo fi)
{
type = fi.FieldType;
}
else if (memberInfo is PropertyInfo pi)
{
type = pi.PropertyType;
}
else if (memberInfo is MethodInfo mi)
{
type = mi.ReturnType;
}
}
else if (obj != null)
{
type = ReflectionHelpers.GetActualType(obj);
}
if (type == null)
{
return null;
}
return GetCacheObject(obj, memberInfo, declarer, type);
}
public static CacheObjectBase GetCacheObject(object obj, Type valueType)
=> GetCacheObject(obj, null, null, valueType);
private static CacheObjectBase GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance, Type valueType)
{
CacheObjectBase cached;
var pi = memberInfo as PropertyInfo;
var mi = memberInfo as MethodInfo;
// Check if can process args
if ((pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|| (mi != null && !CanProcessArgs(mi.GetParameters())))
{
return null;
}
if (mi != null)
{
cached = new CacheMethod();
}
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
{
cached = new CacheGameObject();
}
else if (valueType.IsPrimitive || valueType == typeof(string))
{
cached = new CachePrimitive();
}
else if (valueType.IsEnum)
{
if (valueType.GetCustomAttributes(typeof(FlagsAttribute), true) is object[] attributes && attributes.Length > 0)
{
cached = new CacheEnumFlags();
}
else
{
cached = new CacheEnum();
}
}
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
{
cached = new CacheVector();
}
else if (valueType == typeof(Quaternion))
{
cached = new CacheQuaternion();
}
else if (valueType == typeof(Color))
{
cached = new CacheColor();
}
else if (valueType == typeof(Rect))
{
cached = new CacheRect();
}
// must check this before IsEnumerable
else if (ReflectionHelpers.IsDictionary(valueType))
{
cached = new CacheDictionary();
}
else if (ReflectionHelpers.IsEnumerable(valueType))
{
cached = new CacheList();
}
else
{
cached = new CacheOther();
}
cached.Value = obj;
cached.ValueType = valueType;
if (memberInfo != null)
{
cached.MemInfo = memberInfo;
cached.DeclaringType = memberInfo.DeclaringType;
cached.DeclaringInstance = declaringInstance;
}
if (pi != null)
{
cached.m_arguments = pi.GetIndexParameters();
}
else if (mi != null)
{
cached.m_arguments = mi.GetParameters();
}
cached.m_argumentInput = new string[cached.m_arguments.Length];
cached.UpdateValue();
cached.Init();
return cached;
}
public static bool CanProcessArgs(ParameterInfo[] parameters)
{
foreach (var param in parameters)
{
var pType = param.ParameterType;
if (pType.IsByRef && pType.HasElementType)
{
pType = pType.GetElementType();
}
if (pType.IsPrimitive || pType == typeof(string))
{
continue;
}
else
{
return false;
}
}
return true;
}
}
}

View File

@ -27,279 +27,13 @@ namespace Explorer
public string RichTextName => m_richTextName ?? GetRichTextName(); public string RichTextName => m_richTextName ?? GetRichTextName();
private string m_richTextName; private string m_richTextName;
public bool CanWrite public bool CanWrite => m_canWrite ?? (bool)(m_canWrite = GetCanWrite());
{ private bool? m_canWrite;
get
{
if (MemInfo is FieldInfo fi)
return !(fi.IsLiteral && !fi.IsInitOnly);
else if (MemInfo is PropertyInfo pi)
return pi.CanWrite;
else
return false;
}
}
public virtual void Init() { } public virtual void Init() { }
public abstract void DrawValue(Rect window, float width); public abstract void DrawValue(Rect window, float width);
/// <summary>
/// Get CacheObject from only an object instance
/// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (obj, null, null)</summary>
public static CacheObjectBase GetCacheObject(object obj)
{
return GetCacheObject(obj, null, null);
}
/// <summary>
/// Get CacheObject from an object instance and provide the value type
/// Calls GetCacheObjectImpl directly</summary>
public static CacheObjectBase GetCacheObject(object obj, Type valueType)
{
return GetCacheObjectImpl(obj, null, null, valueType);
}
/// <summary>
/// Get CacheObject from only a MemberInfo and declaring instance
/// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (null, memberInfo, declaringInstance)</summary>
public static CacheObjectBase GetCacheObject(MemberInfo memberInfo, object declaringInstance)
{
return GetCacheObject(null, memberInfo, declaringInstance);
}
/// <summary>
/// Get CacheObject from either an object or MemberInfo, and don't provide the type.
/// This gets the type and then calls GetCacheObjectImpl</summary>
public static CacheObjectBase GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance)
{
Type type = null;
if (memberInfo != null)
{
if (memberInfo is FieldInfo fi)
{
type = fi.FieldType;
}
else if (memberInfo is PropertyInfo pi)
{
type = pi.PropertyType;
}
else if (memberInfo is MethodInfo mi)
{
type = mi.ReturnType;
}
}
else if (obj != null)
{
type = ReflectionHelpers.GetActualType(obj);
}
if (type == null)
{
return null;
}
return GetCacheObjectImpl(obj, memberInfo, declaringInstance, type);
}
/// <summary>
/// Actual GetCacheObject implementation (private)
/// </summary>
private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberInfo, object declaringInstance, Type valueType)
{
CacheObjectBase holder;
var pi = memberInfo as PropertyInfo;
var mi = memberInfo as MethodInfo;
// Check if can process args
if ((pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|| (mi != null && !CanProcessArgs(mi.GetParameters())))
{
return null;
}
if (mi != null)
{
holder = new CacheMethod();
}
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
{
holder = new CacheGameObject();
}
else if (valueType.IsPrimitive || valueType == typeof(string))
{
holder = new CachePrimitive();
}
else if (valueType.IsEnum)
{
if (valueType.GetCustomAttributes(typeof(FlagsAttribute), true) is object[] attributes && attributes.Length > 0)
{
holder = new CacheEnumFlags();
}
else
{
holder = new CacheEnum();
}
}
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
{
holder = new CacheVector();
}
else if (valueType == typeof(Quaternion))
{
holder = new CacheQuaternion();
}
else if (valueType == typeof(Color))
{
holder = new CacheColor();
}
else if (valueType == typeof(Rect))
{
holder = new CacheRect();
}
// must check this before IsEnumerable
else if (ReflectionHelpers.IsDictionary(valueType))
{
holder = new CacheDictionary();
}
else if (ReflectionHelpers.IsEnumerable(valueType))
{
holder = new CacheList();
}
else
{
holder = new CacheOther();
}
holder.Value = obj;
holder.ValueType = valueType;
if (memberInfo != null)
{
holder.MemInfo = memberInfo;
holder.DeclaringType = memberInfo.DeclaringType;
holder.DeclaringInstance = declaringInstance;
}
if (pi != null)
{
holder.m_arguments = pi.GetIndexParameters();
}
else if (mi != null)
{
holder.m_arguments = mi.GetParameters();
}
holder.m_argumentInput = new string[holder.m_arguments.Length];
holder.UpdateValue();
holder.Init();
return holder;
}
public static bool CanProcessArgs(ParameterInfo[] parameters)
{
foreach (var param in parameters)
{
var pType = param.ParameterType;
if (pType.IsByRef && pType.HasElementType)
{
pType = pType.GetElementType();
}
if (pType.IsPrimitive || pType == typeof(string))
{
continue;
}
else
{
return false;
}
}
return true;
}
public float CalcWhitespace(Rect window)
{
if (!(this is IExpandHeight)) return 0f;
float whitespace = (this as IExpandHeight).WhiteSpace;
if (whitespace > 0)
{
ClampLabelWidth(window, ref whitespace);
}
return whitespace;
}
public object[] ParseArguments()
{
var parsedArgs = new List<object>();
for (int i = 0; i < m_arguments.Length; i++)
{
var input = m_argumentInput[i];
var type = m_arguments[i].ParameterType;
if (type.IsByRef)
{
type = type.GetElementType();
}
if (!string.IsNullOrEmpty(input))
{
// strings can obviously just be used directly
if (type == typeof(string))
{
parsedArgs.Add(input);
continue;
}
else
{
// try to invoke the parse method and use that.
try
{
parsedArgs.Add(type.GetMethod("Parse", new Type[] { typeof(string) })
.Invoke(null, new object[] { input }));
continue;
}
catch
{
ExplorerCore.Log($"Argument #{i} '{m_arguments[i].Name}' ({type.Name}), could not parse input '{input}'.");
}
}
}
// Didn't use input, see if there is a default value.
if (HasDefaultValue(m_arguments[i]))
{
parsedArgs.Add(m_arguments[i].DefaultValue);
continue;
}
// Try add a null arg I guess
parsedArgs.Add(null);
}
return parsedArgs.ToArray();
}
public static bool HasDefaultValue(ParameterInfo arg)
{
return
#if NET35
arg.DefaultValue != null; // rip null default args in NET35
#else
arg.HasDefaultValue;
#endif
}
public virtual void UpdateValue() public virtual void UpdateValue()
{ {
if (MemInfo == null) if (MemInfo == null)
@ -367,11 +101,83 @@ namespace Explorer
} }
} }
public object[] ParseArguments()
{
var parsedArgs = new List<object>();
for (int i = 0; i < m_arguments.Length; i++)
{
var input = m_argumentInput[i];
var type = m_arguments[i].ParameterType;
if (type.IsByRef)
{
type = type.GetElementType();
}
if (string.IsNullOrEmpty(input))
{
// No input, see if there is a default value.
if (HasDefaultValue(m_arguments[i]))
{
parsedArgs.Add(m_arguments[i].DefaultValue);
continue;
}
// Try add a null arg I guess
parsedArgs.Add(null);
continue;
}
// strings can obviously just be used directly
if (type == typeof(string))
{
parsedArgs.Add(input);
continue;
}
else
{
try
{
var arg = type.GetMethod("Parse", new Type[] { typeof(string) })
.Invoke(null, new object[] { input });
parsedArgs.Add(arg);
continue;
}
catch
{
ExplorerCore.Log($"Argument #{i} '{m_arguments[i].Name}' ({type.Name}), could not parse input '{input}'.");
}
}
}
return parsedArgs.ToArray();
}
public static bool HasDefaultValue(ParameterInfo arg) =>
#if NET35
arg.DefaultValue != null;
#else
arg.HasDefaultValue;
#endif
// ========= Gui Draw ========== // ========= Gui Draw ==========
public const float MAX_LABEL_WIDTH = 400f; public const float MAX_LABEL_WIDTH = 400f;
public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>"; public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>";
public float CalcWhitespace(Rect window)
{
if (!(this is IExpandHeight)) return 0f;
float whitespace = (this as IExpandHeight).WhiteSpace;
if (whitespace > 0)
{
ClampLabelWidth(window, ref whitespace);
}
return whitespace;
}
public static void ClampLabelWidth(Rect window, ref float labelWidth) public static void ClampLabelWidth(Rect window, ref float labelWidth)
{ {
float min = window.width * 0.37f; float min = window.width * 0.37f;
@ -436,7 +242,10 @@ namespace Explorer
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label($"<color={UIStyles.Syntax.StructGreen}>{cm.GenericArgs[i].Name}</color>", new GUILayoutOption[] { GUILayout.Width(15) }); GUILayout.Label(
$"<color={UIStyles.Syntax.StructGreen}>{cm.GenericArgs[i].Name}</color>",
new GUILayoutOption[] { GUILayout.Width(15) }
);
cm.GenericArgInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); cm.GenericArgInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(types, new GUILayoutOption[0]); GUILayout.Label(types, new GUILayoutOption[0]);
@ -477,13 +286,9 @@ namespace Explorer
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) })) if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
{ {
if (cm != null) if (cm != null)
{
cm.Evaluate(); cm.Evaluate();
}
else else
{
UpdateValue(); UpdateValue();
}
} }
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) })) if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
{ {
@ -506,21 +311,17 @@ namespace Explorer
GUILayout.EndVertical(); GUILayout.EndVertical();
// new line and space
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(labelWidth); GUIUnstrip.Space(labelWidth);
} }
else if (cm != null) else if (cm != null)
{ {
//GUILayout.BeginHorizontal(null);
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) })) if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
{ {
cm.Evaluate(); cm.Evaluate();
} }
// new line and space
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(labelWidth); GUIUnstrip.Space(labelWidth);
@ -546,6 +347,16 @@ namespace Explorer
} }
} }
private bool GetCanWrite()
{
if (MemInfo is FieldInfo fi)
return !(fi.IsLiteral && !fi.IsInitOnly);
else if (MemInfo is PropertyInfo pi)
return pi.CanWrite;
else
return false;
}
private string GetRichTextName() private string GetRichTextName()
{ {
string memberColor = ""; string memberColor = "";
@ -582,9 +393,19 @@ namespace Explorer
memberColor = UIStyles.Syntax.Prop_Instance; memberColor = UIStyles.Syntax.Prop_Instance;
} }
string classColor = MemInfo.DeclaringType.IsAbstract && MemInfo.DeclaringType.IsSealed string classColor;
? UIStyles.Syntax.Class_Static if (MemInfo.DeclaringType.IsValueType)
: UIStyles.Syntax.Class_Instance; {
classColor = UIStyles.Syntax.StructGreen;
}
else if (MemInfo.DeclaringType.IsAbstract && MemInfo.DeclaringType.IsSealed)
{
classColor = UIStyles.Syntax.Class_Static;
}
else
{
classColor = UIStyles.Syntax.Class_Instance;
}
m_richTextName = $"<color={classColor}>{MemInfo.DeclaringType.Name}</color>."; m_richTextName = $"<color={classColor}>{MemInfo.DeclaringType.Name}</color>.";
if (isStatic) m_richTextName += "<i>"; if (isStatic) m_richTextName += "<i>";
@ -607,23 +428,6 @@ namespace Explorer
m_richTextName += ">"; m_richTextName += ">";
} }
// Method / Property arguments
//if (m_arguments.Length > 0 || this is CacheMethod)
//{
// m_richTextName += "(";
// var args = "";
// foreach (var param in m_arguments)
// {
// if (args != "") args += ", ";
// args += $"<color={classColor}>{param.ParameterType.Name}</color> ";
// args += $"<color={UIStyles.Syntax.Local}>{param.Name}</color>";
// }
// m_richTextName += args;
// m_richTextName += ")";
//}
return m_richTextName; return m_richTextName;
} }
} }

View File

@ -131,7 +131,7 @@ namespace Explorer
foreach (var key in IDict.Keys) foreach (var key in IDict.Keys)
{ {
Type t = ReflectionHelpers.GetActualType(key) ?? TypeOfKeys; Type t = ReflectionHelpers.GetActualType(key) ?? TypeOfKeys;
var cache = GetCacheObject(key, t); var cache = CacheFactory.GetCacheObject(key, t);
keys.Add(cache); keys.Add(cache);
} }
@ -139,7 +139,7 @@ namespace Explorer
foreach (var val in IDict.Values) foreach (var val in IDict.Values)
{ {
Type t = ReflectionHelpers.GetActualType(val) ?? TypeOfValues; Type t = ReflectionHelpers.GetActualType(val) ?? TypeOfValues;
var cache = GetCacheObject(val, t); var cache = CacheFactory.GetCacheObject(val, t);
values.Add(cache); values.Add(cache);
} }

View File

@ -246,7 +246,7 @@ namespace Explorer
} }
#endif #endif
if (GetCacheObject(obj, t) is CacheObjectBase cached) if (CacheFactory.GetCacheObject(obj, t) is CacheObjectBase cached)
{ {
list.Add(cached); list.Add(cached);
} }
@ -354,6 +354,7 @@ namespace Explorer
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
entry.DrawValue(window, window.width - (whitespace + 85)); entry.DrawValue(window, window.width - (whitespace + 85));
} }

View File

@ -64,7 +64,7 @@ namespace Explorer
if (ret != null) if (ret != null)
{ {
m_cachedReturnValue = GetCacheObject(ret); m_cachedReturnValue = CacheFactory.GetTypeAndCacheObject(ret);
m_cachedReturnValue.UpdateValue(); m_cachedReturnValue.UpdateValue();
} }
else else

View File

@ -56,7 +56,7 @@ namespace Explorer
} }
} }
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", new GUILayoutOption[0]); GUILayout.Label(Value.ToString() + $"<color={UIStyles.Syntax.StructGreen}><i> ({ValueType})</i></color>", new GUILayoutOption[0]);
} }
public void SetEnum(int change) public void SetEnum(int change)

View File

@ -6,9 +6,8 @@ using UnityEngine;
namespace Explorer namespace Explorer
{ {
public class CacheEnumFlags : CacheObjectBase, IExpandHeight public class CacheEnumFlags : CacheEnum, IExpandHeight
{ {
public string[] EnumNames = new string[0];
public bool[] m_enabledFlags = new bool[0]; public bool[] m_enabledFlags = new bool[0];
public bool IsExpanded { get; set; } public bool IsExpanded { get; set; }
@ -18,38 +17,12 @@ namespace Explorer
{ {
base.Init(); base.Init();
if (ValueType == null && Value != null)
{
ValueType = Value.GetType();
}
if (ValueType != null) if (ValueType != null)
{ {
EnumNames = Enum.GetNames(ValueType);
m_enabledFlags = new bool[EnumNames.Length]; m_enabledFlags = new bool[EnumNames.Length];
UpdateValue(); UpdateValue();
} }
else
{
ReflectionException = "Unknown, could not get Enum names.";
}
}
public void SetFlagsFromInput()
{
string val = "";
for (int i = 0; i < EnumNames.Length; i++)
{
if (m_enabledFlags[i])
{
if (val != "") val += ", ";
val += EnumNames[i];
}
}
Value = Enum.Parse(ValueType, val);
SetValue();
} }
public override void UpdateValue() public override void UpdateValue()
@ -71,7 +44,6 @@ namespace Explorer
} }
} }
public override void DrawValue(Rect window, float width) public override void DrawValue(Rect window, float width)
{ {
if (CanWrite) if (CanWrite)
@ -121,5 +93,20 @@ namespace Explorer
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
} }
} }
public void SetFlagsFromInput()
{
string val = "";
for (int i = 0; i < EnumNames.Length; i++)
{
if (m_enabledFlags[i])
{
if (val != "") val += ", ";
val += EnumNames[i];
}
}
Value = Enum.Parse(ValueType, val);
SetValue();
}
} }
} }

View File

@ -2,28 +2,26 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using UnityEngine;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
#endif #endif
using UnityEngine;
namespace Explorer namespace Explorer
{ {
public class CachePrimitive : CacheObjectBase public class CachePrimitive : CacheObjectBase
{ {
private string m_valueToString;
private bool m_isBool; private bool m_isBool;
private bool m_isString; private bool m_isString;
private string m_valueToString;
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) })); public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
private MethodInfo m_parseMethod; private MethodInfo m_parseMethod;
private bool m_canBitwiseOperate; private bool m_canBitwiseOperate;
private bool m_inBitwiseMode; private bool m_inBitwiseMode;
private string m_bitwiseOperatorInput = "0"; private string m_bitwiseOperatorInput = "0";
private string m_bitwiseToString; private string m_binaryInput;
//private BitArray m_bitMask; // not needed I think
public override void Init() public override void Init()
{ {
@ -48,6 +46,8 @@ namespace Explorer
} }
m_canBitwiseOperate = typeof(int).IsAssignableFrom(ValueType); m_canBitwiseOperate = typeof(int).IsAssignableFrom(ValueType);
UpdateValue();
} }
public override void UpdateValue() public override void UpdateValue()
@ -57,20 +57,19 @@ namespace Explorer
RefreshToString(); RefreshToString();
} }
public void RefreshToString() private void RefreshToString()
{ {
m_valueToString = Value?.ToString(); m_valueToString = Value?.ToString();
if (m_inBitwiseMode) if (m_canBitwiseOperate)
{ {
var _int = (int)Value; var _int = (int)Value;
m_bitwiseToString = Convert.ToString(_int, toBase: 2); m_binaryInput = Convert.ToString(_int, toBase: 2);
} }
} }
public override void DrawValue(Rect window, float width) public override void DrawValue(Rect window, float width)
{ {
// bool uses Toggle
if (m_isBool) if (m_isBool)
{ {
var b = (bool)Value; var b = (bool)Value;
@ -81,7 +80,8 @@ namespace Explorer
b = GUILayout.Toggle(b, label, new GUILayoutOption[0]); b = GUILayout.Toggle(b, label, new GUILayoutOption[0]);
if (b != (bool)Value) if (b != (bool)Value)
{ {
SetValueFromInput(b.ToString()); Value = b;
SetValue();
} }
} }
else else
@ -98,39 +98,20 @@ namespace Explorer
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
// using ValueType.Name instead of ValueTypeName, because we only want the short name.
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) }); GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
int dynSize = 25 + (m_valueToString.Length * 15); m_valueToString = GUIUnstrip.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
var maxwidth = window.width - 310f;
if (CanWrite) maxwidth -= 60;
if (dynSize > maxwidth)
{
m_valueToString = GUIUnstrip.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.Width(maxwidth) });
}
else
{
m_valueToString = GUILayout.TextField(m_valueToString, new GUILayoutOption[] { GUILayout.Width(dynSize) });
}
if (CanWrite) if (CanWrite)
{ {
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) })) if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
{ {
SetValueFromInput(m_valueToString); SetValueFromInput();
RefreshToString();
} }
} }
if (m_canBitwiseOperate) if (m_canBitwiseOperate)
{ {
bool orig = m_inBitwiseMode;
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]); m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]);
if (orig != m_inBitwiseMode)
{
RefreshToString();
}
} }
GUIUnstrip.Space(10); GUIUnstrip.Space(10);
@ -139,79 +120,91 @@ namespace Explorer
if (m_inBitwiseMode) if (m_inBitwiseMode)
{ {
if (CanWrite) DrawBitwise();
{
GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
GUI.skin.label.alignment = TextAnchor.UpperLeft;
if (GUILayout.Button("~", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = ~bit;
RefreshToString();
}
}
if (GUILayout.Button("<<", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value << bit;
RefreshToString();
}
}
if (GUILayout.Button(">>", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value >> bit;
RefreshToString();
}
}
if (GUILayout.Button("|", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value | bit;
RefreshToString();
}
}
if (GUILayout.Button("&", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value & bit;
RefreshToString();
}
}
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value ^ bit;
RefreshToString();
}
}
m_bitwiseOperatorInput = GUILayout.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
GUILayout.TextField(m_bitwiseToString, new GUILayoutOption[0]);
GUILayout.EndHorizontal();
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
public void SetValueFromInput(string valueString) private void DrawBitwise()
{
if (CanWrite)
{
GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
GUI.skin.label.alignment = TextAnchor.UpperLeft;
if (GUILayout.Button("~", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = ~bit;
RefreshToString();
}
}
if (GUILayout.Button("<<", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value << bit;
RefreshToString();
}
}
if (GUILayout.Button(">>", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value >> bit;
RefreshToString();
}
}
if (GUILayout.Button("|", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value | bit;
RefreshToString();
}
}
if (GUILayout.Button("&", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value & bit;
RefreshToString();
}
}
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
if (int.TryParse(m_bitwiseOperatorInput, out int bit))
{
Value = (int)Value ^ bit;
RefreshToString();
}
}
m_bitwiseOperatorInput = GUILayout.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
m_binaryInput = GUILayout.TextField(m_binaryInput, new GUILayoutOption[0]);
if (CanWrite)
{
if (GUILayout.Button("Apply", new GUILayoutOption[0]))
{
SetValueFromBinaryInput();
}
}
GUILayout.EndHorizontal();
}
public void SetValueFromInput()
{ {
if (MemInfo == null) if (MemInfo == null)
{ {
@ -221,23 +214,13 @@ namespace Explorer
if (m_isString) if (m_isString)
{ {
Value = valueString; Value = m_valueToString;
} }
else else
{ {
try try
{ {
Value = ParseMethod.Invoke(null, new object[] { valueString }); Value = ParseMethod.Invoke(null, new object[] { m_valueToString });
//if (m_inBitwiseMode)
//{
// var method = typeof(Convert).GetMethod($"To{ValueType.Name}", new Type[] { typeof(string), typeof(int) });
// Value = method.Invoke(null, new object[] { valueString, 2 });
//}
//else
//{
// Value = ParseMethod.Invoke(null, new object[] { valueString });
//}
} }
catch (Exception e) catch (Exception e)
{ {
@ -246,6 +229,23 @@ namespace Explorer
} }
SetValue(); SetValue();
RefreshToString();
}
private void SetValueFromBinaryInput()
{
try
{
var method = typeof(Convert).GetMethod($"To{ValueType.Name}", new Type[] { typeof(string), typeof(int) });
Value = method.Invoke(null, new object[] { m_binaryInput, 2 });
SetValue();
RefreshToString();
}
catch (Exception e)
{
ExplorerCore.Log("Exception setting value: " + e.GetType() + ", " + e.Message);
}
} }
} }
} }

View File

@ -2,58 +2,48 @@
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Release_ML_Cpp</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}</ProjectGuid> <ProjectGuid>{B21DBDE3-5D6F-4726-93AB-CC3CC68BAE7D}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Explorer</RootNamespace>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic> <Deterministic>true</Deterministic>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
<AssemblyName>Explorer</AssemblyName>
<IsCpp>true</IsCpp> <IsCpp>true</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
<IsNet35>false</IsNet35> <IsNet35>false</IsNet35>
<!-- Set this to the MelonLoader Il2Cpp Game folder, without the ending '\' character. -->
<MLCppGameFolder>D:\Steam\steamapps\common\Hellpoint</MLCppGameFolder>
<!-- Set this to the MelonLoader Mono Game folder, without the ending '\' character. -->
<MLMonoGameFolder>D:\Steam\steamapps\common\Outward</MLMonoGameFolder>
<!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. -->
<BIECppGameFolder>D:\Steam\steamapps\common\Outward - Il2Cpp</BIECppGameFolder>
<!-- Set this to the BepInEx Mono Game folder, without the ending '\' character. -->
<BIEMonoGameFolder>D:\Steam\steamapps\common\Outward</BIEMonoGameFolder>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols> <DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>CPP,ML</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<RootNamespace>Explorer</RootNamespace>
<AssemblyName>Explorer</AssemblyName>
<!-- Set this to the MelonLoader Il2Cpp Game folder, without the ending '\' character. -->
<MLCppGameFolder>D:\Steam\steamapps\common\Hellpoint</MLCppGameFolder>
<!-- Set this to the MelonLoader Mono Game folder, without the ending '\' character. -->
<MLMonoGameFolder>D:\Steam\steamapps\common\Outward</MLMonoGameFolder>
<!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. -->
<BIECppGameFolder>D:\Steam\steamapps\common\Outward - Il2Cpp</BIECppGameFolder>
<!-- Set this to the BepInEx Mono Game folder, without the ending '\' character. -->
<BIEMonoGameFolder>D:\Steam\steamapps\common\Outward</BIEMonoGameFolder>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<OutputPath>..\Release\Explorer.MelonLoader.Il2Cpp\</OutputPath>
<DefineConstants>CPP,ML</DefineConstants>
<IsCpp>true</IsCpp> <IsCpp>true</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
<IsNet35>false</IsNet35> <IsNet35>false</IsNet35>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.MelonLoader.Mono\</OutputPath> <OutputPath>..\Release\Explorer.MelonLoader.Mono\</OutputPath>
<DefineConstants>MONO,ML</DefineConstants> <DefineConstants>MONO,ML</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
@ -61,60 +51,32 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono_NET35|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono_NET35|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.MelonLoader.Mono.NET35\</OutputPath> <OutputPath>..\Release\Explorer.MelonLoader.Mono.NET35\</OutputPath>
<DefineConstants>MONO,ML,NET35</DefineConstants> <DefineConstants>MONO,ML,NET35</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
<IsNet35>true</IsNet35> <IsNet35>true</IsNet35>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.BepInEx.Il2Cpp\</OutputPath> <OutputPath>..\Release\Explorer.BepInEx.Il2Cpp\</OutputPath>
<DefineConstants>CPP,BIE</DefineConstants> <DefineConstants>CPP,BIE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>true</IsCpp> <IsCpp>true</IsCpp>
<IsMelonLoader>false</IsMelonLoader> <IsMelonLoader>false</IsMelonLoader>
<IsNet35>false</IsNet35> <IsNet35>false</IsNet35>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.BepInEx.Mono\</OutputPath> <OutputPath>..\Release\Explorer.BepInEx.Mono\</OutputPath>
<DefineConstants>MONO,BIE</DefineConstants> <DefineConstants>MONO,BIE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader> <IsMelonLoader>false</IsMelonLoader>
<IsNet35>false</IsNet35> <IsNet35>false</IsNet35>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono_NET35|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono_NET35|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<DebugSymbols>false</DebugSymbols>
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Release\Explorer.BepInEx.Mono.NET35\</OutputPath> <OutputPath>..\Release\Explorer.BepInEx.Mono.NET35\</OutputPath>
<DefineConstants>MONO,BIE,NET35</DefineConstants> <DefineConstants>MONO,BIE,NET35</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader> <IsMelonLoader>false</IsMelonLoader>
<IsNet35>true</IsNet35> <IsNet35>true</IsNet35>
@ -126,7 +88,7 @@
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<!-- MCS Ref --> <!-- MCS ref -->
<Reference Include="mcs" Condition="'$(IsNet35)'=='false'"> <Reference Include="mcs" Condition="'$(IsNet35)'=='false'">
<HintPath>..\lib\mcs.dll</HintPath> <HintPath>..\lib\mcs.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -135,119 +97,128 @@
<HintPath>..\lib\mcs.NET35.dll</HintPath> <HintPath>..\lib\mcs.NET35.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<!-- MelonLoader Il2Cpp core ref --> </ItemGroup>
<Reference Include="MelonLoader.ModHandler" Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'"> <!-- Universal Mono UnityEngine.dll ref (v5.3) -->
<HintPath>$(MLCppGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath> <ItemGroup Condition="'$(IsCpp)'=='false'">
<Private>False</Private> <Reference Include="UnityEngine">
</Reference>
<!-- MelonLoader Mono core ref -->
<Reference Include="MelonLoader.ModHandler" Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
<HintPath>$(MLMonoGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
<Private>False</Private>
</Reference>
<!-- BepInEx Mono core ref -->
<Reference Include="BepInEx" Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|false'">
<HintPath>$(BIEMonoGameFolder)\BepInEx\core\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony" Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|false'">
<HintPath>$(BIEMonoGameFolder)\BepInEx\core\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<!-- BepInEx Il2Cpp core ref -->
<Reference Include="BepInEx" Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
<HintPath>$(BIECppGameFolder)\BepInEx\core\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony" Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
<HintPath>$(BIECppGameFolder)\BepInEx\core\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.IL2CPP" Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
<HintPath>$(BIECppGameFolder)\BepInEx\core\BepInEx.IL2CPP.dll</HintPath>
<Private>False</Private>
</Reference>
<!-- MONO UnityEngine.dll ref -->
<Reference Include="UnityEngine" Condition="'$(IsCpp)'=='false'">
<HintPath>..\lib\UnityEngine.dll</HintPath> <HintPath>..\lib\UnityEngine.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<!-- MelonLoader Il2Cpp UnityEngine References --> </ItemGroup>
<Reference Include="UnhollowerBaseLib" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <!-- MelonLoader Mono ref -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|false'">
<Reference Include="MelonLoader.ModHandler">
<HintPath>$(MLMonoGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- BepInEx Mono refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|false'">
<Reference Include="BepInEx">
<HintPath>$(BIEMonoGameFolder)\BepInEx\core\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony">
<HintPath>$(BIEMonoGameFolder)\BepInEx\core\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<!-- MelonLoader Il2Cpp refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='true|true'">
<Reference Include="MelonLoader.ModHandler">
<HintPath>$(MLCppGameFolder)\MelonLoader\MelonLoader.ModHandler.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnhollowerBaseLib">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnhollowerBaseLib.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnhollowerBaseLib.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Il2Cppmscorlib" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="Il2Cppmscorlib">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\Il2Cppmscorlib.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\Il2Cppmscorlib.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Il2CppSystem.Core" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="Il2CppSystem.Core">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\Il2CppSystem.Core.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\Il2CppSystem.Core.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.CoreModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine.CoreModule">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.CoreModule.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.IMGUIModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine.IMGUIModule">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.IMGUIModule.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.PhysicsModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine.PhysicsModule">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.PhysicsModule.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.PhysicsModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.TextRenderingModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine.TextRenderingModule">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.TextRenderingModule.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.TextRenderingModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.UI" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|true'"> <Reference Include="UnityEngine.UI">
<HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.UI.dll</HintPath> <HintPath>$(MLCppGameFolder)\MelonLoader\Managed\UnityEngine.UI.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<!-- BepInEx Il2Cpp UnityEngine References --> </ItemGroup>
<Reference Include="UnhollowerBaseLib" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <!-- BepInEx Il2Cpp refs -->
<ItemGroup Condition="'$(IsMelonLoader)|$(IsCpp)'=='false|true'">
<Reference Include="BepInEx">
<HintPath>$(BIECppGameFolder)\BepInEx\core\BepInEx.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="0Harmony">
<HintPath>$(BIECppGameFolder)\BepInEx\core\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx.IL2CPP">
<HintPath>$(BIECppGameFolder)\BepInEx\core\BepInEx.IL2CPP.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnhollowerBaseLib">
<HintPath>$(BIECppGameFolder)\BepInEx\core\UnhollowerBaseLib.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\core\UnhollowerBaseLib.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Il2Cppmscorlib" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="Il2Cppmscorlib">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\Il2Cppmscorlib.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\Il2Cppmscorlib.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="Il2CppSystem.Core" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="Il2CppSystem.Core">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\Il2CppSystem.Core.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\Il2CppSystem.Core.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.CoreModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine.CoreModule">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.CoreModule.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.IMGUIModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine.IMGUIModule">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.IMGUIModule.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.PhysicsModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine.PhysicsModule">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.PhysicsModule.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.PhysicsModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.TextRenderingModule" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine.TextRenderingModule">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.TextRenderingModule.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.TextRenderingModule.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="UnityEngine.UI" Condition="'$(IsCpp)|$(IsMelonLoader)'=='true|false'"> <Reference Include="UnityEngine.UI">
<HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.UI.dll</HintPath> <HintPath>$(BIECppGameFolder)\BepInEx\unhollowed\UnityEngine.UI.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CachedObjects\CacheFactory.cs" />
<Compile Include="CachedObjects\IExpandHeight.cs" /> <Compile Include="CachedObjects\IExpandHeight.cs" />
<Compile Include="CachedObjects\Struct\CacheColor.cs" /> <Compile Include="CachedObjects\Struct\CacheColor.cs" />
<Compile Include="CachedObjects\Object\CacheDictionary.cs" /> <Compile Include="CachedObjects\Object\CacheDictionary.cs" />
@ -263,8 +234,8 @@
<Compile Include="CachedObjects\Struct\CacheRect.cs" /> <Compile Include="CachedObjects\Struct\CacheRect.cs" />
<Compile Include="Config\ModConfig.cs" /> <Compile Include="Config\ModConfig.cs" />
<Compile Include="ExplorerCore.cs" /> <Compile Include="ExplorerCore.cs" />
<Compile Include="Explorer_BepInPlugin.cs" /> <Compile Include="ExplorerBepInPlugin.cs" />
<Compile Include="Explorer_MelonMod.cs" /> <Compile Include="ExplorerMelonMod.cs" />
<Compile Include="Extensions\ReflectionExtensions.cs" /> <Compile Include="Extensions\ReflectionExtensions.cs" />
<Compile Include="Helpers\InputHelper.cs" /> <Compile Include="Helpers\InputHelper.cs" />
<Compile Include="Menu\CursorControl.cs" /> <Compile Include="Menu\CursorControl.cs" />

View File

@ -1,17 +1,12 @@
#if BIE #if BIE
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO; using System.IO;
using System.Reflection;
using BepInEx; using BepInEx;
using BepInEx.Logging; using BepInEx.Logging;
using HarmonyLib; using HarmonyLib;
using Mono.CSharp;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using BepInEx.IL2CPP; using BepInEx.IL2CPP;
@ -21,15 +16,16 @@ namespace Explorer
{ {
[BepInPlugin(ExplorerCore.GUID, ExplorerCore.NAME, ExplorerCore.VERSION)] [BepInPlugin(ExplorerCore.GUID, ExplorerCore.NAME, ExplorerCore.VERSION)]
#if CPP #if CPP
public class Explorer_BepInPlugin : BasePlugin public class ExplorerBepInPlugin : BasePlugin
#else #else
public class Explorer_BepInPlugin : BaseUnityPlugin public class ExplorerBepInPlugin : BaseUnityPlugin
#endif #endif
{ {
public static Explorer_BepInPlugin Instance; public static ExplorerBepInPlugin Instance;
public static ManualLogSource Logging => public static ManualLogSource Logging =>
#if CPP #if CPP
Instance.Log; Instance?.Log;
#else #else
Instance?.Logger; Instance?.Logger;
#endif #endif
@ -37,8 +33,7 @@ namespace Explorer
public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID); public static readonly Harmony HarmonyInstance = new Harmony(ExplorerCore.GUID);
#if CPP #if CPP
// temporary for BIE Il2Cpp // temporary for Il2Cpp until scene change delegate works
private static bool tempSceneChangeCheck;
private static string lastSceneName; private static string lastSceneName;
#endif #endif
@ -53,17 +48,16 @@ namespace Explorer
Instance = this; Instance = this;
#if CPP #if CPP
tempSceneChangeCheck = true; ClassInjector.RegisterTypeInIl2Cpp<ExplorerBehaviour>();
ClassInjector.RegisterTypeInIl2Cpp<DummyMB>();
GameObject.DontDestroyOnLoad( var obj = new GameObject(
new GameObject( "ExplorerBehaviour",
"Explorer_Dummy", new Il2CppSystem.Type[]
new Il2CppSystem.Type[] {
{ Il2CppType.Of<ExplorerBehaviour>()
Il2CppType.Of<DummyMB>() }
})
); );
GameObject.DontDestroyOnLoad(obj);
#else #else
SceneManager.activeSceneChanged += DoSceneChange; SceneManager.activeSceneChanged += DoSceneChange;
#endif #endif
@ -91,47 +85,34 @@ namespace Explorer
ExplorerCore.OnSceneChange(); ExplorerCore.OnSceneChange();
} }
internal static void DoUpdate() #if CPP // BepInEx Il2Cpp mod class doesn't have monobehaviour methods yet, so wrap them in a dummy.
public class ExplorerBehaviour : MonoBehaviour
{ {
ExplorerCore.Update(); public ExplorerBehaviour(IntPtr ptr) : base(ptr) { }
internal void Awake()
{
Logging.LogMessage("ExplorerBehaviour.Awake");
}
#endif
internal void Update()
{
ExplorerCore.Update();
#if CPP #if CPP
if (tempSceneChangeCheck)
{
var scene = SceneManager.GetActiveScene(); var scene = SceneManager.GetActiveScene();
if (scene.name != lastSceneName) if (scene.name != lastSceneName)
{ {
lastSceneName = scene.name; lastSceneName = scene.name;
DoSceneChange(scene, scene); DoSceneChange(scene, scene);
} }
}
#endif #endif
}
internal static void DoOnGUI()
{
ExplorerCore.OnGUI();
}
#if CPP
public class DummyMB : MonoBehaviour
{
public DummyMB(IntPtr ptr) : base(ptr) { }
internal void Awake()
{
Logging.LogMessage("DummyMB Awake");
}
#endif
internal void Update()
{
DoUpdate();
} }
internal void OnGUI() internal void OnGUI()
{ {
DoOnGUI(); ExplorerCore.OnGUI();
} }
#if CPP #if CPP
} }

View File

@ -95,7 +95,7 @@ namespace Explorer
#if ML #if ML
MelonLoader.MelonLogger.Log(message); MelonLoader.MelonLogger.Log(message);
#else #else
Explorer_BepInPlugin.Logging?.LogMessage(message); ExplorerBepInPlugin.Logging?.LogMessage(message);
#endif #endif
} }
@ -104,7 +104,7 @@ namespace Explorer
#if ML #if ML
MelonLoader.MelonLogger.LogWarning(message); MelonLoader.MelonLogger.LogWarning(message);
#else #else
Explorer_BepInPlugin.Logging?.LogWarning(message); ExplorerBepInPlugin.Logging?.LogWarning(message);
#endif #endif
} }
@ -113,7 +113,7 @@ namespace Explorer
#if ML #if ML
MelonLoader.MelonLogger.LogError(message); MelonLoader.MelonLogger.LogError(message);
#else #else
Explorer_BepInPlugin.Logging?.LogError(message); ExplorerBepInPlugin.Logging?.LogError(message);
#endif #endif
} }
} }

View File

@ -7,9 +7,9 @@ using MelonLoader;
namespace Explorer namespace Explorer
{ {
public class Explorer_MelonMod : MelonMod public class ExplorerMelonMod : MelonMod
{ {
public static Explorer_MelonMod Instance; public static ExplorerMelonMod Instance;
public override void OnApplicationStart() public override void OnApplicationStart()
{ {

View File

@ -8,19 +8,12 @@ namespace Explorer
public static class ReflectionExtensions public static class ReflectionExtensions
{ {
#if CPP #if CPP
/// <summary>
/// Extension to allow for easy, non-generic Il2Cpp casting.
/// The extension is on System.Object, but only Il2Cpp objects would be a valid target.
/// </summary>
public static object Il2CppCast(this object obj, Type castTo) public static object Il2CppCast(this object obj, Type castTo)
{ {
return ReflectionHelpers.Il2CppCast(obj, castTo); return ReflectionHelpers.Il2CppCast(obj, castTo);
} }
#endif #endif
/// <summary>
/// Extension to safely try to get all Types from an Assembly, with a fallback for ReflectionTypeLoadException.
/// </summary>
public static IEnumerable<Type> TryGetTypes(this Assembly asm) public static IEnumerable<Type> TryGetTypes(this Assembly asm)
{ {
try try
@ -29,7 +22,14 @@ namespace Explorer
} }
catch (ReflectionTypeLoadException e) catch (ReflectionTypeLoadException e)
{ {
return e.Types.Where(t => t != null); try
{
return asm.GetExportedTypes();
}
catch
{
return e.Types.Where(t => t != null);
}
} }
catch catch
{ {

View File

@ -82,7 +82,7 @@ namespace Explorer
{ {
ExplorerCore.Log("UnityEngine.Input is null, trying to load manually...."); ExplorerCore.Log("UnityEngine.Input is null, trying to load manually....");
if ((ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule.dll") || ReflectionHelpers.LoadModule("UnityEngine.CoreModule.dll")) if ((ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") || ReflectionHelpers.LoadModule("UnityEngine.CoreModule"))
&& Input != null) && Input != null)
{ {
ExplorerCore.Log("Ok!"); ExplorerCore.Log("Ok!");

View File

@ -20,10 +20,10 @@ namespace Explorer
#if CPP #if CPP
public static ILType GameObjectType => Il2CppType.Of<GameObject>(); public static ILType GameObjectType => Il2CppType.Of<GameObject>();
public static ILType TransformType => Il2CppType.Of<Transform>(); public static ILType TransformType => Il2CppType.Of<Transform>();
public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>(); public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>();
public static ILType ComponentType => Il2CppType.Of<Component>(); public static ILType ComponentType => Il2CppType.Of<Component>();
public static ILType BehaviourType => Il2CppType.Of<Behaviour>(); public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
private static readonly MethodInfo tryCastMethodInfo = typeof(Il2CppObjectBase).GetMethod("TryCast"); private static readonly MethodInfo tryCastMethodInfo = typeof(Il2CppObjectBase).GetMethod("TryCast");
private static readonly Dictionary<Type, MethodInfo> cachedTryCastMethods = new Dictionary<Type, MethodInfo>(); private static readonly Dictionary<Type, MethodInfo> cachedTryCastMethods = new Dictionary<Type, MethodInfo>();
@ -41,10 +41,10 @@ namespace Explorer
} }
#else #else
public static Type GameObjectType => typeof(GameObject); public static Type GameObjectType => typeof(GameObject);
public static Type TransformType => typeof(Transform); public static Type TransformType => typeof(Transform);
public static Type ObjectType => typeof(UnityEngine.Object); public static Type ObjectType => typeof(UnityEngine.Object);
public static Type ComponentType => typeof(Component); public static Type ComponentType => typeof(Component);
public static Type BehaviourType => typeof(Behaviour); public static Type BehaviourType => typeof(Behaviour);
#endif #endif
public static bool IsEnumerable(Type t) public static bool IsEnumerable(Type t)
@ -148,7 +148,12 @@ namespace Explorer
public static bool LoadModule(string module) public static bool LoadModule(string module)
{ {
var path = $@"MelonLoader\Managed\{module}"; #if CPP
#if ML
var path = $@"MelonLoader\Managed\{module}.dll";
#else
var path = $@"BepInEx\unhollowed\{module}.dll";
#endif
if (!File.Exists(path)) return false; if (!File.Exists(path)) return false;
try try
@ -159,8 +164,9 @@ namespace Explorer
catch (Exception e) catch (Exception e)
{ {
ExplorerCore.Log(e.GetType() + ", " + e.Message); ExplorerCore.Log(e.GetType() + ", " + e.Message);
return false;
} }
#endif
return false;
} }
public static string ExceptionToString(Exception e) public static string ExceptionToString(Exception e)
@ -175,7 +181,6 @@ namespace Explorer
return "Garbage collected in Il2Cpp."; return "Garbage collected in Il2Cpp.";
} }
#endif #endif
return e.GetType() + ", " + e.Message; return e.GetType() + ", " + e.Message;
} }

View File

@ -74,9 +74,9 @@ namespace Explorer
var harmony = var harmony =
#if ML #if ML
Explorer_MelonMod.Instance.harmonyInstance; ExplorerMelonMod.Instance.harmonyInstance;
#else #else
Explorer_BepInPlugin.HarmonyInstance; ExplorerBepInPlugin.HarmonyInstance;
#endif #endif
; ;

View File

@ -76,7 +76,7 @@ namespace Explorer
} }
#endif #endif
var cache = CacheObjectBase.GetCacheObject(toCache); var cache = CacheFactory.GetTypeAndCacheObject(toCache);
m_searchResults.Add(cache); m_searchResults.Add(cache);
} }

View File

@ -21,7 +21,7 @@ namespace Explorer
public const string Local = "#a6e9e9"; public const string Local = "#a6e9e9";
public const string StructGreen = "#b8d7a3"; public const string StructGreen = "#92c470";
} }
public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f); public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);

View File

@ -369,7 +369,7 @@ namespace Explorer
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]);
var width = m_rect.width / 2 - 115f; var width = m_rect.width / 2 - 135f;
m_addComponentInput = GUILayout.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) }); m_addComponentInput = GUILayout.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
if (GUILayout.Button("Add Comp", new GUILayoutOption[0])) if (GUILayout.Button("Add Comp", new GUILayoutOption[0]))
{ {

View File

@ -204,7 +204,7 @@ namespace Explorer
try try
{ {
var cached = CacheObjectBase.GetCacheObject(member, target); var cached = CacheFactory.GetTypeAndCacheObject(member, target);
if (cached != null) if (cached != null)
{ {
cachedSigs.Add(sig); cachedSigs.Add(sig);

View File

@ -6,7 +6,7 @@ using Explorer;
#if ML #if ML
using MelonLoader; using MelonLoader;
[assembly: MelonInfo(typeof(Explorer_MelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)] [assembly: MelonInfo(typeof(ExplorerMelonMod), ExplorerCore.NAME, ExplorerCore.VERSION, ExplorerCore.AUTHOR)]
[assembly: MelonGame(null, null)] [assembly: MelonGame(null, null)]
#endif #endif