Compare commits

..

11 Commits
1.7.0 ... 1.7.1

14 changed files with 232 additions and 113 deletions

View File

@ -1,7 +1,7 @@
# CppExplorer [![Version](https://img.shields.io/badge/MelonLoader-0.2.7.1-green.svg)](https://github.com/HerpDerpinstine/MelonLoader) # CppExplorer [![Version](https://img.shields.io/badge/MelonLoader-0.2.7.1-green.svg)](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,6 +13,9 @@
<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
* 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. * 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.
@ -23,7 +26,7 @@
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.

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
lib/mcs.NET35.dll Normal file

Binary file not shown.

View File

@ -244,7 +244,6 @@ 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 (!string.IsNullOrEmpty(input)) if (!string.IsNullOrEmpty(input))
{ {
// strings can obviously just be used directly // strings can obviously just be used directly
@ -417,21 +416,17 @@ namespace Explorer
} }
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;

View File

@ -13,7 +13,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.1";
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 +36,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 +56,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;

View File

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

View File

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

View File

@ -58,7 +58,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);
} }
} }

View File

@ -12,10 +12,12 @@ 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 bool m_hideControls;
// gui element holders // gui element holders
private string m_name; private string m_name;
@ -23,11 +25,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 +44,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 +54,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 +75,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 +89,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 +120,7 @@ namespace Explorer
} }
} }
if (!m_object && !GetObjectAsGameObject()) if (!TargetGO && !GetObjectAsGameObject())
{ {
throw new Exception("Object is null!"); throw new Exception("Object is null!");
} }
@ -127,22 +129,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 +153,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 +184,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 +212,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 +223,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 +235,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 +272,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 +362,28 @@ namespace Explorer
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(null);
m_addComponentInput = GUILayout.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(130) });
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 +463,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 +518,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 +528,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 +543,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 +585,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 +597,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 +630,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:

View File

@ -36,13 +36,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()
@ -194,6 +196,8 @@ namespace Explorer
continue; continue;
} }
// MelonLogger.Log($"Trying to cache member {signature}...");
try try
{ {
var cached = CacheObjectBase.GetCacheObject(member, target); var cached = CacheObjectBase.GetCacheObject(member, target);
@ -228,7 +232,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 +358,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)

View File

@ -65,7 +65,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 +109,7 @@ namespace Explorer
} }
catch { } catch { }
GUILayout.EndArea(); GUIUnstrip.EndArea();
} }
catch { } catch { }
} }

View File

@ -8,7 +8,6 @@ using UnhollowerBaseLib;
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace Explorer namespace Explorer
{ {

View File

@ -20,34 +20,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();
{ private static PropertyInfo m_scrollViewStatesInfo;
get private static GenericStack m_scrollStack;
public static DateTime nextScrollStepTime;
private static GenericStack GetScrollStack()
{ {
if (m_scrollViewStatesInfo == null) if (m_scrollViewStatesInfo == null)
{ {
try if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo)
{ {
m_scrollViewStatesInfo = typeof(GUI).GetProperty("scrollViewStates"); m_scrollViewStatesInfo = scrollStatesInfo;
if (m_scrollViewStatesInfo == null) throw new Exception();
} }
catch else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo)
{ {
m_scrollViewStatesInfo = typeof(GUI).GetProperty("s_scrollViewStates"); m_scrollViewStatesInfo = s_scrollStatesInfo;
} }
} }
return (GenericStack)m_scrollViewStatesInfo?.GetValue(null, null); if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack)
{
m_scrollStack = stack;
} }
else
{
m_scrollStack = new GenericStack();
}
return m_scrollStack;
} }
private static PropertyInfo m_scrollViewStatesInfo;
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 +67,78 @@ namespace Explorer
} }
} }
// 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 +193,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 +224,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 +467,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)
{ {

View File

@ -81,7 +81,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 +155,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 +165,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;