Compare commits

..

18 Commits
1.7.2 ... 1.7.5

Author SHA1 Message Date
f203ae37fc 1.7.5
* Added support for Enums with [Flags] attribute (can set each flag individually)
* Added support for easier bitwise operations on ints (or any primitive assignable to int), and viewing the int as binary. This is intended for things like `Camera.cullingMask`, etc.
* Fixed an issue with Enums that contain duplicate values, for example `CameraClearFlags` (has duplicate values for 2).
2020-09-23 19:19:29 +10:00
2006a9ea76 Faster non-generic Il2Cpp casting 2020-09-21 22:45:33 +10:00
c9bc450d09 Update README.md 2020-09-21 17:48:13 +10:00
a1198f3a92 Update CacheColor.cs 2020-09-21 05:59:01 +10:00
04248a89ce Fix for cases when structs return null (due to null declaring instance) 2020-09-20 20:26:05 +10:00
3639824df3 Cleanup 2020-09-19 01:55:27 +10:00
939861b5f0 Cleanup 2020-09-19 01:44:38 +10:00
ad5fc04a3b Fix methods with multiple generic constraints 2020-09-19 01:27:33 +10:00
c39e097378 Add support for methods with ref/in/out args 2020-09-19 00:14:04 +10:00
129a7e3765 Improved interaction with generic methods and some minor UI fixes 2020-09-18 23:10:46 +10:00
643bb4519c Remove and sort usings 2020-09-18 18:38:11 +10:00
b154cbf39d Add support for generic methods, improved non-generic dictionary output 2020-09-18 18:03:17 +10:00
db91968519 Cleanup and improve syntax highlighting
* Static class members are now displayed in Italics and in a darker color, making them easier to distinguish.
* Cleaned up some issues related to syntax highlighting and refactored it into a global class.
* Methods and properties no longer display their arguments as part of the member name, they are only displayed when "Evaluate" is pressed.
2020-09-16 20:03:57 +10:00
5d58993b07 1.7.31
* Added support for Il2Cpp Hashtable (non-generic Dict)
* Dictionaries should now display CacheOther values better (smaller buttons)
* Cleaned up and improved some of CacheDictionary performance
2020-09-15 17:38:10 +10:00
eea581f8d5 Update ResizeDrag.cs 2020-09-14 20:27:49 +10:00
9bb3c77bae 1.7.3
* Reverted some unstrip fixes from 1.7.2 because it was causing more problems than it solved.
2020-09-14 20:25:38 +10:00
477a6859d7 Update README.md 2020-09-14 17:07:52 +10:00
f8f9671746 Update README.md 2020-09-14 16:56:42 +10:00
47 changed files with 1238 additions and 1021 deletions

View File

@ -17,9 +17,21 @@
<a href="https://github.com/sinai-dev/MonoExplorer">Looking for a Mono version?</a>
</p>
### Known issues
* CppExplorer may experience a `MissingMethodException` when trying to use certain UnityEngine methods. If you experience this, please open an issue and I will do my best to fix it.
* Reflection may fail with certain types (eg. `Nullable<T>`, some Dictionary types, etc). Please see [Il2CppAssemblyUnhollower](https://github.com/knah/Il2CppAssemblyUnhollower#known-issues) for more details.
- [Known issues](#known-issues)
- [How to install](#how-to-install)
- [How to use](#how-to-use)
- [Mod Config](#mod-config)
- [Features](#features)
- [Mouse Control](#mouse-control)
- [Building](#building)
- [Credits](#credits)
## Known issues
As of version 1.7+, CppExplorer has reached a fairly stable state for most Il2Cpp games.
* .NET 3.5 is not currently supported (Unity 5.6.1 and older), this might change in the future.
* Some methods may still fail with a `MissingMethodException`, please let me know if you experience this (with full MelonLoader log please).
* Reflection may fail with certain types, see [here](https://github.com/knah/Il2CppAssemblyUnhollower#known-issues) for more details.
* Scrolling with mouse wheel in the CppExplorer menu may not work on all games at the moment.
## How to install
@ -53,7 +65,7 @@ This config is generated to `Mods\CppExplorer\config.xml`. Edit the config while
* Default: `<x>550</x> <y>700</y>`
## Features
[![](overview.png)](overview.png)
[![](overview.png)](https://raw.githubusercontent.com/sinai-dev/CppExplorer/master/overview.png)
<i>An overview of the different CppExplorer menus.</i>
@ -87,9 +99,9 @@ CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Re
* Filter by name, type, etc.
* For GameObjects and Transforms you can filter which scene they are found in too.
### C# REPL console
### C# console
* A simple C# REPL console, allows you to execute a method body on the fly.
* A simple C# console, allows you to execute a method body on the fly.
### Inspect-under-mouse
@ -105,6 +117,23 @@ CppExplorer can force the mouse to be visible and unlocked when the menu is open
* For Hellpoint, use [HPExplorerMouseControl](https://github.com/sinai-dev/Hellpoint-Mods/tree/master/HPExplorerMouseControl/HPExplorerMouseControl)
* You can create your own plugin using one of the two plugins above as an example. Usually only a few simple Harmony patches are needed to fix the problem.
For example:
```csharp
using Explorer;
using Harmony;
// ...
[HarmonyPatch(typeof(MyGame.MenuClass), nameof(MyGame.MenuClass.CursorUpdate)]
public class MenuClass_CursorUpdate
{
[HarmonyPrefix]
public static bool Prefix()
{
// prevent method running if menu open, let it run if not.
return !CppExplorer.ShowMenu;
}
}
```
## Building
If you'd like to build this yourself, everything you need (other than MelonLoader) is included with this repository, there is no need for recursive cloning etc.

View File

@ -2,10 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnhollowerBaseLib;
using UnityEngine;
namespace Explorer
@ -13,14 +10,14 @@ namespace Explorer
public abstract class CacheObjectBase
{
public object Value;
public string ValueTypeName;
public Type ValueType;
public MemberInfo MemInfo { get; set; }
public Type DeclaringType { get; set; }
public object DeclaringInstance { get; set; }
public bool HasParameters => m_arguments != null && m_arguments.Length > 0;
public virtual bool HasParameters => m_arguments != null && m_arguments.Length > 0;
public bool m_evaluated = false;
public bool m_isEvaluating;
public ParameterInfo[] m_arguments = new ParameterInfo[0];
@ -117,27 +114,16 @@ namespace Explorer
var pi = memberInfo as PropertyInfo;
var mi = memberInfo as MethodInfo;
// if PropertyInfo, check if can process args
if (pi != null && !CanProcessArgs(pi.GetIndexParameters()))
// Check if can process args
if ((pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|| (mi != null && !CanProcessArgs(mi.GetParameters())))
{
return null;
}
// This is pretty ugly, could probably make a cleaner implementation.
// However, the only cleaner ways I can think of are slower and probably not worth it.
// Note: the order is somewhat important.
if (mi != null)
{
if (CacheMethod.CanEvaluate(mi))
{
holder = new CacheMethod();
}
else
{
return null;
}
holder = new CacheMethod();
}
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
{
@ -149,7 +135,14 @@ namespace Explorer
}
else if (valueType.IsEnum)
{
holder = new CacheEnum();
if (valueType.GetCustomAttributes(typeof(FlagsAttribute), false) is object[] attributes && attributes.Length > 0)
{
holder = new CacheEnumFlags();
}
else
{
holder = new CacheEnum();
}
}
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
{
@ -172,7 +165,7 @@ namespace Explorer
{
holder = new CacheDictionary();
}
else if (ReflectionHelpers.IsEnumerable(valueType) || ReflectionHelpers.IsCppEnumerable(valueType))
else if (ReflectionHelpers.IsEnumerable(valueType))
{
holder = new CacheList();
}
@ -183,7 +176,6 @@ namespace Explorer
holder.Value = obj;
holder.ValueType = valueType;
holder.ValueTypeName = valueType.FullName;
if (memberInfo != null)
{
@ -214,7 +206,18 @@ namespace Explorer
{
foreach (var param in parameters)
{
if (!param.ParameterType.IsPrimitive && param.ParameterType != typeof(string))
var pType = param.ParameterType;
if (pType.IsByRef && pType.HasElementType)
{
pType = pType.GetElementType();
}
if (pType.IsPrimitive || pType == typeof(string))
{
continue;
}
else
{
return false;
}
@ -244,6 +247,11 @@ namespace Explorer
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
@ -308,14 +316,7 @@ namespace Explorer
var pi = MemInfo as PropertyInfo;
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
if (HasParameters)
{
Value = pi.GetValue(target, ParseArguments());
}
else
{
Value = pi.GetValue(target, null);
}
Value = pi.GetValue(target, ParseArguments());
}
ReflectionException = null;
@ -379,7 +380,7 @@ namespace Explorer
if (MemInfo != null)
{
GUIUnstrip.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
GUILayout.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
}
else
{
@ -390,33 +391,81 @@ namespace Explorer
if (HasParameters)
{
GUIUnstrip.BeginVertical();
GUILayout.BeginVertical(null);
if (m_isEvaluating)
{
for (int i = 0; i < m_arguments.Length; i++)
if (cm != null && cm.GenericArgs.Length > 0)
{
var name = m_arguments[i].Name;
var input = m_argumentInput[i];
var type = m_arguments[i].ParameterType.Name;
GUILayout.Label($"<b><color=orange>Generic Arguments:</color></b>", null);
var label = "<color=#2df7b2>" + type + "</color> <color=#a6e9e9>" + name + "</color>";
if (m_arguments[i].HasDefaultValue)
for (int i = 0; i < cm.GenericArgs.Length; i++)
{
label = $"<i>[{label} = {m_arguments[i].DefaultValue}]</i>";
string types = "";
if (cm.GenericConstraints[i].Length > 0)
{
foreach (var constraint in cm.GenericConstraints[i])
{
if (types != "") types += ", ";
string type;
if (constraint == null)
type = "Any";
else
type = constraint.ToString();
types += $"<color={UIStyles.Syntax.Class_Instance}>{type}</color>";
}
}
else
{
types = $"<color={UIStyles.Syntax.Class_Instance}>Any</color>";
}
var input = cm.GenericArgInput[i];
GUILayout.BeginHorizontal(null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
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) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(types, null);
GUILayout.EndHorizontal();
}
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(20) });
m_argumentInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
GUIUnstrip.Label(label);
GUIUnstrip.EndHorizontal();
}
GUIUnstrip.BeginHorizontal();
if (GUIUnstrip.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
if (m_arguments.Length > 0)
{
GUILayout.Label($"<b><color=orange>Arguments:</color></b>", null);
for (int i = 0; i < m_arguments.Length; i++)
{
var name = m_arguments[i].Name;
var input = m_argumentInput[i];
var type = m_arguments[i].ParameterType.Name;
var label = $"<color={UIStyles.Syntax.Class_Instance}>{type}</color> ";
label += $"<color={UIStyles.Syntax.Local}>{name}</color>";
if (m_arguments[i].HasDefaultValue)
{
label = $"<i>[{label} = {m_arguments[i].DefaultValue ?? "null"}]</i>";
}
GUILayout.BeginHorizontal(null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) });
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(label, null);
GUILayout.EndHorizontal();
}
}
GUILayout.BeginHorizontal(null);
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
{
if (cm != null)
{
@ -427,53 +476,60 @@ namespace Explorer
UpdateValue();
}
}
if (GUIUnstrip.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
{
m_isEvaluating = false;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
else
{
if (GUIUnstrip.Button($"Evaluate ({m_arguments.Length} params)", new GUILayoutOption[] { GUILayout.Width(150) }))
var lbl = $"Evaluate (";
int len = m_arguments.Length;
if (cm != null) len += cm.GenericArgs.Length;
lbl += len + " params)";
if (GUILayout.Button(lbl, new GUILayoutOption[] { GUILayout.Width(150) }))
{
m_isEvaluating = true;
}
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
// new line and space
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(labelWidth);
}
else if (cm != null)
{
//GUIUnstrip.BeginHorizontal();
//GUILayout.BeginHorizontal(null);
if (GUIUnstrip.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
{
cm.Evaluate();
}
// new line and space
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(labelWidth);
}
string typeName = $"<color={UIStyles.Syntax.Class_Instance}>{ValueType.FullName}</color>";
if (!string.IsNullOrEmpty(ReflectionException))
{
GUIUnstrip.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")");
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
}
else if ((HasParameters || this is CacheMethod) && !m_evaluated)
{
GUIUnstrip.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)");
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeName})", null);
}
else if (Value == null && !(this is CacheMethod))
{
GUIUnstrip.Label("<i>null (" + ValueTypeName + ")</i>");
GUILayout.Label($"<i>null ({typeName})</i>", null);
}
else
{
@ -484,31 +540,80 @@ namespace Explorer
private string GetRichTextName()
{
string memberColor = "";
switch (MemInfo.MemberType)
{
case MemberTypes.Field:
memberColor = "#c266ff"; break;
case MemberTypes.Property:
memberColor = "#72a6a6"; break;
case MemberTypes.Method:
memberColor = "#ff8000"; break;
};
bool isStatic = false;
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
if (m_arguments.Length > 0 || this is CacheMethod)
if (MemInfo is FieldInfo fi)
{
m_richTextName += "(";
var _params = "";
foreach (var param in m_arguments)
if (fi.IsStatic)
{
if (_params != "") _params += ", ";
_params += $"<color=#2df7b2>{param.ParameterType.Name}</color> <color=#a6e9e9>{param.Name}</color>";
isStatic = true;
memberColor = UIStyles.Syntax.Field_Static;
}
m_richTextName += _params;
m_richTextName += ")";
else
memberColor = UIStyles.Syntax.Field_Instance;
}
else if (MemInfo is MethodInfo mi)
{
if (mi.IsStatic)
{
isStatic = true;
memberColor = UIStyles.Syntax.Method_Static;
}
else
memberColor = UIStyles.Syntax.Method_Instance;
}
else if (MemInfo is PropertyInfo pi)
{
if (pi.GetAccessors()[0].IsStatic)
{
isStatic = true;
memberColor = UIStyles.Syntax.Prop_Static;
}
else
memberColor = UIStyles.Syntax.Prop_Instance;
}
string classColor = MemInfo.DeclaringType.IsAbstract && MemInfo.DeclaringType.IsSealed
? UIStyles.Syntax.Class_Static
: UIStyles.Syntax.Class_Instance;
m_richTextName = $"<color={classColor}>{MemInfo.DeclaringType.Name}</color>.";
if (isStatic) m_richTextName += "<i>";
m_richTextName += $"<color={memberColor}>{MemInfo.Name}</color>";
if (isStatic) m_richTextName += "</i>";
// generic method args
if (this is CacheMethod cm && cm.GenericArgs.Length > 0)
{
m_richTextName += "<";
var args = "";
for (int i = 0; i < cm.GenericArgs.Length; i++)
{
if (args != "") args += ", ";
args += $"<color={UIStyles.Syntax.StructGreen}>{cm.GenericArgs[i].Name}</color>";
}
m_richTextName += args;
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;
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Explorer
namespace Explorer
{
interface IExpandHeight
{

View File

@ -1,13 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnityEngine;
using System.Reflection;
using UnhollowerBaseLib;
using UnityEngine;
namespace Explorer
{
@ -98,37 +93,16 @@ namespace Explorer
private void GetGenericArguments()
{
if (this.MemInfo != null)
if (ValueType.IsGenericType)
{
Type memberType = null;
switch (this.MemInfo.MemberType)
{
case MemberTypes.Field:
memberType = (MemInfo as FieldInfo).FieldType;
break;
case MemberTypes.Property:
memberType = (MemInfo as PropertyInfo).PropertyType;
break;
}
if (memberType != null && memberType.IsGenericType)
{
m_keysType = memberType.GetGenericArguments()[0];
m_valuesType = memberType.GetGenericArguments()[1];
}
m_keysType = ValueType.GetGenericArguments()[0];
m_valuesType = ValueType.GetGenericArguments()[1];
}
else if (Value != null)
else
{
var type = Value.GetType();
if (type.IsGenericType)
{
m_keysType = type.GetGenericArguments()[0];
m_valuesType = type.GetGenericArguments()[1];
}
else
{
MelonLogger.Log("TODO? Dictionary is of type: " + Value.GetType().FullName);
}
// It's non-generic, just use System.Object to allow for anything.
m_keysType = typeof(object);
m_valuesType = typeof(object);
}
}
@ -154,14 +128,16 @@ namespace Explorer
var keys = new List<CacheObjectBase>();
foreach (var key in IDict.Keys)
{
var cache = GetCacheObject(key, TypeOfKeys);
Type t = ReflectionHelpers.GetActualType(key) ?? TypeOfKeys;
var cache = GetCacheObject(key, t);
keys.Add(cache);
}
var values = new List<CacheObjectBase>();
foreach (var val in IDict.Values)
{
var cache = GetCacheObject(val, TypeOfValues);
Type t = ReflectionHelpers.GetActualType(val) ?? TypeOfValues;
var cache = GetCacheObject(val, t);
values.Add(cache);
}
@ -202,7 +178,7 @@ namespace Explorer
{
if (m_cachedKeys == null || m_cachedValues == null)
{
GUIUnstrip.Label("Cached keys or values is null!");
GUILayout.Label("Cached keys or values is null!", null);
return;
}
@ -212,14 +188,14 @@ namespace Explorer
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
@ -229,7 +205,7 @@ namespace Explorer
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
string btnLabel = $"[{count}] <color=#2df7b2>Dictionary<{TypeOfKeys.FullName}, {TypeOfValues.FullName}></color>";
if (GUIUnstrip.Button(btnLabel, new GUILayoutOption[] { GUILayout.Width(negativeWhitespace) }))
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.Width(negativeWhitespace) }))
{
WindowManager.InspectObject(Value, out bool _);
}
@ -243,19 +219,19 @@ namespace Explorer
if (count > Pages.ItemsPerPage)
{
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
Pages.CurrentPageLabel();
// prev/next page buttons
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(60) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(60) }))
{
Pages.TurnPage(Turn.Left);
}
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(60) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(60) }))
{
Pages.TurnPage(Turn.Right);
}
@ -273,25 +249,25 @@ namespace Explorer
var val = m_cachedValues[i];
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
//GUIUnstrip.Space(whitespace);
if (key == null || val == null)
{
GUIUnstrip.Label($"[{i}] <i><color=grey>(null)</color></i>");
GUILayout.Label($"[{i}] <i><color=grey>(null)</color></i>", null);
}
else
{
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
GUIUnstrip.Label("Key:", new GUILayoutOption[] { GUILayout.Width(40) });
key.DrawValue(window, (window.width / 2) - 30f);
GUILayout.Label("Key:", new GUILayoutOption[] { GUILayout.Width(40) });
key.DrawValue(window, (window.width / 2) - 80f);
GUIUnstrip.Label("Value:", new GUILayoutOption[] { GUILayout.Width(40) });
val.DrawValue(window, (window.width / 2) - 30f);
GUILayout.Label("Value:", new GUILayoutOption[] { GUILayout.Width(40) });
val.DrawValue(window, (window.width / 2) - 80f);
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using MelonLoader;
using UnityEngine;
@ -264,7 +263,7 @@ namespace Explorer
{
if (m_cachedEntries == null)
{
GUIUnstrip.Label("m_cachedEntries is null!");
GUILayout.Label("m_cachedEntries is null!", null);
return;
}
@ -274,14 +273,14 @@ namespace Explorer
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
@ -291,7 +290,7 @@ namespace Explorer
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
string btnLabel = $"[{count}] <color=#2df7b2>{EntryType.FullName}</color>";
if (GUIUnstrip.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(negativeWhitespace) }))
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(negativeWhitespace) }))
{
WindowManager.InspectObject(Value, out bool _);
}
@ -305,19 +304,19 @@ namespace Explorer
if (count > Pages.ItemsPerPage)
{
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
Pages.CurrentPageLabel();
// prev/next page buttons
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(60) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(60) }))
{
Pages.TurnPage(Turn.Left);
}
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(60) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(60) }))
{
Pages.TurnPage(Turn.Right);
}
@ -334,19 +333,19 @@ namespace Explorer
var entry = m_cachedEntries[i];
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (entry == null || entry.Value == null)
{
GUIUnstrip.Label($"[{i}] <i><color=grey>(null)</color></i>");
GUILayout.Label($"[{i}] <i><color=grey>(null)</color></i>", null);
}
else
{
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
entry.DrawValue(window, window.width - (whitespace + 85));
}

View File

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using UnityEngine;
using MelonLoader;
using UnityEngine;
namespace Explorer
{
@ -13,16 +11,24 @@ namespace Explorer
{
private CacheObjectBase m_cachedReturnValue;
public static bool CanEvaluate(MethodInfo mi)
{
// TODO generic args
if (mi.GetGenericArguments().Length > 0)
{
return false;
}
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
// primitive and string args supported
return CanProcessArgs(mi.GetParameters());
public Type[] GenericArgs { get; private set; }
public Type[][] GenericConstraints { get; private set; }
public string[] GenericArgInput = new string[0];
public override void Init()
{
var mi = (MemInfo as MethodInfo);
GenericArgs = mi.GetGenericArguments();
GenericConstraints = GenericArgs.Select(x => x.GetGenericParameterConstraints())
.ToArray();
GenericArgInput = new string[GenericArgs.Length];
ValueType = mi.ReturnType;
}
public override void UpdateValue()
@ -32,27 +38,29 @@ namespace Explorer
public void Evaluate()
{
m_isEvaluating = false;
var mi = MemInfo as MethodInfo;
object ret = null;
if (!HasParameters)
MethodInfo mi;
if (GenericArgs.Length > 0)
{
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, new object[0]);
m_evaluated = true;
mi = MakeGenericMethodFromInput();
if (mi == null) return;
}
else
{
try
{
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments());
m_evaluated = true;
}
catch (Exception e)
{
MelonLogger.Log($"Exception evaluating: {e.GetType()}, {e.Message}");
}
mi = MemInfo as MethodInfo;
}
object ret = null;
try
{
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments());
m_evaluated = true;
m_isEvaluating = false;
}
catch (Exception e)
{
MelonLogger.LogWarning($"Exception evaluating: {e.GetType()}, {e.Message}");
ReflectionException = ReflectionHelpers.ExceptionToString(e);
}
if (ret != null)
@ -66,10 +74,54 @@ namespace Explorer
}
}
private MethodInfo MakeGenericMethodFromInput()
{
var mi = MemInfo as MethodInfo;
var list = new List<Type>();
for (int i = 0; i < GenericArgs.Length; i++)
{
var input = GenericArgInput[i];
if (ReflectionHelpers.GetTypeByName(input) is Type t)
{
if (GenericConstraints[i].Length == 0)
{
list.Add(t);
}
else
{
foreach (var constraint in GenericConstraints[i].Where(x => x != null))
{
if (!constraint.IsAssignableFrom(t))
{
MelonLogger.LogWarning($"Generic argument #{i}, '{input}' is not assignable from the constraint '{constraint}'!");
return null;
}
}
list.Add(t);
}
}
else
{
MelonLogger.LogWarning($"Generic argument #{i}, could not get any type by the name of '{input}'!" +
$" Make sure you use the full name, including the NameSpace.");
return null;
}
}
// make into a generic with type list
mi = mi.MakeGenericMethod(list.ToArray());
return mi;
}
// ==== GUI DRAW ====
public override void DrawValue(Rect window, float width)
{
string typeLabel = $"<color={UIStyles.Syntax.Class_Instance}>{ValueType.FullName}</color>";
if (m_evaluated)
{
if (m_cachedReturnValue != null)
@ -78,12 +130,12 @@ namespace Explorer
}
else
{
GUIUnstrip.Label($"null (<color=#2df7b2>{ValueTypeName}</color>)");
GUILayout.Label($"null ({typeLabel})", null);
}
}
else
{
GUIUnstrip.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)");
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeLabel})", null);
}
}
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using UnityEngine;
@ -11,55 +6,75 @@ namespace Explorer
{
public class CacheOther : CacheObjectBase
{
public string ButtonLabel => m_btnLabel ?? GetButtonLabel();
private string m_btnLabel;
public MethodInfo ToStringMethod => m_toStringMethod ?? GetToStringMethod();
private MethodInfo m_toStringMethod;
public MethodInfo ToStringMethod
public override void UpdateValue()
{
get
{
if (m_toStringMethod == null)
{
try
{
m_toStringMethod = ReflectionHelpers.GetActualType(Value).GetMethod("ToString", new Type[0])
?? typeof(object).GetMethod("ToString", new Type[0]);
base.UpdateValue();
// test invoke
m_toStringMethod.Invoke(Value, null);
}
catch
{
m_toStringMethod = typeof(object).GetMethod("ToString", new Type[0]);
}
}
return m_toStringMethod;
}
GetButtonLabel();
}
public override void DrawValue(Rect window, float width)
{
string label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
if (!label.Contains(ValueTypeName))
{
label += $" (<color=#2df7b2>{ValueTypeName}</color>)";
}
else
{
label = label.Replace(ValueTypeName, $"<color=#2df7b2>{ValueTypeName}</color>");
}
if (Value is UnityEngine.Object unityObj && !label.Contains(unityObj.name))
{
label = unityObj.name + " | " + label;
}
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
if (GUIUnstrip.Button(label, new GUILayoutOption[] { GUILayout.Width(width - 15) }))
if (GUILayout.Button(ButtonLabel, new GUILayoutOption[] { GUILayout.Width(width - 15) }))
{
WindowManager.InspectObject(Value, out bool _);
}
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
}
private MethodInfo GetToStringMethod()
{
try
{
m_toStringMethod = ReflectionHelpers.GetActualType(Value).GetMethod("ToString", new Type[0])
?? typeof(object).GetMethod("ToString", new Type[0]);
// test invoke
m_toStringMethod.Invoke(Value, null);
}
catch
{
m_toStringMethod = typeof(object).GetMethod("ToString", new Type[0]);
}
return m_toStringMethod;
}
private string GetButtonLabel()
{
if (Value == null) return null;
string label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
var classColor = ValueType.IsAbstract && ValueType.IsSealed
? UIStyles.Syntax.Class_Static
: UIStyles.Syntax.Class_Instance;
string typeLabel = $"<color={classColor}>{ValueType.FullName}</color>";
if (Value is UnityEngine.Object)
{
label = label.Replace($"({ValueType.FullName})", $"({typeLabel})");
}
else
{
if (!label.Contains(ValueType.FullName))
{
label += $" ({typeLabel})";
}
else
{
label = label.Replace(ValueType.FullName, typeLabel);
}
}
return m_btnLabel = label;
}
}
}

View File

@ -21,6 +21,8 @@ namespace Explorer
{
base.UpdateValue();
if (Value == null) return;
var color = (Color)Value;
r = color.r.ToString();
@ -35,14 +37,14 @@ namespace Explorer
{
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
@ -51,49 +53,49 @@ namespace Explorer
//var c = (Color)Value;
//GUI.color = c;
GUIUnstrip.Label($"<color=#2df7b2>Color:</color> {((Color)Value).ToString()}");
GUILayout.Label($"<color=#2df7b2>Color:</color> {((Color)Value).ToString()}", null);
//GUI.color = Color.white;
if (CanWrite && IsExpanded)
{
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) });
r = GUIUnstrip.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) });
r = GUILayout.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
g = GUIUnstrip.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
g = GUILayout.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
b = GUIUnstrip.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
b = GUILayout.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
a = GUIUnstrip.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
a = GUILayout.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
// draw set value button
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (GUIUnstrip.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{
SetValueFromInput();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
}
}
@ -104,7 +106,7 @@ namespace Explorer
&& float.TryParse(b, out float fB)
&& float.TryParse(a, out float fA))
{
Value = new Color(fR, fB, fG, fA);
Value = new Color(fR, fG, fB, fA);
SetValue();
}
}

View File

@ -11,23 +11,30 @@ namespace Explorer
{
public class CacheEnum : CacheObjectBase
{
public Type EnumType;
// public Type EnumType;
public string[] EnumNames;
public override void Init()
{
try
if (ValueType == null && Value != null)
{
EnumType = Value.GetType();
}
catch
{
EnumType = (MemInfo as FieldInfo)?.FieldType ?? (MemInfo as PropertyInfo).PropertyType;
ValueType = Value.GetType();
}
if (EnumType != null)
if (ValueType != null)
{
EnumNames = Enum.GetNames(EnumType);
// using GetValues not GetNames, to catch instances of weird enums (eg CameraClearFlags)
var values = Enum.GetValues(ValueType);
var list = new List<string>();
foreach (var value in values)
{
var v = value.ToString();
if (list.Contains(v)) continue;
list.Add(v);
}
EnumNames = list.ToArray();
}
else
{
@ -39,30 +46,30 @@ namespace Explorer
{
if (CanWrite)
{
if (GUIUnstrip.Button("<", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) }))
{
SetEnum(ref Value, -1);
SetEnum(-1);
SetValue();
}
if (GUIUnstrip.Button(">", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) }))
{
SetEnum(ref Value, 1);
SetEnum(1);
SetValue();
}
}
GUIUnstrip.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>");
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", null);
}
public void SetEnum(ref object value, int change)
public void SetEnum(int change)
{
var names = EnumNames.ToList();
int newindex = names.IndexOf(value.ToString()) + change;
int newindex = names.IndexOf(Value.ToString()) + change;
if ((change < 0 && newindex >= 0) || (change > 0 && newindex < names.Count))
if (newindex >= 0 && newindex < names.Count)
{
value = Enum.Parse(EnumType, names[newindex]);
Value = Enum.Parse(ValueType, EnumNames[newindex]);
}
}
}

View File

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnityEngine;
namespace Explorer
{
public class CacheEnumFlags : CacheObjectBase, IExpandHeight
{
public string[] EnumNames = new string[0];
public bool[] m_enabledFlags = new bool[0];
public bool IsExpanded { get; set; }
public float WhiteSpace { get; set; } = 215f;
public override void Init()
{
base.Init();
if (ValueType == null && Value != null)
{
ValueType = Value.GetType();
}
if (ValueType != null)
{
EnumNames = Enum.GetNames(ValueType);
m_enabledFlags = new bool[EnumNames.Length];
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()
{
base.UpdateValue();
try
{
var enabledNames = Value.ToString().Split(',').Select(it => it.Trim());
for (int i = 0; i < EnumNames.Length; i++)
{
m_enabledFlags[i] = enabledNames.Contains(EnumNames[i]);
}
}
catch (Exception e)
{
MelonLogger.Log(e.ToString());
}
}
public override void DrawValue(Rect window, float width)
{
if (CanWrite)
{
if (!IsExpanded)
{
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
}
}
GUILayout.Label(Value.ToString() + "<color=#2df7b2><i> (" + ValueType + ")</i></color>", null);
if (IsExpanded)
{
GUILayout.EndHorizontal();
var whitespace = CalcWhitespace(window);
for (int i = 0; i < EnumNames.Length; i++)
{
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
m_enabledFlags[i] = GUILayout.Toggle(m_enabledFlags[i], EnumNames[i], null);
GUILayout.EndHorizontal();
}
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{
SetFlagsFromInput();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
}
}
}
}

View File

@ -1,7 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using MelonLoader;
using UnhollowerRuntimeLib;
using UnityEngine;
namespace Explorer
@ -16,6 +18,12 @@ namespace Explorer
public MethodInfo ParseMethod => m_parseMethod ?? (m_parseMethod = Value.GetType().GetMethod("Parse", new Type[] { typeof(string) }));
private MethodInfo m_parseMethod;
private bool m_canBitwiseOperate;
private bool m_inBitwiseMode;
private string m_bitwiseOperatorInput = "0";
private string m_bitwiseToString;
//private BitArray m_bitMask; // not needed I think
public override void Init()
{
if (ValueType == null)
@ -37,17 +45,31 @@ namespace Explorer
{
m_isBool = true;
}
m_canBitwiseOperate = typeof(int).IsAssignableFrom(ValueType);
}
public override void UpdateValue()
{
base.UpdateValue();
RefreshToString();
}
public void RefreshToString()
{
m_valueToString = Value?.ToString();
if (m_inBitwiseMode)
{
var _int = (int)Value;
m_bitwiseToString = Convert.ToString(_int, toBase: 2);
}
}
public override void DrawValue(Rect window, float width)
{
// bool uses Toggle
if (m_isBool)
{
var b = (bool)Value;
@ -55,7 +77,7 @@ namespace Explorer
if (CanWrite)
{
b = GUIUnstrip.Toggle(b, label);
b = GUILayout.Toggle(b, label, null);
if (b != (bool)Value)
{
SetValueFromInput(b.ToString());
@ -63,37 +85,129 @@ namespace Explorer
}
else
{
GUIUnstrip.Label(label);
GUILayout.Label(label, null);
}
return;
}
// all other non-bool values use TextField
GUILayout.BeginVertical(null);
GUILayout.BeginHorizontal(null);
// 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) });
int dynSize = 25 + (m_valueToString.Length * 15);
var maxwidth = window.width - 310f;
if (CanWrite) maxwidth -= 60;
if (dynSize > maxwidth)
{
m_valueToString = GUILayout.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(maxwidth) });
}
else
{
// using ValueType.Name instead of ValueTypeName, because we only want the short name.
GUIUnstrip.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
m_valueToString = GUILayout.TextField(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(dynSize) });
}
int dynSize = 25 + (m_valueToString.Length * 15);
var maxwidth = window.width - 310f;
if (CanWrite) maxwidth -= 60;
if (dynSize > maxwidth)
if (CanWrite)
{
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
{
m_valueToString = GUIUnstrip.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(maxwidth) });
}
else
{
m_valueToString = GUIUnstrip.TextField(m_valueToString, new GUILayoutOption[] { GUILayout.MaxWidth(dynSize) });
SetValueFromInput(m_valueToString);
RefreshToString();
}
}
if (m_canBitwiseOperate)
{
bool orig = m_inBitwiseMode;
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", null);
if (orig != m_inBitwiseMode)
{
RefreshToString();
}
}
GUIUnstrip.Space(10);
GUILayout.EndHorizontal();
if (m_inBitwiseMode)
{
if (CanWrite)
{
if (GUIUnstrip.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
GUILayout.BeginHorizontal(null);
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) }))
{
SetValueFromInput(m_valueToString);
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();
}
GUIUnstrip.Space(10);
GUILayout.BeginHorizontal(null);
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
GUILayout.TextField(m_bitwiseToString, null);
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
}
public void SetValueFromInput(string valueString)
@ -113,6 +227,16 @@ namespace Explorer
try
{
Value = ParseMethod.Invoke(null, new object[] { valueString });
//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)
{

View File

@ -20,6 +20,8 @@ namespace Explorer
{
base.UpdateValue();
if (Value == null) return;
var euler = ((Quaternion)Value).eulerAngles;
x = euler.x.ToString();
@ -33,57 +35,56 @@ namespace Explorer
{
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
}
}
string lbl = $"<color=#2df7b2>Quaternion</color>: {((Quaternion)Value).eulerAngles.ToString()}";
GUIUnstrip.Label(lbl);
GUILayout.Label($"<color=#2df7b2>Quaternion</color>: {((Quaternion)Value).eulerAngles.ToString()}", null);
if (CanWrite && IsExpanded)
{
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
// draw set value button
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (GUIUnstrip.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{
SetValueFromInput();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
}
}

View File

@ -21,6 +21,8 @@ namespace Explorer
{
base.UpdateValue();
if (Value == null) return;
var rect = (Rect)Value;
x = rect.x.ToString();
@ -35,62 +37,62 @@ namespace Explorer
{
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
}
}
GUIUnstrip.Label($"<color=#2df7b2>Rect</color>: {((Rect)Value).ToString()}");
GUILayout.Label($"<color=#2df7b2>Rect</color>: {((Rect)Value).ToString()}", null);
if (CanWrite && IsExpanded)
{
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
h = GUIUnstrip.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
h = GUILayout.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
// draw set value button
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (GUIUnstrip.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{
SetValueFromInput();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
}
}

View File

@ -24,20 +24,26 @@ namespace Explorer
public override void Init()
{
if (Value is Vector2)
if (ValueType == null && Value != null)
{
ValueType = Value.GetType();
}
if (ValueType == typeof(Vector2))
{
VectorSize = 2;
m_toStringMethod = typeof(Vector2).GetMethod("ToString", new Type[0]);
}
else if (Value is Vector3)
else if (ValueType == typeof(Vector3))
{
VectorSize = 3;
m_toStringMethod = typeof(Vector3).GetMethod("ToString", new Type[0]);
}
else
{
VectorSize = 4;
m_toStringMethod = typeof(Vector4).GetMethod("ToString", new Type[0]);
}
m_toStringMethod = Value.GetType().GetMethod("ToString", new Type[0]);
}
public override void UpdateValue()
@ -70,70 +76,70 @@ namespace Explorer
{
if (!IsExpanded)
{
if (GUIUnstrip.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
}
}
else
{
if (GUIUnstrip.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
}
}
GUIUnstrip.Label($"<color=#2df7b2>Vector{VectorSize}</color>: {(string)m_toStringMethod.Invoke(Value, new object[0])}");
GUILayout.Label($"<color=#2df7b2>Vector{VectorSize}</color>: {(string)m_toStringMethod.Invoke(Value, new object[0])}", null);
if (CanWrite && IsExpanded)
{
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
var whitespace = CalcWhitespace(window);
// always draw x and y
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUILayout.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUILayout.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
if (VectorSize > 2)
{
// draw z
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUILayout.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
}
if (VectorSize > 3)
{
// draw w
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
GUIUnstrip.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUIUnstrip.EndHorizontal();
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUILayout.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal();
}
// draw set value button
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Space(whitespace);
if (GUIUnstrip.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{
SetValueFromInput();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
}
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

View File

@ -1,11 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Harmony;
using MelonLoader;
using UnhollowerBaseLib;
using MelonLoader;
using UnityEngine;
namespace Explorer
@ -13,7 +6,7 @@ namespace Explorer
public class CppExplorer : MelonMod
{
public const string NAME = "CppExplorer";
public const string VERSION = "1.7.2";
public const string VERSION = "1.7.5";
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.cppexplorer";

View File

@ -83,6 +83,7 @@
<Compile Include="CachedObjects\Struct\CacheEnum.cs" />
<Compile Include="CachedObjects\Object\CacheGameObject.cs" />
<Compile Include="CachedObjects\Object\CacheList.cs" />
<Compile Include="CachedObjects\Struct\CacheEnumFlags.cs" />
<Compile Include="CachedObjects\Struct\CachePrimitive.cs" />
<Compile Include="CachedObjects\Other\CacheOther.cs" />
<Compile Include="CachedObjects\Other\CacheMethod.cs" />
@ -107,7 +108,7 @@
<Compile Include="CachedObjects\CacheObjectBase.cs" />
<Compile Include="UnstripFixes\SliderHandlerUnstrip.cs" />
<Compile Include="UnstripFixes\UnstripExtensions.cs" />
<Compile Include="Menu\Windows\ResizeDrag.cs" />
<Compile Include="Menu\ResizeDrag.cs" />
<Compile Include="Menu\Windows\TabViewWindow.cs" />
<Compile Include="Menu\Windows\UIWindow.cs" />
<Compile Include="Menu\MainMenu\Pages\ConsolePage.cs" />

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace Explorer

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnhollowerBaseLib;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -1,12 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using UnityEngine;
using MelonLoader;
using UnityEngine;
namespace Explorer
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{
@ -51,7 +46,7 @@ namespace Explorer
var orig = GUI.skin.label.alignment;
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Label($"Page {PageOffset + 1}/{MaxPageOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
GUILayout.Label($"Page {PageOffset + 1}/{MaxPageOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
GUI.skin.label.alignment = orig;
}
@ -97,9 +92,9 @@ namespace Explorer
public void DrawLimitInputArea()
{
GUIUnstrip.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
var limit = this.ItemsPerPage.ToString();
limit = GUIUnstrip.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
limit = GUILayout.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i))
{
ItemsPerPage = i;

View File

@ -1,9 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.IO;
using System.Reflection;
using MelonLoader;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
@ -23,23 +22,24 @@ namespace Explorer
public static ILType ComponentType => Il2CppType.Of<Component>();
public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
private static readonly MethodInfo m_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>();
public static object Il2CppCast(object obj, Type castTo)
{
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo)) return obj;
return m_tryCastMethodInfo
.MakeGenericMethod(castTo)
.Invoke(obj, null);
if (!cachedTryCastMethods.ContainsKey(castTo))
{
cachedTryCastMethods.Add(castTo, tryCastMethodInfo.MakeGenericMethod(castTo));
}
return cachedTryCastMethods[castTo].Invoke(obj, null);
}
public static bool IsEnumerable(Type t)
{
// Not needed for Il2Cpp at the moment. Don't want these to behave as Enumerables.
//if (typeof(Transform).IsAssignableFrom(t)) return false;
return typeof(IEnumerable).IsAssignableFrom(t);
return typeof(IEnumerable).IsAssignableFrom(t) || IsCppEnumerable(t);
}
// Checks for Il2Cpp List or HashSet.
@ -71,7 +71,8 @@ namespace Explorer
}
else
{
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t);
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
}
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -1,12 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Harmony;
using MelonLoader;
using System.Reflection;
using UnityEngine;
namespace Explorer
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -83,7 +83,7 @@ namespace Explorer
private void MainHeader()
{
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
for (int i = 0; i < Pages.Count; i++)
{
if (m_currentPage == i)
@ -91,23 +91,23 @@ namespace Explorer
else
GUI.color = Color.white;
if (GUIUnstrip.Button(Pages[i].Name))
if (GUILayout.Button(Pages[i].Name, null))
{
m_currentPage = i;
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUI.color = Color.white;
InspectUnderMouse.EnableInspect = GUIUnstrip.Toggle(InspectUnderMouse.EnableInspect, "Inspect Under Mouse (Shift + RMB)");
InspectUnderMouse.EnableInspect = GUILayout.Toggle(InspectUnderMouse.EnableInspect, "Inspect Under Mouse (Shift + RMB)", null);
bool mouseState = CursorControl.ForceUnlockMouse;
bool setMouse = GUIUnstrip.Toggle(mouseState, "Force Unlock Mouse (Left Alt)");
bool setMouse = GUILayout.Toggle(mouseState, "Force Unlock Mouse (Left Alt)", null);
if (setMouse != mouseState) CursorControl.ForceUnlockMouse = setMouse;
WindowManager.TabView = GUIUnstrip.Toggle(WindowManager.TabView, "Tab View");
GUIUnstrip.EndHorizontal();
WindowManager.TabView = GUILayout.Toggle(WindowManager.TabView, "Tab View", null);
GUILayout.EndHorizontal();
//GUIUnstrip.Space(10);
GUIUnstrip.Space(10);

View File

@ -1,9 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Mono.CSharp;
using UnityEngine;
using Attribute = System.Attribute;

View File

@ -1,8 +1,5 @@
using System.Collections;
//using Il2CppSystem;
using MelonLoader;
using System;
using UnityEngine;
using System;
using Object = UnityEngine.Object;
namespace Explorer

View File

@ -1,14 +1,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Reflection;
using Mono.CSharp;
using System.IO;
using System.Reflection;
using System.Text;
using MelonLoader;
using Mono.CSharp;
using UnityEngine;
namespace Explorer
{
@ -43,7 +40,7 @@ namespace Explorer
try
{
MethodInput = @"// This is a basic C# REPL console.
MethodInput = @"// This is a basic C# console.
// Some common using directives are added by default, you can add more below.
// If you want to return some output, MelonLogger.Log() it.
@ -123,19 +120,19 @@ MelonLogger.Log(""hello world"");";
public override void DrawWindow()
{
GUIUnstrip.Label("<b><size=15><color=cyan>C# REPL Console</color></size></b>");
GUILayout.Label("<b><size=15><color=cyan>C# Console</color></size></b>", null);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUIUnstrip.Label("Enter code here as though it is a method body:");
GUILayout.Label("Enter code here as though it is a method body:", null);
inputAreaScroll = GUIUnstrip.BeginScrollView(inputAreaScroll, new GUILayoutOption[] { GUILayout.Height(250) });
MethodInput = GUIUnstrip.TextArea(MethodInput, new GUILayoutOption[] { GUILayout.ExpandHeight(true) });
MethodInput = GUILayout.TextArea(MethodInput, new GUILayoutOption[] { GUILayout.ExpandHeight(true) });
GUIUnstrip.EndScrollView();
if (GUIUnstrip.Button("<color=cyan><b>Execute</b></color>"))
if (GUILayout.Button("<color=cyan><b>Execute</b></color>", null))
{
try
{
@ -157,24 +154,24 @@ MelonLogger.Log(""hello world"");";
}
}
GUIUnstrip.Label("<b>Using directives:</b>");
GUILayout.Label("<b>Using directives:</b>", null);
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) });
UsingInput = GUIUnstrip.TextField(UsingInput, new GUILayoutOption[] { GUILayout.Width(150) });
if (GUIUnstrip.Button("<b><color=lime>Add</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
GUILayout.BeginHorizontal(null);
GUILayout.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) });
UsingInput = GUILayout.TextField(UsingInput, new GUILayoutOption[] { GUILayout.Width(150) });
if (GUILayout.Button("<b><color=lime>Add</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
{
AddUsing(UsingInput);
}
if (GUIUnstrip.Button("<b><color=red>Clear All</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
if (GUILayout.Button("<b><color=red>Clear All</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
{
ResetConsole();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
foreach (var asm in UsingDirectives)
{
GUIUnstrip.Label(AsmToUsing(asm, true));
GUILayout.Label(AsmToUsing(asm, true), null);
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MelonLoader;
using UnityEngine;
using UnityEngine.SceneManagement;
@ -200,7 +199,7 @@ namespace Explorer
{
DrawHeaderArea();
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
DrawPageButtons();
@ -213,7 +212,7 @@ namespace Explorer
DrawSearchResultsList();
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
catch
{
@ -223,26 +222,26 @@ namespace Explorer
private void DrawHeaderArea()
{
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
// Current Scene label
GUIUnstrip.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) });
SceneChangeButtons();
GUIUnstrip.Label("<color=cyan>" + m_currentScene + "</color>");
GUILayout.Label("<color=cyan>" + m_currentScene + "</color>", null); //new GUILayoutOption[] { GUILayout.Width(250) });
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
// ----- GameObject Search -----
GUIUnstrip.BeginHorizontal(GUI.skin.box, null);
GUIUnstrip.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) });
GUILayout.BeginHorizontal(GUI.skin.box, null);
GUILayout.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIUnstrip.TextField(m_searchInput);
m_searchInput = GUILayout.TextField(m_searchInput, null);
if (GUIUnstrip.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Search();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.Space(5);
}
@ -255,11 +254,11 @@ namespace Explorer
if (scenes.Count > 1)
{
int changeWanted = 0;
if (GUIUnstrip.Button("<", new GUILayoutOption[] { GUILayout.Width(30) }))
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(30) }))
{
changeWanted = -1;
}
if (GUIUnstrip.Button(">", new GUILayoutOption[] { GUILayout.Width(30) }))
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(30) }))
{
changeWanted = 1;
}
@ -282,13 +281,13 @@ namespace Explorer
private void DrawPageButtons()
{
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
Pages.DrawLimitInputArea();
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.scroll);
@ -297,7 +296,7 @@ namespace Explorer
Pages.CurrentPageLabel();
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.scroll);
@ -305,7 +304,7 @@ namespace Explorer
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUI.skin.label.alignment = TextAnchor.UpperLeft;
}
@ -313,28 +312,28 @@ namespace Explorer
{
if (m_currentTransform != null)
{
GUIUnstrip.BeginHorizontal();
if (GUIUnstrip.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
GUILayout.BeginHorizontal(null);
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
{
TraverseUp();
}
else
{
GUIUnstrip.Label("<color=cyan>" + m_currentTransform.GetGameObjectPath() + "</color>",
GUILayout.Label("<color=cyan>" + m_currentTransform.GetGameObjectPath() + "</color>",
new GUILayoutOption[] { GUILayout.Width(MainMenu.MainRect.width - 187f) });
}
UIHelpers.SmallInspectButton(m_currentTransform);
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
else
{
GUIUnstrip.Label("Scene Root GameObjects:");
GUILayout.Label("Scene Root GameObjects:", null);
if (m_getRootObjectsFailed)
{
if (GUIUnstrip.Button("Update Root Object List (auto-update failed!)"))
if (GUILayout.Button("Update Root Object List (auto-update failed!)", null))
{
Update_Impl(true);
}
@ -359,7 +358,7 @@ namespace Explorer
}
label += "</i></color>";
GUIUnstrip.Label(label);
GUILayout.Label(label, null);
}
else
{
@ -377,12 +376,12 @@ namespace Explorer
private void DrawSearchResultsList()
{
if (GUIUnstrip.Button("<- Cancel Search", new GUILayoutOption[] { GUILayout.Width(150) }))
if (GUILayout.Button("<- Cancel Search", new GUILayoutOption[] { GUILayout.Width(150) }))
{
CancelSearch();
}
GUIUnstrip.Label("Search Results:");
GUILayout.Label("Search Results:", null);
if (m_searchResults.Count > 0)
{
@ -404,13 +403,13 @@ namespace Explorer
}
else
{
GUIUnstrip.Label("<i><color=red>Null or destroyed!</color></i>");
GUILayout.Label("<i><color=red>Null or destroyed!</color></i>", null);
}
}
}
else
{
GUIUnstrip.Label("<color=red><i>No results found!</i></color>");
GUILayout.Label("<color=red><i>No results found!</i></color>", null);
}
}

View File

@ -2,10 +2,9 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.Reflection;
using MelonLoader;
using UnityEngine;
namespace Explorer
{
@ -84,28 +83,28 @@ namespace Explorer
try
{
// helpers
GUIUnstrip.BeginHorizontal(GUI.skin.box, null);
GUIUnstrip.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
if (GUIUnstrip.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
GUILayout.BeginHorizontal(GUI.skin.box, null);
GUILayout.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
if (GUILayout.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
{
//m_searchResults = GetInstanceClassScanner().ToList();
CacheResults(GetInstanceClassScanner());
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
// search box
SearchBox();
// results
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")");
GUILayout.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")", null);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
int count = m_searchResults.Count;
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
Pages.DrawLimitInputArea();
@ -115,21 +114,21 @@ namespace Explorer
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.resultsScroll);
}
Pages.CurrentPageLabel();
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.resultsScroll);
}
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
resultsScroll = GUIUnstrip.BeginScrollView(resultsScroll);
@ -146,11 +145,11 @@ namespace Explorer
}
else
{
GUIUnstrip.Label("<color=red><i>No results found!</i></color>");
GUILayout.Label("<color=red><i>No results found!</i></color>", null);
}
GUIUnstrip.EndScrollView();
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
catch
{
@ -160,52 +159,52 @@ namespace Explorer
private void SearchBox()
{
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
// ----- GameObject Search -----
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Label("<b><color=orange>Search</color></b>");
GUILayout.Label("<b><color=orange>Search</color></b>", null);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUILayout.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
GUILayout.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
ClassFilterToggle(TypeFilter.Object, "Object");
ClassFilterToggle(TypeFilter.GameObject, "GameObject");
ClassFilterToggle(TypeFilter.Component, "Component");
ClassFilterToggle(TypeFilter.Custom, "Custom");
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
if (TypeMode == TypeFilter.Custom)
{
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUIUnstrip.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
GUI.skin.label.alignment = TextAnchor.UpperLeft;
m_typeInput = GUIUnstrip.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
GUIUnstrip.EndHorizontal();
m_typeInput = GUILayout.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.EndHorizontal();
}
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
GUILayout.BeginHorizontal(null);
GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
SceneFilterToggle(SceneFilter.Any, "Any", 60);
SceneFilterToggle(SceneFilter.This, "This Scene", 100);
SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140);
SceneFilterToggle(SceneFilter.None, "No Scene", 80);
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
if (GUIUnstrip.Button("<b><color=cyan>Search</color></b>"))
if (GUILayout.Button("<b><color=cyan>Search</color></b>", null))
{
Search();
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
private void ClassFilterToggle(TypeFilter mode, string label)
@ -218,7 +217,7 @@ namespace Explorer
{
GUI.color = Color.white;
}
if (GUIUnstrip.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
{
TypeMode = mode;
}
@ -235,7 +234,7 @@ namespace Explorer
{
GUI.color = Color.white;
}
if (GUIUnstrip.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
{
SceneMode = mode;
}
@ -428,7 +427,7 @@ namespace Explorer
{
var t = ReflectionHelpers.GetActualType(obj);
if (!FilterName(t.FullName) || ReflectionHelpers.IsEnumerable(t) || ReflectionHelpers.IsCppEnumerable(t))
if (!FilterName(t.FullName) || ReflectionHelpers.IsEnumerable(t))
{
continue;
}

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using MelonLoader;
using UnhollowerBaseLib;
using UnityEngine;
namespace Explorer
{
@ -26,38 +22,45 @@ namespace Explorer
try
{
GUIUnstrip.BeginHorizontal(GUI.skin.box, null);
GUILayout.BeginHorizontal(GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
//var r = GUILayoutUtility.GetLastRect();
var r = LayoutUtilityUnstrip.GetLastRect();
var mousePos = InputHelper.mousePosition;
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
try
{
var mouse = GUIUtility.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
if (r.Contains(mouse) && InputHelper.GetMouseButtonDown(0))
{
isResizing = true;
m_currentWindow = ID;
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
}
else if (!InputHelper.GetMouseButton(0))
{
isResizing = false;
}
if (r.Contains(mouse) && InputHelper.GetMouseButtonDown(0))
{
isResizing = true;
m_currentWindow = ID;
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
if (isResizing && ID == m_currentWindow)
{
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x));
_rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
_rect.xMax = Mathf.Min(Screen.width, _rect.xMax); // modifying xMax affects width, not x
_rect.yMax = Mathf.Min(Screen.height, _rect.yMax); // modifying yMax affects height, not y
}
}
else if (!InputHelper.GetMouseButton(0))
catch
{
isResizing = false;
// throw safe Managed exception
throw new Exception("");
}
if (isResizing && ID == m_currentWindow)
{
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x));
_rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
_rect.xMax = Mathf.Min(Screen.width, _rect.xMax); // modifying xMax affects width, not x
_rect.yMax = Mathf.Min(Screen.height, _rect.yMax); // modifying yMax affects height, not y
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
catch (Il2CppException e) when (e.Message.StartsWith("System.ArgumentException"))
{
@ -68,7 +71,7 @@ namespace Explorer
{
RESIZE_FAILED = true;
MelonLogger.Log("Exception on GuiResize: " + e.GetType() + ", " + e.Message);
MelonLogger.Log(e.StackTrace);
//MelonLogger.Log(e.StackTrace);
return origRect;
}
@ -76,12 +79,12 @@ namespace Explorer
}
else
{
GUIUnstrip.BeginHorizontal(GUI.skin.box, null);
GUILayout.BeginHorizontal(GUI.skin.box, null);
GUIUnstrip.Label("Resize window:", new GUILayoutOption[] { GUILayout.Width(100) });
GUILayout.Label("Resize window:", new GUILayoutOption[] { GUILayout.Width(100) });
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUIUnstrip.Label("<color=cyan>Width:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
GUILayout.Label("<color=cyan>Width:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
{
_rect.width -= 5f;
@ -90,7 +93,7 @@ namespace Explorer
{
_rect.width += 5f;
}
GUIUnstrip.Label("<color=cyan>Height:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
GUILayout.Label("<color=cyan>Height:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
{
_rect.height -= 5f;
@ -100,7 +103,7 @@ namespace Explorer
_rect.height += 5f;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUI.skin.label.alignment = TextAnchor.UpperLeft;
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using UnhollowerRuntimeLib;
using UnityEngine;
using Object = UnityEngine.Object;
@ -15,7 +9,7 @@ namespace Explorer
// helper for "Instantiate" button on UnityEngine.Objects
public static void InstantiateButton(Object obj, float width = 100)
{
if (GUIUnstrip.Button("Instantiate", new GUILayoutOption[] { GUILayout.Width(width) }))
if (GUILayout.Button("Instantiate", new GUILayoutOption[] { GUILayout.Width(width) }))
{
var newobj = Object.Instantiate(obj);
@ -62,18 +56,18 @@ namespace Explorer
if (!obj)
{
GUIUnstrip.Label("<i><color=red>null</color></i>");
GUILayout.Label("<i><color=red>null</color></i>", null);
return;
}
// ------ toggle active button ------
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUI.skin.button.alignment = TextAnchor.UpperLeft;
GUI.color = activeColor;
enabled = GUIUnstrip.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
enabled = GUILayout.Toggle(enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
if (obj.activeSelf != enabled)
{
obj.SetActive(enabled);
@ -81,7 +75,7 @@ namespace Explorer
// ------- actual button ---------
if (GUIUnstrip.Button(label, new GUILayoutOption[] { GUILayout.Height(22), GUILayout.Width(width) }))
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Height(22), GUILayout.Width(width) }))
{
if (specialInspectMethod != null)
{
@ -103,12 +97,12 @@ namespace Explorer
SmallInspectButton(_obj);
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
public static void SmallInspectButton(object obj)
{
if (GUIUnstrip.Button("Inspect"))
if (GUILayout.Button("Inspect", null))
{
WindowManager.InspectObject(obj, out bool _);
}

View File

@ -1,16 +1,29 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Explorer
{
public class UIStyles
{
public class Syntax
{
public const string Field_Static = "#8d8dc6";
public const string Field_Instance = "#c266ff";
public const string Method_Static = "#b55b02";
public const string Method_Instance = "#ff8000";
public const string Prop_Static = "#588075";
public const string Prop_Instance = "#55a38e";
public const string Class_Static = "#3a8d71";
public const string Class_Instance = "#2df7b2";
public const string Local = "#a6e9e9";
public const string StructGreen = "#b8d7a3";
}
public static Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
public static GUISkin WindowSkin
@ -38,7 +51,7 @@ namespace Explorer
var orig = GUI.color;
GUI.color = _color;
GUIUnstrip.Box(GUIContent.none, !small ? HorizontalBar : HorizontalBarSmall, null);
GUILayout.Box(GUIContent.none, !small ? HorizontalBar : HorizontalBarSmall, null);
GUI.color = orig;
}

View File

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MelonLoader;
using UnhollowerRuntimeLib;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Explorer
{
@ -217,52 +214,52 @@ namespace Explorer
scroll = GUIUnstrip.BeginScrollView(scroll);
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>");
GUILayout.BeginHorizontal(null);
GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", null);
if (m_scene == UnityHelpers.ActiveSceneName)
{
if (GUIUnstrip.Button("<color=#00FF00>Send to Scene View</color>", new GUILayoutOption[] { GUILayout.Width(150) }))
if (GUILayout.Button("<color=#00FF00>Send to Scene View</color>", new GUILayoutOption[] { GUILayout.Width(150) }))
{
ScenePage.Instance.SetTransformTarget(TargetGO.transform);
MainMenu.SetCurrentPage(0);
}
}
if (GUIUnstrip.Button("Reflection Inspect", new GUILayoutOption[] { GUILayout.Width(150) }))
if (GUILayout.Button("Reflection Inspect", new GUILayoutOption[] { GUILayout.Width(150) }))
{
WindowManager.InspectObject(Target, out _, true);
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
GUILayout.BeginHorizontal(null);
GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
string pathlabel = TargetGO.transform.GetGameObjectPath();
if (TargetGO.transform.parent != null)
{
if (GUIUnstrip.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
{
InspectGameObject(TargetGO.transform.parent);
}
}
GUIUnstrip.TextArea(pathlabel);
GUIUnstrip.EndHorizontal();
GUILayout.TextArea(pathlabel, null);
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("Name:", new GUILayoutOption[] { GUILayout.Width(50) });
GUIUnstrip.TextArea(m_name);
GUIUnstrip.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUILayout.Label("Name:", new GUILayoutOption[] { GUILayout.Width(50) });
GUILayout.TextArea(m_name, null);
GUILayout.EndHorizontal();
// --- Horizontal Columns section ---
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
TransformList(rect);
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
GUILayout.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
ComponentList(rect);
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
GUIUnstrip.EndHorizontal(); // end horiz columns
GUILayout.EndHorizontal(); // end horiz columns
GameObjectControls();
@ -283,31 +280,31 @@ namespace Explorer
private void TransformList(Rect m_rect)
{
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
m_transformScroll = GUIUnstrip.BeginScrollView(m_transformScroll);
GUIUnstrip.Label("<b><size=15>Children</size></b>");
GUILayout.Label("<b><size=15>Children</size></b>", null);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
ChildPages.DrawLimitInputArea();
if (ChildPages.ItemCount > ChildPages.ItemsPerPage)
{
ChildPages.CurrentPageLabel();
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
ChildPages.TurnPage(Turn.Left, ref this.m_transformScroll);
}
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
ChildPages.TurnPage(Turn.Right, ref this.m_transformScroll);
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
if (m_children != null && m_children.Length > 0)
{
@ -319,7 +316,7 @@ namespace Explorer
if (!obj)
{
GUIUnstrip.Label("null");
GUILayout.Label("null", null);
continue;
}
@ -328,44 +325,44 @@ namespace Explorer
}
else
{
GUIUnstrip.Label("<i>None</i>");
GUILayout.Label("<i>None</i>", null);
}
GUIUnstrip.EndScrollView();
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
private void ComponentList(Rect m_rect)
{
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
m_compScroll = GUIUnstrip.BeginScrollView(m_compScroll);
GUIUnstrip.Label("<b><size=15>Components</size></b>");
GUILayout.Label("<b><size=15>Components</size></b>", null);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
CompPages.DrawLimitInputArea();
if (CompPages.ItemCount > CompPages.ItemsPerPage)
{
CompPages.CurrentPageLabel();
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
CompPages.TurnPage(Turn.Left, ref this.m_compScroll);
}
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
CompPages.TurnPage(Turn.Right, ref this.m_compScroll);
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
var width = m_rect.width / 2 - 115f;
m_addComponentInput = GUIUnstrip.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
if (GUIUnstrip.Button("Add Comp"))
m_addComponentInput = GUILayout.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
if (GUILayout.Button("Add Comp", null))
{
if (ReflectionHelpers.GetTypeByName(m_addComponentInput) is Type compType)
{
@ -383,7 +380,7 @@ namespace Explorer
MelonLogger.LogWarning($"Could not find a type by the name of '{m_addComponentInput}'!");
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
if (m_cachedDestroyList.Count > 0)
@ -403,7 +400,7 @@ namespace Explorer
var ilType = component.GetIl2CppType();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
if (ReflectionHelpers.BehaviourType.IsAssignableFrom(ilType))
{
BehaviourEnabledBtn(component.TryCast<Behaviour>());
@ -412,15 +409,15 @@ namespace Explorer
{
GUIUnstrip.Space(26);
}
if (GUIUnstrip.Button("<color=cyan>" + ilType.Name + "</color>", new GUILayoutOption[] { GUILayout.Width(m_rect.width / 2 - 100) }))
if (GUILayout.Button("<color=cyan>" + ilType.Name + "</color>", new GUILayoutOption[] { GUILayout.Width(m_rect.width / 2 - 100) }))
{
ReflectObject(component);
}
if (GUIUnstrip.Button("<color=red>-</color>", new GUILayoutOption[] { GUILayout.Width(20) }))
if (GUILayout.Button("<color=red>-</color>", new GUILayoutOption[] { GUILayout.Width(20) }))
{
m_cachedDestroyList.Add(component);
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
}
@ -436,7 +433,7 @@ namespace Explorer
GUIUnstrip.EndScrollView();
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
private void BehaviourEnabledBtn(Behaviour obj)
@ -454,7 +451,7 @@ namespace Explorer
// ------ toggle active button ------
_enabled = GUIUnstrip.Toggle(_enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
_enabled = GUILayout.Toggle(_enabled, "", new GUILayoutOption[] { GUILayout.Width(18) });
if (obj.enabled != _enabled)
{
obj.enabled = _enabled;
@ -466,43 +463,43 @@ namespace Explorer
{
if (m_hideControls)
{
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
if (GUIUnstrip.Button("^ Show ^", new GUILayoutOption[] { GUILayout.Width(75) }))
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
if (GUILayout.Button("^ Show ^", new GUILayoutOption[] { GUILayout.Width(75) }))
{
m_hideControls = false;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
return;
}
GUIUnstrip.BeginVertical(GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
GUILayout.BeginVertical(GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
if (GUIUnstrip.Button("v Hide v", new GUILayoutOption[] { GUILayout.Width(75) }))
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
if (GUILayout.Button("v Hide v", new GUILayoutOption[] { GUILayout.Width(75) }))
{
m_hideControls = true;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
bool m_active = TargetGO.activeSelf;
m_active = GUIUnstrip.Toggle(m_active, (m_active ? "<color=lime>Enabled " : "<color=red>Disabled") + "</color>",
m_active = GUILayout.Toggle(m_active, (m_active ? "<color=lime>Enabled " : "<color=red>Disabled") + "</color>",
new GUILayoutOption[] { GUILayout.Width(80) });
if (TargetGO.activeSelf != m_active) { TargetGO.SetActive(m_active); }
UIHelpers.InstantiateButton(TargetGO, 100);
if (GUIUnstrip.Button("Set DontDestroyOnLoad", new GUILayoutOption[] { GUILayout.Width(170) }))
if (GUILayout.Button("Set DontDestroyOnLoad", new GUILayoutOption[] { GUILayout.Width(170) }))
{
GameObject.DontDestroyOnLoad(TargetGO);
TargetGO.hideFlags |= HideFlags.DontUnloadUnusedAsset;
}
var lbl = m_freeze ? "<color=lime>Unfreeze</color>" : "<color=orange>Freeze Pos/Rot</color>";
if (GUIUnstrip.Button(lbl, new GUILayoutOption[] { GUILayout.Width(110) }))
if (GUILayout.Button(lbl, new GUILayoutOption[] { GUILayout.Width(110) }))
{
m_freeze = !m_freeze;
if (m_freeze)
@ -511,11 +508,11 @@ namespace Explorer
}
}
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
m_setParentInput = GUIUnstrip.TextField(m_setParentInput);
if (GUIUnstrip.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) }))
m_setParentInput = GUILayout.TextField(m_setParentInput, null);
if (GUILayout.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) }))
{
if (GameObject.Find(m_setParentInput) is GameObject newparent)
{
@ -527,20 +524,20 @@ namespace Explorer
}
}
if (GUIUnstrip.Button("Detach from parent", new GUILayoutOption[] { GUILayout.Width(160) }))
if (GUILayout.Button("Detach from parent", new GUILayoutOption[] { GUILayout.Width(160) }))
{
TargetGO.transform.parent = null;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false);
m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true);
m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false);
GUIUnstrip.BeginHorizontal();
if (GUIUnstrip.Button("<color=lime>Apply to Transform</color>") || m_autoApplyTransform)
GUILayout.BeginHorizontal(null);
if (GUILayout.Button("<color=lime>Apply to Transform</color>", null) || m_autoApplyTransform)
{
if (m_localContext)
{
@ -559,19 +556,19 @@ namespace Explorer
UpdateFreeze();
}
}
if (GUIUnstrip.Button("<color=lime>Update from Transform</color>") || m_autoUpdateTransform)
if (GUILayout.Button("<color=lime>Update from Transform</color>", null) || m_autoUpdateTransform)
{
CacheTransformValues();
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
BoolToggle(ref m_autoApplyTransform, "Auto-apply to Transform?");
BoolToggle(ref m_autoUpdateTransform, "Auto-update from transform?");
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
bool b = m_localContext;
b = GUIUnstrip.Toggle(b, "<color=" + (b ? "lime" : "red") + ">Use local transform values?</color>");
b = GUILayout.Toggle(b, "<color=" + (b ? "lime" : "orange") + ">Use local transform values?</color>", null);
if (b != m_localContext)
{
m_localContext = b;
@ -582,16 +579,16 @@ namespace Explorer
}
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
if (GUIUnstrip.Button("<color=red><b>Destroy</b></color>", new GUILayoutOption[] { GUILayout.Width(120) }))
if (GUILayout.Button("<color=red><b>Destroy</b></color>", new GUILayoutOption[] { GUILayout.Width(120) }))
{
GameObject.Destroy(TargetGO);
DestroyWindow();
return;
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
}
private void UpdateFreeze()
@ -612,10 +609,10 @@ namespace Explorer
private void BoolToggle(ref bool value, string message)
{
string lbl = "<color=";
lbl += value ? "lime" : "red";
lbl += value ? "lime" : "orange";
lbl += $">{message}</color>";
value = GUIUnstrip.Toggle(value, lbl);
value = GUILayout.Toggle(value, lbl, null);
}
public enum TranslateType
@ -627,8 +624,8 @@ namespace Explorer
private Vector3 TranslateControl(TranslateType mode, ref float amount, bool multByTime)
{
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
GUILayout.BeginHorizontal(null);
GUILayout.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
var transform = TargetGO.transform;
@ -636,42 +633,42 @@ namespace Explorer
{
case TranslateType.Position:
var pos = m_localContext ? transform.localPosition : transform.position;
GUIUnstrip.Label(pos.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.Label(pos.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
break;
case TranslateType.Rotation:
var rot = m_localContext ? transform.localEulerAngles : transform.eulerAngles;
GUIUnstrip.Label(rot.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.Label(rot.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
break;
case TranslateType.Scale:
GUIUnstrip.Label(transform.localScale.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.Label(transform.localScale.ToString(), new GUILayoutOption[] { GUILayout.Width(250) });
break;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
Vector3 input = m_cachedInput[(int)mode];
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUIUnstrip.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
PlusMinusFloat(ref input.x, amount, multByTime);
GUIUnstrip.Label("<color=cyan>Y:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
GUILayout.Label("<color=cyan>Y:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
PlusMinusFloat(ref input.y, amount, multByTime);
GUIUnstrip.Label("<color=cyan>Z:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
GUILayout.Label("<color=cyan>Z:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
PlusMinusFloat(ref input.z, amount, multByTime);
GUIUnstrip.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
var amountInput = amount.ToString("F3");
amountInput = GUIUnstrip.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
amountInput = GUILayout.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
if (float.TryParse(amountInput, out float f))
{
amount = f;
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
return input;
}
@ -679,7 +676,7 @@ namespace Explorer
private void PlusMinusFloat(ref float f, float amount, bool multByTime)
{
string s = f.ToString("F3");
s = GUIUnstrip.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) });
s = GUILayout.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) });
if (float.TryParse(s, out float f2))
{
f = f2;

View File

@ -1,6 +1,4 @@
using System;
using System.CodeDom;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -163,15 +161,13 @@ namespace Explorer
continue;
// check blacklisted members
var name = member.DeclaringType.Name + "." + member.Name;
if (_typeAndMemberBlacklist.Any(it => it == name))
var sig = $"{member.DeclaringType.Name}.{member.Name}";
if (_typeAndMemberBlacklist.Any(it => it == sig))
continue;
if (_methodStartsWithBlacklist.Any(it => member.Name.StartsWith(it)))
continue;
// compare signature to already cached members
var signature = $"{member.DeclaringType.Name}.{member.Name}";
if (member is MethodInfo mi)
{
AppendParams(mi.GetParameters());
@ -183,15 +179,15 @@ namespace Explorer
void AppendParams(ParameterInfo[] _args)
{
signature += " (";
sig += " (";
foreach (var param in _args)
{
signature += $"{param.ParameterType.Name} {param.Name}, ";
sig += $"{param.ParameterType.Name} {param.Name}, ";
}
signature += ")";
sig += ")";
}
if (cachedSigs.Contains(signature))
if (cachedSigs.Contains(sig))
{
continue;
}
@ -203,14 +199,14 @@ namespace Explorer
var cached = CacheObjectBase.GetCacheObject(member, target);
if (cached != null)
{
cachedSigs.Add(signature);
cachedSigs.Add(sig);
list.Add(cached);
cached.ReflectionException = exception;
}
}
catch (Exception e)
{
MelonLogger.LogWarning($"Exception caching member {signature}!");
MelonLogger.LogWarning($"Exception caching member {sig}!");
MelonLogger.Log(e.ToString());
}
}
@ -235,87 +231,87 @@ namespace Explorer
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
}
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", new GUILayoutOption[] { GUILayout.Width(245f) });
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", new GUILayoutOption[] { GUILayout.Width(245f) });
if (m_uObj)
{
GUIUnstrip.Label("Name: " + m_uObj.name);
GUILayout.Label("Name: " + m_uObj.name, null);
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
if (m_uObj)
{
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b>Tools:</b>", new GUILayoutOption[] { GUILayout.Width(80) });
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b>Tools:</b>", new GUILayoutOption[] { GUILayout.Width(80) });
UIHelpers.InstantiateButton(m_uObj);
if (m_component && m_component.gameObject is GameObject obj)
{
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUIUnstrip.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) });
GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) });
var charWidth = obj.name.Length * 15;
var maxWidth = rect.width - 350;
var labelWidth = charWidth < maxWidth ? charWidth : maxWidth;
if (GUIUnstrip.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) }))
if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) }))
{
WindowManager.InspectObject(obj, out bool _);
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
}
UIStyles.HorizontalLine(Color.grey);
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b>Search:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
m_search = GUIUnstrip.TextField(m_search);
GUIUnstrip.EndHorizontal();
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b>Search:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
m_search = GUILayout.TextField(m_search, null);
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b>Filter:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b>Filter:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
FilterToggle(MemberTypes.All, "All");
FilterToggle(MemberTypes.Property, "Properties");
FilterToggle(MemberTypes.Field, "Fields");
FilterToggle(MemberTypes.Method, "Methods");
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUIUnstrip.Label("<b>Values:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
if (GUIUnstrip.Button("Update", new GUILayoutOption[] { GUILayout.Width(100) }))
GUILayout.BeginHorizontal(null);
GUILayout.Label("<b>Values:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
if (GUILayout.Button("Update", new GUILayoutOption[] { GUILayout.Width(100) }))
{
UpdateValues();
}
GUI.color = m_autoUpdate ? Color.green : Color.red;
m_autoUpdate = GUIUnstrip.Toggle(m_autoUpdate, "Auto-update?", new GUILayoutOption[] { GUILayout.Width(100) });
m_autoUpdate = GUILayout.Toggle(m_autoUpdate, "Auto-update?", new GUILayoutOption[] { GUILayout.Width(100) });
GUI.color = m_hideFailedReflection ? Color.green : Color.red;
m_hideFailedReflection = GUIUnstrip.Toggle(m_hideFailedReflection, "Hide failed Reflection?", new GUILayoutOption[] { GUILayout.Width(150) });
m_hideFailedReflection = GUILayout.Toggle(m_hideFailedReflection, "Hide failed Reflection?", new GUILayoutOption[] { GUILayout.Width(150) });
GUI.color = Color.white;
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
GUIUnstrip.Space(10);
Pages.ItemCount = m_cachedMembersFiltered.Length;
// prev/next page buttons
GUIUnstrip.BeginHorizontal();
GUILayout.BeginHorizontal(null);
Pages.DrawLimitInputArea();
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUIUnstrip.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.scroll);
}
Pages.CurrentPageLabel();
if (GUIUnstrip.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.scroll);
}
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
// ====== BODY ======
@ -325,7 +321,7 @@ namespace Explorer
UIStyles.HorizontalLine(Color.grey);
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUILayout.BeginVertical(GUI.skin.box, null);
var members = this.m_cachedMembersFiltered;
int start = Pages.CalculateOffsetIndex();
@ -334,24 +330,24 @@ namespace Explorer
{
var holder = members[j];
GUIUnstrip.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
GUILayout.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
try
{
holder.Draw(rect, 180f);
}
catch
{
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
continue;
}
GUIUnstrip.EndHorizontal();
GUILayout.EndHorizontal();
// if not last element
if (!(j == (start + Pages.ItemsPerPage - 1) || j == (members.Length - 1)))
UIStyles.HorizontalLine(new Color(0.07f, 0.07f, 0.07f), true);
}
GUIUnstrip.EndVertical();
GUILayout.EndVertical();
GUIUnstrip.EndScrollView();
if (!WindowManager.TabView)
@ -386,7 +382,7 @@ namespace Explorer
{
GUI.color = Color.white;
}
if (GUIUnstrip.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
{
m_filter = mode;
Pages.PageOffset = 0;

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using UnityEngine;
using UnityEngine;
namespace Explorer
{
@ -67,8 +61,8 @@ namespace Explorer
GUIUnstrip.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
GUIUnstrip.BeginVertical(GUI.skin.box, null);
GUIUnstrip.BeginHorizontal();
GUILayout.BeginVertical(GUI.skin.box, null);
GUILayout.BeginHorizontal(null);
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
int tabPerRow = Mathf.FloorToInt((float)((decimal)m_rect.width / 238));
int rowCount = 0;
@ -77,8 +71,8 @@ namespace Explorer
if (rowCount >= tabPerRow)
{
rowCount = 0;
GUIUnstrip.EndHorizontal();
GUIUnstrip.BeginHorizontal();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
}
rowCount++;
@ -87,18 +81,18 @@ namespace Explorer
GUI.color = focused ? Color.green : Color.white;
var window = WindowManager.Windows[i];
if (GUIUnstrip.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) }))
if (GUILayout.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) }))
{
TargetTabID = i;
}
if (GUIUnstrip.Button("<color=red><b>X</b></color>", new GUILayoutOption[] { GUILayout.Width(22) }))
if (GUILayout.Button("<color=red><b>X</b></color>", new GUILayoutOption[] { GUILayout.Width(22) }))
{
window.DestroyWindow();
}
}
GUI.color = Color.white;
GUIUnstrip.EndHorizontal();
GUIUnstrip.EndVertical();
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
m_targetWindow.WindowFunction(m_targetWindow.windowID);

View File

@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Harmony;
using MelonLoader;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using UnityEngine;
namespace Explorer

View File

@ -1,13 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Harmony;
using MelonLoader;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Explorer
{

View File

@ -1,16 +1,46 @@
using System;
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MelonLoader;
using System;
using UnityEngine;
using System.Reflection;
using System.Collections.Specialized;
using MelonLoader;
// used to test multiple generic constraints
public class TestGeneric : IComparable<string>
{
public TestGeneric() { }
public int CompareTo(string other) => throw new NotImplementedException();
}
[Flags]
public enum TestFlags
{
Red,
Green,
Blue
}
// test non-flags weird enum
public enum WeirdEnum
{
First = 1,
Second,
Third = 2,
Fourth,
Fifth
}
namespace Explorer.Tests
{
public class TestClass
{
public static TestFlags testFlags = TestFlags.Blue | TestFlags.Green;
public static WeirdEnum testWeird = WeirdEnum.First;
public static int testBitmask;
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
private static TestClass m_instance;
@ -20,8 +50,56 @@ namespace Explorer.Tests
ILHashSetTest.Add("1");
ILHashSetTest.Add("2");
ILHashSetTest.Add("3");
testBitmask = 1 | 2;
}
public static int StaticProperty => 5;
public static int StaticField = 5;
public int NonStaticField;
public static string TestGeneric<C, T>(string arg0) where C : Component where T : TestGeneric, IComparable<string>
{
return $"C: '{typeof(C).FullName}', T: '{typeof(T).FullName}', arg0: '{arg0}'";
}
public static string TestRefInOutGeneric<T>(ref string arg0, in int arg1, out string arg2)
{
arg2 = "this is arg2";
return $"T: '{typeof(T).FullName}', ref arg0: '{arg0}', in arg1: '{arg1}', out arg2: '{arg2}'";
}
//// this type of generic is not supported, due to requiring a non-primitive argument.
//public static T TestDifferentGeneric<T>(T obj) where T : Component
//{
// return obj;
//}
// test a non-generic dictionary
public Hashtable TestNonGenericDict()
{
return new Hashtable
{
{ "One", 1 },
{ "Two", 2 },
{ "Three", 3 },
};
}
// IL2CPP HASHTABLE NOT SUPPORTED! Cannot assign Il2CppSystem.Object from primitive struct / string.
// Technically they are "supported" but if they contain System types they will not work.
//public Il2CppSystem.Collections.Hashtable TestIl2CppNonGenericDict()
//{
// var table = new Il2CppSystem.Collections.Hashtable();
// table.Add("One", 1);
// table.Add("One", 2);
// table.Add("One", 3);
// return table;
//}
// test HashSets
public static HashSet<string> HashSetTest = new HashSet<string>

View File

@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using MelonLoader;
using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
using System.Reflection;
using MelonLoader;
using UnhollowerRuntimeLib;
using UnityEngine;
using UnityEngineInternal;
using Harmony;
namespace Explorer
{
@ -52,21 +46,6 @@ namespace Explorer
return m_scrollStack;
}
// ======== Fix for GUIUtility.ScreenToGuiPoint ========
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
{
return GUIClip.ClipToWindow(InternalScreenToWindowPoint(screenPoint));
}
private static Vector2 InternalScreenToWindowPoint(Vector2 screenPoint)
{
GUIUtility.InternalScreenToWindowPoint_Injected(ref screenPoint, out Vector2 result);
return result;
}
// ================= Fix for Space =================
public static void Space(float pixels)
{
GUIUtility.CheckOnGUI();
@ -82,7 +61,19 @@ namespace Explorer
}
}
// ================= Fix for BeginArea =================
// fix for repeatbutton
static public bool RepeatButton(Texture image, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), GUI.skin.button, options); }
static public bool RepeatButton(string text, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); }
static public bool RepeatButton(GUIContent content, params GUILayoutOption[] options) { return DoRepeatButton(content, GUI.skin.button, options); }
static public bool RepeatButton(Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), style, options); }
static public bool RepeatButton(string text, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(text), style, options); }
// Make a repeating button. The button returns true as long as the user holds down the mouse
static public bool RepeatButton(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(content, style, options); }
static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ return GUI.RepeatButton(LayoutUtilityUnstrip.GetRect(content, style, options), content, style); }
// Fix for BeginArea
static public void BeginArea(Rect screenRect) { BeginArea(screenRect, GUIContent.none, GUIStyle.none); }
static public void BeginArea(Rect screenRect, string text) { BeginArea(screenRect, GUIContent.Temp(text), GUIStyle.none); }
@ -92,6 +83,7 @@ namespace Explorer
static public void BeginArea(Rect screenRect, string text, GUIStyle style) { BeginArea(screenRect, GUIContent.Temp(text), style); }
static public void BeginArea(Rect screenRect, Texture image, GUIStyle style) { BeginArea(screenRect, GUIContent.Temp(image), style); }
// Begin a GUILayout block of GUI controls in a fixed screen area.
static public void BeginArea(Rect screenRect, GUIContent content, GUIStyle style)
{
GUILayoutGroup g = GUILayoutUtility.BeginLayoutArea(style, Il2CppType.Of<GUILayoutGroup>());
@ -106,6 +98,7 @@ namespace Explorer
GUI.BeginGroup(g.rect, content, style);
}
// Close a GUILayout block started with BeginArea
static public void EndArea()
{
if (Event.current.type == EventType.Used)
@ -115,7 +108,7 @@ namespace Explorer
GUI.EndGroup();
}
// ================= Fix for BeginGroup =================
// Fix for BeginGroup
public static void BeginGroup(Rect position) { BeginGroup(position, GUIContent.none, GUIStyle.none); }
public static void BeginGroup(Rect position, string text) { BeginGroup(position, GUIContent.Temp(text), GUIStyle.none); }
@ -152,196 +145,7 @@ namespace Explorer
GUIClip.Internal_Pop();
}
// ================= Fix for BeginVertical =================
public static void BeginVertical(params GUILayoutOption[] options) { BeginVertical(GUIContent.none, GUIStyle.none, options); }
public static void BeginVertical(GUIStyle style, params GUILayoutOption[] options) { BeginVertical(GUIContent.none, style, options); }
public static void BeginVertical(string text, GUIStyle style, params GUILayoutOption[] options) { BeginVertical(GUIContent.Temp(text), style, options); }
public static void BeginVertical(Texture image, GUIStyle style, params GUILayoutOption[] options) { BeginVertical(GUIContent.Temp(image), style, options); }
public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
{
var g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
g.isVertical = true;
if (style != GUIStyle.none || content != GUIContent.none)
GUI.Box(g.rect, content, style);
}
public static void EndVertical()
{
GUILayoutUtility.EndLayoutGroup();
}
// ================= Fix for BeginHorizontal ==================
public static void BeginHorizontal(params GUILayoutOption[] options) { BeginHorizontal(GUIContent.none, GUIStyle.none, options); }
public static void BeginHorizontal(GUIStyle style, params GUILayoutOption[] options) { BeginHorizontal(GUIContent.none, style, options); }
public static void BeginHorizontal(string text, GUIStyle style, params GUILayoutOption[] options) { BeginHorizontal(GUIContent.Temp(text), style, options); }
public static void BeginHorizontal(Texture image, GUIStyle style, params GUILayoutOption[] options)
{ BeginHorizontal(GUIContent.Temp(image), style, options); }
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
{
GUILayoutGroup g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
g.isVertical = false;
if (style != GUIStyle.none || content != GUIContent.none)
GUI.Box(g.rect, content, style);
}
public static void EndHorizontal()
{
GUILayoutUtility.EndLayoutGroup();
}
// =========== Fix for GUI elements =============
static public void Label(Texture image, params GUILayoutOption[] options) { DoLabel(GUIContent.Temp(image), GUI.skin.label, options); }
static public void Label(string text, params GUILayoutOption[] options) { DoLabel(GUIContent.Temp(text), GUI.skin.label, options); }
static public void Label(GUIContent content, params GUILayoutOption[] options) { DoLabel(content, GUI.skin.label, options); }
static public void Label(Texture image, GUIStyle style, params GUILayoutOption[] options) { DoLabel(GUIContent.Temp(image), style, options); }
static public void Label(string text, GUIStyle style, params GUILayoutOption[] options) { DoLabel(GUIContent.Temp(text), style, options); }
// Make an auto-layout label.
static public void Label(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { DoLabel(content, style, options); }
static void DoLabel(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ GUI.Label(LayoutUtilityUnstrip.GetRect(content, style, options), content, style); }
static public void Box(Texture image, params GUILayoutOption[] options) { DoBox(GUIContent.Temp(image), GUI.skin.box, options); }
static public void Box(string text, params GUILayoutOption[] options) { DoBox(GUIContent.Temp(text), GUI.skin.box, options); }
static public void Box(GUIContent content, params GUILayoutOption[] options) { DoBox(content, GUI.skin.box, options); }
static public void Box(Texture image, GUIStyle style, params GUILayoutOption[] options) { DoBox(GUIContent.Temp(image), style, options); }
static public void Box(string text, GUIStyle style, params GUILayoutOption[] options) { DoBox(GUIContent.Temp(text), style, options); }
// Make an auto-layout box.
static public void Box(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { DoBox(content, style, options); }
static void DoBox(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ GUI.Box(LayoutUtilityUnstrip.GetRect(content, style, options), content, style); }
static public bool Button(Texture image, params GUILayoutOption[] options) { return DoButton(GUIContent.Temp(image), GUI.skin.button, options); }
static public bool Button(string text, params GUILayoutOption[] options) { return DoButton(GUIContent.Temp(text), GUI.skin.button, options); }
static public bool Button(GUIContent content, params GUILayoutOption[] options) { return DoButton(content, GUI.skin.button, options); }
static public bool Button(Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoButton(GUIContent.Temp(image), style, options); }
static public bool Button(string text, GUIStyle style, params GUILayoutOption[] options) { return DoButton(GUIContent.Temp(text), style, options); }
// Make a single press button. The user clicks them and something happens immediately.
static public bool Button(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoButton(content, style, options); }
static bool DoButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ return GUI.Button(LayoutUtilityUnstrip.GetRect(content, style, options), content, style); }
static public bool RepeatButton(Texture image, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), GUI.skin.button, options); }
static public bool RepeatButton(string text, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); }
static public bool RepeatButton(GUIContent content, params GUILayoutOption[] options) { return DoRepeatButton(content, GUI.skin.button, options); }
static public bool RepeatButton(Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(image), style, options); }
static public bool RepeatButton(string text, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(GUIContent.Temp(text), style, options); }
// Make a repeating button. The button returns true as long as the user holds down the mouse
static public bool RepeatButton(GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton(content, style, options); }
static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ return RepeatButton(LayoutUtilityUnstrip.GetRect(content, style, options), content, style); }
public static string TextField(string text, params GUILayoutOption[] options) { return DoTextField(text, -1, false, GUI.skin.textField, options); }
public static string TextField(string text, int maxLength, params GUILayoutOption[] options) { return DoTextField(text, maxLength, false, GUI.skin.textField, options); }
public static string TextField(string text, GUIStyle style, params GUILayoutOption[] options) { return DoTextField(text, -1, false, style, options); }
// Make a single-line text field where the user can edit a string.
public static string TextField(string text, int maxLength, GUIStyle style, params GUILayoutOption[] options) { return DoTextField(text, maxLength, false, style, options); }
public static string TextArea(string text, params GUILayoutOption[] options) { return DoTextField(text, -1, true, GUI.skin.textArea, options); }
public static string TextArea(string text, int maxLength, params GUILayoutOption[] options) { return DoTextField(text, maxLength, true, GUI.skin.textArea, options); }
public static string TextArea(string text, GUIStyle style, params GUILayoutOption[] options) { return DoTextField(text, -1, true, style, options); }
// Make a multi-line text field where the user can edit a string.
public static string TextArea(string text, int maxLength, GUIStyle style, params GUILayoutOption[] options) { return DoTextField(text, maxLength, true, style, options); }
static string DoTextField(string text, int maxLength, bool multiline, GUIStyle style, GUILayoutOption[] options)
{
int id = GUIUtility.GetControlID(FocusType.Keyboard);
GUIContent content;
Rect r;
if (GUIUtility.keyboardControl != id)
content = GUIContent.Temp(text);
else
content = GUIContent.Temp(text + GUIUtility.compositionString);
r = LayoutUtilityUnstrip.GetRect(content, style, options);
if (GUIUtility.keyboardControl == id)
content = GUIContent.Temp(text);
GUI.DoTextField(r, id, content, multiline, maxLength, style);
return content.text;
}
static public bool Toggle(bool value, Texture image, params GUILayoutOption[] options) { return DoToggle(value, GUIContent.Temp(image), GUI.skin.toggle, options); }
static public bool Toggle(bool value, string text, params GUILayoutOption[] options) { return DoToggle(value, GUIContent.Temp(text), GUI.skin.toggle, options); }
static public bool Toggle(bool value, GUIContent content, params GUILayoutOption[] options) { return DoToggle(value, content, GUI.skin.toggle, options); }
static public bool Toggle(bool value, Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoToggle(value, GUIContent.Temp(image), style, options); }
static public bool Toggle(bool value, string text, GUIStyle style, params GUILayoutOption[] options) { return DoToggle(value, GUIContent.Temp(text), style, options); }
// Make an on/off toggle button.
static public bool Toggle(bool value, GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoToggle(value, content, style, options); }
static bool DoToggle(bool value, GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ return GUI.Toggle(LayoutUtilityUnstrip.GetRect(content, style, options), value, content, style); }
// =========== Fix for GUI.RepeatButton (not GUILayout) ===========
public static bool RepeatButton(Rect position, string text)
{
return DoRepeatButton(position, GUIContent.Temp(text), GUI.s_Skin.button, FocusType.Passive);
}
public static bool RepeatButton(Rect position, Texture image)
{
return DoRepeatButton(position, GUIContent.Temp(image), GUI.s_Skin.button, FocusType.Passive);
}
public static bool RepeatButton(Rect position, GUIContent content)
{
return DoRepeatButton(position, content, GUI.s_Skin.button, FocusType.Passive);
}
public static bool RepeatButton(Rect position, string text, GUIStyle style)
{
return DoRepeatButton(position, GUIContent.Temp(text), style, FocusType.Passive);
}
public static bool RepeatButton(Rect position, Texture image, GUIStyle style)
{
return DoRepeatButton(position, GUIContent.Temp(image), style, FocusType.Passive);
}
public static bool RepeatButton(Rect position, GUIContent content, GUIStyle style)
{
return DoRepeatButton(position, content, style, FocusType.Passive);
}
private static bool DoRepeatButton(Rect position, GUIContent content, GUIStyle style, FocusType focusType)
{
int id = GUIUtility.GetControlID(GUI.s_RepeatButtonHash, focusType, position);
switch (Event.current.GetTypeForControl(id))
{
case EventType.MouseDown:
// If the mouse is inside the button, we say that we're the hot control
if (position.Contains(Event.current.mousePosition))
{
GUIUtility.hotControl = id;
Event.current.Use();
}
return false;
case EventType.MouseUp:
if (GUIUtility.hotControl == id)
{
GUIUtility.hotControl = 0;
// If we got the mousedown, the mouseup is ours as well
// (no matter if the click was in the button or not)
Event.current.Use();
// But we only return true if the button was actually clicked
return position.Contains(Event.current.mousePosition);
}
return false;
case EventType.Repaint:
style.Draw(position, content, id, false, position.Contains(Event.current.mousePosition));
return id == GUIUtility.hotControl && position.Contains(Event.current.mousePosition);
}
return false;
}
// ================= Fix for BeginScrollView. =======================
// Fix for BeginScrollView.
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
{
@ -350,7 +154,7 @@ namespace Explorer
{
try
{
return GUIUnstrip.BeginScrollView(scroll, options);
return GUILayout.BeginScrollView(scroll, options);
}
catch
{
@ -382,7 +186,7 @@ namespace Explorer
if (!ScrollFailed)
{
GUIUnstrip.EndScrollView();
GUILayout.EndScrollView();
}
else if (!ManualUnstripFailed)
{

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Harmony;
using MelonLoader;
using UnityEngine;
namespace Explorer

View File

@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnhollowerRuntimeLib;
using UnityEngine;
namespace Explorer
{
public struct SliderHandlerUnstrip
public struct SliderHandlerUnstrip
{
private readonly Rect position;
private readonly float currentValue;

View File

@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine;
namespace Explorer
{