mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-13 07:16:37 +08:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
a1198f3a92 | |||
04248a89ce | |||
3639824df3 | |||
939861b5f0 | |||
ad5fc04a3b | |||
c39e097378 | |||
129a7e3765 | |||
643bb4519c | |||
b154cbf39d | |||
db91968519 | |||
5d58993b07 | |||
eea581f8d5 | |||
9bb3c77bae | |||
477a6859d7 | |||
f8f9671746 | |||
dc2759c599 | |||
653b4a2304 | |||
065ab033c9 | |||
11cbd24a6a | |||
fbf9859e0f | |||
2d7dfa53eb | |||
eff8d63c81 | |||
006cf0fc2c | |||
e5ca3530ff | |||
4de378907b | |||
bbdfb46a1e | |||
e6e2b3cd67 | |||
1d07046a74 |
46
README.md
46
README.md
@ -1,7 +1,7 @@
|
|||||||
# CppExplorer [](https://github.com/HerpDerpinstine/MelonLoader)
|
# CppExplorer [](https://github.com/HerpDerpinstine/MelonLoader)
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img align="center" src="https://sinai-dev.github.io/images/thumbs/02.png">
|
<img align="center" src="icon.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@ -13,17 +13,32 @@
|
|||||||
|
|
||||||
<img src="https://img.shields.io/github/downloads/sinai-dev/CppExplorer/total.svg" />
|
<img src="https://img.shields.io/github/downloads/sinai-dev/CppExplorer/total.svg" />
|
||||||
</p>
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/sinai-dev/MonoExplorer">Looking for a Mono version?</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
### Known issues
|
- [Known issues](#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.
|
- [How to install](#how-to-install)
|
||||||
* 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.
|
- [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.
|
* Scrolling with mouse wheel in the CppExplorer menu may not work on all games at the moment.
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
Requires [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) to be installed for your game.
|
Requires [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) to be installed for your game.
|
||||||
|
|
||||||
1. Download <b>CppExplorer.zip</b> from [Releases](https://github.com/sinaioutlander/CppExplorer/releases).
|
1. Download <b>CppExplorer.zip</b> from [Releases](https://github.com/sinai-dev/CppExplorer/releases).
|
||||||
2. Unzip the file into the `Mods` folder in your game's installation directory, created by MelonLoader.
|
2. Unzip the file into the `Mods` folder in your game's installation directory, created by MelonLoader.
|
||||||
3. Make sure it's not in a sub-folder, `CppExplorer.dll` and `mcs.dll` should be directly in the `Mods\` folder.
|
3. Make sure it's not in a sub-folder, `CppExplorer.dll` and `mcs.dll` should be directly in the `Mods\` folder.
|
||||||
|
|
||||||
@ -84,9 +99,9 @@ CppExplorer has two main inspector modes: <b>GameObject Inspector</b>, and <b>Re
|
|||||||
* Filter by name, type, etc.
|
* Filter by name, type, etc.
|
||||||
* For GameObjects and Transforms you can filter which scene they are found in too.
|
* 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
|
### Inspect-under-mouse
|
||||||
|
|
||||||
@ -102,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)
|
* 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.
|
* 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
|
## 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.
|
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.
|
||||||
|
BIN
lib/mcs.NET35.dll
Normal file
BIN
lib/mcs.NET35.dll
Normal file
Binary file not shown.
@ -2,10 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnhollowerBaseLib;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
@ -13,14 +10,14 @@ namespace Explorer
|
|||||||
public abstract class CacheObjectBase
|
public abstract class CacheObjectBase
|
||||||
{
|
{
|
||||||
public object Value;
|
public object Value;
|
||||||
public string ValueTypeName;
|
|
||||||
public Type ValueType;
|
public Type ValueType;
|
||||||
|
|
||||||
public MemberInfo MemInfo { get; set; }
|
public MemberInfo MemInfo { get; set; }
|
||||||
public Type DeclaringType { get; set; }
|
public Type DeclaringType { get; set; }
|
||||||
public object DeclaringInstance { 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_evaluated = false;
|
||||||
public bool m_isEvaluating;
|
public bool m_isEvaluating;
|
||||||
public ParameterInfo[] m_arguments = new ParameterInfo[0];
|
public ParameterInfo[] m_arguments = new ParameterInfo[0];
|
||||||
@ -117,8 +114,9 @@ namespace Explorer
|
|||||||
var pi = memberInfo as PropertyInfo;
|
var pi = memberInfo as PropertyInfo;
|
||||||
var mi = memberInfo as MethodInfo;
|
var mi = memberInfo as MethodInfo;
|
||||||
|
|
||||||
// if PropertyInfo, check if can process args
|
// Check if can process args
|
||||||
if (pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|
if ((pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|
||||||
|
|| (mi != null && !CanProcessArgs(mi.GetParameters())))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -130,14 +128,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
{
|
{
|
||||||
if (CacheMethod.CanEvaluate(mi))
|
holder = new CacheMethod();
|
||||||
{
|
|
||||||
holder = new CacheMethod();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
|
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
|
||||||
{
|
{
|
||||||
@ -172,7 +163,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
holder = new CacheDictionary();
|
holder = new CacheDictionary();
|
||||||
}
|
}
|
||||||
else if (ReflectionHelpers.IsEnumerable(valueType) || ReflectionHelpers.IsCppEnumerable(valueType))
|
else if (ReflectionHelpers.IsEnumerable(valueType))
|
||||||
{
|
{
|
||||||
holder = new CacheList();
|
holder = new CacheList();
|
||||||
}
|
}
|
||||||
@ -183,7 +174,6 @@ namespace Explorer
|
|||||||
|
|
||||||
holder.Value = obj;
|
holder.Value = obj;
|
||||||
holder.ValueType = valueType;
|
holder.ValueType = valueType;
|
||||||
holder.ValueTypeName = valueType.FullName;
|
|
||||||
|
|
||||||
if (memberInfo != null)
|
if (memberInfo != null)
|
||||||
{
|
{
|
||||||
@ -214,7 +204,18 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
foreach (var param in parameters)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -244,7 +245,11 @@ namespace Explorer
|
|||||||
var input = m_argumentInput[i];
|
var input = m_argumentInput[i];
|
||||||
var type = m_arguments[i].ParameterType;
|
var type = m_arguments[i].ParameterType;
|
||||||
|
|
||||||
// First, try parse the input and use that.
|
if (type.IsByRef)
|
||||||
|
{
|
||||||
|
type = type.GetElementType();
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(input))
|
if (!string.IsNullOrEmpty(input))
|
||||||
{
|
{
|
||||||
// strings can obviously just be used directly
|
// strings can obviously just be used directly
|
||||||
@ -309,14 +314,7 @@ namespace Explorer
|
|||||||
var pi = MemInfo as PropertyInfo;
|
var pi = MemInfo as PropertyInfo;
|
||||||
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
||||||
|
|
||||||
if (HasParameters)
|
Value = pi.GetValue(target, ParseArguments());
|
||||||
{
|
|
||||||
Value = pi.GetValue(target, ParseArguments());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Value = pi.GetValue(target, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReflectionException = null;
|
ReflectionException = null;
|
||||||
@ -395,43 +393,87 @@ namespace Explorer
|
|||||||
|
|
||||||
if (m_isEvaluating)
|
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;
|
GUILayout.Label($"<b><color=orange>Generic Arguments:</color></b>", null);
|
||||||
var input = m_argumentInput[i];
|
|
||||||
var type = m_arguments[i].ParameterType.Name;
|
|
||||||
|
|
||||||
var label = "<color=#2df7b2>" + type + "</color> <color=#a6e9e9>" + name + "</color>";
|
for (int i = 0; i < cm.GenericArgs.Length; i++)
|
||||||
if (m_arguments[i].HasDefaultValue)
|
|
||||||
{
|
{
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
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;
|
||||||
|
|
||||||
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(20) });
|
var label = $"<color={UIStyles.Syntax.Class_Instance}>{type}</color> ";
|
||||||
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
label += $"<color={UIStyles.Syntax.Local}>{name}</color>";
|
||||||
GUILayout.Label(label, null);
|
if (m_arguments[i].HasDefaultValue)
|
||||||
|
{
|
||||||
|
label = $"<i>[{label} = {m_arguments[i].DefaultValue ?? "null"}]</i>";
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
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);
|
GUILayout.BeginHorizontal(null);
|
||||||
if (cm != null)
|
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
||||||
{
|
{
|
||||||
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
if (cm != null)
|
||||||
{
|
{
|
||||||
cm.Evaluate();
|
cm.Evaluate();
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
|
||||||
{
|
{
|
||||||
UpdateValue();
|
UpdateValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
|
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
|
||||||
{
|
{
|
||||||
m_isEvaluating = false;
|
m_isEvaluating = false;
|
||||||
@ -440,7 +482,12 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GUILayout.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;
|
m_isEvaluating = true;
|
||||||
}
|
}
|
||||||
@ -468,17 +515,19 @@ namespace Explorer
|
|||||||
GUIUnstrip.Space(labelWidth);
|
GUIUnstrip.Space(labelWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string typeName = $"<color={UIStyles.Syntax.Class_Instance}>{ValueType.FullName}</color>";
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(ReflectionException))
|
if (!string.IsNullOrEmpty(ReflectionException))
|
||||||
{
|
{
|
||||||
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
||||||
}
|
}
|
||||||
else if ((HasParameters || this is CacheMethod) && !m_evaluated)
|
else if ((HasParameters || this is CacheMethod) && !m_evaluated)
|
||||||
{
|
{
|
||||||
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)", null);
|
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeName})", null);
|
||||||
}
|
}
|
||||||
else if (Value == null && !(this is CacheMethod))
|
else if (Value == null && !(this is CacheMethod))
|
||||||
{
|
{
|
||||||
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
|
GUILayout.Label($"<i>null ({typeName})</i>", null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -489,31 +538,80 @@ namespace Explorer
|
|||||||
private string GetRichTextName()
|
private string GetRichTextName()
|
||||||
{
|
{
|
||||||
string memberColor = "";
|
string memberColor = "";
|
||||||
switch (MemInfo.MemberType)
|
bool isStatic = false;
|
||||||
{
|
|
||||||
case MemberTypes.Field:
|
|
||||||
memberColor = "#c266ff"; break;
|
|
||||||
case MemberTypes.Property:
|
|
||||||
memberColor = "#72a6a6"; break;
|
|
||||||
case MemberTypes.Method:
|
|
||||||
memberColor = "#ff8000"; break;
|
|
||||||
};
|
|
||||||
|
|
||||||
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
|
if (MemInfo is FieldInfo fi)
|
||||||
|
|
||||||
if (m_arguments.Length > 0 || this is CacheMethod)
|
|
||||||
{
|
{
|
||||||
m_richTextName += "(";
|
if (fi.IsStatic)
|
||||||
var _params = "";
|
|
||||||
foreach (var param in m_arguments)
|
|
||||||
{
|
{
|
||||||
if (_params != "") _params += ", ";
|
isStatic = true;
|
||||||
|
memberColor = UIStyles.Syntax.Field_Static;
|
||||||
_params += $"<color=#2df7b2>{param.ParameterType.Name}</color> <color=#a6e9e9>{param.Name}</color>";
|
|
||||||
}
|
}
|
||||||
m_richTextName += _params;
|
else
|
||||||
m_richTextName += ")";
|
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;
|
return m_richTextName;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace Explorer
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Explorer
|
|
||||||
{
|
{
|
||||||
interface IExpandHeight
|
interface IExpandHeight
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -98,37 +93,16 @@ namespace Explorer
|
|||||||
|
|
||||||
private void GetGenericArguments()
|
private void GetGenericArguments()
|
||||||
{
|
{
|
||||||
if (this.MemInfo != null)
|
if (ValueType.IsGenericType)
|
||||||
{
|
{
|
||||||
Type memberType = null;
|
m_keysType = ValueType.GetGenericArguments()[0];
|
||||||
switch (this.MemInfo.MemberType)
|
m_valuesType = ValueType.GetGenericArguments()[1];
|
||||||
{
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (Value != null)
|
else
|
||||||
{
|
{
|
||||||
var type = Value.GetType();
|
// It's non-generic, just use System.Object to allow for anything.
|
||||||
if (type.IsGenericType)
|
m_keysType = typeof(object);
|
||||||
{
|
m_valuesType = typeof(object);
|
||||||
m_keysType = type.GetGenericArguments()[0];
|
|
||||||
m_valuesType = type.GetGenericArguments()[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MelonLogger.Log("TODO? Dictionary is of type: " + Value.GetType().FullName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,14 +128,16 @@ namespace Explorer
|
|||||||
var keys = new List<CacheObjectBase>();
|
var keys = new List<CacheObjectBase>();
|
||||||
foreach (var key in IDict.Keys)
|
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);
|
keys.Add(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
var values = new List<CacheObjectBase>();
|
var values = new List<CacheObjectBase>();
|
||||||
foreach (var val in IDict.Values)
|
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);
|
values.Add(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,10 +264,10 @@ namespace Explorer
|
|||||||
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
|
GUILayout.Label($"[{i}]", new GUILayoutOption[] { GUILayout.Width(30) });
|
||||||
|
|
||||||
GUILayout.Label("Key:", new GUILayoutOption[] { GUILayout.Width(40) });
|
GUILayout.Label("Key:", new GUILayoutOption[] { GUILayout.Width(40) });
|
||||||
key.DrawValue(window, (window.width / 2) - 30f);
|
key.DrawValue(window, (window.width / 2) - 80f);
|
||||||
|
|
||||||
GUILayout.Label("Value:", new GUILayoutOption[] { GUILayout.Width(40) });
|
GUILayout.Label("Value:", new GUILayoutOption[] { GUILayout.Width(40) });
|
||||||
val.DrawValue(window, (window.width / 2) - 30f);
|
val.DrawValue(window, (window.width / 2) - 80f);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -13,16 +11,24 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
private CacheObjectBase m_cachedReturnValue;
|
private CacheObjectBase m_cachedReturnValue;
|
||||||
|
|
||||||
public static bool CanEvaluate(MethodInfo mi)
|
public override bool HasParameters => base.HasParameters || GenericArgs.Length > 0;
|
||||||
{
|
|
||||||
// TODO generic args
|
|
||||||
if (mi.GetGenericArguments().Length > 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// primitive and string args supported
|
public Type[] GenericArgs { get; private set; }
|
||||||
return CanProcessArgs(mi.GetParameters());
|
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()
|
public override void UpdateValue()
|
||||||
@ -32,27 +38,29 @@ namespace Explorer
|
|||||||
|
|
||||||
public void Evaluate()
|
public void Evaluate()
|
||||||
{
|
{
|
||||||
m_isEvaluating = false;
|
MethodInfo mi;
|
||||||
|
if (GenericArgs.Length > 0)
|
||||||
var mi = MemInfo as MethodInfo;
|
|
||||||
object ret = null;
|
|
||||||
|
|
||||||
if (!HasParameters)
|
|
||||||
{
|
{
|
||||||
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, new object[0]);
|
mi = MakeGenericMethodFromInput();
|
||||||
m_evaluated = true;
|
if (mi == null) return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
mi = MemInfo as MethodInfo;
|
||||||
{
|
}
|
||||||
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments());
|
|
||||||
m_evaluated = true;
|
object ret = null;
|
||||||
}
|
|
||||||
catch (Exception e)
|
try
|
||||||
{
|
{
|
||||||
MelonLogger.Log($"Exception evaluating: {e.GetType()}, {e.Message}");
|
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)
|
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 ====
|
// ==== GUI DRAW ====
|
||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
public override void DrawValue(Rect window, float width)
|
||||||
{
|
{
|
||||||
|
string typeLabel = $"<color={UIStyles.Syntax.Class_Instance}>{ValueType.FullName}</color>";
|
||||||
|
|
||||||
if (m_evaluated)
|
if (m_evaluated)
|
||||||
{
|
{
|
||||||
if (m_cachedReturnValue != null)
|
if (m_cachedReturnValue != null)
|
||||||
@ -78,12 +130,12 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUILayout.Label($"null (<color=#2df7b2>{ValueTypeName}</color>)", null);
|
GUILayout.Label($"null ({typeLabel})", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)", null);
|
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeLabel})", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@ -11,55 +6,75 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class CacheOther : CacheObjectBase
|
public class CacheOther : CacheObjectBase
|
||||||
{
|
{
|
||||||
|
public string ButtonLabel => m_btnLabel ?? GetButtonLabel();
|
||||||
|
private string m_btnLabel;
|
||||||
|
|
||||||
|
public MethodInfo ToStringMethod => m_toStringMethod ?? GetToStringMethod();
|
||||||
private MethodInfo m_toStringMethod;
|
private MethodInfo m_toStringMethod;
|
||||||
|
|
||||||
public MethodInfo ToStringMethod
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
get
|
base.UpdateValue();
|
||||||
{
|
|
||||||
if (m_toStringMethod == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_toStringMethod = ReflectionHelpers.GetActualType(Value).GetMethod("ToString", new Type[0])
|
|
||||||
?? typeof(object).GetMethod("ToString", new Type[0]);
|
|
||||||
|
|
||||||
// test invoke
|
GetButtonLabel();
|
||||||
m_toStringMethod.Invoke(Value, null);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
m_toStringMethod = typeof(object).GetMethod("ToString", new Type[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m_toStringMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawValue(Rect window, float width)
|
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;
|
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
|
||||||
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width - 15) }))
|
if (GUILayout.Button(ButtonLabel, new GUILayoutOption[] { GUILayout.Width(width - 15) }))
|
||||||
{
|
{
|
||||||
WindowManager.InspectObject(Value, out bool _);
|
WindowManager.InspectObject(Value, out bool _);
|
||||||
}
|
}
|
||||||
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
|
if (Value == null) return;
|
||||||
|
|
||||||
var color = (Color)Value;
|
var color = (Color)Value;
|
||||||
|
|
||||||
r = color.r.ToString();
|
r = color.r.ToString();
|
||||||
@ -104,7 +106,7 @@ namespace Explorer
|
|||||||
&& float.TryParse(b, out float fB)
|
&& float.TryParse(b, out float fB)
|
||||||
&& float.TryParse(a, out float fA))
|
&& float.TryParse(a, out float fA))
|
||||||
{
|
{
|
||||||
Value = new Color(fR, fB, fG, fA);
|
Value = new Color(fR, fG, fB, fA);
|
||||||
SetValue();
|
SetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,23 +11,19 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
public class CacheEnum : CacheObjectBase
|
public class CacheEnum : CacheObjectBase
|
||||||
{
|
{
|
||||||
public Type EnumType;
|
// public Type EnumType;
|
||||||
public string[] EnumNames;
|
public string[] EnumNames;
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
try
|
if (ValueType == null && Value != null)
|
||||||
{
|
{
|
||||||
EnumType = Value.GetType();
|
ValueType = Value.GetType();
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
EnumType = (MemInfo as FieldInfo)?.FieldType ?? (MemInfo as PropertyInfo).PropertyType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnumType != null)
|
if (ValueType != null)
|
||||||
{
|
{
|
||||||
EnumNames = Enum.GetNames(EnumType);
|
EnumNames = Enum.GetNames(ValueType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -62,7 +58,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if ((change < 0 && newindex >= 0) || (change > 0 && newindex < names.Count))
|
if ((change < 0 && newindex >= 0) || (change > 0 && newindex < names.Count))
|
||||||
{
|
{
|
||||||
value = Enum.Parse(EnumType, names[newindex]);
|
value = Enum.Parse(ValueType, names[newindex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
|
if (Value == null) return;
|
||||||
|
|
||||||
var euler = ((Quaternion)Value).eulerAngles;
|
var euler = ((Quaternion)Value).eulerAngles;
|
||||||
|
|
||||||
x = euler.x.ToString();
|
x = euler.x.ToString();
|
||||||
|
@ -21,6 +21,8 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
base.UpdateValue();
|
base.UpdateValue();
|
||||||
|
|
||||||
|
if (Value == null) return;
|
||||||
|
|
||||||
var rect = (Rect)Value;
|
var rect = (Rect)Value;
|
||||||
|
|
||||||
x = rect.x.ToString();
|
x = rect.x.ToString();
|
||||||
|
@ -24,20 +24,26 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
{
|
{
|
||||||
if (Value is Vector2)
|
if (ValueType == null && Value != null)
|
||||||
|
{
|
||||||
|
ValueType = Value.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ValueType == typeof(Vector2))
|
||||||
{
|
{
|
||||||
VectorSize = 2;
|
VectorSize = 2;
|
||||||
|
m_toStringMethod = typeof(Vector2).GetMethod("ToString", new Type[0]);
|
||||||
}
|
}
|
||||||
else if (Value is Vector3)
|
else if (ValueType == typeof(Vector3))
|
||||||
{
|
{
|
||||||
VectorSize = 3;
|
VectorSize = 3;
|
||||||
|
m_toStringMethod = typeof(Vector3).GetMethod("ToString", new Type[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VectorSize = 4;
|
VectorSize = 4;
|
||||||
|
m_toStringMethod = typeof(Vector4).GetMethod("ToString", new Type[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_toStringMethod = Value.GetType().GetMethod("ToString", new Type[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateValue()
|
public override void UpdateValue()
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
using System;
|
using MelonLoader;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Harmony;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnhollowerBaseLib;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
@ -13,7 +6,7 @@ namespace Explorer
|
|||||||
public class CppExplorer : MelonMod
|
public class CppExplorer : MelonMod
|
||||||
{
|
{
|
||||||
public const string NAME = "CppExplorer";
|
public const string NAME = "CppExplorer";
|
||||||
public const string VERSION = "1.7.0";
|
public const string VERSION = "1.7.4";
|
||||||
public const string AUTHOR = "Sinai";
|
public const string AUTHOR = "Sinai";
|
||||||
public const string GUID = "com.sinai.cppexplorer";
|
public const string GUID = "com.sinai.cppexplorer";
|
||||||
|
|
||||||
@ -36,17 +29,13 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
|
|
||||||
// First, load config
|
|
||||||
ModConfig.OnLoad();
|
ModConfig.OnLoad();
|
||||||
|
|
||||||
// Setup InputHelper class (UnityEngine.Input)
|
|
||||||
InputHelper.Init();
|
InputHelper.Init();
|
||||||
|
|
||||||
// Create CppExplorer modules
|
|
||||||
new MainMenu();
|
new MainMenu();
|
||||||
new WindowManager();
|
new WindowManager();
|
||||||
|
|
||||||
// Init cursor control
|
|
||||||
CursorControl.Init();
|
CursorControl.Init();
|
||||||
|
|
||||||
MelonLogger.Log($"CppExplorer {VERSION} initialized.");
|
MelonLogger.Log($"CppExplorer {VERSION} initialized.");
|
||||||
@ -60,7 +49,6 @@ namespace Explorer
|
|||||||
|
|
||||||
public override void OnUpdate()
|
public override void OnUpdate()
|
||||||
{
|
{
|
||||||
// Check main toggle key input
|
|
||||||
if (InputHelper.GetKeyDown(ModConfig.Instance.Main_Menu_Toggle))
|
if (InputHelper.GetKeyDown(ModConfig.Instance.Main_Menu_Toggle))
|
||||||
{
|
{
|
||||||
ShowMenu = !ShowMenu;
|
ShowMenu = !ShowMenu;
|
||||||
|
@ -101,13 +101,13 @@
|
|||||||
<Compile Include="Extensions\UnityExtensions.cs" />
|
<Compile Include="Extensions\UnityExtensions.cs" />
|
||||||
<Compile Include="Helpers\PageHelper.cs" />
|
<Compile Include="Helpers\PageHelper.cs" />
|
||||||
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
<Compile Include="Helpers\ReflectionHelpers.cs" />
|
||||||
<Compile Include="Helpers\UIHelpers.cs" />
|
<Compile Include="Menu\UIHelpers.cs" />
|
||||||
<Compile Include="Helpers\UnityHelpers.cs" />
|
<Compile Include="Helpers\UnityHelpers.cs" />
|
||||||
<Compile Include="Menu\InspectUnderMouse.cs" />
|
<Compile Include="Menu\InspectUnderMouse.cs" />
|
||||||
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
<Compile Include="CachedObjects\CacheObjectBase.cs" />
|
||||||
<Compile Include="UnstripFixes\SliderHandlerUnstrip.cs" />
|
<Compile Include="UnstripFixes\SliderHandlerUnstrip.cs" />
|
||||||
<Compile Include="UnstripFixes\UnstripExtensions.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\TabViewWindow.cs" />
|
||||||
<Compile Include="Menu\Windows\UIWindow.cs" />
|
<Compile Include="Menu\Windows\UIWindow.cs" />
|
||||||
<Compile Include="Menu\MainMenu\Pages\ConsolePage.cs" />
|
<Compile Include="Menu\MainMenu\Pages\ConsolePage.cs" />
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnhollowerBaseLib;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using UnityEngine;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
@ -36,7 +35,7 @@ namespace Explorer
|
|||||||
|
|
||||||
public static bool IsEnumerable(Type t)
|
public static bool IsEnumerable(Type t)
|
||||||
{
|
{
|
||||||
return typeof(IEnumerable).IsAssignableFrom(t);
|
return typeof(IEnumerable).IsAssignableFrom(t) || IsCppEnumerable(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for Il2Cpp List or HashSet.
|
// Checks for Il2Cpp List or HashSet.
|
||||||
@ -68,7 +67,8 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t);
|
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|
||||||
|
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,6 @@ namespace Explorer
|
|||||||
return typeof(ILType);
|
return typeof(ILType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the System.Type using the qualified name, or fallback to GetType.
|
|
||||||
return Type.GetType(ilObject.GetIl2CppType().AssemblyQualifiedName) ?? obj.GetType();
|
return Type.GetType(ilObject.GetIl2CppType().AssemblyQualifiedName) ?? obj.GetType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using System.Reflection;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -3,8 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
@ -21,8 +19,9 @@ namespace Explorer
|
|||||||
Pages.Add(new SearchPage());
|
Pages.Add(new SearchPage());
|
||||||
Pages.Add(new ConsolePage());
|
Pages.Add(new ConsolePage());
|
||||||
|
|
||||||
foreach (var page in Pages)
|
for (int i = 0; i < Pages.Count; i++)
|
||||||
{
|
{
|
||||||
|
var page = Pages[i];
|
||||||
page.Init();
|
page.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +29,7 @@ namespace Explorer
|
|||||||
public const int MainWindowID = 5000;
|
public const int MainWindowID = 5000;
|
||||||
public static Rect MainRect = new Rect(5,5, ModConfig.Instance.Default_Window_Size.x,ModConfig.Instance.Default_Window_Size.y);
|
public static Rect MainRect = new Rect(5,5, ModConfig.Instance.Default_Window_Size.x,ModConfig.Instance.Default_Window_Size.y);
|
||||||
|
|
||||||
private static readonly List<WindowPage> Pages = new List<WindowPage>();
|
public static readonly List<WindowPage> Pages = new List<WindowPage>();
|
||||||
private static int m_currentPage = 0;
|
private static int m_currentPage = 0;
|
||||||
|
|
||||||
public static void SetCurrentPage(int index)
|
public static void SetCurrentPage(int index)
|
||||||
@ -65,7 +64,7 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box);
|
GUIUnstrip.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box);
|
||||||
|
|
||||||
MainHeader();
|
MainHeader();
|
||||||
|
|
||||||
@ -79,7 +78,7 @@ namespace Explorer
|
|||||||
|
|
||||||
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
|
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
|
||||||
|
|
||||||
GUILayout.EndArea();
|
GUIUnstrip.EndArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainHeader()
|
private void MainHeader()
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using Mono.CSharp;
|
using Mono.CSharp;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Attribute = System.Attribute;
|
using Attribute = System.Attribute;
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
using System.Collections;
|
using System;
|
||||||
//using Il2CppSystem;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System;
|
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
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.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using Mono.CSharp;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -43,7 +40,7 @@ namespace Explorer
|
|||||||
|
|
||||||
try
|
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.
|
// Some common using directives are added by default, you can add more below.
|
||||||
// If you want to return some output, MelonLogger.Log() it.
|
// If you want to return some output, MelonLogger.Log() it.
|
||||||
|
|
||||||
@ -58,7 +55,9 @@ MelonLogger.Log(""hello world"");";
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MelonLogger.Log($"Error setting up console!\r\nMessage: {e.Message}\r\nStack: {e.StackTrace}");
|
MelonLogger.Log($"Error setting up console!\r\nMessage: {e.Message}");
|
||||||
|
MainMenu.SetCurrentPage(0);
|
||||||
|
MainMenu.Pages.Remove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +120,7 @@ MelonLogger.Log(""hello world"");";
|
|||||||
|
|
||||||
public override void DrawWindow()
|
public override void DrawWindow()
|
||||||
{
|
{
|
||||||
GUILayout.Label("<b><size=15><color=cyan>C# REPL Console</color></size></b>", null);
|
GUILayout.Label("<b><size=15><color=cyan>C# Console</color></size></b>", null);
|
||||||
|
|
||||||
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
GUI.skin.label.alignment = TextAnchor.UpperLeft;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -428,7 +427,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
var t = ReflectionHelpers.GetActualType(obj);
|
var t = ReflectionHelpers.GetActualType(obj);
|
||||||
|
|
||||||
if (!FilterName(t.FullName) || ReflectionHelpers.IsEnumerable(t) || ReflectionHelpers.IsCppEnumerable(t))
|
if (!FilterName(t.FullName) || ReflectionHelpers.IsEnumerable(t))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -36,25 +32,32 @@ namespace Explorer
|
|||||||
|
|
||||||
var mousePos = InputHelper.mousePosition;
|
var mousePos = InputHelper.mousePosition;
|
||||||
|
|
||||||
Vector2 mouse = GUIUtility.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))
|
if (isResizing && ID == m_currentWindow)
|
||||||
{
|
{
|
||||||
isResizing = true;
|
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x));
|
||||||
m_currentWindow = ID;
|
_rect.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
|
||||||
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
|
_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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
@ -68,7 +71,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
RESIZE_FAILED = true;
|
RESIZE_FAILED = true;
|
||||||
MelonLogger.Log("Exception on GuiResize: " + e.GetType() + ", " + e.Message);
|
MelonLogger.Log("Exception on GuiResize: " + e.GetType() + ", " + e.Message);
|
||||||
MelonLogger.Log(e.StackTrace);
|
//MelonLogger.Log(e.StackTrace);
|
||||||
return origRect;
|
return origRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,20 +85,20 @@ namespace Explorer
|
|||||||
|
|
||||||
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
GUI.skin.label.alignment = TextAnchor.MiddleRight;
|
||||||
GUILayout.Label("<color=cyan>Width:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
GUILayout.Label("<color=cyan>Width:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||||
if (GUILayout.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
_rect.width -= 5f;
|
_rect.width -= 5f;
|
||||||
}
|
}
|
||||||
if (GUILayout.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
_rect.width += 5f;
|
_rect.width += 5f;
|
||||||
}
|
}
|
||||||
GUILayout.Label("<color=cyan>Height:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
GUILayout.Label("<color=cyan>Height:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
|
||||||
if (GUILayout.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
_rect.height -= 5f;
|
_rect.height -= 5f;
|
||||||
}
|
}
|
||||||
if (GUILayout.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
_rect.height += 5f;
|
_rect.height += 5f;
|
||||||
}
|
}
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Reflection;
|
|
||||||
using UnhollowerRuntimeLib;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
@ -1,16 +1,29 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using UnityEngine;
|
|
||||||
using Object = UnityEngine.Object;
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public class UIStyles
|
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 Color LightGreen = new Color(Color.green.r - 0.3f, Color.green.g - 0.3f, Color.green.b - 0.3f);
|
||||||
|
|
||||||
public static GUISkin WindowSkin
|
public static GUISkin WindowSkin
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using MelonLoader;
|
using MelonLoader;
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public class GameObjectWindow : UIWindow
|
public class GameObjectWindow : UIWindow
|
||||||
{
|
{
|
||||||
public override string Title => WindowManager.TabView
|
public override string Title => WindowManager.TabView
|
||||||
? $"<color=cyan>[G]</color> {m_object.name}"
|
? $"<color=cyan>[G]</color> {TargetGO.name}"
|
||||||
: $"GameObject Inspector ({m_object.name})";
|
: $"GameObject Inspector ({TargetGO.name})";
|
||||||
|
|
||||||
public GameObject m_object;
|
public GameObject TargetGO;
|
||||||
|
|
||||||
|
private static bool m_hideControls;
|
||||||
|
|
||||||
// gui element holders
|
// gui element holders
|
||||||
private string m_name;
|
private string m_name;
|
||||||
@ -23,11 +22,11 @@ namespace Explorer
|
|||||||
|
|
||||||
private Transform[] m_children;
|
private Transform[] m_children;
|
||||||
private Vector2 m_transformScroll = Vector2.zero;
|
private Vector2 m_transformScroll = Vector2.zero;
|
||||||
private PageHelper ChildPages = new PageHelper();
|
private readonly PageHelper ChildPages = new PageHelper();
|
||||||
|
|
||||||
private Component[] m_components;
|
private Component[] m_components;
|
||||||
private Vector2 m_compScroll = Vector2.zero;
|
private Vector2 m_compScroll = Vector2.zero;
|
||||||
private PageHelper CompPages = new PageHelper();
|
private readonly PageHelper CompPages = new PageHelper();
|
||||||
|
|
||||||
private readonly Vector3[] m_cachedInput = new Vector3[3];
|
private readonly Vector3[] m_cachedInput = new Vector3[3];
|
||||||
private float m_translateAmount = 0.3f;
|
private float m_translateAmount = 0.3f;
|
||||||
@ -42,7 +41,7 @@ namespace Explorer
|
|||||||
private bool m_localContext;
|
private bool m_localContext;
|
||||||
|
|
||||||
private readonly List<Component> m_cachedDestroyList = new List<Component>();
|
private readonly List<Component> m_cachedDestroyList = new List<Component>();
|
||||||
//private string m_addComponentInput = "";
|
private string m_addComponentInput = "";
|
||||||
|
|
||||||
private string m_setParentInput = "Enter a GameObject name or path";
|
private string m_setParentInput = "Enter a GameObject name or path";
|
||||||
|
|
||||||
@ -52,12 +51,12 @@ namespace Explorer
|
|||||||
|
|
||||||
if (targetType == typeof(GameObject))
|
if (targetType == typeof(GameObject))
|
||||||
{
|
{
|
||||||
m_object = Target as GameObject;
|
TargetGO = Target as GameObject;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (targetType == typeof(Transform))
|
else if (targetType == typeof(Transform))
|
||||||
{
|
{
|
||||||
m_object = (Target as Transform).gameObject;
|
TargetGO = (Target as Transform).gameObject;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +72,10 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_name = m_object.name;
|
m_name = TargetGO.name;
|
||||||
m_scene = string.IsNullOrEmpty(m_object.scene.name)
|
m_scene = string.IsNullOrEmpty(TargetGO.scene.name)
|
||||||
? "None (Asset/Resource)"
|
? "None (Asset/Resource)"
|
||||||
: m_object.scene.name;
|
: TargetGO.scene.name;
|
||||||
|
|
||||||
CacheTransformValues();
|
CacheTransformValues();
|
||||||
|
|
||||||
@ -87,15 +86,15 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (m_localContext)
|
if (m_localContext)
|
||||||
{
|
{
|
||||||
m_cachedInput[0] = m_object.transform.localPosition;
|
m_cachedInput[0] = TargetGO.transform.localPosition;
|
||||||
m_cachedInput[1] = m_object.transform.localEulerAngles;
|
m_cachedInput[1] = TargetGO.transform.localEulerAngles;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_cachedInput[0] = m_object.transform.position;
|
m_cachedInput[0] = TargetGO.transform.position;
|
||||||
m_cachedInput[1] = m_object.transform.eulerAngles;
|
m_cachedInput[1] = TargetGO.transform.eulerAngles;
|
||||||
}
|
}
|
||||||
m_cachedInput[2] = m_object.transform.localScale;
|
m_cachedInput[2] = TargetGO.transform.localScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
@ -118,7 +117,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_object && !GetObjectAsGameObject())
|
if (!TargetGO && !GetObjectAsGameObject())
|
||||||
{
|
{
|
||||||
throw new Exception("Object is null!");
|
throw new Exception("Object is null!");
|
||||||
}
|
}
|
||||||
@ -127,22 +126,22 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (m_localContext)
|
if (m_localContext)
|
||||||
{
|
{
|
||||||
m_object.transform.localPosition = m_frozenPosition;
|
TargetGO.transform.localPosition = m_frozenPosition;
|
||||||
m_object.transform.localRotation = m_frozenRotation;
|
TargetGO.transform.localRotation = m_frozenRotation;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_object.transform.position = m_frozenPosition;
|
TargetGO.transform.position = m_frozenPosition;
|
||||||
m_object.transform.rotation = m_frozenRotation;
|
TargetGO.transform.rotation = m_frozenRotation;
|
||||||
}
|
}
|
||||||
m_object.transform.localScale = m_frozenScale;
|
TargetGO.transform.localScale = m_frozenScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update child objects
|
// update child objects
|
||||||
var childList = new List<Transform>();
|
var childList = new List<Transform>();
|
||||||
for (int i = 0; i < m_object.transform.childCount; i++)
|
for (int i = 0; i < TargetGO.transform.childCount; i++)
|
||||||
{
|
{
|
||||||
childList.Add(m_object.transform.GetChild(i));
|
childList.Add(TargetGO.transform.GetChild(i));
|
||||||
}
|
}
|
||||||
childList.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
childList.Sort((a, b) => b.childCount.CompareTo(a.childCount));
|
||||||
m_children = childList.ToArray();
|
m_children = childList.ToArray();
|
||||||
@ -151,7 +150,7 @@ namespace Explorer
|
|||||||
|
|
||||||
// update components
|
// update components
|
||||||
var compList = new Il2CppSystem.Collections.Generic.List<Component>();
|
var compList = new Il2CppSystem.Collections.Generic.List<Component>();
|
||||||
m_object.GetComponentsInternal(ReflectionHelpers.ComponentType, true, false, true, false, compList);
|
TargetGO.GetComponentsInternal(ReflectionHelpers.ComponentType, true, false, true, false, compList);
|
||||||
|
|
||||||
m_components = compList.ToArray();
|
m_components = compList.ToArray();
|
||||||
|
|
||||||
@ -182,7 +181,7 @@ namespace Explorer
|
|||||||
|
|
||||||
private void ReflectObject(Il2CppSystem.Object obj)
|
private void ReflectObject(Il2CppSystem.Object obj)
|
||||||
{
|
{
|
||||||
var window = WindowManager.InspectObject(obj, out bool created);
|
var window = WindowManager.InspectObject(obj, out bool created, true);
|
||||||
|
|
||||||
if (created)
|
if (created)
|
||||||
{
|
{
|
||||||
@ -210,7 +209,7 @@ namespace Explorer
|
|||||||
if (!WindowManager.TabView)
|
if (!WindowManager.TabView)
|
||||||
{
|
{
|
||||||
Header();
|
Header();
|
||||||
GUILayout.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||||
}
|
}
|
||||||
|
|
||||||
scroll = GUIUnstrip.BeginScrollView(scroll);
|
scroll = GUIUnstrip.BeginScrollView(scroll);
|
||||||
@ -221,7 +220,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (GUILayout.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(m_object.transform);
|
ScenePage.Instance.SetTransformTarget(TargetGO.transform);
|
||||||
MainMenu.SetCurrentPage(0);
|
MainMenu.SetCurrentPage(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,12 +232,12 @@ namespace Explorer
|
|||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
|
GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
|
||||||
string pathlabel = m_object.transform.GetGameObjectPath();
|
string pathlabel = TargetGO.transform.GetGameObjectPath();
|
||||||
if (m_object.transform.parent != null)
|
if (TargetGO.transform.parent != null)
|
||||||
{
|
{
|
||||||
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
|
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
|
||||||
{
|
{
|
||||||
InspectGameObject(m_object.transform.parent);
|
InspectGameObject(TargetGO.transform.parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GUILayout.TextArea(pathlabel, null);
|
GUILayout.TextArea(pathlabel, null);
|
||||||
@ -270,7 +269,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
||||||
|
|
||||||
GUILayout.EndArea();
|
GUIUnstrip.EndArea();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -360,6 +359,29 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
var width = m_rect.width / 2 - 115f;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (typeof(Component).IsAssignableFrom(compType))
|
||||||
|
{
|
||||||
|
TargetGO.AddComponent(Il2CppType.From(compType));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MelonLogger.LogWarning($"Type '{compType.Name}' is not assignable from Component!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MelonLogger.LogWarning($"Could not find a type by the name of '{m_addComponentInput}'!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
|
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
|
||||||
if (m_cachedDestroyList.Count > 0)
|
if (m_cachedDestroyList.Count > 0)
|
||||||
{
|
{
|
||||||
@ -439,21 +461,41 @@ namespace Explorer
|
|||||||
|
|
||||||
private void GameObjectControls()
|
private void GameObjectControls()
|
||||||
{
|
{
|
||||||
|
if (m_hideControls)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GUILayout.BeginVertical(GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
|
GUILayout.BeginVertical(GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
|
||||||
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", null);
|
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
bool m_active = m_object.activeSelf;
|
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;
|
||||||
|
}
|
||||||
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
GUILayout.BeginHorizontal(null);
|
||||||
|
bool m_active = TargetGO.activeSelf;
|
||||||
m_active = GUILayout.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) });
|
new GUILayoutOption[] { GUILayout.Width(80) });
|
||||||
if (m_object.activeSelf != m_active) { m_object.SetActive(m_active); }
|
if (TargetGO.activeSelf != m_active) { TargetGO.SetActive(m_active); }
|
||||||
|
|
||||||
UIHelpers.InstantiateButton(m_object, 100);
|
UIHelpers.InstantiateButton(TargetGO, 100);
|
||||||
|
|
||||||
if (GUILayout.Button("Set DontDestroyOnLoad", new GUILayoutOption[] { GUILayout.Width(170) }))
|
if (GUILayout.Button("Set DontDestroyOnLoad", new GUILayoutOption[] { GUILayout.Width(170) }))
|
||||||
{
|
{
|
||||||
GameObject.DontDestroyOnLoad(m_object);
|
GameObject.DontDestroyOnLoad(TargetGO);
|
||||||
m_object.hideFlags |= HideFlags.DontUnloadUnusedAsset;
|
TargetGO.hideFlags |= HideFlags.DontUnloadUnusedAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lbl = m_freeze ? "<color=lime>Unfreeze</color>" : "<color=orange>Freeze Pos/Rot</color>";
|
var lbl = m_freeze ? "<color=lime>Unfreeze</color>" : "<color=orange>Freeze Pos/Rot</color>";
|
||||||
@ -474,7 +516,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (GameObject.Find(m_setParentInput) is GameObject newparent)
|
if (GameObject.Find(m_setParentInput) is GameObject newparent)
|
||||||
{
|
{
|
||||||
m_object.transform.parent = newparent.transform;
|
TargetGO.transform.parent = newparent.transform;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -484,7 +526,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if (GUILayout.Button("Detach from parent", new GUILayoutOption[] { GUILayout.Width(160) }))
|
if (GUILayout.Button("Detach from parent", new GUILayoutOption[] { GUILayout.Width(160) }))
|
||||||
{
|
{
|
||||||
m_object.transform.parent = null;
|
TargetGO.transform.parent = null;
|
||||||
}
|
}
|
||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
|
|
||||||
@ -499,15 +541,15 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (m_localContext)
|
if (m_localContext)
|
||||||
{
|
{
|
||||||
m_object.transform.localPosition = m_cachedInput[0];
|
TargetGO.transform.localPosition = m_cachedInput[0];
|
||||||
m_object.transform.localEulerAngles = m_cachedInput[1];
|
TargetGO.transform.localEulerAngles = m_cachedInput[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_object.transform.position = m_cachedInput[0];
|
TargetGO.transform.position = m_cachedInput[0];
|
||||||
m_object.transform.eulerAngles = m_cachedInput[1];
|
TargetGO.transform.eulerAngles = m_cachedInput[1];
|
||||||
}
|
}
|
||||||
m_object.transform.localScale = m_cachedInput[2];
|
TargetGO.transform.localScale = m_cachedInput[2];
|
||||||
|
|
||||||
if (m_freeze)
|
if (m_freeze)
|
||||||
{
|
{
|
||||||
@ -541,7 +583,7 @@ namespace Explorer
|
|||||||
|
|
||||||
if (GUILayout.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(m_object);
|
GameObject.Destroy(TargetGO);
|
||||||
DestroyWindow();
|
DestroyWindow();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -553,15 +595,15 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
if (m_localContext)
|
if (m_localContext)
|
||||||
{
|
{
|
||||||
m_frozenPosition = m_object.transform.localPosition;
|
m_frozenPosition = TargetGO.transform.localPosition;
|
||||||
m_frozenRotation = m_object.transform.localRotation;
|
m_frozenRotation = TargetGO.transform.localRotation;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_frozenPosition = m_object.transform.position;
|
m_frozenPosition = TargetGO.transform.position;
|
||||||
m_frozenRotation = m_object.transform.rotation;
|
m_frozenRotation = TargetGO.transform.rotation;
|
||||||
}
|
}
|
||||||
m_frozenScale = m_object.transform.localScale;
|
m_frozenScale = TargetGO.transform.localScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BoolToggle(ref bool value, string message)
|
private void BoolToggle(ref bool value, string message)
|
||||||
@ -586,7 +628,7 @@ namespace Explorer
|
|||||||
GUILayout.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
|
GUILayout.Label($"<color=cyan><b>{(m_localContext ? "Local " : "")}{mode}</b></color>:",
|
||||||
new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
|
new GUILayoutOption[] { GUILayout.Width(m_localContext ? 110 : 65) });
|
||||||
|
|
||||||
var transform = m_object.transform;
|
var transform = TargetGO.transform;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case TranslateType.Position:
|
case TranslateType.Position:
|
||||||
@ -639,11 +681,11 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
f = f2;
|
f = f2;
|
||||||
}
|
}
|
||||||
if (GUILayout.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
f -= multByTime ? amount * Time.deltaTime : amount;
|
f -= multByTime ? amount * Time.deltaTime : amount;
|
||||||
}
|
}
|
||||||
if (GUILayout.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
|
||||||
{
|
{
|
||||||
f += multByTime ? amount * Time.deltaTime : amount;
|
f += multByTime ? amount * Time.deltaTime : amount;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.CodeDom;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -36,13 +34,15 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
// Causes a crash
|
// Causes a crash
|
||||||
"Type.DeclaringMethod",
|
"Type.DeclaringMethod",
|
||||||
|
// Causes a crash
|
||||||
|
"Rigidbody2D.Cast",
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly HashSet<string> _methodStartsWithBlacklist = new HashSet<string>
|
private static readonly HashSet<string> _methodStartsWithBlacklist = new HashSet<string>
|
||||||
{
|
{
|
||||||
// Pointless (handled by Properties)
|
// Pointless (handled by Properties)
|
||||||
"get_",
|
"get_",
|
||||||
"set_"
|
"set_",
|
||||||
};
|
};
|
||||||
|
|
||||||
public override void Init()
|
public override void Init()
|
||||||
@ -161,15 +161,13 @@ namespace Explorer
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check blacklisted members
|
// check blacklisted members
|
||||||
var name = member.DeclaringType.Name + "." + member.Name;
|
var sig = $"{member.DeclaringType.Name}.{member.Name}";
|
||||||
if (_typeAndMemberBlacklist.Any(it => it == name))
|
if (_typeAndMemberBlacklist.Any(it => it == sig))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_methodStartsWithBlacklist.Any(it => member.Name.StartsWith(it)))
|
if (_methodStartsWithBlacklist.Any(it => member.Name.StartsWith(it)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// compare signature to already cached members
|
|
||||||
var signature = $"{member.DeclaringType.Name}.{member.Name}";
|
|
||||||
if (member is MethodInfo mi)
|
if (member is MethodInfo mi)
|
||||||
{
|
{
|
||||||
AppendParams(mi.GetParameters());
|
AppendParams(mi.GetParameters());
|
||||||
@ -181,32 +179,34 @@ namespace Explorer
|
|||||||
|
|
||||||
void AppendParams(ParameterInfo[] _args)
|
void AppendParams(ParameterInfo[] _args)
|
||||||
{
|
{
|
||||||
signature += " (";
|
sig += " (";
|
||||||
foreach (var param in _args)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MelonLogger.Log($"Trying to cache member {signature}...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cached = CacheObjectBase.GetCacheObject(member, target);
|
var cached = CacheObjectBase.GetCacheObject(member, target);
|
||||||
if (cached != null)
|
if (cached != null)
|
||||||
{
|
{
|
||||||
cachedSigs.Add(signature);
|
cachedSigs.Add(sig);
|
||||||
list.Add(cached);
|
list.Add(cached);
|
||||||
cached.ReflectionException = exception;
|
cached.ReflectionException = exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
MelonLogger.LogWarning($"Exception caching member {signature}!");
|
MelonLogger.LogWarning($"Exception caching member {sig}!");
|
||||||
MelonLogger.Log(e.ToString());
|
MelonLogger.Log(e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ namespace Explorer
|
|||||||
if (!WindowManager.TabView)
|
if (!WindowManager.TabView)
|
||||||
{
|
{
|
||||||
Header();
|
Header();
|
||||||
GUILayout.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
@ -354,7 +354,7 @@ namespace Explorer
|
|||||||
{
|
{
|
||||||
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
m_rect = ResizeDrag.ResizeWindow(rect, windowID);
|
||||||
|
|
||||||
GUILayout.EndArea();
|
GUIUnstrip.EndArea();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Il2CppException e)
|
catch (Il2CppException e)
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -65,7 +59,7 @@ namespace Explorer
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUILayout.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
|
GUIUnstrip.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
|
||||||
|
|
||||||
GUILayout.BeginVertical(GUI.skin.box, null);
|
GUILayout.BeginVertical(GUI.skin.box, null);
|
||||||
GUILayout.BeginHorizontal(null);
|
GUILayout.BeginHorizontal(null);
|
||||||
@ -109,7 +103,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
GUILayout.EndArea();
|
GUIUnstrip.EndArea();
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Harmony;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnhollowerBaseLib;
|
|
||||||
using UnhollowerRuntimeLib;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Harmony;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnhollowerBaseLib;
|
|
||||||
using UnhollowerRuntimeLib;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
|
||||||
using UnityEngine.EventSystems;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
using System;
|
using System.Collections;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
// used to test multiple generic constraints
|
||||||
|
public class TestGeneric : IComparable<string>
|
||||||
|
{
|
||||||
|
public TestGeneric() { }
|
||||||
|
|
||||||
|
public int CompareTo(string other) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
namespace Explorer.Tests
|
namespace Explorer.Tests
|
||||||
{
|
{
|
||||||
public class TestClass
|
public class TestClass
|
||||||
@ -22,6 +26,53 @@ namespace Explorer.Tests
|
|||||||
ILHashSetTest.Add("3");
|
ILHashSetTest.Add("3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// test HashSets
|
||||||
|
|
||||||
public static HashSet<string> HashSetTest = new HashSet<string>
|
public static HashSet<string> HashSetTest = new HashSet<string>
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
using System;
|
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 System.Reflection;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnhollowerRuntimeLib;
|
||||||
|
using UnityEngine;
|
||||||
using UnityEngineInternal;
|
using UnityEngineInternal;
|
||||||
using Harmony;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
@ -20,34 +14,43 @@ namespace Explorer
|
|||||||
public static bool ScrollFailed = false;
|
public static bool ScrollFailed = false;
|
||||||
public static bool ManualUnstripFailed = false;
|
public static bool ManualUnstripFailed = false;
|
||||||
|
|
||||||
private static GenericStack ScrollStack
|
private static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_scrollViewStatesInfo == null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_scrollViewStatesInfo = typeof(GUI).GetProperty("scrollViewStates");
|
|
||||||
if (m_scrollViewStatesInfo == null) throw new Exception();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
m_scrollViewStatesInfo = typeof(GUI).GetProperty("s_scrollViewStates");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (GenericStack)m_scrollViewStatesInfo?.GetValue(null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static PropertyInfo m_scrollViewStatesInfo;
|
private static PropertyInfo m_scrollViewStatesInfo;
|
||||||
|
private static GenericStack m_scrollStack;
|
||||||
|
|
||||||
|
public static DateTime nextScrollStepTime;
|
||||||
|
|
||||||
|
private static GenericStack GetScrollStack()
|
||||||
|
{
|
||||||
|
if (m_scrollViewStatesInfo == null)
|
||||||
|
{
|
||||||
|
if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo)
|
||||||
|
{
|
||||||
|
m_scrollViewStatesInfo = scrollStatesInfo;
|
||||||
|
}
|
||||||
|
else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo)
|
||||||
|
{
|
||||||
|
m_scrollViewStatesInfo = s_scrollStatesInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack)
|
||||||
|
{
|
||||||
|
m_scrollStack = stack;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_scrollStack = new GenericStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_scrollStack;
|
||||||
|
}
|
||||||
|
|
||||||
public static void Space(float pixels)
|
public static void Space(float pixels)
|
||||||
{
|
{
|
||||||
GUIUtility.CheckOnGUI();
|
GUIUtility.CheckOnGUI();
|
||||||
|
|
||||||
if (GUILayoutUtility.current.topLevel.isVertical)
|
if (GUILayoutUtility.current.topLevel.isVertical)
|
||||||
|
|
||||||
LayoutUtilityUnstrip.GetRect(0, pixels, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
|
LayoutUtilityUnstrip.GetRect(0, pixels, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
|
||||||
else
|
else
|
||||||
LayoutUtilityUnstrip.GetRect(pixels, 0, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
|
LayoutUtilityUnstrip.GetRect(pixels, 0, GUILayoutUtility.spaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
|
||||||
@ -58,6 +61,90 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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); }
|
||||||
|
static public void BeginArea(Rect screenRect, Texture image) { BeginArea(screenRect, GUIContent.Temp(image), GUIStyle.none); }
|
||||||
|
static public void BeginArea(Rect screenRect, GUIContent content) { BeginArea(screenRect, content, GUIStyle.none); }
|
||||||
|
static public void BeginArea(Rect screenRect, GUIStyle style) { BeginArea(screenRect, GUIContent.none, style); }
|
||||||
|
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>());
|
||||||
|
if (Event.current.type == EventType.Layout)
|
||||||
|
{
|
||||||
|
g.resetCoords = true;
|
||||||
|
g.minWidth = g.maxWidth = screenRect.width;
|
||||||
|
g.minHeight = g.maxHeight = screenRect.height;
|
||||||
|
g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI.BeginGroup(g.rect, content, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close a GUILayout block started with BeginArea
|
||||||
|
static public void EndArea()
|
||||||
|
{
|
||||||
|
if (Event.current.type == EventType.Used)
|
||||||
|
return;
|
||||||
|
GUILayoutUtility.current.layoutGroups.Pop();
|
||||||
|
GUILayoutUtility.current.topLevel = GUILayoutUtility.current.layoutGroups.Peek().TryCast<GUILayoutGroup>();
|
||||||
|
GUI.EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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); }
|
||||||
|
public static void BeginGroup(Rect position, Texture image) { BeginGroup(position, GUIContent.Temp(image), GUIStyle.none); }
|
||||||
|
public static void BeginGroup(Rect position, GUIContent content) { BeginGroup(position, content, GUIStyle.none); }
|
||||||
|
public static void BeginGroup(Rect position, GUIStyle style) { BeginGroup(position, GUIContent.none, style); }
|
||||||
|
public static void BeginGroup(Rect position, string text, GUIStyle style) { BeginGroup(position, GUIContent.Temp(text), style); }
|
||||||
|
public static void BeginGroup(Rect position, Texture image, GUIStyle style) { BeginGroup(position, GUIContent.Temp(image), style); }
|
||||||
|
|
||||||
|
public static void BeginGroup(Rect position, GUIContent content, GUIStyle style) { BeginGroup(position, content, style, Vector2.zero); }
|
||||||
|
|
||||||
|
internal static void BeginGroup(Rect position, GUIContent content, GUIStyle style, Vector2 scrollOffset)
|
||||||
|
{
|
||||||
|
int id = GUIUtility.GetControlID(GUI.s_BeginGroupHash, FocusType.Passive);
|
||||||
|
|
||||||
|
if (content != GUIContent.none || style != GUIStyle.none)
|
||||||
|
{
|
||||||
|
switch (Event.current.type)
|
||||||
|
{
|
||||||
|
case EventType.Repaint:
|
||||||
|
style.Draw(position, content, id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (position.Contains(Event.current.mousePosition))
|
||||||
|
GUIUtility.mouseUsed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUIClip.Push(position, scrollOffset, Vector2.zero, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EndGroup()
|
||||||
|
{
|
||||||
|
GUIClip.Internal_Pop();
|
||||||
|
}
|
||||||
|
|
||||||
// Fix for BeginScrollView.
|
// Fix for BeginScrollView.
|
||||||
|
|
||||||
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
|
||||||
@ -112,8 +199,6 @@ namespace Explorer
|
|||||||
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
private static Vector2 BeginScrollView_ImplLayout(Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical,
|
||||||
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options)
|
||||||
{
|
{
|
||||||
GUIUtility.CheckOnGUI();
|
|
||||||
|
|
||||||
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<GUIScrollGroup>())
|
var guiscrollGroup = GUILayoutUtility.BeginLayoutGroup(background, null, Il2CppType.Of<GUIScrollGroup>())
|
||||||
.TryCast<GUIScrollGroup>();
|
.TryCast<GUIScrollGroup>();
|
||||||
|
|
||||||
@ -145,7 +230,7 @@ namespace Explorer
|
|||||||
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
private static Vector2 BeginScrollView_Impl(Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal,
|
||||||
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background)
|
||||||
{
|
{
|
||||||
GUIUtility.CheckOnGUI();
|
// GUIUtility.CheckOnGUI();
|
||||||
|
|
||||||
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
|
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
|
||||||
|
|
||||||
@ -388,12 +473,12 @@ namespace Explorer
|
|||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
GUI.nextScrollStepTime = Il2CppSystem.DateTime.Now.AddMilliseconds(250.0);
|
nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||||
}
|
}
|
||||||
else if (Il2CppSystem.DateTime.Now >= GUI.nextScrollStepTime)
|
else if (DateTime.Now >= nextScrollStepTime)
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
GUI.nextScrollStepTime = Il2CppSystem.DateTime.Now.AddMilliseconds(30.0);
|
nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||||
}
|
}
|
||||||
if (Event.current.type == EventType.Repaint)
|
if (Event.current.type == EventType.Repaint)
|
||||||
{
|
{
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Harmony;
|
|
||||||
using MelonLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
public struct SliderHandlerUnstrip
|
public struct SliderHandlerUnstrip
|
||||||
{
|
{
|
||||||
private readonly Rect position;
|
private readonly Rect position;
|
||||||
private readonly float currentValue;
|
private readonly float currentValue;
|
||||||
@ -81,7 +77,7 @@ namespace Explorer
|
|||||||
if (this.SupportsPageMovements())
|
if (this.SupportsPageMovements())
|
||||||
{
|
{
|
||||||
this.SliderState().isDragging = false;
|
this.SliderState().isDragging = false;
|
||||||
GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(250.0);
|
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
|
||||||
GUI.scrollTroughSide = this.CurrentScrollTroughSide();
|
GUI.scrollTroughSide = this.CurrentScrollTroughSide();
|
||||||
result = this.PageMovementValue();
|
result = this.PageMovementValue();
|
||||||
}
|
}
|
||||||
@ -155,7 +151,7 @@ namespace Explorer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.InternalRepaintEditorWindow();
|
GUI.InternalRepaintEditorWindow();
|
||||||
if (SystemClock.now < GUI.nextScrollStepTime)
|
if (DateTime.Now < GUIUnstrip.nextScrollStepTime)
|
||||||
{
|
{
|
||||||
result = this.currentValue;
|
result = this.currentValue;
|
||||||
}
|
}
|
||||||
@ -165,7 +161,7 @@ namespace Explorer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(30.0);
|
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
|
||||||
if (this.SupportsPageMovements())
|
if (this.SupportsPageMovements())
|
||||||
{
|
{
|
||||||
this.SliderState().isDragging = false;
|
this.SliderState().isDragging = false;
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
using System;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Explorer
|
namespace Explorer
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user