Compare commits

..

25 Commits
2.0.0 ... 2.1.0

Author SHA1 Message Date
f4ba14cd13 2.1.0
* Fix a bug with Il2Cpp reflection causing TargetInvocationException and other weird issues.
2020-10-30 19:24:42 +11:00
4263cef26a Update ExplorerCore.cs 2020-10-28 20:49:53 +11:00
626e680510 2.0.9
* Fix an issue in mono builds causing a crash
* Fix for games which only contain one scene
* A few small cleanups
2020-10-28 20:49:18 +11:00
7c85969085 Update ExplorerCore.cs 2020-10-24 15:46:11 +11:00
1fce3465c2 Fix bug in ForceUnlockCursor, fix mistake in Reflection Inspector, reduced amount casting with Reflection Inspector 2020-10-24 15:45:37 +11:00
8949e3dc7d Revert "some early steps remaking the GUI with UnityEngine.UI, working in all tested game so far"
This reverts commit 4280a071f6.
2020-10-23 01:48:18 +11:00
4280a071f6 some early steps remaking the GUI with UnityEngine.UI, working in all tested game so far 2020-10-23 01:48:00 +11:00
48ed78ec36 A few small fixes 2020-10-22 21:00:33 +11:00
3c964cfef9 2.0.7
* More unstripping fixes. Explorer now works 100% on a blank Unity project (so should therefore work on any Unity game, regardless of stripping).
* Some cleanups
2020-10-18 21:41:04 +11:00
184b037523 Update ReflectionHelpers.cs 2020-10-18 04:46:50 +11:00
a49a918790 faster il2cpp cast, a few cleanups 2020-10-18 04:39:50 +11:00
e3a58bf675 Update CacheMember.cs 2020-10-17 22:00:53 +11:00
cc29dbda30 Update ReflectionInspector.cs 2020-10-16 20:20:36 +11:00
bc0ad5eab6 refactored icalls using icall helper 2020-10-16 19:40:01 +11:00
bdf86a7448 2.0.6 2020-10-14 20:55:44 +11:00
968546d43c 2.0.6
* Unstrip fixes and cleanups
2020-10-14 20:47:19 +11:00
680556d74e Update README.md 2020-10-12 20:23:21 +11:00
f490203b10 2.0.5
* Added Max Results option to Search (default 5000)
* Fixed a TypeInitializationException which can happen when inspecting some classes with Dictionary members
* Fixed an issue which could prevent Input support from initializating
* Improved and fixed the display of TextAsset objects
* A few other minor fixes
2020-10-12 20:15:41 +11:00
39d9585f1d 2.0.4
* Added ability to see and change the layer of a gameobject from the GameObject inspector more easily, and shows you the actual layer name (where possible).
* Fixed an issue related to the recently-added clickthrough prevention and resize drag
* Fixed write-only properties in the inspector
* A few other minor fixes
2020-10-11 22:57:46 +11:00
2d414e544b Update README.md 2020-10-11 20:52:08 +11:00
513fcaa534 Universal click-through prevention attempt 2020-10-11 20:49:14 +11:00
b41f7211e5 2.0.3
* Fixed a few issues related to the Texture2D support/export.
2020-10-11 20:07:23 +11:00
dd6cce1df1 2.0.2 2020-10-10 20:20:10 +11:00
ad54d2c76b 2.0.2
* Added support for viewing Texture2D (and Sprite) from the Inspector, and exporting them to PNG
* Fixed an issue with generic methods not showing their return value type
* Fixed an issue where destroyed UnityEngine.Objects would cause issues in the inspector
* Fixed an issue when caching a ValueCollection of a Dictionary (the generic argument for the Entry Type is the last arg, not the first as with other Enumerables)
2020-10-10 20:19:56 +11:00
867370ccee 2.0.1
* Added unstrip fix for GetRootSceneObjects using Il2CPP internal call
2020-10-09 21:11:15 +11:00
65 changed files with 4220 additions and 1537 deletions

View File

@ -80,9 +80,14 @@ There is a simple Mod Config for the Explorer. You can access the settings via t
`Enable Tab View` (bool) | Default: `true` `Enable Tab View` (bool) | Default: `true`
* Whether or not all inspector windows a grouped into a single window with tabs. * Whether or not all inspector windows a grouped into a single window with tabs.
`Default Output Path` (string) | Default: `Mods\Explorer`
* Where output is generated to, by default (for Texture PNG saving, etc).
## Mouse Control ## Mouse Control
Explorer can force the mouse to be visible and unlocked when the menu is open, if you have enabled "Force Unlock Mouse" (Left-Alt toggle). However, you may also want to prevent the mouse clicking-through onto the game behind Explorer, this is possible but it requires specific patches for that game. Explorer can force the mouse to be visible and unlocked when the menu is open, if you have enabled "Force Unlock Mouse" (Left-Alt toggle). Explorer also attempts to prevent clicking-through onto the game behind the Explorer menu.
If you need more mouse control:
* For VRChat, use [VRCExplorerMouseControl](https://github.com/sinai-dev/VRCExplorerMouseControl) * For VRChat, use [VRCExplorerMouseControl](https://github.com/sinai-dev/VRCExplorerMouseControl)
* 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)
@ -93,8 +98,9 @@ For example:
using Explorer; using Explorer;
using Harmony; // or 'using HarmonyLib;' for BepInEx using Harmony; // or 'using HarmonyLib;' for BepInEx
// ... // ...
[HarmonyPatch(typeof(MyGame.MenuClass), nameof(MyGame.MenuClass.CursorUpdate)] // You will need to figure out the relevant Class and Method for your game using dnSpy.
public class MenuClass_CursorUpdate [HarmonyPatch(typeof(MyGame.InputManager), nameof(MyGame.InputManager.Update))]
public class InputManager_Update
{ {
[HarmonyPrefix] [HarmonyPrefix]
public static bool Prefix() public static bool Prefix()

View File

@ -2,6 +2,7 @@
using System.Reflection; using System.Reflection;
using Explorer.CacheObject; using Explorer.CacheObject;
using UnityEngine; using UnityEngine;
using Explorer.Helpers;
namespace Explorer namespace Explorer
{ {

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Reflection; using System.Reflection;
using Explorer.UI;
using Explorer.Helpers;
namespace Explorer.CacheObject namespace Explorer.CacheObject
{ {
@ -21,6 +23,15 @@ namespace Explorer.CacheObject
public override void UpdateValue() public override void UpdateValue()
{ {
if (IValue is InteractiveDictionary iDict)
{
if (!iDict.EnsureDictionaryIsSupported())
{
ReflectionException = "Not supported due to TypeInitializationException";
return;
}
}
try try
{ {
var fi = MemInfo as FieldInfo; var fi = MemInfo as FieldInfo;
@ -38,8 +49,6 @@ namespace Explorer.CacheObject
{ {
var fi = MemInfo as FieldInfo; var fi = MemInfo as FieldInfo;
fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value); fi.SetValue(fi.IsStatic ? null : DeclaringInstance, IValue.Value);
base.SetValue();
} }
} }
} }

View File

@ -53,7 +53,7 @@ namespace Explorer.CacheObject
{ {
if (m_arguments.Length < 1) if (m_arguments.Length < 1)
{ {
return null; return new object[0];
} }
var parsedArgs = new List<object>(); var parsedArgs = new List<object>();
@ -123,13 +123,15 @@ namespace Explorer.CacheObject
label = $"<i>[{label} = {this.m_arguments[i].DefaultValue ?? "null"}]</i>"; label = $"<i>[{label} = {this.m_arguments[i].DefaultValue ?? "null"}]</i>";
} }
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) }); GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) });
this.m_argumentInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); GUILayout.Label(label, new GUILayoutOption[] { GUIHelper.ExpandWidth(false) });
this.m_argumentInput[i] = GUIHelper.TextField(input, new GUILayoutOption[] { GUIHelper.ExpandWidth(true) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(label, new GUILayoutOption[0]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.Helpers;
namespace Explorer.CacheObject namespace Explorer.CacheObject
{ {
@ -73,7 +74,7 @@ namespace Explorer.CacheObject
if (ret != null) if (ret != null)
{ {
//m_cachedReturnValue = CacheFactory.GetTypeAndCacheObject(ret); //m_cachedReturnValue = CacheFactory.GetTypeAndCacheObject(ret);
m_cachedReturnValue = CacheFactory.GetCacheObject(ret, IValue.ValueType); m_cachedReturnValue = CacheFactory.GetCacheObject(ret);
m_cachedReturnValue.UpdateValue(); m_cachedReturnValue.UpdateValue();
} }
else else
@ -181,14 +182,14 @@ namespace Explorer.CacheObject
} }
var input = this.GenericArgInput[i]; var input = this.GenericArgInput[i];
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label( GUILayout.Label(
$"<color={Syntax.StructGreen}>{this.GenericArgs[i].Name}</color>", $"<color={Syntax.StructGreen}>{this.GenericArgs[i].Name}</color>",
new GUILayoutOption[] { GUILayout.Width(15) } new GUILayoutOption[] { GUILayout.Width(15) }
); );
this.GenericArgInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) }); this.GenericArgInput[i] = GUIHelper.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUILayout.Label(types, new GUILayoutOption[0]); GUILayout.Label(types, new GUILayoutOption[0]);

View File

@ -5,6 +5,7 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI; using Explorer.UI;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.Helpers;
namespace Explorer.CacheObject namespace Explorer.CacheObject
{ {
@ -25,12 +26,26 @@ namespace Explorer.CacheObject
return; return;
} }
//ExplorerCore.Log("Initializing InteractiveValue of type " + valueType.FullName);
InteractiveValue interactive; InteractiveValue interactive;
if (valueType == typeof(GameObject) || valueType == typeof(Transform)) if (valueType == typeof(GameObject) || valueType == typeof(Transform))
{ {
interactive = new InteractiveGameObject(); interactive = new InteractiveGameObject();
} }
else if (valueType == typeof(Texture2D))
{
interactive = new InteractiveTexture2D();
}
else if (valueType == typeof(Texture))
{
interactive = new InteractiveTexture();
}
else if (valueType == typeof(Sprite))
{
interactive = new InteractiveSprite();
}
else if (valueType.IsPrimitive || valueType == typeof(string)) else if (valueType.IsPrimitive || valueType == typeof(string))
{ {
interactive = new InteractivePrimitive(); interactive = new InteractivePrimitive();

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Reflection; using System.Reflection;
using Explorer.UI;
using Explorer.Helpers;
namespace Explorer.CacheObject namespace Explorer.CacheObject
{ {
@ -32,15 +34,39 @@ namespace Explorer.CacheObject
return; return;
} }
if (IValue is InteractiveDictionary iDict)
{
if (!iDict.EnsureDictionaryIsSupported())
{
ReflectionException = "Not supported due to TypeInitializationException";
return;
}
}
try try
{ {
var pi = MemInfo as PropertyInfo; var pi = MemInfo as PropertyInfo;
if (pi.CanRead)
{
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance; var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
IValue.Value = pi.GetValue(target, ParseArguments()); IValue.Value = pi.GetValue(target, ParseArguments());
base.UpdateValue(); base.UpdateValue();
} }
else // create a dummy value for Write-Only properties.
{
if (IValue.ValueType == typeof(string))
{
IValue.Value = "";
}
else
{
IValue.Value = Activator.CreateInstance(IValue.ValueType);
}
}
}
catch (Exception e) catch (Exception e)
{ {
ReflectionException = ReflectionHelpers.ExceptionToString(e); ReflectionException = ReflectionHelpers.ExceptionToString(e);
@ -53,8 +79,6 @@ namespace Explorer.CacheObject
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance; var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
pi.SetValue(target, IValue.Value, ParseArguments()); pi.SetValue(target, IValue.Value, ParseArguments());
base.SetValue();
} }
} }
} }

View File

@ -19,7 +19,7 @@ namespace Explorer.Config
public int Default_Page_Limit = 20; public int Default_Page_Limit = 20;
public bool Bitwise_Support = false; public bool Bitwise_Support = false;
public bool Tab_View = true; public bool Tab_View = true;
//public bool Main_Toggle_Global = true; public string Default_Output_Path = @"Mods\Explorer";
public static void OnLoad() public static void OnLoad()
{ {

View File

@ -25,7 +25,7 @@
<RootNamespace>Explorer</RootNamespace> <RootNamespace>Explorer</RootNamespace>
<AssemblyName>Explorer</AssemblyName> <AssemblyName>Explorer</AssemblyName>
<!-- Set this to the MelonLoader Il2Cpp Game folder, without the ending '\' character. --> <!-- Set this to the MelonLoader Il2Cpp Game folder, without the ending '\' character. -->
<MLCppGameFolder>D:\Steam\steamapps\common\Hellpoint</MLCppGameFolder> <MLCppGameFolder>D:\Steam\steamapps\common\VRChat</MLCppGameFolder>
<!-- Set this to the MelonLoader Mono Game folder, without the ending '\' character. --> <!-- Set this to the MelonLoader Mono Game folder, without the ending '\' character. -->
<MLMonoGameFolder>D:\Steam\steamapps\common\Outward</MLMonoGameFolder> <MLMonoGameFolder>D:\Steam\steamapps\common\Outward</MLMonoGameFolder>
<!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. --> <!-- Set this to the BepInEx Il2Cpp Game folder, without the ending '\' character. -->
@ -41,6 +41,7 @@
<DefineConstants>CPP,ML</DefineConstants> <DefineConstants>CPP,ML</DefineConstants>
<IsCpp>true</IsCpp> <IsCpp>true</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_ML_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
@ -49,6 +50,7 @@
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>true</IsMelonLoader> <IsMelonLoader>true</IsMelonLoader>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Cpp|AnyCPU' ">
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
@ -56,6 +58,7 @@
<DefineConstants>CPP,BIE</DefineConstants> <DefineConstants>CPP,BIE</DefineConstants>
<IsCpp>true</IsCpp> <IsCpp>true</IsCpp>
<IsMelonLoader>false</IsMelonLoader> <IsMelonLoader>false</IsMelonLoader>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release_BIE_Mono|AnyCPU' ">
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
@ -63,6 +66,7 @@
<DefineConstants>MONO,BIE</DefineConstants> <DefineConstants>MONO,BIE</DefineConstants>
<IsCpp>false</IsCpp> <IsCpp>false</IsCpp>
<IsMelonLoader>false</IsMelonLoader> <IsMelonLoader>false</IsMelonLoader>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
@ -204,10 +208,14 @@
<Compile Include="CacheObject\CacheMethod.cs" /> <Compile Include="CacheObject\CacheMethod.cs" />
<Compile Include="CacheObject\CacheProperty.cs" /> <Compile Include="CacheObject\CacheProperty.cs" />
<Compile Include="CacheObject\CacheObjectBase.cs" /> <Compile Include="CacheObject\CacheObjectBase.cs" />
<Compile Include="Helpers\Texture2DHelpers.cs" />
<Compile Include="UI\InteractiveValue\InteractiveValue.cs" /> <Compile Include="UI\InteractiveValue\InteractiveValue.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveDictionary.cs" /> <Compile Include="UI\InteractiveValue\Object\InteractiveDictionary.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveEnumerable.cs" /> <Compile Include="UI\InteractiveValue\Object\InteractiveEnumerable.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveGameObject.cs" /> <Compile Include="UI\InteractiveValue\Object\InteractiveGameObject.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveSprite.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveTexture.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveTexture2D.cs" />
<Compile Include="UI\InteractiveValue\Struct\InteractiveQuaternion.cs" /> <Compile Include="UI\InteractiveValue\Struct\InteractiveQuaternion.cs" />
<Compile Include="UI\InteractiveValue\Struct\InteractiveRect.cs" /> <Compile Include="UI\InteractiveValue\Struct\InteractiveRect.cs" />
<Compile Include="UI\InteractiveValue\Struct\InteractiveVector.cs" /> <Compile Include="UI\InteractiveValue\Struct\InteractiveVector.cs" />
@ -223,14 +231,13 @@
<Compile Include="Extensions\UnityExtensions.cs" /> <Compile Include="Extensions\UnityExtensions.cs" />
<Compile Include="Helpers\ReflectionHelpers.cs" /> <Compile Include="Helpers\ReflectionHelpers.cs" />
<Compile Include="Helpers\UnityHelpers.cs" /> <Compile Include="Helpers\UnityHelpers.cs" />
<Compile Include="Input\AbstractInput.cs" /> <Compile Include="Input\IAbstractInput.cs" />
<Compile Include="Tests\TestClass.cs" /> <Compile Include="Tests\TestClass.cs" />
<Compile Include="UI\ForceUnlockCursor.cs" /> <Compile Include="UI\ForceUnlockCursor.cs" />
<Compile Include="Input\InputManager.cs" /> <Compile Include="Input\InputManager.cs" />
<Compile Include="Input\InputSystem.cs" /> <Compile Include="Input\InputSystem.cs" />
<Compile Include="Input\LegacyInput.cs" /> <Compile Include="Input\LegacyInput.cs" />
<Compile Include="Input\NoInput.cs" /> <Compile Include="Input\NoInput.cs" />
<Compile Include="Tests\TestClass.cs" />
<Compile Include="UI\Inspectors\InspectUnderMouse.cs" /> <Compile Include="UI\Inspectors\InspectUnderMouse.cs" />
<Compile Include="UI\Inspectors\Reflection\InstanceInspector.cs" /> <Compile Include="UI\Inspectors\Reflection\InstanceInspector.cs" />
<Compile Include="UI\Inspectors\ReflectionInspector.cs" /> <Compile Include="UI\Inspectors\ReflectionInspector.cs" />
@ -254,13 +261,20 @@
<Compile Include="UI\TabViewWindow.cs" /> <Compile Include="UI\TabViewWindow.cs" />
<Compile Include="UI\WindowBase.cs" /> <Compile Include="UI\WindowBase.cs" />
<Compile Include="UI\WindowManager.cs" /> <Compile Include="UI\WindowManager.cs" />
<Compile Include="UnstripFixes\GUIUnstrip.cs" /> <Compile Include="Unstrip\ImageConversion\ImageConversionUnstrip.cs" />
<Compile Include="UnstripFixes\Internal_LayoutUtility.cs" /> <Compile Include="Unstrip\IMGUI\GUIUtilityUnstrip.cs" />
<Compile Include="UnstripFixes\Internal_ScrollViewState.cs" /> <Compile Include="Unstrip\IMGUI\TextEditorUnstrip.cs" />
<Compile Include="UnstripFixes\Internal_SliderHandler.cs" /> <Compile Include="Helpers\ICallHelper.cs" />
<Compile Include="Unstrip\LayerMask\LayerMaskUnstrip.cs" />
<Compile Include="Unstrip\Resources\ResourcesUnstrip.cs" />
<Compile Include="Unstrip\Scene\SceneUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\GUIHelper.cs" />
<Compile Include="Unstrip\IMGUI\LayoutUtilityUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\ScrollViewStateUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\SliderHandlerUnstrip.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UnstripFixes\Internal.cs" /> <Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" />
<Compile Include="UnstripFixes\Internal_SliderState.cs" /> <Compile Include="Unstrip\IMGUI\SliderStateUnstrip.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ILRepack.targets" /> <None Include="ILRepack.targets" />

View File

@ -1,4 +1,6 @@
using Explorer.Config; using System.Collections;
using System.Linq;
using Explorer.Config;
using Explorer.UI; using Explorer.UI;
using Explorer.UI.Inspectors; using Explorer.UI.Inspectors;
using Explorer.UI.Main; using Explorer.UI.Main;
@ -10,7 +12,7 @@ namespace Explorer
public class ExplorerCore public class ExplorerCore
{ {
public const string NAME = "Explorer " + VERSION + " (" + PLATFORM + ", " + MODLOADER + ")"; public const string NAME = "Explorer " + VERSION + " (" + PLATFORM + ", " + MODLOADER + ")";
public const string VERSION = "2.0.0"; public const string VERSION = "2.1.0";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.explorer"; public const string GUID = "com.sinai.explorer";
@ -31,6 +33,12 @@ namespace Explorer
public ExplorerCore() public ExplorerCore()
{ {
if (Instance != null)
{
Log("An instance of Explorer is already active!");
return;
}
Instance = this; Instance = this;
ModConfig.OnLoad(); ModConfig.OnLoad();
@ -68,7 +76,7 @@ namespace Explorer
if (ShowMenu) if (ShowMenu)
{ {
//CursorControl.Update(); ForceUnlockCursor.Update();
InspectUnderMouse.Update(); InspectUnderMouse.Update();
MainMenu.Instance.Update(); MainMenu.Instance.Update();
@ -87,6 +95,11 @@ namespace Explorer
WindowManager.Instance.OnGUI(); WindowManager.Instance.OnGUI();
InspectUnderMouse.OnGUI(); InspectUnderMouse.OnGUI();
if (!ResizeDrag.IsMouseInResizeArea && WindowManager.IsMouseInWindow)
{
InputManager.ResetInputAxes();
}
GUI.skin = origSkin; GUI.skin = origSkin;
} }
@ -99,27 +112,27 @@ namespace Explorer
public static void Log(object message) public static void Log(object message)
{ {
#if ML #if ML
MelonLoader.MelonLogger.Log(message.ToString()); MelonLoader.MelonLogger.Log(message?.ToString());
#else #else
ExplorerBepInPlugin.Logging?.LogMessage(message.ToString()); ExplorerBepInPlugin.Logging?.LogMessage(message?.ToString());
#endif #endif
} }
public static void LogWarning(object message) public static void LogWarning(object message)
{ {
#if ML #if ML
MelonLoader.MelonLogger.LogWarning(message.ToString()); MelonLoader.MelonLogger.LogWarning(message?.ToString());
#else #else
ExplorerBepInPlugin.Logging?.LogWarning(message.ToString()); ExplorerBepInPlugin.Logging?.LogWarning(message?.ToString());
#endif #endif
} }
public static void LogError(object message) public static void LogError(object message)
{ {
#if ML #if ML
MelonLoader.MelonLogger.LogError(message.ToString()); MelonLoader.MelonLogger.LogError(message?.ToString());
#else #else
ExplorerBepInPlugin.Logging?.LogError(message.ToString()); ExplorerBepInPlugin.Logging?.LogError(message?.ToString());
#endif #endif
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Explorer.Helpers;
namespace Explorer namespace Explorer
{ {

View File

@ -0,0 +1,41 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
namespace Explorer.Helpers
{
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
public static class ICallHelper
{
private static readonly Dictionary<string, Delegate> iCallCache = new Dictionary<string, Delegate>();
public static T GetICall<T>(string iCallName) where T : Delegate
{
if (iCallCache.ContainsKey(iCallName))
{
return (T)iCallCache[iCallName];
}
var ptr = il2cpp_resolve_icall(iCallName);
if (ptr == IntPtr.Zero)
{
throw new MissingMethodException($"Could not resolve internal call by name '{iCallName}'!");
}
var iCall = Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
iCallCache.Add(iCallName, iCall);
return (T)iCall;
}
[DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr il2cpp_resolve_icall([MarshalAs(UnmanagedType.LPStr)] string name);
}
}
#endif

View File

@ -5,15 +5,17 @@ using System.IO;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using BF = System.Reflection.BindingFlags; using BF = System.Reflection.BindingFlags;
using System.Diagnostics.CodeAnalysis;
#if CPP #if CPP
using ILType = Il2CppSystem.Type; using ILType = Il2CppSystem.Type;
using UnhollowerBaseLib; using UnhollowerBaseLib;
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using System.Runtime.InteropServices;
#endif #endif
namespace Explorer namespace Explorer.Helpers
{ {
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "External methods")]
public class ReflectionHelpers public class ReflectionHelpers
{ {
public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static; public static BF CommonFlags = BF.Public | BF.Instance | BF.NonPublic | BF.Static;
@ -24,21 +26,6 @@ namespace Explorer
public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>(); public static ILType ObjectType => Il2CppType.Of<UnityEngine.Object>();
public static ILType ComponentType => Il2CppType.Of<Component>(); public static ILType ComponentType => Il2CppType.Of<Component>();
public static ILType BehaviourType => Il2CppType.Of<Behaviour>(); public static ILType BehaviourType => Il2CppType.Of<Behaviour>();
private static readonly MethodInfo tryCastMethodInfo = typeof(Il2CppObjectBase).GetMethod("TryCast");
private static readonly Dictionary<Type, MethodInfo> cachedTryCastMethods = new Dictionary<Type, MethodInfo>();
public static object Il2CppCast(object obj, Type castTo)
{
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo)) return obj;
if (!cachedTryCastMethods.ContainsKey(castTo))
{
cachedTryCastMethods.Add(castTo, tryCastMethodInfo.MakeGenericMethod(castTo));
}
return cachedTryCastMethods[castTo].Invoke(obj, null);
}
#else #else
public static Type GameObjectType => typeof(GameObject); public static Type GameObjectType => typeof(GameObject);
public static Type TransformType => typeof(Transform); public static Type TransformType => typeof(Transform);
@ -47,51 +34,53 @@ namespace Explorer
public static Type BehaviourType => typeof(Behaviour); public static Type BehaviourType => typeof(Behaviour);
#endif #endif
public static bool IsEnumerable(Type t)
{
if (typeof(IEnumerable).IsAssignableFrom(t))
{
return true;
}
#if CPP #if CPP
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g) private static readonly Dictionary<Type, IntPtr> ClassPointers = new Dictionary<Type, IntPtr>();
public static object Il2CppCast(object obj, Type castTo)
{ {
return typeof(Il2CppSystem.Collections.Generic.List<>).IsAssignableFrom(g) if (!(obj is Il2CppSystem.Object ilObj))
|| typeof(Il2CppSystem.Collections.Generic.IList<>).IsAssignableFrom(g) return obj;
|| typeof(Il2CppSystem.Collections.Generic.HashSet<>).IsAssignableFrom(g);
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(castTo))
return obj as System.Object;
IntPtr castToPtr;
if (!ClassPointers.ContainsKey(castTo))
{
castToPtr = (IntPtr)typeof(Il2CppClassPointerStore<>)
.MakeGenericType(new Type[] { castTo })
.GetField("NativeClassPtr", BF.Public | BF.Static)
.GetValue(null);
ClassPointers.Add(castTo, castToPtr);
} }
else else
{ {
return typeof(Il2CppSystem.Collections.IList).IsAssignableFrom(t); castToPtr = ClassPointers[castTo];
}
#else
return false;
#endif
} }
public static bool IsDictionary(Type t) if (castToPtr == IntPtr.Zero)
{ return obj;
if (typeof(IDictionary).IsAssignableFrom(t))
{ var classPtr = il2cpp_object_get_class(ilObj.Pointer);
return true;
if (!il2cpp_class_is_assignable_from(castToPtr, classPtr))
return obj;
if (RuntimeSpecificsStore.IsInjected(castToPtr))
return UnhollowerBaseLib.Runtime.ClassInjectorBase.GetMonoObjectFromIl2CppPointer(ilObj.Pointer);
return Activator.CreateInstance(castTo, ilObj.Pointer);
} }
#if CPP [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g) public static extern bool il2cpp_class_is_assignable_from(IntPtr klass, IntPtr oklass);
{
return typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).IsAssignableFrom(g) [DllImport("GameAssembly", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|| typeof(Il2CppSystem.Collections.Generic.IDictionary<,>).IsAssignableFrom(g); public static extern IntPtr il2cpp_object_get_class(IntPtr obj);
}
else
{
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
}
#else
return false;
#endif #endif
}
public static Type GetTypeByName(string fullName) public static Type GetTypeByName(string fullName)
{ {
@ -169,48 +158,55 @@ namespace Explorer
return false; return false;
} }
public static bool IsEnumerable(Type t)
{
if (typeof(IEnumerable).IsAssignableFrom(t))
{
return true;
}
#if CPP
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
{
return typeof(Il2CppSystem.Collections.Generic.List<>).IsAssignableFrom(g)
|| typeof(Il2CppSystem.Collections.Generic.IList<>).IsAssignableFrom(g)
|| typeof(Il2CppSystem.Collections.Generic.HashSet<>).IsAssignableFrom(g);
}
else
{
return typeof(Il2CppSystem.Collections.IList).IsAssignableFrom(t);
}
#else
return false;
#endif
}
public static bool IsDictionary(Type t)
{
if (typeof(IDictionary).IsAssignableFrom(t))
{
return true;
}
#if CPP
if (t.IsGenericType && t.GetGenericTypeDefinition() is Type g)
{
return typeof(Il2CppSystem.Collections.Generic.Dictionary<,>).IsAssignableFrom(g)
|| typeof(Il2CppSystem.Collections.Generic.IDictionary<,>).IsAssignableFrom(g);
}
else
{
return typeof(Il2CppSystem.Collections.IDictionary).IsAssignableFrom(t)
|| typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(t);
}
#else
return false;
#endif
}
public static string ExceptionToString(Exception e) public static string ExceptionToString(Exception e)
{ {
#if CPP
if (IsFailedGeneric(e))
{
return "Unable to initialize this type.";
}
else if (IsObjectCollected(e))
{
return "Garbage collected in Il2Cpp.";
}
#endif
return e.GetType() + ", " + e.Message; return e.GetType() + ", " + e.Message;
} }
#if CPP
public static bool IsFailedGeneric(Exception e)
{
return IsExceptionOfType(e, typeof(TargetInvocationException)) && IsExceptionOfType(e, typeof(TypeLoadException));
}
public static bool IsObjectCollected(Exception e)
{
return IsExceptionOfType(e, typeof(ObjectCollectedException));
}
public static bool IsExceptionOfType(Exception e, Type t, bool strict = true, bool checkInner = true)
{
bool isType;
if (strict)
isType = e.GetType() == t;
else
isType = t.IsAssignableFrom(e.GetType());
if (isType) return true;
if (e.InnerException != null && checkInner)
return IsExceptionOfType(e.InnerException, t, strict);
else
return false;
}
#endif
} }
} }

View File

@ -0,0 +1,178 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.IO;
using System.Reflection;
#if CPP
using Explorer.Unstrip.ImageConversion;
#endif
namespace Explorer.Helpers
{
public static class Texture2DHelpers
{
#if CPP // If Mono
#else
private static bool isNewEncodeMethod = false;
private static MethodInfo EncodeToPNGMethod => m_encodeToPNGMethod ?? GetEncodeToPNGMethod();
private static MethodInfo m_encodeToPNGMethod;
private static MethodInfo GetEncodeToPNGMethod()
{
if (ReflectionHelpers.GetTypeByName("UnityEngine.ImageConversion") is Type imageConversion)
{
isNewEncodeMethod = true;
return m_encodeToPNGMethod = imageConversion.GetMethod("EncodeToPNG", ReflectionHelpers.CommonFlags);
}
var method = typeof(Texture2D).GetMethod("EncodeToPNG", ReflectionHelpers.CommonFlags);
if (method != null)
{
return m_encodeToPNGMethod = method;
}
ExplorerCore.Log("ERROR: Cannot get any EncodeToPNG method!");
return null;
}
#endif
public static bool IsReadable(this Texture2D tex)
{
try
{
// This will cause an exception if it's not readable.
// Reason for doing it this way is not all Unity versions
// ship with the 'Texture.isReadable' property.
tex.GetPixel(0, 0);
return true;
}
catch
{
return false;
}
}
public static Texture2D Copy(Texture2D orig, Rect rect, bool isDTXnmNormal = false)
{
Color[] pixels;
if (!orig.IsReadable())
{
orig = ForceReadTexture(orig);
}
pixels = orig.GetPixels((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
var _newTex = new Texture2D((int)rect.width, (int)rect.height);
_newTex.SetPixels(pixels);
return _newTex;
}
public static Texture2D ForceReadTexture(Texture2D tex)
{
try
{
var origFilter = tex.filterMode;
tex.filterMode = FilterMode.Point;
var rt = RenderTexture.GetTemporary(tex.width, tex.height, 0, RenderTextureFormat.ARGB32);
rt.filterMode = FilterMode.Point;
RenderTexture.active = rt;
Graphics.Blit(tex, rt);
var _newTex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
_newTex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
_newTex.Apply(false, false);
RenderTexture.active = null;
tex.filterMode = origFilter;
return _newTex;
}
catch (Exception e)
{
ExplorerCore.Log("Exception on ForceReadTexture: " + e.ToString());
return default;
}
}
public static void SaveTextureAsPNG(Texture2D tex, string dir, string name, bool isDTXnmNormal = false)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
byte[] data;
var savepath = dir + @"\" + name + ".png";
// Make sure we can EncodeToPNG it.
if (tex.format != TextureFormat.ARGB32 || !tex.IsReadable())
{
tex = ForceReadTexture(tex);
}
if (isDTXnmNormal)
{
tex = DTXnmToRGBA(tex);
tex.Apply(false, false);
}
#if CPP
data = tex.EncodeToPNG();
#else
if (isNewEncodeMethod)
{
data = (byte[])EncodeToPNGMethod.Invoke(null, new object[] { tex });
}
else
{
data = (byte[])EncodeToPNGMethod.Invoke(tex, new object[0]);
}
#endif
if (data == null || data.Length < 1)
{
ExplorerCore.LogWarning("Couldn't get any data for the texture!");
}
else
{
File.WriteAllBytes(savepath, data);
}
}
// Converts DTXnm-format Normal Map to RGBA-format Normal Map.
public static Texture2D DTXnmToRGBA(Texture2D tex)
{
Color[] colors = tex.GetPixels();
for (int i = 0; i < colors.Length; i++)
{
Color c = colors[i];
c.r = c.a * 2 - 1; // red <- alpha
c.g = c.g * 2 - 1; // green is always the same
Vector2 rg = new Vector2(c.r, c.g); //this is the red-green vector
c.b = Mathf.Sqrt(1 - Mathf.Clamp01(Vector2.Dot(rg, rg))); //recalculate the blue channel
colors[i] = new Color(
(c.r * 0.5f) + 0.5f,
(c.g * 0.5f) + 0.25f,
(c.b * 0.5f) + 0.5f
);
}
var newtex = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
newtex.SetPixels(colors);
return newtex;
}
}
}

View File

@ -1,6 +1,6 @@
using UnityEngine; using UnityEngine;
namespace Explorer namespace Explorer.Helpers
{ {
public class UnityHelpers public class UnityHelpers
{ {

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Explorer.Input
{
public abstract class AbstractInput
{
public abstract void Init();
public abstract Vector2 MousePosition { get; }
public abstract bool GetKeyDown(KeyCode key);
public abstract bool GetKey(KeyCode key);
public abstract bool GetMouseButtonDown(int btn);
public abstract bool GetMouseButton(int btn);
}
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Explorer.Input
{
public interface IAbstractInput
{
void Init();
Vector2 MousePosition { get; }
bool GetKeyDown(KeyCode key);
bool GetKey(KeyCode key);
bool GetMouseButtonDown(int btn);
bool GetMouseButton(int btn);
}
}

View File

@ -2,41 +2,87 @@
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.Input; using Explorer.Input;
using Explorer.Helpers;
using System.Diagnostics.CodeAnalysis;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer namespace Explorer
{ {
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Unity style")]
public static class InputManager public static class InputManager
{ {
private static AbstractInput inputModule; private static IAbstractInput m_inputModule;
public static void Init() public static void Init()
{ {
if (InputSystem.TKeyboard != null || TryLoadModule("Unity.InputSystem", InputSystem.TKeyboard)) if (InputSystem.TKeyboard != null || (ReflectionHelpers.LoadModule("Unity.InputSystem") && InputSystem.TKeyboard != null))
{ {
inputModule = new InputSystem(); m_inputModule = new InputSystem();
} }
else if (LegacyInput.TInput != null || TryLoadModule("UnityEngine.Input", LegacyInput.TInput)) else if (LegacyInput.TInput != null || (ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") && LegacyInput.TInput != null))
{ {
inputModule = new LegacyInput(); m_inputModule = new LegacyInput();
} }
if (inputModule == null) if (m_inputModule == null)
{ {
ExplorerCore.LogWarning("Could not find any Input module!"); ExplorerCore.LogWarning("Could not find any Input module!");
inputModule = new NoInput(); m_inputModule = new NoInput();
} }
inputModule.Init(); m_inputModule.Init();
bool TryLoadModule(string dll, Type check) => ReflectionHelpers.LoadModule(dll) && check != null;
} }
public static Vector3 MousePosition => inputModule.MousePosition; public static Vector3 MousePosition => m_inputModule.MousePosition;
public static bool GetKeyDown(KeyCode key) => inputModule.GetKeyDown(key); public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
public static bool GetKey(KeyCode key) => inputModule.GetKey(key); public static bool GetKey(KeyCode key) => m_inputModule.GetKey(key);
public static bool GetMouseButtonDown(int btn) => inputModule.GetMouseButtonDown(btn); public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
public static bool GetMouseButton(int btn) => inputModule.GetMouseButton(btn); public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
#if CPP
internal delegate void d_ResetInputAxes();
public static void ResetInputAxes() => ICallHelper.GetICall<d_ResetInputAxes>("UnityEngine.Input::ResetInputAxes").Invoke();
#else
public static void ResetInputAxes() => UnityEngine.Input.ResetInputAxes();
#endif
#if CPP
// public extern static string compositionString { get; }
internal delegate IntPtr d_get_compositionString();
public static string compositionString
{
get
{
var iCall = ICallHelper.GetICall<d_get_compositionString>("UnityEngine.Input::get_compositionString");
return IL2CPP.Il2CppStringToManaged(iCall.Invoke());
}
}
// public extern static Vector2 compositionCursorPos { get; set; }
internal delegate void d_get_compositionCursorPos(out Vector2 ret);
internal delegate void d_set_compositionCursorPos(ref Vector2 value);
public static Vector2 compositionCursorPos
{
get
{
var iCall = ICallHelper.GetICall<d_get_compositionCursorPos>("UnityEngine.Input::get_compositionCursorPos_Injected");
iCall.Invoke(out Vector2 ret);
return ret;
}
set
{
var iCall = ICallHelper.GetICall<d_set_compositionCursorPos>("UnityEngine.Input::set_compositionCursorPos_Injected");
iCall.Invoke(ref value);
}
}
#endif
} }
} }

View File

@ -4,104 +4,105 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using Explorer.Helpers;
namespace Explorer.Input namespace Explorer.Input
{ {
public class InputSystem : AbstractInput public class InputSystem : IAbstractInput
{ {
public static Type TKeyboard => _keyboard ?? (_keyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard")); public static Type TKeyboard => m_tKeyboard ?? (m_tKeyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard"));
private static Type _keyboard; private static Type m_tKeyboard;
public static Type TMouse => _mouse ?? (_mouse = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Mouse")); public static Type TMouse => m_tMouse ?? (m_tMouse = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Mouse"));
private static Type _mouse; private static Type m_tMouse;
public static Type TKey => _key ?? (_key = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Key")); public static Type TKey => m_tKey ?? (m_tKey = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Key"));
private static Type _key; private static Type m_tKey;
private static PropertyInfo _btnIsPressedProp; private static PropertyInfo m_btnIsPressedProp;
private static PropertyInfo _btnWasPressedProp; private static PropertyInfo m_btnWasPressedProp;
private static object CurrentKeyboard => _currentKeyboard ?? (_currentKeyboard = _kbCurrentProp.GetValue(null, null)); private static object CurrentKeyboard => m_currentKeyboard ?? (m_currentKeyboard = m_kbCurrentProp.GetValue(null, null));
private static object _currentKeyboard; private static object m_currentKeyboard;
private static PropertyInfo _kbCurrentProp; private static PropertyInfo m_kbCurrentProp;
private static PropertyInfo _kbIndexer; private static PropertyInfo m_kbIndexer;
private static object CurrentMouse => _currentMouse ?? (_currentMouse = _mouseCurrentProp.GetValue(null, null)); private static object CurrentMouse => m_currentMouse ?? (m_currentMouse = m_mouseCurrentProp.GetValue(null, null));
private static object _currentMouse; private static object m_currentMouse;
private static PropertyInfo _mouseCurrentProp; private static PropertyInfo m_mouseCurrentProp;
private static object LeftMouseButton => _lmb ?? (_lmb = _leftButtonProp.GetValue(CurrentMouse, null)); private static object LeftMouseButton => m_lmb ?? (m_lmb = m_leftButtonProp.GetValue(CurrentMouse, null));
private static object _lmb; private static object m_lmb;
private static PropertyInfo _leftButtonProp; private static PropertyInfo m_leftButtonProp;
private static object RightMouseButton => _rmb ?? (_rmb = _rightButtonProp.GetValue(CurrentMouse, null)); private static object RightMouseButton => m_rmb ?? (m_rmb = m_rightButtonProp.GetValue(CurrentMouse, null));
private static object _rmb; private static object m_rmb;
private static PropertyInfo _rightButtonProp; private static PropertyInfo m_rightButtonProp;
private static object MousePositionInfo => _pos ?? (_pos = _positionProp.GetValue(CurrentMouse, null)); private static object MousePositionInfo => m_pos ?? (m_pos = m_positionProp.GetValue(CurrentMouse, null));
private static object _pos; private static object m_pos;
private static PropertyInfo _positionProp; private static PropertyInfo m_positionProp;
private static MethodInfo _readVector2InputMethod; private static MethodInfo m_readVector2InputMethod;
public override Vector2 MousePosition => (Vector2)_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]); public Vector2 MousePosition => (Vector2)m_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
public override bool GetKeyDown(KeyCode key) public bool GetKeyDown(KeyCode key)
{ {
var parsedKey = Enum.Parse(TKey, key.ToString()); var parsedKey = Enum.Parse(TKey, key.ToString());
var actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey }); var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey });
return (bool)_btnWasPressedProp.GetValue(actualKey, null); return (bool)m_btnWasPressedProp.GetValue(actualKey, null);
} }
public override bool GetKey(KeyCode key) public bool GetKey(KeyCode key)
{ {
var parsed = Enum.Parse(TKey, key.ToString()); var parsed = Enum.Parse(TKey, key.ToString());
var actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed }); var actualKey = m_kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
return (bool)_btnIsPressedProp.GetValue(actualKey, null); return (bool)m_btnIsPressedProp.GetValue(actualKey, null);
} }
public override bool GetMouseButtonDown(int btn) public bool GetMouseButtonDown(int btn)
{ {
switch (btn) switch (btn)
{ {
case 0: return (bool)_btnWasPressedProp.GetValue(LeftMouseButton, null); case 0: return (bool)m_btnWasPressedProp.GetValue(LeftMouseButton, null);
case 1: return (bool)_btnWasPressedProp.GetValue(RightMouseButton, null); case 1: return (bool)m_btnWasPressedProp.GetValue(RightMouseButton, null);
// case 2: return (bool)_btnWasPressedProp.GetValue(MiddleMouseButton, null); // case 2: return (bool)_btnWasPressedProp.GetValue(MiddleMouseButton, null);
default: throw new NotImplementedException(); default: throw new NotImplementedException();
} }
} }
public override bool GetMouseButton(int btn) public bool GetMouseButton(int btn)
{ {
switch (btn) switch (btn)
{ {
case 0: return (bool)_btnIsPressedProp.GetValue(LeftMouseButton, null); case 0: return (bool)m_btnIsPressedProp.GetValue(LeftMouseButton, null);
case 1: return (bool)_btnIsPressedProp.GetValue(RightMouseButton, null); case 1: return (bool)m_btnIsPressedProp.GetValue(RightMouseButton, null);
// case 2: return (bool)_btnIsPressedProp.GetValue(MiddleMouseButton, null); // case 2: return (bool)_btnIsPressedProp.GetValue(MiddleMouseButton, null);
default: throw new NotImplementedException(); default: throw new NotImplementedException();
} }
} }
public override void Init() public void Init()
{ {
ExplorerCore.Log("Initializing new InputSystem support..."); ExplorerCore.Log("Initializing new InputSystem support...");
_kbCurrentProp = TKeyboard.GetProperty("current"); m_kbCurrentProp = TKeyboard.GetProperty("current");
_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey }); m_kbIndexer = TKeyboard.GetProperty("Item", new Type[] { TKey });
var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl"); var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl");
_btnIsPressedProp = btnControl.GetProperty("isPressed"); m_btnIsPressedProp = btnControl.GetProperty("isPressed");
_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame"); m_btnWasPressedProp = btnControl.GetProperty("wasPressedThisFrame");
_mouseCurrentProp = TMouse.GetProperty("current"); m_mouseCurrentProp = TMouse.GetProperty("current");
_leftButtonProp = TMouse.GetProperty("leftButton"); m_leftButtonProp = TMouse.GetProperty("leftButton");
_rightButtonProp = TMouse.GetProperty("rightButton"); m_rightButtonProp = TMouse.GetProperty("rightButton");
_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer") m_positionProp = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer")
.GetProperty("position"); .GetProperty("position");
_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1") m_readVector2InputMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1")
.MakeGenericType(typeof(Vector2)) .MakeGenericType(typeof(Vector2))
.GetMethod("ReadValue"); .GetMethod("ReadValue");
} }

View File

@ -4,39 +4,40 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using Explorer.Helpers;
namespace Explorer.Input namespace Explorer.Input
{ {
public class LegacyInput : AbstractInput public class LegacyInput : IAbstractInput
{ {
public static Type TInput => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input")); public static Type TInput => m_tInput ?? (m_tInput = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
private static Type _input; private static Type m_tInput;
private static PropertyInfo _mousePositionProp; private static PropertyInfo m_mousePositionProp;
private static MethodInfo _getKeyMethod; private static MethodInfo m_getKeyMethod;
private static MethodInfo _getKeyDownMethod; private static MethodInfo m_getKeyDownMethod;
private static MethodInfo _getMouseButtonMethod; private static MethodInfo m_getMouseButtonMethod;
private static MethodInfo _getMouseButtonDownMethod; private static MethodInfo m_getMouseButtonDownMethod;
public override Vector2 MousePosition => (Vector3)_mousePositionProp.GetValue(null, null); public Vector2 MousePosition => (Vector3)m_mousePositionProp.GetValue(null, null);
public override bool GetKey(KeyCode key) => (bool)_getKeyMethod.Invoke(null, new object[] { key }); public bool GetKey(KeyCode key) => (bool)m_getKeyMethod.Invoke(null, new object[] { key });
public override bool GetKeyDown(KeyCode key) => (bool)_getKeyDownMethod.Invoke(null, new object[] { key }); public bool GetKeyDown(KeyCode key) => (bool)m_getKeyDownMethod.Invoke(null, new object[] { key });
public override bool GetMouseButton(int btn) => (bool)_getMouseButtonMethod.Invoke(null, new object[] { btn }); public bool GetMouseButton(int btn) => (bool)m_getMouseButtonMethod.Invoke(null, new object[] { btn });
public override bool GetMouseButtonDown(int btn) => (bool)_getMouseButtonDownMethod.Invoke(null, new object[] { btn }); public bool GetMouseButtonDown(int btn) => (bool)m_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
public override void Init() public void Init()
{ {
ExplorerCore.Log("Initializing Legacy Input support..."); ExplorerCore.Log("Initializing Legacy Input support...");
_mousePositionProp = TInput.GetProperty("mousePosition"); m_mousePositionProp = TInput.GetProperty("mousePosition");
_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) }); m_getKeyMethod = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) });
_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) }); m_getKeyDownMethod = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) });
_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) }); m_getMouseButtonMethod = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) });
_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) }); m_getMouseButtonDownMethod = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) });
} }
} }
} }

View File

@ -8,18 +8,16 @@ namespace Explorer.Input
{ {
// Just a stub for games where no Input module was able to load at all. // Just a stub for games where no Input module was able to load at all.
public class NoInput : AbstractInput public class NoInput : IAbstractInput
{ {
public override Vector2 MousePosition => Vector2.zero; public Vector2 MousePosition => Vector2.zero;
public override bool GetKey(KeyCode key) => false; public bool GetKey(KeyCode key) => false;
public bool GetKeyDown(KeyCode key) => false;
public override bool GetKeyDown(KeyCode key) => false; public bool GetMouseButton(int btn) => false;
public bool GetMouseButtonDown(int btn) => false;
public override bool GetMouseButton(int btn) => false; public void Init() { }
public override bool GetMouseButtonDown(int btn) => false;
public override void Init() { }
} }
} }

View File

@ -3,22 +3,26 @@ using System.Collections.Generic;
using System; using System;
using UnityEngine; using UnityEngine;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using Explorer.UI.Shared;
#if CPP
using UnhollowerBaseLib;
using UnityEngine.SceneManagement;
using Explorer.Unstrip.ImageConversion;
#endif
namespace Explorer.Tests namespace Explorer.Tests
{ {
public static class StaticTestClass public static class StaticTestClass
{ {
public static int StaticProperty => 5; public static int StaticProperty => 5;
public static int StaticField = 69; public static int StaticField = 69;
public static List<string> StaticList = new List<string> public static List<string> StaticList = new List<string>
{ {
"one", "one",
"two", "two",
"three", "three",
}; };
public static void StaticMethod() { } public static void StaticMethod() { }
} }
@ -28,17 +32,49 @@ namespace Explorer.Tests
public static TestClass Instance => m_instance ?? (m_instance = new TestClass()); public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
private static TestClass m_instance; private static TestClass m_instance;
public static bool ReadSetOnlyProperty => m_setOnlyProperty;
public static bool SetOnlyProperty
{
set => m_setOnlyProperty = value;
}
private static bool m_setOnlyProperty;
public Texture2D TestTexture = UIStyles.MakeTex(200, 200, Color.white);
public static Sprite TestSprite;
public static int StaticProperty => 5; public static int StaticProperty => 5;
public static int StaticField = 5; public static int StaticField = 5;
public int NonStaticField; public int NonStaticField;
#if CPP #if CPP
public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest; public static Il2CppSystem.Collections.Generic.HashSet<string> ILHashSetTest;
public static Il2CppReferenceArray<Il2CppSystem.Object> testRefArray;
#endif #endif
public TestClass() public TestClass()
{ {
#if CPP #if CPP
TestTexture.name = "TestTexture";
var r = new Rect(0, 0, TestTexture.width, TestTexture.height);
var v2 = Vector2.zero;
var v4 = Vector4.zero;
TestSprite = Sprite.CreateSprite_Injected(TestTexture, ref r, ref v2, 100f, 0u, SpriteMeshType.Tight, ref v4, false);
GameObject.DontDestroyOnLoad(TestTexture);
GameObject.DontDestroyOnLoad(TestSprite);
testRefArray = new Il2CppReferenceArray<Il2CppSystem.Object>(5);
for (int i = 0; i < 5; i++)
{
testRefArray[i] = "hi " + i;
}
//// test loading a tex from file
//var dataToLoad = System.IO.File.ReadAllBytes(@"Mods\Explorer\Tex_Nemundis_Nebula.png");
//ExplorerCore.Log($"Tex load success: {TestTexture.LoadImage(dataToLoad, false)}");
ILHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>(); ILHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
ILHashSetTest.Add("1"); ILHashSetTest.Add("1");
ILHashSetTest.Add("2"); ILHashSetTest.Add("2");

View File

@ -1,5 +1,7 @@
using System; using System;
using UnityEngine; using UnityEngine;
using Explorer.Helpers;
using BF = System.Reflection.BindingFlags;
#if ML #if ML
using Harmony; using Harmony;
#else #else
@ -17,37 +19,38 @@ namespace Explorer.UI
} }
private static bool m_forceUnlock; private static bool m_forceUnlock;
private static CursorLockMode m_lastLockMode;
private static bool m_lastVisibleState;
private static bool m_currentlySettingCursor = false;
public static bool ShouldForceMouse => ExplorerCore.ShowMenu && Unlock; public static bool ShouldForceMouse => ExplorerCore.ShowMenu && Unlock;
private static Type CursorType => m_cursorType ?? (m_cursorType = ReflectionHelpers.GetTypeByName("UnityEngine.Cursor")); private static CursorLockMode m_lastLockMode;
private static bool m_lastVisibleState;
private static bool m_currentlySettingCursor = false;
private static Type CursorType
=> m_cursorType
?? (m_cursorType = ReflectionHelpers.GetTypeByName("UnityEngine.Cursor"));
private static Type m_cursorType; private static Type m_cursorType;
public static void Init() public static void Init()
{ {
try try
{ {
// Check if Cursor class is loaded
if (CursorType == null) if (CursorType == null)
{ {
ExplorerCore.Log("Trying to manually load Cursor module..."); throw new Exception("Could not find Type 'UnityEngine.Cursor'!");
if (ReflectionHelpers.LoadModule("UnityEngine.CoreModule") && CursorType != null)
{
ExplorerCore.Log("Ok!");
}
else
{
throw new Exception("Could not load UnityEngine.Cursor module!");
}
} }
// Get current cursor state and enable cursor // Get current cursor state and enable cursor
m_lastLockMode = Cursor.lockState; try
m_lastVisibleState = Cursor.visible; {
m_lastLockMode = (CursorLockMode)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static).GetValue(null, null);
m_lastVisibleState = (bool)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static).GetValue(null, null);
}
catch
{
m_lastLockMode = CursorLockMode.None;
m_lastVisibleState = true;
}
// Setup Harmony Patches // Setup Harmony Patches
TryPatch("lockState", new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_lockState))), true); TryPatch("lockState", new HarmonyMethod(typeof(ForceUnlockCursor).GetMethod(nameof(Prefix_set_lockState))), true);
@ -91,7 +94,8 @@ namespace Explorer.UI
} }
catch (Exception e) catch (Exception e)
{ {
ExplorerCore.Log($"[NON-FATAL] Couldn't patch a method: {e.Message}"); string s = setter ? "set_" : "get_" ;
ExplorerCore.Log($"Unable to patch Cursor.{s}{property}: {e.Message}");
} }
} }

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.UI.Main; using Explorer.UI.Main;
using Explorer.Unstrip.LayerMasks;
using Explorer.Helpers;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
#endif #endif
@ -17,6 +19,8 @@ namespace Explorer.UI.Inspectors
public GameObject TargetGO; public GameObject TargetGO;
public bool pendingDestroy;
private static bool m_hideControls; private static bool m_hideControls;
// gui element holders // gui element holders
@ -43,6 +47,8 @@ namespace Explorer.UI.Inspectors
private bool m_autoUpdateTransform; private bool m_autoUpdateTransform;
private bool m_localContext; private bool m_localContext;
private int m_layer;
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 = "";
@ -104,16 +110,16 @@ namespace Explorer.UI.Inspectors
{ {
try try
{ {
if (pendingDestroy) return;
if (Target == null) if (Target == null)
{ {
ExplorerCore.Log("Target is null!"); DestroyOnException(new Exception("Target was destroyed."));
DestroyWindow();
return; return;
} }
if (!TargetGO && !GetObjectAsGameObject()) if (!TargetGO && !GetObjectAsGameObject())
{ {
ExplorerCore.Log("Target was destroyed!"); DestroyOnException(new Exception("Target was destroyed."));
DestroyWindow();
return; return;
} }
@ -132,6 +138,8 @@ namespace Explorer.UI.Inspectors
TargetGO.transform.localScale = m_frozenScale; TargetGO.transform.localScale = m_frozenScale;
} }
m_layer = TargetGO.layer;
// update child objects // update child objects
var childList = new List<Transform>(); var childList = new List<Transform>();
for (int i = 0; i < TargetGO.transform.childCount; i++) for (int i = 0; i < TargetGO.transform.childCount; i++)
@ -162,7 +170,10 @@ namespace Explorer.UI.Inspectors
private void DestroyOnException(Exception e) private void DestroyOnException(Exception e)
{ {
if (pendingDestroy) return;
ExplorerCore.Log($"Exception drawing GameObject Window: {e.GetType()}, {e.Message}"); ExplorerCore.Log($"Exception drawing GameObject Window: {e.GetType()}, {e.Message}");
pendingDestroy = true;
DestroyWindow(); DestroyWindow();
} }
@ -204,6 +215,8 @@ namespace Explorer.UI.Inspectors
public override void WindowFunction(int windowID) public override void WindowFunction(int windowID)
{ {
if (pendingDestroy) return;
try try
{ {
var rect = WindowManager.TabView ? TabViewWindow.Instance.m_rect : this.m_rect; var rect = WindowManager.TabView ? TabViewWindow.Instance.m_rect : this.m_rect;
@ -211,12 +224,12 @@ namespace Explorer.UI.Inspectors
if (!WindowManager.TabView) if (!WindowManager.TabView)
{ {
Header(); Header();
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box); GUIHelper.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
} }
scroll = GUIUnstrip.BeginScrollView(scroll); scroll = GUIHelper.BeginScrollView(scroll);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", new GUILayoutOption[0]); GUILayout.Label("Scene: <color=cyan>" + (m_scene == "" ? "n/a" : m_scene) + "</color>", new GUILayoutOption[0]);
if (m_scene == UnityHelpers.ActiveSceneName) if (m_scene == UnityHelpers.ActiveSceneName)
{ {
@ -232,7 +245,7 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) }); GUILayout.Label("Path:", new GUILayoutOption[] { GUILayout.Width(50) });
string pathlabel = TargetGO.transform.GetGameObjectPath(); string pathlabel = TargetGO.transform.GetGameObjectPath();
if (TargetGO.transform.parent != null) if (TargetGO.transform.parent != null)
@ -242,22 +255,24 @@ namespace Explorer.UI.Inspectors
InspectGameObject(TargetGO.transform.parent); InspectGameObject(TargetGO.transform.parent);
} }
} }
GUIUnstrip.TextArea(pathlabel, new GUILayoutOption[0]); GUIHelper.TextArea(pathlabel, new GUILayoutOption[0]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Name:", new GUILayoutOption[] { GUILayout.Width(50) }); GUILayout.Label("Name:", new GUILayoutOption[] { GUILayout.Width(50) });
GUIUnstrip.TextArea(m_name, new GUILayoutOption[0]); GUIHelper.TextArea(m_name, new GUILayoutOption[0]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
LayerControls();
// --- Horizontal Columns section --- // --- Horizontal Columns section ---
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) }); GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
TransformList(rect); TransformList(rect);
GUILayout.EndVertical(); GUILayout.EndVertical();
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) }); GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.Width(rect.width / 2 - 17) });
ComponentList(rect); ComponentList(rect);
GUILayout.EndVertical(); GUILayout.EndVertical();
@ -265,13 +280,13 @@ namespace Explorer.UI.Inspectors
GameObjectControls(); GameObjectControls();
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
if (!WindowManager.TabView) if (!WindowManager.TabView)
{ {
m_rect = ResizeDrag.ResizeWindow(rect, windowID); m_rect = ResizeDrag.ResizeWindow(rect, windowID);
GUIUnstrip.EndArea(); GUIHelper.EndArea();
} }
} }
catch (Exception e) catch (Exception e)
@ -280,14 +295,42 @@ namespace Explorer.UI.Inspectors
} }
} }
private void LayerControls()
{
GUIHelper.BeginHorizontal();
GUILayout.Label("Layer:", new GUILayoutOption[] { GUILayout.Width(50) });
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(30) }))
{
if (m_layer > 0)
{
m_layer--;
if (TargetGO) TargetGO.layer = m_layer;
}
}
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(30) }))
{
if (m_layer < 32)
{
m_layer++;
if (TargetGO) TargetGO.layer = m_layer;
}
}
GUILayout.Label($"{m_layer} (<color=cyan>{LayerMaskUnstrip.LayerToName(m_layer)}</color>)",
new GUILayoutOption[] { GUILayout.Width(200) });
GUILayout.EndHorizontal();
}
private void TransformList(Rect m_rect) private void TransformList(Rect m_rect)
{ {
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
m_transformScroll = GUIUnstrip.BeginScrollView(m_transformScroll); m_transformScroll = GUIHelper.BeginScrollView(m_transformScroll);
GUILayout.Label("<b><size=15>Children</size></b>", new GUILayoutOption[0]); GUILayout.Label("<b><size=15>Children</size></b>", new GUILayoutOption[0]);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
ChildPages.DrawLimitInputArea(); ChildPages.DrawLimitInputArea();
if (ChildPages.ItemCount > ChildPages.ItemsPerPage) if (ChildPages.ItemCount > ChildPages.ItemsPerPage)
@ -295,7 +338,7 @@ namespace Explorer.UI.Inspectors
ChildPages.CurrentPageLabel(); ChildPages.CurrentPageLabel();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) })) if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{ {
@ -330,17 +373,17 @@ namespace Explorer.UI.Inspectors
GUILayout.Label("<i>None</i>", new GUILayoutOption[0]); GUILayout.Label("<i>None</i>", new GUILayoutOption[0]);
} }
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
private void ComponentList(Rect m_rect) private void ComponentList(Rect m_rect)
{ {
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
m_compScroll = GUIUnstrip.BeginScrollView(m_compScroll); m_compScroll = GUIHelper.BeginScrollView(m_compScroll);
GUILayout.Label("<b><size=15>Components</size></b>", new GUILayoutOption[0]); GUILayout.Label("<b><size=15>Components</size></b>", new GUILayoutOption[0]);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
CompPages.DrawLimitInputArea(); CompPages.DrawLimitInputArea();
if (CompPages.ItemCount > CompPages.ItemsPerPage) if (CompPages.ItemCount > CompPages.ItemsPerPage)
@ -348,7 +391,7 @@ namespace Explorer.UI.Inspectors
CompPages.CurrentPageLabel(); CompPages.CurrentPageLabel();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) })) if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{ {
@ -361,9 +404,9 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
var width = m_rect.width / 2 - 135f; var width = m_rect.width / 2 - 135f;
m_addComponentInput = GUIUnstrip.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) }); m_addComponentInput = GUIHelper.TextField(m_addComponentInput, new GUILayoutOption[] { GUILayout.Width(width) });
if (GUILayout.Button("Add Comp", new GUILayoutOption[0])) if (GUILayout.Button("Add Comp", new GUILayoutOption[0]))
{ {
if (ReflectionHelpers.GetTypeByName(m_addComponentInput) is Type compType) if (ReflectionHelpers.GetTypeByName(m_addComponentInput) is Type compType)
@ -410,7 +453,7 @@ namespace Explorer.UI.Inspectors
#else #else
component.GetType(); component.GetType();
#endif #endif
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (ReflectionHelpers.BehaviourType.IsAssignableFrom(type)) if (ReflectionHelpers.BehaviourType.IsAssignableFrom(type))
{ {
#if CPP #if CPP
@ -421,7 +464,7 @@ namespace Explorer.UI.Inspectors
} }
else else
{ {
GUIUnstrip.Space(26); GUIHelper.Space(26);
} }
if (GUILayout.Button("<color=cyan>" + type.Name + "</color>", new GUILayoutOption[] { GUILayout.Width(m_rect.width / 2 - 100) })) if (GUILayout.Button("<color=cyan>" + type.Name + "</color>", new GUILayoutOption[] { GUILayout.Width(m_rect.width / 2 - 100) }))
{ {
@ -445,7 +488,7 @@ namespace Explorer.UI.Inspectors
} }
} }
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
@ -477,7 +520,7 @@ namespace Explorer.UI.Inspectors
{ {
if (m_hideControls) if (m_hideControls)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) }); GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) });
if (GUILayout.Button("^ Show ^", new GUILayoutOption[] { GUILayout.Width(75) })) if (GUILayout.Button("^ Show ^", new GUILayoutOption[] { GUILayout.Width(75) }))
{ {
@ -488,9 +531,9 @@ namespace Explorer.UI.Inspectors
return; return;
} }
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) }); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[] { GUILayout.Width(520) });
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b><size=15>GameObject Controls</size></b>", new GUILayoutOption[] { GUILayout.Width(200) }); 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) })) if (GUILayout.Button("v Hide v", new GUILayoutOption[] { GUILayout.Width(75) }))
{ {
@ -498,7 +541,7 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
bool m_active = TargetGO.activeSelf; 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) });
@ -523,9 +566,9 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
m_setParentInput = GUIUnstrip.TextField(m_setParentInput, new GUILayoutOption[0]); m_setParentInput = GUIHelper.TextField(m_setParentInput, new GUILayoutOption[0]);
if (GUILayout.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) })) if (GUILayout.Button("Set Parent", new GUILayoutOption[] { GUILayout.Width(80) }))
{ {
if (GameObject.Find(m_setParentInput) is GameObject newparent) if (GameObject.Find(m_setParentInput) is GameObject newparent)
@ -544,13 +587,13 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false); m_cachedInput[0] = TranslateControl(TranslateType.Position, ref m_translateAmount, false);
m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true); m_cachedInput[1] = TranslateControl(TranslateType.Rotation, ref m_rotateAmount, true);
m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false); m_cachedInput[2] = TranslateControl(TranslateType.Scale, ref m_scaleAmount, false);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button("<color=lime>Apply to Transform</color>", new GUILayoutOption[0]) || m_autoApplyTransform) if (GUILayout.Button("<color=lime>Apply to Transform</color>", new GUILayoutOption[0]) || m_autoApplyTransform)
{ {
if (m_localContext) if (m_localContext)
@ -576,7 +619,7 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
BoolToggle(ref m_autoApplyTransform, "Auto-apply to Transform?"); BoolToggle(ref m_autoApplyTransform, "Auto-apply to Transform?");
BoolToggle(ref m_autoUpdateTransform, "Auto-update from transform?"); BoolToggle(ref m_autoUpdateTransform, "Auto-update from transform?");
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
@ -638,7 +681,7 @@ namespace Explorer.UI.Inspectors
private Vector3 TranslateControl(TranslateType mode, ref float amount, bool multByTime) private Vector3 TranslateControl(TranslateType mode, ref float amount, bool multByTime)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
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) });
@ -661,7 +704,7 @@ namespace Explorer.UI.Inspectors
Vector3 input = m_cachedInput[(int)mode]; Vector3 input = m_cachedInput[(int)mode];
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight; GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) }); GUILayout.Label("<color=cyan>X:</color>", new GUILayoutOption[] { GUILayout.Width(20) });
@ -675,7 +718,7 @@ namespace Explorer.UI.Inspectors
GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("+/-:", new GUILayoutOption[] { GUILayout.Width(30) });
var amountInput = amount.ToString("F3"); var amountInput = amount.ToString("F3");
amountInput = GUIUnstrip.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) }); amountInput = GUIHelper.TextField(amountInput, new GUILayoutOption[] { GUILayout.Width(60) });
if (float.TryParse(amountInput, out float f)) if (float.TryParse(amountInput, out float f))
{ {
amount = f; amount = f;
@ -690,16 +733,16 @@ namespace Explorer.UI.Inspectors
private void PlusMinusFloat(ref float f, float amount, bool multByTime) private void PlusMinusFloat(ref float f, float amount, bool multByTime)
{ {
string s = f.ToString("F3"); string s = f.ToString("F3");
s = GUIUnstrip.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) }); s = GUIHelper.TextField(s, new GUILayoutOption[] { GUILayout.Width(60) });
if (float.TryParse(s, out float f2)) if (float.TryParse(s, out float f2))
{ {
f = f2; f = f2;
} }
if (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
{ {
f -= multByTime ? amount * Time.deltaTime : amount; f -= multByTime ? amount * Time.deltaTime : amount;
} }
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
{ {
f += multByTime ? amount * Time.deltaTime : amount; f += multByTime ? amount * Time.deltaTime : amount;
} }

View File

@ -1,4 +1,5 @@
using UnityEngine; using UnityEngine;
using Explorer.Helpers;
namespace Explorer.UI.Inspectors namespace Explorer.UI.Inspectors
{ {

View File

@ -72,15 +72,15 @@ namespace Explorer.UI.Inspectors
public void DrawInstanceControls(Rect rect) public void DrawInstanceControls(Rect rect)
{ {
if (m_uObj) //if (m_uObj)
{ //{
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]); // GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
} //}
GUILayout.EndHorizontal(); //GUILayout.EndHorizontal();
if (m_uObj) if (m_uObj)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b>Tools:</b>", new GUILayoutOption[] { GUILayout.Width(80) }); GUILayout.Label("<b>Tools:</b>", new GUILayoutOption[] { GUILayout.Width(80) });
Buttons.InstantiateButton(m_uObj); Buttons.InstantiateButton(m_uObj);
if (m_component && m_component.gameObject is GameObject obj) if (m_component && m_component.gameObject is GameObject obj)
@ -89,13 +89,17 @@ namespace Explorer.UI.Inspectors
GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) }); GUILayout.Label("GameObject:", new GUILayoutOption[] { GUILayout.Width(135) });
var charWidth = obj.name.Length * 15; var charWidth = obj.name.Length * 15;
var maxWidth = rect.width - 350; var maxWidth = rect.width - 350;
var labelWidth = charWidth < maxWidth ? charWidth : maxWidth; var btnWidth = charWidth < maxWidth ? charWidth : maxWidth;
if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) })) if (GUILayout.Button("<color=#00FF00>" + obj.name + "</color>", new GUILayoutOption[] { GUILayout.Width(btnWidth) }))
{ {
WindowManager.InspectObject(obj, out bool _); WindowManager.InspectObject(obj, out bool _);
} }
GUI.skin.label.alignment = TextAnchor.UpperLeft; GUI.skin.label.alignment = TextAnchor.UpperLeft;
} }
else
{
GUILayout.Label("Name: " + m_uObj.name, new GUILayoutOption[0]);
}
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
} }

View File

@ -7,8 +7,10 @@ using Explorer.UI;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using Explorer.UI.Inspectors; using Explorer.UI.Inspectors;
using Explorer.Helpers;
#if CPP #if CPP
using UnhollowerBaseLib; using UnhollowerBaseLib;
using UnhollowerRuntimeLib;
#endif #endif
namespace Explorer.UI.Inspectors namespace Explorer.UI.Inspectors
@ -98,20 +100,20 @@ namespace Explorer.UI.Inspectors
if (m_typeFilter != MemberTypes.All && m_typeFilter != holder.MemInfo?.MemberType) if (m_typeFilter != MemberTypes.All && m_typeFilter != holder.MemInfo?.MemberType)
return false; return false;
// check scope filter
if (m_scopeFilter == MemberScopes.Instance)
{
return !holder.IsStatic;
}
else if (m_scopeFilter == MemberScopes.Static)
{
return holder.IsStatic;
}
// hide failed reflection // hide failed reflection
if (!string.IsNullOrEmpty(holder.ReflectionException) && m_hideFailedReflection) if (!string.IsNullOrEmpty(holder.ReflectionException) && m_hideFailedReflection)
return false; return false;
// check scope filter
if (m_scopeFilter == MemberScopes.Instance && holder.IsStatic)
{
return false;
}
else if (m_scopeFilter == MemberScopes.Static && !holder.IsStatic)
{
return false;
}
// see if we should do name search // see if we should do name search
if (m_search == "" || holder.MemInfo == null) if (m_search == "" || holder.MemInfo == null)
return true; return true;
@ -125,7 +127,7 @@ namespace Explorer.UI.Inspectors
private void CacheMembers(Type[] types) private void CacheMembers(Type[] types)
{ {
var list = new List<CacheMember>(); var list = new List<CacheMember>();
var cachedSigs = new List<string>(); var cachedSigs = new HashSet<string>();
foreach (var declaringType in types) foreach (var declaringType in types)
{ {
@ -140,39 +142,34 @@ namespace Explorer.UI.Inspectors
continue; continue;
} }
object target = Target; var target = Target;
string exception = null;
#if CPP #if CPP
if (!IsStaticInspector && target is Il2CppSystem.Object ilObject)
{
try try
{ {
target = ilObject.Il2CppCast(declaringType); target = target.Il2CppCast(declaringType);
} }
catch (Exception e) catch //(Exception e)
{ {
exception = ReflectionHelpers.ExceptionToString(e); //ExplorerCore.LogWarning("Excepting casting " + target.GetType().FullName + " to " + declaringType.FullName);
}
} }
#endif #endif
foreach (var member in infos) foreach (var member in infos)
{ {
try try
{ {
// make sure member type is Field, Method of Property (4 / 8 / 16) // make sure member type is Field, Method or Property (4 / 8 / 16)
int m = (int)member.MemberType; int m = (int)member.MemberType;
if (m < 4 || m > 16) if (m < 4 || m > 16)
continue; continue;
var fi = member as FieldInfo;
var pi = member as PropertyInfo; var pi = member as PropertyInfo;
var mi = member as MethodInfo; var mi = member as MethodInfo;
if (IsStaticInspector) if (IsStaticInspector)
{ {
if (fi != null && !fi.IsStatic) continue; if (member is FieldInfo fi && !fi.IsStatic) continue;
else if (pi != null && !pi.GetAccessors()[0].IsStatic) continue; else if (pi != null && !pi.GetAccessors(true)[0].IsStatic) continue;
else if (mi != null && !mi.IsStatic) continue; else if (mi != null && !mi.IsStatic) continue;
} }
@ -208,16 +205,16 @@ namespace Explorer.UI.Inspectors
continue; continue;
} }
//ExplorerCore.Log($"Trying to cache member {sig}...");
try try
{ {
// ExplorerCore.Log($"Trying to cache member {sig}...");
var cached = CacheFactory.GetCacheObject(member, target); var cached = CacheFactory.GetCacheObject(member, target);
if (cached != null) if (cached != null)
{ {
cachedSigs.Add(sig); cachedSigs.Add(sig);
list.Add(cached); list.Add(cached);
cached.ReflectionException = exception;
} }
} }
catch (Exception e) catch (Exception e)
@ -250,34 +247,31 @@ namespace Explorer.UI.Inspectors
if (!WindowManager.TabView) if (!WindowManager.TabView)
{ {
Header(); Header();
GUIUnstrip.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box); GUIHelper.BeginArea(new Rect(5, 25, rect.width - 10, rect.height - 35), GUI.skin.box);
} }
var asInstance = this as InstanceInspector; var asInstance = this as InstanceInspector;
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
var labelWidth = (asInstance != null && asInstance.m_uObj) var labelWidth = (asInstance != null && asInstance.m_uObj)
? new GUILayoutOption[] { GUILayout.Width(245f) } ? new GUILayoutOption[] { GUILayout.Width(245f) }
: new GUILayoutOption[0]; : new GUILayoutOption[0];
GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth); GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth);
GUILayout.EndHorizontal();
if (asInstance != null) if (asInstance != null)
{ {
asInstance.DrawInstanceControls(rect); asInstance.DrawInstanceControls(rect);
} }
else
{
GUILayout.EndHorizontal();
}
UIStyles.HorizontalLine(Color.grey); UIStyles.HorizontalLine(Color.grey);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b>Search:</b>", new GUILayoutOption[] { GUILayout.Width(75) }); GUILayout.Label("<b>Search:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
m_search = GUIUnstrip.TextField(m_search, new GUILayoutOption[0]); m_search = GUIHelper.TextField(m_search, new GUILayoutOption[0]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b>Filter:</b>", new GUILayoutOption[] { GUILayout.Width(75) }); GUILayout.Label("<b>Filter:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
FilterTypeToggle(MemberTypes.All, "All"); FilterTypeToggle(MemberTypes.All, "All");
FilterTypeToggle(MemberTypes.Property, "Properties"); FilterTypeToggle(MemberTypes.Property, "Properties");
@ -287,7 +281,7 @@ namespace Explorer.UI.Inspectors
if (this is InstanceInspector) if (this is InstanceInspector)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b>Scope:</b>", new GUILayoutOption[] { GUILayout.Width(75) }); GUILayout.Label("<b>Scope:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
FilterScopeToggle(MemberScopes.Both, "Both"); FilterScopeToggle(MemberScopes.Both, "Both");
FilterScopeToggle(MemberScopes.Instance, "Instance"); FilterScopeToggle(MemberScopes.Instance, "Instance");
@ -295,7 +289,7 @@ namespace Explorer.UI.Inspectors
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<b>Values:</b>", new GUILayoutOption[] { GUILayout.Width(75) }); GUILayout.Label("<b>Values:</b>", new GUILayoutOption[] { GUILayout.Width(75) });
if (GUILayout.Button("Update", new GUILayoutOption[] { GUILayout.Width(100) })) if (GUILayout.Button("Update", new GUILayoutOption[] { GUILayout.Width(100) }))
{ {
@ -308,12 +302,12 @@ namespace Explorer.UI.Inspectors
GUI.color = Color.white; GUI.color = Color.white;
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.Space(10); GUIHelper.Space(10);
Pages.ItemCount = m_cachedMembersFiltered.Length; Pages.ItemCount = m_cachedMembersFiltered.Length;
// prev/next page buttons // prev/next page buttons
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
Pages.DrawLimitInputArea(); Pages.DrawLimitInputArea();
@ -335,13 +329,13 @@ namespace Explorer.UI.Inspectors
// ====== BODY ====== // ====== BODY ======
scroll = GUIUnstrip.BeginScrollView(scroll); scroll = GUIHelper.BeginScrollView(scroll);
GUIUnstrip.Space(10); GUIHelper.Space(10);
UIStyles.HorizontalLine(Color.grey); UIStyles.HorizontalLine(Color.grey);
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
var members = this.m_cachedMembersFiltered; var members = this.m_cachedMembersFiltered;
int start = Pages.CalculateOffsetIndex(); int start = Pages.CalculateOffsetIndex();
@ -350,7 +344,7 @@ namespace Explorer.UI.Inspectors
{ {
var holder = members[j]; var holder = members[j];
GUIUnstrip.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) }); GUIHelper.BeginHorizontal(new GUILayoutOption[] { GUILayout.Height(25) });
try try
{ {
holder.Draw(rect, 180f); holder.Draw(rect, 180f);
@ -368,13 +362,13 @@ namespace Explorer.UI.Inspectors
} }
GUILayout.EndVertical(); GUILayout.EndVertical();
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
if (!WindowManager.TabView) if (!WindowManager.TabView)
{ {
m_rect = ResizeDrag.ResizeWindow(rect, windowID); m_rect = ResizeDrag.ResizeWindow(rect, windowID);
GUIUnstrip.EndArea(); GUIHelper.EndArea();
} }
} }
catch (Exception e) when (e.Message.Contains("in a group with only")) catch (Exception e) when (e.Message.Contains("in a group with only"))

View File

@ -5,6 +5,7 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using Explorer.Helpers;
namespace Explorer.UI namespace Explorer.UI
{ {
@ -70,14 +71,14 @@ namespace Explorer.UI
} }
else else
{ {
GUIUnstrip.Space(labelWidth); GUIHelper.Space(labelWidth);
} }
var cacheMethod = OwnerCacheObject as CacheMethod; var cacheMethod = OwnerCacheObject as CacheMethod;
if (cacheMember != null && cacheMember.HasParameters) if (cacheMember != null && cacheMember.HasParameters)
{ {
GUIUnstrip.BeginVertical(new GUILayoutOption[] { GUILayout.ExpandHeight(true) } ); GUIHelper.BeginVertical(new GUILayoutOption[] { GUILayout.ExpandHeight(true) } );
if (cacheMember.m_isEvaluating) if (cacheMember.m_isEvaluating)
{ {
@ -91,7 +92,7 @@ namespace Explorer.UI
cacheMember.DrawArgsInput(); cacheMember.DrawArgsInput();
} }
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) })) if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
{ {
if (cacheMethod != null) if (cacheMethod != null)
@ -121,8 +122,8 @@ namespace Explorer.UI
GUILayout.EndVertical(); GUILayout.EndVertical();
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(labelWidth); GUIHelper.Space(labelWidth);
} }
else if (cacheMethod != null) else if (cacheMethod != null)
{ {
@ -132,8 +133,8 @@ namespace Explorer.UI
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(labelWidth); GUIHelper.Space(labelWidth);
} }
string typeName = $"<color={Syntax.Class_Instance}>{ValueType.FullName}</color>"; string typeName = $"<color={Syntax.Class_Instance}>{ValueType.FullName}</color>";
@ -146,7 +147,7 @@ namespace Explorer.UI
{ {
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeName})", new GUILayoutOption[0]); GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeName})", new GUILayoutOption[0]);
} }
else if (Value == null && !(cacheMember is CacheMethod)) else if ((Value == null || Value is UnityEngine.Object uObj && !uObj) && !(cacheMember is CacheMethod))
{ {
GUILayout.Label($"<i>null ({typeName})</i>", new GUILayoutOption[0]); GUILayout.Label($"<i>null ({typeName})</i>", new GUILayoutOption[0]);
} }
@ -198,31 +199,56 @@ namespace Explorer.UI
return m_toStringMethod; return m_toStringMethod;
} }
private string GetButtonLabel() public string GetButtonLabel()
{ {
if (Value == null) return null; if (Value == null) return null;
string label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString(); var valueType = ReflectionHelpers.GetActualType(Value);
var classColor = ValueType.IsAbstract && ValueType.IsSealed string label;
? Syntax.Class_Static
: Syntax.Class_Instance;
string typeLabel = $"<color={classColor}>{ValueType.FullName}</color>"; if (valueType == typeof(TextAsset))
if (Value is UnityEngine.Object)
{ {
label = label.Replace($"({ValueType.FullName})", $"({typeLabel})"); var textAsset = Value as TextAsset;
label = textAsset.text;
if (label.Length > 10)
{
label = $"{label.Substring(0, 10)}...";
}
label = $"\"{label}\" {textAsset.name} (<color={Syntax.Class_Instance}>UnityEngine.TextAsset</color>)";
} }
else else
{ {
if (!label.Contains(ValueType.FullName)) label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
if (label.Length > 100)
{
label = label.Substring(0, 99);
}
var classColor = valueType.IsAbstract && valueType.IsSealed
? Syntax.Class_Static
: 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})"; label += $" ({typeLabel})";
} }
else else
{ {
label = label.Replace(ValueType.FullName, typeLabel); label = label.Replace(valueType.FullName, typeLabel);
}
} }
} }

View File

@ -2,14 +2,18 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared;
using Explorer.CacheObject;
using Explorer.Helpers;
#if CPP #if CPP
using UnhollowerBaseLib; using UnhollowerBaseLib;
#endif #endif
using Explorer.UI.Shared;
using Explorer.CacheObject;
namespace Explorer.UI namespace Explorer.UI
{ {
// TODO: Re-work class using InteractiveEnumerable or maybe InteractiveCollection for the Keys/Value lists.
// Make the keys and values editable.
public class InteractiveDictionary : InteractiveValue, IExpandHeight public class InteractiveDictionary : InteractiveValue, IExpandHeight
{ {
public bool IsExpanded { get; set; } public bool IsExpanded { get; set; }
@ -158,7 +162,7 @@ namespace Explorer.UI
m_cachedValues = values.ToArray(); m_cachedValues = values.ToArray();
} }
private bool EnsureDictionaryIsSupported() public bool EnsureDictionaryIsSupported()
{ {
if (typeof(IDictionary).IsAssignableFrom(ValueType)) if (typeof(IDictionary).IsAssignableFrom(ValueType))
{ {
@ -177,6 +181,11 @@ namespace Explorer.UI
.GetField("NativeClassPtr") .GetField("NativeClassPtr")
.GetValue(null); .GetValue(null);
if (ptr == IntPtr.Zero)
{
return false;
}
return Il2CppSystem.Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(ptr)) is Il2CppSystem.Type; return Il2CppSystem.Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(ptr)) is Il2CppSystem.Type;
} }
} }
@ -228,7 +237,7 @@ namespace Explorer.UI
} }
GUI.skin.button.alignment = TextAnchor.MiddleCenter; GUI.skin.button.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Space(5); GUIHelper.Space(5);
if (IsExpanded) if (IsExpanded)
{ {
@ -237,9 +246,9 @@ namespace Explorer.UI
if (count > Pages.ItemsPerPage) if (count > Pages.ItemsPerPage)
{ {
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
Pages.CurrentPageLabel(); Pages.CurrentPageLabel();
@ -255,7 +264,7 @@ namespace Explorer.UI
Pages.DrawLimitInputArea(); Pages.DrawLimitInputArea();
GUIUnstrip.Space(5); GUIHelper.Space(5);
} }
int offset = Pages.CalculateOffsetIndex(); int offset = Pages.CalculateOffsetIndex();
@ -267,7 +276,7 @@ namespace Explorer.UI
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry //collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
//GUIUnstrip.Space(whitespace); //GUIUnstrip.Space(whitespace);

View File

@ -6,6 +6,11 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using System.Linq;
using Explorer.Helpers;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.UI namespace Explorer.UI
{ {
@ -173,38 +178,20 @@ namespace Explorer.UI
private Type GetEntryType() private Type GetEntryType()
{ {
if (m_entryType == null) if (ValueType.IsGenericType)
{ {
if (OwnerCacheObject is CacheMember cacheMember && cacheMember.MemInfo != null) var gArgs = ValueType.GetGenericArguments();
{
Type memberType = null;
switch (cacheMember.MemInfo.MemberType)
{
case MemberTypes.Field:
memberType = (cacheMember.MemInfo as FieldInfo).FieldType;
break;
case MemberTypes.Property:
memberType = (cacheMember.MemInfo as PropertyInfo).PropertyType;
break;
}
if (memberType != null && memberType.IsGenericType) if (ValueType.FullName.Contains("ValueCollection"))
{ {
m_entryType = memberType.GetGenericArguments()[0]; m_entryType = gArgs[gArgs.Length - 1];
} }
} else
else if (Value != null)
{ {
var type = Value.GetType(); m_entryType = gArgs[0];
if (type.IsGenericType)
{
m_entryType = type.GetGenericArguments()[0];
} }
} }
} else
// use System.Object for non-generic.
if (m_entryType == null)
{ {
m_entryType = typeof(object); m_entryType = typeof(object);
} }
@ -255,18 +242,11 @@ namespace Explorer.UI
} }
#endif #endif
//ExplorerCore.Log("Caching enumeration entry " + obj.ToString() + " as " + EntryType.FullName);
var cached = new CacheEnumerated() { Index = index, RefIList = Value as IList, ParentEnumeration = this }; var cached = new CacheEnumerated() { Index = index, RefIList = Value as IList, ParentEnumeration = this };
cached.Init(obj, EntryType); cached.Init(obj, EntryType);
list.Add(cached); list.Add(cached);
//if (CacheFactory.GetCacheObject(obj, t) is CacheObjectBase cached)
//{
// list.Add(cached);
//}
//else
//{
// list.Add(null);
//}
} }
else else
{ {
@ -318,7 +298,7 @@ namespace Explorer.UI
} }
GUI.skin.button.alignment = TextAnchor.MiddleCenter; GUI.skin.button.alignment = TextAnchor.MiddleCenter;
GUIUnstrip.Space(5); GUIHelper.Space(5);
if (IsExpanded) if (IsExpanded)
{ {
@ -327,9 +307,9 @@ namespace Explorer.UI
if (count > Pages.ItemsPerPage) if (count > Pages.ItemsPerPage)
{ {
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
Pages.CurrentPageLabel(); Pages.CurrentPageLabel();
@ -345,7 +325,7 @@ namespace Explorer.UI
Pages.DrawLimitInputArea(); Pages.DrawLimitInputArea();
GUIUnstrip.Space(5); GUIHelper.Space(5);
} }
int offset = Pages.CalculateOffsetIndex(); int offset = Pages.CalculateOffsetIndex();
@ -356,9 +336,9 @@ namespace Explorer.UI
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry //collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (entry == null || entry.IValue == null) if (entry == null || entry.IValue == null)
{ {

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Explorer.Helpers;
using UnityEngine;
namespace Explorer.UI
{
public class InteractiveSprite : InteractiveTexture2D
{
private Sprite refSprite;
public override void Init()
{
base.Init();
}
public override void UpdateValue()
{
#if CPP
if (Value != null && Value.Il2CppCast(typeof(Sprite)) is Sprite sprite)
{
refSprite = sprite;
}
#else
if (Value is Sprite sprite)
{
refSprite = sprite;
}
#endif
base.UpdateValue();
}
public override void GetTexture2D()
{
if (refSprite && refSprite.texture)
{
currentTex = refSprite.texture;
}
}
public override void GetGUIContent()
{
// Check if the Sprite.textureRect is just the entire texture
if (refSprite.textureRect != new Rect(0, 0, currentTex.width, currentTex.height))
{
// It's not, do a sub-copy.
currentTex = Texture2DHelpers.Copy(refSprite.texture, refSprite.textureRect);
}
base.GetGUIContent();
}
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Explorer.UI
{
// This class is possibly unnecessary.
// It's just for CacheMembers that have 'Texture' as the value type, but is actually a Texture2D.
public class InteractiveTexture : InteractiveTexture2D
{
public override void GetTexture2D()
{
#if CPP
if (Value != null && Value.Il2CppCast(typeof(Texture2D)) is Texture2D tex)
#else
if (Value is Texture2D tex)
#endif
{
currentTex = tex;
texContent = new GUIContent
{
image = currentTex
};
}
}
}
}

View File

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Explorer.CacheObject;
using Explorer.Config;
using UnityEngine;
using System.IO;
using Explorer.Helpers;
#if CPP
using Explorer.Unstrip.ImageConversion;
#endif
namespace Explorer.UI
{
public class InteractiveTexture2D : InteractiveValue, IExpandHeight
{
public bool IsExpanded { get; set; }
public float WhiteSpace { get; set; } = 215f;
public Texture2D currentTex;
public GUIContent texContent;
private string saveFolder = ModConfig.Instance.Default_Output_Path;
public override void Init()
{
base.Init();
}
public override void UpdateValue()
{
base.UpdateValue();
GetTexture2D();
}
public virtual void GetTexture2D()
{
#if CPP
if (Value != null && Value.Il2CppCast(typeof(Texture2D)) is Texture2D tex)
#else
if (Value is Texture2D tex)
#endif
{
currentTex = tex;
}
}
public virtual void GetGUIContent()
{
texContent = new GUIContent
{
image = currentTex
};
}
public override void DrawValue(Rect window, float width)
{
GUIHelper.BeginVertical();
GUIHelper.BeginHorizontal();
if (currentTex && !IsExpanded)
{
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = true;
GetGUIContent();
}
}
else if (currentTex)
{
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
{
IsExpanded = false;
}
}
base.DrawValue(window, width);
GUILayout.EndHorizontal();
if (currentTex && IsExpanded)
{
DrawTextureControls();
DrawTexture();
}
GUILayout.EndVertical();
}
// Temporarily disabled in BepInEx IL2CPP.
private void DrawTexture()
{
#if CPP
#if BIE
#else
GUILayout.Label(texContent, new GUILayoutOption[0]);
#endif
#else
GUILayout.Label(texContent, new GUILayoutOption[0]);
#endif
}
private void DrawTextureControls()
{
GUIHelper.BeginHorizontal();
GUILayout.Label("Save folder:", new GUILayoutOption[] { GUILayout.Width(80f) });
saveFolder = GUIHelper.TextField(saveFolder, new GUILayoutOption[0]);
GUIHelper.Space(10f);
GUILayout.EndHorizontal();
if (GUILayout.Button("Save to PNG", new GUILayoutOption[] { GUILayout.Width(100f) }))
{
var name = RemoveInvalidFilenameChars(currentTex.name ?? "");
if (string.IsNullOrEmpty(name))
{
if (OwnerCacheObject is CacheMember cacheMember)
{
name = cacheMember.MemInfo.Name;
}
else
{
name = "UNTITLED";
}
}
Texture2DHelpers.SaveTextureAsPNG(currentTex, saveFolder, name, false);
ExplorerCore.Log($@"Saved to {saveFolder}\{name}.png!");
}
}
private string RemoveInvalidFilenameChars(string s)
{
var invalid = System.IO.Path.GetInvalidFileNameChars();
foreach (var c in invalid)
{
s = s.Replace(c.ToString(), "");
}
return s;
}
}
}

View File

@ -63,40 +63,40 @@ namespace Explorer.UI
var whitespace = CalcWhitespace(window); var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("R:", new GUILayoutOption[] { GUILayout.Width(30) });
r = GUIUnstrip.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) }); r = GUIHelper.TextField(r, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("G:", new GUILayoutOption[] { GUILayout.Width(30) });
g = GUIUnstrip.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) }); g = GUIHelper.TextField(g, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("B:", new GUILayoutOption[] { GUILayout.Width(30) });
b = GUIUnstrip.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) }); b = GUIHelper.TextField(b, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("A:", new GUILayoutOption[] { GUILayout.Width(30) });
a = GUIUnstrip.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) }); a = GUIHelper.TextField(a, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// draw set value button // draw set value button
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) })) if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{ {
SetValueFromInput(); SetValueFromInput();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
} }

View File

@ -75,23 +75,23 @@ namespace Explorer.UI
for (int i = 0; i < EnumNames.Length; i++) for (int i = 0; i < EnumNames.Length; i++)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
m_enabledFlags[i] = GUILayout.Toggle(m_enabledFlags[i], EnumNames[i], new GUILayoutOption[0]); m_enabledFlags[i] = GUILayout.Toggle(m_enabledFlags[i], EnumNames[i], new GUILayoutOption[0]);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) })) if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{ {
SetFlagsFromInput(); SetFlagsFromInput();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
} }

View File

@ -80,12 +80,13 @@ namespace Explorer.UI
if (OwnerCacheObject.CanWrite) if (OwnerCacheObject.CanWrite)
{ {
b = GUILayout.Toggle(b, label, new GUILayoutOption[0]); Value = GUILayout.Toggle(b, label, new GUILayoutOption[] { GUILayout.Width(60) });
if (b != (bool)Value) DrawApplyButton();
{ //if (b != (bool)Value)
Value = b; //{
OwnerCacheObject.SetValue(); // Value = b;
} // OwnerCacheObject.SetValue();
//}
} }
else else
{ {
@ -97,27 +98,22 @@ namespace Explorer.UI
// all other non-bool values use TextField // all other non-bool values use TextField
GUIUnstrip.BeginVertical(new GUILayoutOption[0]); GUIHelper.BeginVertical(new GUILayoutOption[0]);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) }); GUILayout.Label("<color=#2df7b2><i>" + ValueType.Name + "</i></color>", new GUILayoutOption[] { GUILayout.Width(50) });
m_valueToString = GUIUnstrip.TextArea(m_valueToString, new GUILayoutOption[] { GUILayout.ExpandWidth(true) }); m_valueToString = GUIHelper.TextArea(m_valueToString, new GUILayoutOption[] { GUIHelper.ExpandWidth(true) });
if (OwnerCacheObject.CanWrite)
{ DrawApplyButton();
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
{
SetValueFromInput();
}
}
if (ModConfig.Instance.Bitwise_Support && m_canBitwiseOperate) if (ModConfig.Instance.Bitwise_Support && m_canBitwiseOperate)
{ {
m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]); m_inBitwiseMode = GUILayout.Toggle(m_inBitwiseMode, "Bitwise?", new GUILayoutOption[0]);
} }
GUIUnstrip.Space(10); GUIHelper.Space(10);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
@ -129,11 +125,29 @@ namespace Explorer.UI
GUILayout.EndVertical(); GUILayout.EndVertical();
} }
private void DrawApplyButton()
{
if (OwnerCacheObject.CanWrite)
{
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
{
if (m_isBool)
{
OwnerCacheObject.SetValue();
}
else
{
SetValueFromInput();
}
}
}
}
private void DrawBitwise() private void DrawBitwise()
{ {
if (OwnerCacheObject.CanWrite) if (OwnerCacheObject.CanWrite)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight; GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) }); GUILayout.Label("RHS:", new GUILayoutOption[] { GUILayout.Width(35) });
@ -189,14 +203,14 @@ namespace Explorer.UI
} }
} }
m_bitwiseOperatorInput = GUIUnstrip.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) }); m_bitwiseOperatorInput = GUIHelper.TextField(m_bitwiseOperatorInput, new GUILayoutOption[] { GUILayout.Width(55) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) }); GUILayout.Label($"<color=cyan>Binary:</color>", new GUILayoutOption[] { GUILayout.Width(60) });
m_binaryInput = GUIUnstrip.TextField(m_binaryInput, new GUILayoutOption[0]); m_binaryInput = GUIHelper.TextField(m_binaryInput, new GUILayoutOption[0]);
if (OwnerCacheObject.CanWrite) if (OwnerCacheObject.CanWrite)
{ {
if (GUILayout.Button("Apply", new GUILayoutOption[0])) if (GUILayout.Button("Apply", new GUILayoutOption[0]))

View File

@ -58,34 +58,34 @@ namespace Explorer.UI
var whitespace = CalcWhitespace(window); var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); z = GUIHelper.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// draw set value button // draw set value button
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) })) if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{ {
SetValueFromInput(); SetValueFromInput();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
} }

View File

@ -60,40 +60,40 @@ namespace Explorer.UI
var whitespace = CalcWhitespace(window); var whitespace = CalcWhitespace(window);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); w = GUIHelper.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("H:", new GUILayoutOption[] { GUILayout.Width(30) });
h = GUIUnstrip.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) }); h = GUIHelper.TextField(h, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// draw set value button // draw set value button
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) })) if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{ {
SetValueFromInput(); SetValueFromInput();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
} }

View File

@ -100,47 +100,47 @@ namespace Explorer.UI
var whitespace = CalcWhitespace(window); var whitespace = CalcWhitespace(window);
// always draw x and y // always draw x and y
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("X:", new GUILayoutOption[] { GUILayout.Width(30) });
x = GUIUnstrip.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) }); x = GUIHelper.TextField(x, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("Y:", new GUILayoutOption[] { GUILayout.Width(30) });
y = GUIUnstrip.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) }); y = GUIHelper.TextField(y, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
if (VectorSize > 2) if (VectorSize > 2)
{ {
// draw z // draw z
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("Z:", new GUILayoutOption[] { GUILayout.Width(30) });
z = GUIUnstrip.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) }); z = GUIHelper.TextField(z, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
if (VectorSize > 3) if (VectorSize > 3)
{ {
// draw w // draw w
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) }); GUILayout.Label("W:", new GUILayoutOption[] { GUILayout.Width(30) });
w = GUIUnstrip.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) }); w = GUIHelper.TextField(w, new GUILayoutOption[] { GUILayout.Width(120) });
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
} }
// draw set value button // draw set value button
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUIUnstrip.Space(whitespace); GUIHelper.Space(whitespace);
if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) })) if (GUILayout.Button("<color=lime>Apply</color>", new GUILayoutOption[] { GUILayout.Width(155) }))
{ {
SetValueFromInput(); SetValueFromInput();
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
} }

View File

@ -8,6 +8,8 @@ using System.Reflection;
using System.IO; using System.IO;
#if CPP #if CPP
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
using TextEditor = Explorer.Unstrip.IMGUI.TextEditorUnstrip;
using Explorer.Unstrip.IMGUI;
#endif #endif
namespace Explorer.UI.Main namespace Explorer.UI.Main
@ -33,7 +35,7 @@ namespace Explorer.UI.Main
public static TextEditor textEditor; public static TextEditor textEditor;
private bool shouldRefocus; private bool shouldRefocus;
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetCompletionStyle(); public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetAutocompleteStyle();
private static GUIStyle autocompleteStyle; private static GUIStyle autocompleteStyle;
public static readonly string[] DefaultUsing = new string[] public static readonly string[] DefaultUsing = new string[]
@ -140,15 +142,15 @@ Help();";
GUILayout.Label("Enter code here as though it is a method body:", new GUILayoutOption[0]); GUILayout.Label("Enter code here as though it is a method body:", new GUILayoutOption[0]);
inputAreaScroll = GUIUnstrip.BeginScrollView( inputAreaScroll = GUIHelper.BeginScrollView(
inputAreaScroll, inputAreaScroll,
new GUILayoutOption[] { GUILayout.Height(250), GUILayout.ExpandHeight(true) } new GUILayoutOption[] { GUILayout.Height(250), GUIHelper.ExpandHeight(true) }
); );
GUI.SetNextControlName(INPUT_CONTROL_NAME); GUI.SetNextControlName(INPUT_CONTROL_NAME);
m_input = GUIUnstrip.TextArea(m_input, new GUILayoutOption[] { GUILayout.ExpandHeight(true) }); m_input = GUIHelper.TextArea(m_input, new GUILayoutOption[] { GUIHelper.ExpandHeight(true) });
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
// EXECUTE BUTTON // EXECUTE BUTTON
@ -179,7 +181,7 @@ Help();";
// SUGGESTIONS // SUGGESTIONS
if (AutoCompletes.Count > 0) if (AutoCompletes.Count > 0)
{ {
autocompleteScroll = GUIUnstrip.BeginScrollView(autocompleteScroll, new GUILayoutOption[] { GUILayout.Height(150) }); autocompleteScroll = GUIHelper.BeginScrollView(autocompleteScroll, new GUILayoutOption[] { GUILayout.Height(150) });
var origSkin = GUI.skin.button; var origSkin = GUI.skin.button;
GUI.skin.button = AutocompleteStyle; GUI.skin.button = AutocompleteStyle;
@ -196,7 +198,7 @@ Help();";
GUI.skin.button = origSkin; GUI.skin.button = origSkin;
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
} }
if (shouldRefocus) if (shouldRefocus)
@ -209,9 +211,9 @@ Help();";
GUILayout.Label("<b>Using directives:</b>", new GUILayoutOption[0]); GUILayout.Label("<b>Using directives:</b>", new GUILayoutOption[0]);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) }); GUILayout.Label("Add namespace:", new GUILayoutOption[] { GUILayout.Width(105) });
m_usingInput = GUIUnstrip.TextField(m_usingInput, new GUILayoutOption[] { GUILayout.Width(150) }); m_usingInput = GUIHelper.TextField(m_usingInput, new GUILayoutOption[] { GUILayout.Width(150) });
if (GUILayout.Button("<b><color=lime>Add</color></b>", new GUILayoutOption[] { GUILayout.Width(120) })) if (GUILayout.Button("<b><color=lime>Add</color></b>", new GUILayoutOption[] { GUILayout.Width(120) }))
{ {
AddUsing(m_usingInput); AddUsing(m_usingInput);
@ -245,7 +247,8 @@ Help();";
#endif #endif
#if CPP #if CPP
textEditor = GUIUtility.GetStateObject(Il2CppType.Of<TextEditor>(), GUIUtility.keyboardControl).TryCast<TextEditor>(); //textEditor = GUIUtility.GetStateObject(Il2CppType.Of<TextEditor>(), GUIUtility.keyboardControl).TryCast<TextEditor>();
textEditor = (TextEditor)GUIUtilityUnstrip.GetMonoStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
#else #else
textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl); textEditor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
#endif #endif
@ -342,19 +345,21 @@ Help();";
} }
// Credit ManlyMarco // Credit ManlyMarco
private static GUIStyle GetCompletionStyle() private static GUIStyle GetAutocompleteStyle()
{ {
return autocompleteStyle = new GUIStyle(GUI.skin.button) var style = new GUIStyle
{ {
border = new RectOffset(0, 0, 0, 0), border = new RectOffset(),
margin = new RectOffset(0, 0, 0, 0), margin = new RectOffset(),
padding = new RectOffset(0, 0, 0, 0), padding = new RectOffset(),
hover = { background = Texture2D.whiteTexture, textColor = Color.black }, hover = { background = Texture2D.whiteTexture, textColor = Color.black },
normal = { background = null }, normal = { background = null },
focused = { background = Texture2D.whiteTexture, textColor = Color.black }, focused = { background = Texture2D.whiteTexture, textColor = Color.black },
active = { background = Texture2D.whiteTexture, textColor = Color.black }, active = { background = Texture2D.whiteTexture, textColor = Color.black },
alignment = TextAnchor.MiddleLeft, alignment = TextAnchor.MiddleLeft
}; };
return autocompleteStyle = style;
} }
private class VoidType private class VoidType

View File

@ -18,12 +18,14 @@ namespace Explorer.UI.Main
public int defaultPageLimit; public int defaultPageLimit;
public bool bitwiseSupport; public bool bitwiseSupport;
public bool tabView; public bool tabView;
public string defaultOutputPath;
private CacheObjectBase toggleKeyInput; private CacheObjectBase toggleKeyInput;
private CacheObjectBase defaultSizeInput; private CacheObjectBase defaultSizeInput;
private CacheObjectBase defaultPageLimitInput; private CacheObjectBase defaultPageLimitInput;
private CacheObjectBase bitwiseSupportInput; private CacheObjectBase bitwiseSupportInput;
private CacheObjectBase tabViewInput; private CacheObjectBase tabViewInput;
private CacheObjectBase defaultOutputPathInput;
public override void Init() public override void Init()
{ {
@ -41,6 +43,9 @@ namespace Explorer.UI.Main
tabView = ModConfig.Instance.Tab_View; tabView = ModConfig.Instance.Tab_View;
tabViewInput = CacheFactory.GetCacheObject(typeof(OptionsPage).GetField("tabView"), this); tabViewInput = CacheFactory.GetCacheObject(typeof(OptionsPage).GetField("tabView"), this);
defaultOutputPath = ModConfig.Instance.Default_Output_Path;
defaultOutputPathInput = CacheFactory.GetCacheObject(typeof(OptionsPage).GetField("defaultOutputPath"), this);
} }
public override void Update() { } public override void Update() { }
@ -51,33 +56,48 @@ namespace Explorer.UI.Main
GUILayout.Label("<color=orange><size=16><b>Options</b></size></color>", new GUILayoutOption[0]); GUILayout.Label("<color=orange><size=16><b>Options</b></size></color>", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Menu Toggle Key:", new GUILayoutOption[] { GUILayout.Width(215f) }); GUILayout.Label($"Menu Toggle Key:", new GUILayoutOption[] { GUILayout.Width(215f) });
toggleKeyInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f); toggleKeyInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); UIStyles.HorizontalLine(Color.black, true);
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Default Window Size:", new GUILayoutOption[] { GUILayout.Width(215f) }); GUILayout.Label($"Default Window Size:", new GUILayoutOption[] { GUILayout.Width(215f) });
defaultSizeInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f); defaultSizeInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); UIStyles.HorizontalLine(Color.black, true);
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Default Items per Page:", new GUILayoutOption[] { GUILayout.Width(215f) }); GUILayout.Label($"Default Items per Page:", new GUILayoutOption[] { GUILayout.Width(215f) });
defaultPageLimitInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f); defaultPageLimitInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); UIStyles.HorizontalLine(Color.black, true);
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Enable Bitwise Editing:", new GUILayoutOption[] { GUILayout.Width(215f) }); GUILayout.Label($"Enable Bitwise Editing:", new GUILayoutOption[] { GUILayout.Width(215f) });
bitwiseSupportInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f); bitwiseSupportInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); UIStyles.HorizontalLine(Color.black, true);
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Enable Tab View:", new GUILayoutOption[] { GUILayout.Width(215f) }); GUILayout.Label($"Enable Tab View:", new GUILayoutOption[] { GUILayout.Width(215f) });
tabViewInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f); tabViewInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Default Output Path:", new GUILayoutOption[] { GUILayout.Width(215f) });
defaultOutputPathInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
if (GUILayout.Button("<color=lime><b>Apply and Save</b></color>", new GUILayoutOption[0])) if (GUILayout.Button("<color=lime><b>Apply and Save</b></color>", new GUILayoutOption[0]))
{ {
ApplyAndSave(); ApplyAndSave();
@ -85,13 +105,13 @@ namespace Explorer.UI.Main
GUILayout.EndVertical(); GUILayout.EndVertical();
GUIUnstrip.Space(10f); GUIHelper.Space(10f);
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("<color=orange><size=16><b>Other</b></size></color>", new GUILayoutOption[0]); GUILayout.Label("<color=orange><size=16><b>Other</b></size></color>", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, new GUILayoutOption[0]);
if (GUILayout.Button("Inspect Test Class", new GUILayoutOption[0])) if (GUILayout.Button("Inspect Test Class", new GUILayoutOption[0]))
{ {

View File

@ -5,6 +5,8 @@ using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using Explorer.Helpers;
using Explorer.Unstrip.Resources;
namespace Explorer.UI.Main namespace Explorer.UI.Main
{ {
@ -19,8 +21,6 @@ namespace Explorer.UI.Main
private float m_timeOfLastUpdate = -1f; private float m_timeOfLastUpdate = -1f;
private const int PASSIVE_UPDATE_INTERVAL = 1; private const int PASSIVE_UPDATE_INTERVAL = 1;
private static bool m_getRootObjectsFailed;
private static string m_currentScene = ""; private static string m_currentScene = "";
// gameobject list // gameobject list
@ -35,6 +35,7 @@ namespace Explorer.UI.Main
public override void Init() public override void Init()
{ {
Instance = this; Instance = this;
m_currentScene = UnityHelpers.ActiveSceneName;
} }
public void OnSceneChange() public void OnSceneChange()
@ -50,7 +51,7 @@ namespace Explorer.UI.Main
if (m_searching) if (m_searching)
CancelSearch(); CancelSearch();
Update_Impl(true); Update_Impl();
} }
public void TraverseUp() public void TraverseUp()
@ -75,18 +76,13 @@ namespace Explorer.UI.Main
public void CancelSearch() public void CancelSearch()
{ {
m_searching = false; m_searching = false;
if (m_getRootObjectsFailed && !m_currentTransform)
{
GetRootObjectsManual_Impl();
}
} }
public List<CacheObjectBase> SearchSceneObjects(string _search) public List<CacheObjectBase> SearchSceneObjects(string _search)
{ {
var matches = new List<CacheObjectBase>(); var matches = new List<CacheObjectBase>();
foreach (var obj in Resources.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType)) foreach (var obj in ResourcesUnstrip.FindObjectsOfTypeAll(ReflectionHelpers.GameObjectType))
{ {
#if CPP #if CPP
var go = obj.TryCast<GameObject>(); var go = obj.TryCast<GameObject>();
@ -112,7 +108,7 @@ namespace Explorer.UI.Main
Update_Impl(); Update_Impl();
} }
private void Update_Impl(bool manual = false) private void Update_Impl()
{ {
List<Transform> allTransforms = new List<Transform>(); List<Transform> allTransforms = new List<Transform>();
@ -125,10 +121,6 @@ namespace Explorer.UI.Main
} }
} }
else else
{
if (!m_getRootObjectsFailed)
{
try
{ {
for (int i = 0; i < SceneManager.sceneCount; i++) for (int i = 0; i < SceneManager.sceneCount; i++)
{ {
@ -136,31 +128,19 @@ namespace Explorer.UI.Main
if (scene.name == m_currentScene) if (scene.name == m_currentScene)
{ {
allTransforms.AddRange(scene.GetRootGameObjects() var rootObjects =
.Select(it => it.transform)); #if CPP
Unstrip.Scenes.SceneUnstrip.GetRootGameObjects(scene)
.Select(it => it.transform);
#else
scene.GetRootGameObjects().Select(it => it.transform);
#endif
allTransforms.AddRange(rootObjects);
break; break;
} }
} }
} }
catch
{
ExplorerCore.Log("Exception getting root scene objects, falling back to backup method...");
m_getRootObjectsFailed = true;
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
else
{
if (!manual)
{
return;
}
allTransforms.AddRange(GetRootObjectsManual_Impl());
}
}
Pages.ItemCount = allTransforms.Count; Pages.ItemCount = allTransforms.Count;
@ -178,36 +158,6 @@ namespace Explorer.UI.Main
} }
} }
private IEnumerable<Transform> GetRootObjectsManual_Impl()
{
try
{
var array = Resources.FindObjectsOfTypeAll(ReflectionHelpers.TransformType);
var list = new List<Transform>();
foreach (var obj in array)
{
#if CPP
var transform = obj.TryCast<Transform>();
#else
var transform = obj as Transform;
#endif
if (transform.parent == null && transform.gameObject.scene.name == m_currentScene)
{
list.Add(transform);
}
}
return list;
}
catch (Exception e)
{
ExplorerCore.Log("Exception getting root scene objects (manual): "
+ e.GetType() + ", " + e.Message + "\r\n"
+ e.StackTrace);
return new Transform[0];
}
}
// --------- GUI Draw Function --------- // // --------- GUI Draw Function --------- //
public override void DrawWindow() public override void DrawWindow()
@ -216,7 +166,7 @@ namespace Explorer.UI.Main
{ {
DrawHeaderArea(); DrawHeaderArea();
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
DrawPageButtons(); DrawPageButtons();
@ -242,7 +192,7 @@ namespace Explorer.UI.Main
private void DrawHeaderArea() private void DrawHeaderArea()
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
// Current Scene label // Current Scene label
GUILayout.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) }); GUILayout.Label("Current Scene:", new GUILayoutOption[] { GUILayout.Width(120) });
@ -252,10 +202,10 @@ namespace Explorer.UI.Main
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
// ----- GameObject Search ----- // ----- GameObject Search -----
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUILayout.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) }); GUILayout.Label("<b>Search Scene:</b>", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[0]); m_searchInput = GUIHelper.TextField(m_searchInput, new GUILayoutOption[0]);
if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) })) if (GUILayout.Button("Search", new GUILayoutOption[] { GUILayout.Width(80) }))
{ {
@ -263,7 +213,7 @@ namespace Explorer.UI.Main
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.Space(5); GUIHelper.Space(5);
} }
private void SceneChangeButtons() private void SceneChangeButtons()
@ -292,22 +242,19 @@ namespace Explorer.UI.Main
{ {
int index = names.IndexOf(m_currentScene); int index = names.IndexOf(m_currentScene);
index += changeWanted; index += changeWanted;
if (index > scenes.Count - 1)
if (index >= 0 && index < SceneManager.sceneCount)
{ {
index = 0;
}
else if (index < 0)
{
index = scenes.Count - 1;
}
m_currentScene = scenes[index].name; m_currentScene = scenes[index].name;
Update_Impl();
}
} }
} }
} }
private void DrawPageButtons() private void DrawPageButtons()
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
Pages.DrawLimitInputArea(); Pages.DrawLimitInputArea();
@ -317,7 +264,7 @@ namespace Explorer.UI.Main
{ {
Pages.TurnPage(Turn.Left, ref this.scroll); Pages.TurnPage(Turn.Left, ref this.scroll);
Update_Impl(true); Update_Impl();
} }
Pages.CurrentPageLabel(); Pages.CurrentPageLabel();
@ -326,7 +273,7 @@ namespace Explorer.UI.Main
{ {
Pages.TurnPage(Turn.Right, ref this.scroll); Pages.TurnPage(Turn.Right, ref this.scroll);
Update_Impl(true); Update_Impl();
} }
} }
@ -338,7 +285,7 @@ namespace Explorer.UI.Main
{ {
if (m_currentTransform != null) if (m_currentTransform != null)
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) })) if (GUILayout.Button("<-", new GUILayoutOption[] { GUILayout.Width(35) }))
{ {
TraverseUp(); TraverseUp();
@ -356,14 +303,6 @@ namespace Explorer.UI.Main
else else
{ {
GUILayout.Label("Scene Root GameObjects:", new GUILayoutOption[0]); GUILayout.Label("Scene Root GameObjects:", new GUILayoutOption[0]);
if (m_getRootObjectsFailed)
{
if (GUILayout.Button("Update Root Object List (auto-update failed!)", new GUILayoutOption[0]))
{
Update_Impl(true);
}
}
} }
if (m_objectList.Count > 0) if (m_objectList.Count > 0)

View File

@ -6,6 +6,8 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Explorer.UI.Shared; using Explorer.UI.Shared;
using Explorer.CacheObject; using Explorer.CacheObject;
using Explorer.Helpers;
using Explorer.Unstrip.Resources;
namespace Explorer.UI.Main namespace Explorer.UI.Main
{ {
@ -15,9 +17,13 @@ namespace Explorer.UI.Main
public override string Name { get => "Search"; } public override string Name { get => "Search"; }
private int MaxSearchResults = 5000;
private string m_searchInput = ""; private string m_searchInput = "";
private string m_typeInput = ""; private string m_typeInput = "";
//private bool m_cachingResults;
private Vector2 resultsScroll = Vector2.zero; private Vector2 resultsScroll = Vector2.zero;
public PageHelper Pages = new PageHelper(); public PageHelper Pages = new PageHelper();
@ -58,6 +64,8 @@ namespace Explorer.UI.Main
private void CacheResults(IEnumerable results, bool isStaticClasses = false) private void CacheResults(IEnumerable results, bool isStaticClasses = false)
{ {
//m_cachingResults = true;
m_searchResults = new List<CacheObjectBase>(); m_searchResults = new List<CacheObjectBase>();
foreach (var obj in results) foreach (var obj in results)
@ -67,6 +75,9 @@ namespace Explorer.UI.Main
#if CPP #if CPP
if (toCache is Il2CppSystem.Object ilObject) if (toCache is Il2CppSystem.Object ilObject)
{ {
var type = ReflectionHelpers.GetActualType(ilObject);
ilObject = (Il2CppSystem.Object)ilObject.Il2CppCast(type);
toCache = ilObject.TryCast<GameObject>() ?? ilObject.TryCast<Transform>()?.gameObject ?? ilObject; toCache = ilObject.TryCast<GameObject>() ?? ilObject.TryCast<Transform>()?.gameObject ?? ilObject;
} }
#else #else
@ -76,6 +87,14 @@ namespace Explorer.UI.Main
} }
#endif #endif
if (toCache is TextAsset textAsset)
{
if (string.IsNullOrEmpty(textAsset.text))
{
continue;
}
}
var cache = CacheFactory.GetCacheObject(toCache); var cache = CacheFactory.GetCacheObject(toCache);
cache.IsStaticClassSearchResult = isStaticClasses; cache.IsStaticClassSearchResult = isStaticClasses;
m_searchResults.Add(cache); m_searchResults.Add(cache);
@ -83,187 +102,22 @@ namespace Explorer.UI.Main
Pages.ItemCount = m_searchResults.Count; Pages.ItemCount = m_searchResults.Count;
Pages.PageOffset = 0; Pages.PageOffset = 0;
results = null;
//m_cachingResults = false;
} }
public override void DrawWindow()
{
try
{
// helpers
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUILayout.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
if (GUILayout.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
{
CacheResults(GetStaticInstances());
}
if (GUILayout.Button("Find Static Classes", new GUILayoutOption[] { GUILayout.Width(180) }))
{
CacheResults(GetStaticClasses(), true);
}
GUILayout.EndHorizontal();
// search box
SearchBox();
// results
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
int count = m_searchResults.Count;
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
Pages.DrawLimitInputArea();
if (count > Pages.ItemsPerPage)
{
// prev/next page buttons
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.resultsScroll);
}
Pages.CurrentPageLabel();
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.resultsScroll);
}
}
}
GUILayout.EndHorizontal();
resultsScroll = GUIUnstrip.BeginScrollView(resultsScroll);
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
if (m_searchResults.Count > 0)
{
int offset = Pages.CalculateOffsetIndex();
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
{
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
}
}
else
{
GUILayout.Label("<color=red><i>No results found!</i></color>", new GUILayoutOption[0]);
}
GUIUnstrip.EndScrollView();
GUILayout.EndVertical();
}
catch
{
m_searchResults.Clear();
}
}
private void SearchBox()
{
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
// ----- GameObject Search -----
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("<b><color=orange>Search</color></b>", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIUnstrip.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
ClassFilterToggle(TypeFilter.Object, "Object");
ClassFilterToggle(TypeFilter.GameObject, "GameObject");
ClassFilterToggle(TypeFilter.Component, "Component");
ClassFilterToggle(TypeFilter.Custom, "Custom");
GUILayout.EndHorizontal();
if (TypeMode == TypeFilter.Custom)
{
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
GUI.skin.label.alignment = TextAnchor.UpperLeft;
m_typeInput = GUIUnstrip.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.EndHorizontal();
}
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
SceneFilterToggle(SceneFilter.Any, "Any", 60);
SceneFilterToggle(SceneFilter.This, "This Scene", 100);
SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140);
SceneFilterToggle(SceneFilter.None, "No Scene", 80);
GUILayout.EndHorizontal();
if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
{
Search();
}
GUILayout.EndVertical();
}
private void ClassFilterToggle(TypeFilter mode, string label)
{
if (TypeMode == mode)
{
GUI.color = Color.green;
}
else
{
GUI.color = Color.white;
}
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
{
TypeMode = mode;
}
GUI.color = Color.white;
}
private void SceneFilterToggle(SceneFilter mode, string label, float width)
{
if (SceneMode == mode)
{
GUI.color = Color.green;
}
else
{
GUI.color = Color.white;
}
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
{
SceneMode = mode;
}
GUI.color = Color.white;
}
// -------------- ACTUAL METHODS (not Gui draw) ----------------- //
// ======= search functions =======
private void Search() private void Search()
{ {
Pages.PageOffset = 0; //if (m_cachingResults)
CacheResults(FindAllObjectsOfType(m_searchInput, m_typeInput)); //{
} // ExplorerCore.Log("Cannot search now, we are already caching results...");
// return;
//}
Pages.PageOffset = 0;
private List<object> FindAllObjectsOfType(string searchQuery, string typeName)
{
#if CPP #if CPP
Il2CppSystem.Type searchType = null; Il2CppSystem.Type searchType = null;
@ -272,9 +126,7 @@ namespace Explorer.UI.Main
#endif #endif
if (TypeMode == TypeFilter.Custom) if (TypeMode == TypeFilter.Custom)
{ {
try if (ReflectionHelpers.GetTypeByName(m_typeInput) is Type t)
{
if (ReflectionHelpers.GetTypeByName(typeName) is Type t)
{ {
#if CPP #if CPP
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName); searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
@ -284,12 +136,8 @@ namespace Explorer.UI.Main
} }
else else
{ {
throw new Exception($"Could not find a Type by the name of '{typeName}'!"); ExplorerCore.Log($"Could not find a Type by the name of '{m_typeInput}'!");
} return;
}
catch (Exception e)
{
ExplorerCore.Log("Exception getting Search Type: " + e.GetType() + ", " + e.Message);
} }
} }
else if (TypeMode == TypeFilter.Object) else if (TypeMode == TypeFilter.Object)
@ -311,21 +159,21 @@ namespace Explorer.UI.Main
{ {
ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!"); ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!");
} }
return new List<object>(); return;
} }
var matches = new List<object>(); var matches = new List<object>();
var allObjectsOfType = Resources.FindObjectsOfTypeAll(searchType); var allObjectsOfType = ResourcesUnstrip.FindObjectsOfTypeAll(searchType);
//ExplorerCore.Log("Found count: " + allObjectsOfType.Length); //ExplorerCore.Log("Found count: " + allObjectsOfType.Length);
int i = 0; int i = 0;
foreach (var obj in allObjectsOfType) foreach (var obj in allObjectsOfType)
{ {
if (i >= 2000) break; if (i >= MaxSearchResults) break;
if (searchQuery != "" && !obj.name.ToLower().Contains(searchQuery.ToLower())) if (m_searchInput != "" && !obj.name.ToLower().Contains(m_searchInput.ToLower()))
{ {
continue; continue;
} }
@ -355,7 +203,7 @@ namespace Explorer.UI.Main
i++; i++;
} }
return matches; CacheResults(matches);
} }
public static bool FilterScene(object obj, SceneFilter filter) public static bool FilterScene(object obj, SceneFilter filter)
@ -394,8 +242,6 @@ namespace Explorer.UI.Main
return false; return false;
} }
// ====== other ========
private static bool FilterName(string name) private static bool FilterName(string name)
{ {
// Don't really want these instances. // Don't really want these instances.
@ -497,5 +343,202 @@ namespace Explorer.UI.Main
return list; return list;
} }
// =========== GUI DRAW ============= //
public override void DrawWindow()
{
try
{
// helpers
GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUILayout.Label("<b><color=orange>Helpers</color></b>", new GUILayoutOption[] { GUILayout.Width(70) });
if (GUILayout.Button("Find Static Instances", new GUILayoutOption[] { GUILayout.Width(180) }))
{
CacheResults(GetStaticInstances());
}
if (GUILayout.Button("Find Static Classes", new GUILayoutOption[] { GUILayout.Width(180) }))
{
CacheResults(GetStaticClasses(), true);
}
GUILayout.EndHorizontal();
// search box
SearchBox();
// results
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("<b><color=orange>Results </color></b>" + " (" + m_searchResults.Count + ")", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
int count = m_searchResults.Count;
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
Pages.DrawLimitInputArea();
if (count > Pages.ItemsPerPage)
{
// prev/next page buttons
if (Pages.ItemCount > Pages.ItemsPerPage)
{
if (GUILayout.Button("< Prev", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Left, ref this.resultsScroll);
}
Pages.CurrentPageLabel();
if (GUILayout.Button("Next >", new GUILayoutOption[] { GUILayout.Width(80) }))
{
Pages.TurnPage(Turn.Right, ref this.resultsScroll);
}
}
}
GUILayout.EndHorizontal();
resultsScroll = GUIHelper.BeginScrollView(resultsScroll);
var _temprect = new Rect(MainMenu.MainRect.x, MainMenu.MainRect.y, MainMenu.MainRect.width + 160, MainMenu.MainRect.height);
if (m_searchResults.Count > 0)
{
int offset = Pages.CalculateOffsetIndex();
for (int i = offset; i < offset + Pages.ItemsPerPage && i < count; i++)
{
if (i >= m_searchResults.Count) break;
m_searchResults[i].Draw(MainMenu.MainRect, 0f);
}
}
else
{
GUILayout.Label("<color=red><i>No results found!</i></color>", new GUILayoutOption[0]);
}
GUIHelper.EndScrollView();
GUILayout.EndVertical();
}
catch (Exception e)
{
if (!e.Message.Contains("in a group with only"))
{
ExplorerCore.Log("Exception drawing search results!");
while (e != null)
{
ExplorerCore.Log(e);
e = e.InnerException;
}
m_searchResults.Clear();
}
}
}
private void SearchBox()
{
GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
// ----- GameObject Search -----
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("<b><color=orange>Search</color></b>", new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.UpperLeft;
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Name Contains:", new GUILayoutOption[] { GUILayout.Width(100) });
m_searchInput = GUIHelper.TextField(m_searchInput, new GUILayoutOption[] { GUILayout.Width(200) });
GUILayout.Label("Max Results:", new GUILayoutOption[] { GUILayout.Width(100) });
var s = MaxSearchResults.ToString();
s = GUIHelper.TextField(s, new GUILayoutOption[] { GUILayout.Width(80) });
if (int.TryParse(s, out int i))
{
MaxSearchResults = i;
}
GUILayout.EndHorizontal();
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Class Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
ClassFilterToggle(TypeFilter.Object, "Object");
ClassFilterToggle(TypeFilter.GameObject, "GameObject");
ClassFilterToggle(TypeFilter.Component, "Component");
ClassFilterToggle(TypeFilter.Custom, "Custom");
GUILayout.EndHorizontal();
if (TypeMode == TypeFilter.Custom)
{
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.label.alignment = TextAnchor.MiddleRight;
GUILayout.Label("Custom Class:", new GUILayoutOption[] { GUILayout.Width(250) });
GUI.skin.label.alignment = TextAnchor.UpperLeft;
m_typeInput = GUIHelper.TextField(m_typeInput, new GUILayoutOption[] { GUILayout.Width(250) });
GUILayout.EndHorizontal();
}
GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Scene Filter:", new GUILayoutOption[] { GUILayout.Width(100) });
SceneFilterToggle(SceneFilter.Any, "Any", 60);
SceneFilterToggle(SceneFilter.This, "This Scene", 100);
SceneFilterToggle(SceneFilter.DontDestroy, "DontDestroyOnLoad", 140);
SceneFilterToggle(SceneFilter.None, "No Scene", 80);
GUILayout.EndHorizontal();
if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
{
Search();
}
//if (m_cachingResults)
//{
// GUILayout.Label("Searching...", new GUILayoutOption[0]);
//}
//else
//{
// if (GUILayout.Button("<b><color=cyan>Search</color></b>", new GUILayoutOption[0]))
// {
// Search();
// }
//}
GUILayout.EndVertical();
}
private void ClassFilterToggle(TypeFilter mode, string label)
{
if (TypeMode == mode)
{
GUI.color = Color.green;
}
else
{
GUI.color = Color.white;
}
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(100) }))
{
TypeMode = mode;
}
GUI.color = Color.white;
}
private void SceneFilterToggle(SceneFilter mode, string label, float width)
{
if (SceneMode == mode)
{
GUI.color = Color.green;
}
else
{
GUI.color = Color.white;
}
if (GUILayout.Button(label, new GUILayoutOption[] { GUILayout.Width(width) }))
{
SceneMode = mode;
}
GUI.color = Color.white;
}
} }
} }

View File

@ -47,7 +47,7 @@ namespace Explorer.UI
return; return;
} }
m_currentPage = index; m_currentPage = index;
GUIUnstrip.BringWindowToFront(MainWindowID); GUIHelper.BringWindowToFront(MainWindowID);
GUI.FocusWindow(MainWindowID); GUI.FocusWindow(MainWindowID);
} }
@ -58,39 +58,39 @@ namespace Explorer.UI
public void OnGUI() public void OnGUI()
{ {
MainRect = GUIUnstrip.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, ExplorerCore.NAME); MainRect = GUIHelper.Window(MainWindowID, MainRect, (GUI.WindowFunction)MainWindow, ExplorerCore.NAME);
} }
private void MainWindow(int id) private void MainWindow(int id)
{ {
GUI.DragWindow(new Rect(0, 0, MainRect.width - 90, 20)); GUI.DragWindow(new Rect(0, 0, MainRect.width - 90, 20));
if (GUIUnstrip.Button(new Rect(MainRect.width - 90, 2, 80, 20), $"Hide ({ModConfig.Instance.Main_Menu_Toggle})")) if (GUIHelper.Button(new Rect(MainRect.width - 90, 2, 80, 20), $"Hide ({ModConfig.Instance.Main_Menu_Toggle})"))
{ {
ExplorerCore.ShowMenu = false; ExplorerCore.ShowMenu = false;
return; return;
} }
GUIUnstrip.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box); GUIHelper.BeginArea(new Rect(5, 25, MainRect.width - 10, MainRect.height - 35), GUI.skin.box);
MainHeader(); MainHeader();
var page = Pages[m_currentPage]; var page = Pages[m_currentPage];
page.scroll = GUIUnstrip.BeginScrollView(page.scroll); page.scroll = GUIHelper.BeginScrollView(page.scroll);
page.DrawWindow(); page.DrawWindow();
GUIUnstrip.EndScrollView(); GUIHelper.EndScrollView();
MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID); MainRect = ResizeDrag.ResizeWindow(MainRect, MainWindowID);
GUIUnstrip.EndArea(); GUIHelper.EndArea();
} }
private void MainHeader() private void MainHeader()
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
for (int i = 0; i < Pages.Count; i++) for (int i = 0; i < Pages.Count; i++)
{ {
if (m_currentPage == i) if (m_currentPage == i)
@ -105,7 +105,7 @@ namespace Explorer.UI
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.color = Color.white; GUI.color = Color.white;
InspectUnderMouse.EnableInspect = GUILayout.Toggle(InspectUnderMouse.EnableInspect, "Inspect Under Mouse (Shift + RMB)", new GUILayoutOption[0]); InspectUnderMouse.EnableInspect = GUILayout.Toggle(InspectUnderMouse.EnableInspect, "Inspect Under Mouse (Shift + RMB)", new GUILayoutOption[0]);
@ -117,7 +117,7 @@ namespace Explorer.UI
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
//GUIUnstrip.Space(10); //GUIUnstrip.Space(10);
GUIUnstrip.Space(10); GUIHelper.Space(10);
GUI.color = Color.white; GUI.color = Color.white;
} }

View File

@ -59,7 +59,7 @@ namespace Explorer.UI.Shared
// ------ toggle active button ------ // ------ toggle active button ------
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.button.alignment = TextAnchor.UpperLeft; GUI.skin.button.alignment = TextAnchor.UpperLeft;
GUI.color = color; GUI.color = color;

View File

@ -1,4 +1,5 @@
using UnityEngine; using System;
using UnityEngine;
namespace Explorer.UI.Shared namespace Explorer.UI.Shared
{ {
@ -38,7 +39,7 @@ namespace Explorer.UI.Shared
private int CalculateMaxOffset() private int CalculateMaxOffset()
{ {
return MaxPageOffset = (int)Mathf.Ceil((float)(ItemCount / (decimal)ItemsPerPage)) - 1; return MaxPageOffset = (int)Math.Ceiling((float)(ItemCount / (decimal)ItemsPerPage)) - 1;
} }
public void CurrentPageLabel() public void CurrentPageLabel()
@ -94,7 +95,7 @@ namespace Explorer.UI.Shared
{ {
GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) }); GUILayout.Label("Limit: ", new GUILayoutOption[] { GUILayout.Width(50) });
var limit = this.ItemsPerPage.ToString(); var limit = this.ItemsPerPage.ToString();
limit = GUIUnstrip.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) }); limit = GUIHelper.TextField(limit, new GUILayoutOption[] { GUILayout.Width(50) });
if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i)) if (limit != ItemsPerPage.ToString() && int.TryParse(limit, out int i))
{ {
ItemsPerPage = i; ItemsPerPage = i;

View File

@ -8,52 +8,60 @@ namespace Explorer.UI.Shared
{ {
public class ResizeDrag public class ResizeDrag
{ {
#if CPP
private static bool RESIZE_FAILED = false; private static bool RESIZE_FAILED = false;
#endif
public static bool IsResizing = false;
public static bool IsMouseInResizeArea = false;
private static readonly GUIContent gcDrag = new GUIContent("<-- Drag to resize -->"); private static readonly GUIContent gcDrag = new GUIContent("<-- Drag to resize -->");
private static bool isResizing = false;
private static Rect m_currentResize; private static Rect m_currentResize;
private static int m_currentWindow; private static int m_currentWindow;
public static Rect ResizeWindow(Rect _rect, int ID) public static Rect ResizeWindow(Rect _rect, int ID)
{ {
#if CPP
if (!RESIZE_FAILED) if (!RESIZE_FAILED)
{ {
var origRect = _rect; var origRect = _rect;
try try
{ {
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter; GUI.skin.label.alignment = TextAnchor.MiddleCenter;
#if ML #if BIE
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) }); #if CPP // Temporary for BepInEx IL2CPP
#else
GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) }); GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) });
#else
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
#endif
#else
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
#endif #endif
var r = GUIUnstrip.GetLastRect(); var resizeDragArea = GUIHelper.GetLastRect();
var mousePos = InputManager.MousePosition; var mousePos = InputManager.MousePosition;
try try
{ {
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y)); var mouse = GUIHelper.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
if (r.Contains(mouse) && InputManager.GetMouseButtonDown(0)) if (resizeDragArea.Contains(mouse))
{ {
isResizing = true; IsMouseInResizeArea = true;
if (InputManager.GetMouseButtonDown(0))
{
IsResizing = true;
m_currentWindow = ID; m_currentWindow = ID;
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height); m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
} }
}
else if (!InputManager.GetMouseButton(0)) else if (!InputManager.GetMouseButton(0))
{ {
isResizing = false; IsMouseInResizeArea = false;
IsResizing = false;
} }
if (isResizing && ID == m_currentWindow) if (IsResizing && ID == m_currentWindow)
{ {
_rect.width = Mathf.Max(100, m_currentResize.width + (mouse.x - m_currentResize.x)); _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.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
@ -81,74 +89,36 @@ namespace Explorer.UI.Shared
//ExplorerCore.Log(e.StackTrace); //ExplorerCore.Log(e.StackTrace);
return origRect; return origRect;
} }
GUI.skin.label.alignment = TextAnchor.UpperLeft;
} }
else else
{ {
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label("Resize window:", new GUILayoutOption[] { GUILayout.Width(100) }); GUILayout.Label("Resize window:", new GUILayoutOption[] { GUILayout.Width(100) });
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 (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
{ {
_rect.width -= 5f; _rect.width -= 5f;
} }
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.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 (GUIUnstrip.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.RepeatButton("-", new GUILayoutOption[] { GUILayout.Width(20) }))
{ {
_rect.height -= 5f; _rect.height -= 5f;
} }
if (GUIUnstrip.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) })) if (GUIHelper.RepeatButton("+", new GUILayoutOption[] { GUILayout.Width(20) }))
{ {
_rect.height += 5f; _rect.height += 5f;
} }
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUI.skin.label.alignment = TextAnchor.UpperLeft;
} }
#else // mono
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
//var r = GUILayoutUtility.GetLastRect();
var r = GUILayoutUtility.GetLastRect();
var mousePos = InputManager.MousePosition;
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
if (r.Contains(mouse) && InputManager.GetMouseButtonDown(0))
{
isResizing = true;
m_currentWindow = ID;
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
}
else if (!InputManager.GetMouseButton(0))
{
isResizing = false;
}
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();
#endif
GUI.skin.label.alignment = TextAnchor.MiddleLeft; GUI.skin.label.alignment = TextAnchor.MiddleLeft;
return _rect; return _rect;

View File

@ -52,7 +52,7 @@ namespace Explorer.UI
try try
{ {
GUI.DragWindow(new Rect(0, 0, m_rect.width - 90, 20)); GUI.DragWindow(new Rect(0, 0, m_rect.width - 90, 20));
if (GUIUnstrip.Button(new Rect(m_rect.width - 90, 2, 80, 20), "<color=red>Close All</color>")) if (GUIHelper.Button(new Rect(m_rect.width - 90, 2, 80, 20), "<color=red>Close All</color>"))
{ {
foreach (var window in WindowManager.Windows) foreach (var window in WindowManager.Windows)
{ {
@ -61,20 +61,29 @@ namespace Explorer.UI
return; return;
} }
GUIUnstrip.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box); GUIHelper.BeginArea(new Rect(5, 25, m_rect.width - 10, m_rect.height - 35), GUI.skin.box);
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null); GUIHelper.BeginVertical(GUIContent.none, GUI.skin.box, null);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
GUI.skin.button.alignment = TextAnchor.MiddleLeft; GUI.skin.button.alignment = TextAnchor.MiddleLeft;
int tabPerRow = Mathf.FloorToInt((float)((decimal)m_rect.width / 238)); int tabPerRow = (int)Math.Floor(m_rect.width / 238);
int rowCount = 0; int rowCount = 0;
for (int i = 0; i < WindowManager.Windows.Count; i++) for (int i = 0; i < WindowManager.Windows.Count; i++)
{ {
var window = WindowManager.Windows[i];
// Prevent trying to draw destroyed UnityEngine.Objects
// before the WindowManager removes them.
if (window.Target is UnityEngine.Object uObj && !uObj)
{
continue;
}
if (rowCount >= tabPerRow) if (rowCount >= tabPerRow)
{ {
rowCount = 0; rowCount = 0;
GUILayout.EndHorizontal(); GUILayout.EndHorizontal();
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]); GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
} }
rowCount++; rowCount++;
@ -82,7 +91,6 @@ namespace Explorer.UI
string color = focused ? "<color=lime>" : "<color=orange>"; string color = focused ? "<color=lime>" : "<color=orange>";
GUI.color = focused ? Color.green : Color.white; GUI.color = focused ? Color.green : Color.white;
var window = WindowManager.Windows[i];
if (GUILayout.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) })) if (GUILayout.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) }))
{ {
TargetTabID = i; TargetTabID = i;
@ -101,7 +109,7 @@ namespace Explorer.UI
m_rect = ResizeDrag.ResizeWindow(m_rect, windowID); m_rect = ResizeDrag.ResizeWindow(m_rect, windowID);
GUIUnstrip.EndArea(); GUIHelper.EndArea();
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -2,6 +2,7 @@
using UnityEngine; using UnityEngine;
using Explorer.Config; using Explorer.Config;
using Explorer.UI.Inspectors; using Explorer.UI.Inspectors;
using Explorer.Helpers;
namespace Explorer.UI namespace Explorer.UI
{ {
@ -26,7 +27,15 @@ namespace Explorer.UI
{ {
var window = Activator.CreateInstance<T>(); var window = Activator.CreateInstance<T>();
#if CPP
if (target is Il2CppSystem.Object ilObject)
{
target = ilObject.Il2CppCast(ReflectionHelpers.GetActualType(ilObject));
}
#endif
window.Target = target; window.Target = target;
window.windowID = WindowManager.NextWindowID(); window.windowID = WindowManager.NextWindowID();
window.m_rect = WindowManager.GetNewWindowRect(); window.m_rect = WindowManager.GetNewWindowRect();

View File

@ -11,6 +11,26 @@ namespace Explorer.UI
public static bool TabView = Config.ModConfig.Instance.Tab_View; public static bool TabView = Config.ModConfig.Instance.Tab_View;
public static bool IsMouseInWindow
{
get
{
if (!ExplorerCore.ShowMenu)
{
return false;
}
foreach (var window in Windows)
{
if (RectContainsMouse(window.m_rect))
{
return true;
}
}
return RectContainsMouse(MainMenu.MainRect);
}
}
public static List<WindowBase> Windows = new List<WindowBase>(); public static List<WindowBase> Windows = new List<WindowBase>();
public static int CurrentWindowID { get; set; } = 500000; public static int CurrentWindowID { get; set; } = 500000;
private static Rect m_lastWindowRect; private static Rect m_lastWindowRect;
@ -90,7 +110,7 @@ namespace Explorer.UI
{ {
if (!TabView) if (!TabView)
{ {
GUIUnstrip.BringWindowToFront(window.windowID); GUIHelper.BringWindowToFront(window.windowID);
GUI.FocusWindow(window.windowID); GUI.FocusWindow(window.windowID);
} }
else else
@ -123,26 +143,6 @@ namespace Explorer.UI
return new_window; return new_window;
} }
public static bool IsMouseInWindow
{
get
{
if (!ExplorerCore.ShowMenu)
{
return false;
}
foreach (var window in Windows)
{
if (RectContainsMouse(window.m_rect))
{
return true;
}
}
return RectContainsMouse(MainMenu.MainRect);
}
}
private static bool RectContainsMouse(Rect rect) private static bool RectContainsMouse(Rect rect)
{ {
var mousePos = InputManager.MousePosition; var mousePos = InputManager.MousePosition;

View File

@ -3,13 +3,34 @@ using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
#if CPP #if CPP
using Explorer.UnstripInternals; using Explorer.Unstrip.IMGUI;
#endif #endif
namespace Explorer namespace Explorer
{ {
public class GUIUnstrip // All the pre-processor directive stuff is in this class to keep it separate.
// This is so Mono build can use this class and not have to worry.
public class GUIHelper
{ {
internal static GUILayoutOption ExpandWidth(bool expand)
{
#if CPP
return GUIUnstrip.ExpandWidth(expand);
#else
return GUILayout.ExpandWidth(expand);
#endif
}
internal static GUILayoutOption ExpandHeight(bool expand)
{
#if CPP
return GUIUnstrip.ExpandHeight(expand);
#else
return GUILayout.ExpandHeight(expand);
#endif
}
public static void BeginHorizontal(params GUILayoutOption[] options) public static void BeginHorizontal(params GUILayoutOption[] options)
=> BeginHorizontal(GUIContent.none, GUIStyle.none, options); => BeginHorizontal(GUIContent.none, GUIStyle.none, options);
@ -19,7 +40,7 @@ namespace Explorer
public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options) public static void BeginHorizontal(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
{ {
#if CPP #if CPP
Internal.BeginLayoutDirection(false, content, style, options); GUIUnstrip.BeginLayoutDirection(false, content, style, options);
#else #else
GUILayout.BeginHorizontal(content, style, options); GUILayout.BeginHorizontal(content, style, options);
#endif #endif
@ -34,7 +55,7 @@ namespace Explorer
public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options) public static void BeginVertical(GUIContent content, GUIStyle style, params GUILayoutOption[] options)
{ {
#if CPP #if CPP
Internal.BeginLayoutDirection(true, content, style, options); GUIUnstrip.BeginLayoutDirection(true, content, style, options);
#else #else
GUILayout.BeginVertical(content, style, options); GUILayout.BeginVertical(content, style, options);
#endif #endif
@ -44,7 +65,7 @@ namespace Explorer
public static Rect GetLastRect() public static Rect GetLastRect()
{ {
#if CPP #if CPP
return Internal_LayoutUtility.GetLastRect(); return LayoutUtilityUnstrip.GetLastRect();
#else #else
return GUILayoutUtility.GetLastRect(); return GUILayoutUtility.GetLastRect();
#endif #endif
@ -53,12 +74,21 @@ namespace Explorer
public static string TextField(string text, GUILayoutOption[] options) public static string TextField(string text, GUILayoutOption[] options)
{ {
#if CPP #if CPP
return Internal.TextField(text, options); return GUIUnstrip.TextField(text, options, false);
#else #else
return GUILayout.TextField(text, options); return GUILayout.TextField(text, options);
#endif #endif
} }
public static string TextArea(string text, params GUILayoutOption[] options)
{
#if CPP
return GUIUnstrip.TextField(text, options, true);
#else
return GUILayout.TextArea(text, options);
#endif
}
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title) public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
{ {
#if CPP #if CPP
@ -77,19 +107,10 @@ namespace Explorer
#endif #endif
} }
public static string TextArea(string text, params GUILayoutOption[] options)
{
#if CPP
return GUILayout.DoTextField(text, -1, true, GUI.skin.textArea, options);
#else
return GUILayout.TextArea(text, options);
#endif
}
public static void BringWindowToFront(int id) public static void BringWindowToFront(int id)
{ {
#if CPP #if CPP
Internal.BringWindowToFront(id); GUIUnstrip.BringWindowToFront(id);
#else #else
GUI.BringWindowToFront(id); GUI.BringWindowToFront(id);
#endif #endif
@ -98,7 +119,7 @@ namespace Explorer
public static Vector2 ScreenToGUIPoint(Vector2 screenPoint) public static Vector2 ScreenToGUIPoint(Vector2 screenPoint)
{ {
#if CPP #if CPP
return Internal.ScreenToGUIPoint(screenPoint); return GUIUnstrip.ScreenToGUIPoint(screenPoint);
#else #else
return GUIUtility.ScreenToGUIPoint(screenPoint); return GUIUtility.ScreenToGUIPoint(screenPoint);
#endif #endif
@ -107,7 +128,7 @@ namespace Explorer
public static void Space(float pixels) public static void Space(float pixels)
{ {
#if CPP #if CPP
Internal.Space(pixels); GUIUnstrip.Space(pixels);
#else #else
GUILayout.Space(pixels); GUILayout.Space(pixels);
#endif #endif
@ -116,7 +137,7 @@ namespace Explorer
public static bool RepeatButton(string text, params GUILayoutOption[] options) public static bool RepeatButton(string text, params GUILayoutOption[] options)
{ {
#if CPP #if CPP
return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); return GUIUnstrip.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options);
#else #else
return GUILayout.RepeatButton(text, options); return GUILayout.RepeatButton(text, options);
#endif #endif
@ -125,7 +146,7 @@ namespace Explorer
public static void BeginArea(Rect screenRect, GUIStyle style) public static void BeginArea(Rect screenRect, GUIStyle style)
{ {
#if CPP #if CPP
Internal.BeginArea(screenRect, GUIContent.none, style); GUIUnstrip.BeginArea(screenRect, GUIContent.none, style);
#else #else
GUILayout.BeginArea(screenRect, style); GUILayout.BeginArea(screenRect, style);
#endif #endif
@ -134,7 +155,7 @@ namespace Explorer
static public void EndArea() static public void EndArea()
{ {
#if CPP #if CPP
Internal.EndArea(); GUIUnstrip.EndArea();
#else #else
GUILayout.EndArea(); GUILayout.EndArea();
#endif #endif
@ -144,7 +165,7 @@ namespace Explorer
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
{ {
#if CPP #if CPP
return Internal.BeginScrollView(scroll, options); return GUIUnstrip.BeginScrollView(scroll, options);
#else #else
return GUILayout.BeginScrollView(scroll, options); return GUILayout.BeginScrollView(scroll, options);
#endif #endif
@ -153,7 +174,7 @@ namespace Explorer
public static void EndScrollView(bool handleScrollWheel = true) public static void EndScrollView(bool handleScrollWheel = true)
{ {
#if CPP #if CPP
Internal.EndScrollView(handleScrollWheel); GUIUnstrip.EndScrollView(handleScrollWheel);
#else #else
GUILayout.EndScrollView(); GUILayout.EndScrollView();
#endif #endif

View File

@ -6,9 +6,9 @@ using UnityEngine;
using UnityEngineInternal; using UnityEngineInternal;
using UnhollowerRuntimeLib; using UnhollowerRuntimeLib;
namespace Explorer.UnstripInternals namespace Explorer.Unstrip.IMGUI
{ {
public class Internal public class GUIUnstrip
{ {
#region Properties #region Properties
public static int s_ScrollControlId; public static int s_ScrollControlId;
@ -16,12 +16,9 @@ namespace Explorer.UnstripInternals
public static bool ScrollFailed = false; public static bool ScrollFailed = false;
public static bool ManualUnstripFailed = false; public static bool ManualUnstripFailed = false;
public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack(); public static Stack<object> ScrollStack => m_scrollStack ?? GetScrollStack();
public static PropertyInfo m_scrollViewStatesInfo; public static Stack<object> m_scrollStack;
public static GenericStack m_scrollStack; //public static PropertyInfo m_scrollViewStatesInfo;
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle(); public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle();
public static GUIStyle m_spaceStyle; public static GUIStyle m_spaceStyle;
@ -34,53 +31,13 @@ namespace Explorer.UnstripInternals
public static MethodInfo m_bringWindowToFrontMethod; public static MethodInfo m_bringWindowToFrontMethod;
public static bool m_bringWindowFrontAttempted; public static bool m_bringWindowFrontAttempted;
private static GenericStack GetScrollStack() private static Stack<object> GetScrollStack()
{ {
if (m_scrollViewStatesInfo == null) m_scrollStack = new Stack<object>();
{
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; return m_scrollStack;
} }
private static Dictionary<int, Il2CppSystem.Object> GetStateCacheDict()
{
if (m_stateCacheDict == null)
{
try
{
var type = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects");
m_stateCacheDict = type.GetProperty("s_StateCache")
.GetValue(null, null)
as Dictionary<int, Il2CppSystem.Object>;
if (m_stateCacheDict == null) throw new Exception();
}
catch
{
m_stateCacheDict = new Dictionary<int, Il2CppSystem.Object>();
}
}
return m_stateCacheDict;
}
private static GUIStyle GetSpaceStyle() private static GUIStyle GetSpaceStyle()
{ {
try try
@ -107,17 +64,72 @@ namespace Explorer.UnstripInternals
#region GUILayout Methods #region GUILayout Methods
public static GUILayoutOption ExpandWidth(bool expand)
{
var ilValue = new Il2CppSystem.Int32
{
m_value = (!expand) ? 0 : 1
};
var option = new GUILayoutOption(GUILayoutOption.Type.stretchWidth, ilValue.BoxIl2CppObject());
return option;
}
public static GUILayoutOption ExpandHeight(bool expand)
{
var ilValue = new Il2CppSystem.Int32
{
m_value = (!expand) ? 0 : 1
};
var option = new GUILayoutOption(GUILayoutOption.Type.stretchHeight, ilValue.BoxIl2CppObject());
return option;
}
public static void BeginLayoutDirection(bool vertical, GUIContent content, GUIStyle style, GUILayoutOption[] options) public static void BeginLayoutDirection(bool vertical, GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ {
var g = GUILayoutUtility.BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>()); var g = BeginLayoutGroup(style, options, Il2CppType.Of<GUILayoutGroup>());
g.isVertical = vertical; g.isVertical = vertical;
if (style != GUIStyle.none || content != GUIContent.none) if (style != GUIStyle.none || content != GUIContent.none)
GUI.Box(g.rect, content, style); GUI.Box(g.rect, content, style);
} }
public static string TextField(string text, GUILayoutOption[] options) public static GUILayoutGroup BeginLayoutGroup(GUIStyle style, GUILayoutOption[] options, Il2CppSystem.Type layoutType)
{ {
text = text ?? ""; EventType type = Event.current.type;
GUILayoutGroup guilayoutGroup;
if (type != EventType.Used && type != EventType.Layout)
{
guilayoutGroup = GUILayoutUtility.current.topLevel.GetNext().TryCast<GUILayoutGroup>();
if (guilayoutGroup == null)
{
throw new ArgumentException("GUILayout: Mismatched LayoutGroup." + Event.current.type);
}
guilayoutGroup.ResetCursor();
}
else
{
guilayoutGroup = GUILayoutUtility.CreateGUILayoutGroupInstanceOfType(layoutType);
guilayoutGroup.style = style;
if (options != null)
{
guilayoutGroup.ApplyOptions(options);
}
GUILayoutUtility.current.topLevel.entries.Add(guilayoutGroup);
}
GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup);
GUILayoutUtility.current.topLevel = guilayoutGroup;
return guilayoutGroup;
}
public static string TextField(string text, GUILayoutOption[] options, bool multiLine)
{
text = text ?? string.Empty;
var skin = multiLine ? GUI.skin.textArea : GUI.skin.textField;
int controlID = GUIUtility.GetControlID(FocusType.Keyboard); int controlID = GUIUtility.GetControlID(FocusType.Keyboard);
GUIContent guicontent = GUIContent.Temp(text); GUIContent guicontent = GUIContent.Temp(text);
@ -131,19 +143,19 @@ namespace Explorer.UnstripInternals
guicontent = GUIContent.Temp(text); guicontent = GUIContent.Temp(text);
// guicontent = GUIContent.Temp(text + GUIUtility.compositionString); // guicontent = GUIContent.Temp(text + GUIUtility.compositionString);
} }
Rect rect = Internal_LayoutUtility.GetRect(guicontent, GUI.skin.textField, options); Rect rect = LayoutUtilityUnstrip.GetRect(guicontent, skin, options);
bool flag2 = GUIUtility.keyboardControl == controlID; bool flag2 = GUIUtility.keyboardControl == controlID;
if (flag2) if (flag2)
{ {
guicontent = GUIContent.Temp(text); guicontent = GUIContent.Temp(text);
} }
DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField); DoTextField(rect, controlID, guicontent, multiLine, -1, skin);
return guicontent.text; return guicontent.text;
} }
internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style) internal static void DoTextField(Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style)
{ {
if (GetStateObject(Il2CppType.Of<TextEditor>(), id).TryCast<TextEditor>() is TextEditor textEditor) if (GUIUtilityUnstrip.GetMonoStateObject(typeof(TextEditorUnstrip), id) is TextEditorUnstrip textEditor)
{ {
if (maxLength >= 0 && content.text.Length > maxLength) if (maxLength >= 0 && content.text.Length > maxLength)
{ {
@ -156,22 +168,149 @@ namespace Explorer.UnstripInternals
textEditor.multiline = multiline; textEditor.multiline = multiline;
textEditor.controlID = id; textEditor.controlID = id;
textEditor.DetectFocusChange(); textEditor.DetectFocusChange();
GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor); HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
textEditor.UpdateScrollOffsetIfNeeded(Event.current); textEditor.UpdateScrollOffsetIfNeeded(Event.current);
} }
} }
private static void HandleTextFieldEventForDesktop(Rect position, int id, GUIContent content, bool multiline, int maxLength,
GUIStyle style, TextEditorUnstrip editor)
{
var evt = Event.current;
bool change = false;
switch (evt.type)
{
case EventType.MouseDown:
if (position.Contains(evt.mousePosition))
{
GUIUtility.hotControl = id;
GUIUtility.keyboardControl = id;
editor.m_HasFocus = true;
editor.MoveCursorToPosition(Event.current.mousePosition);
if (Event.current.clickCount == 2 && GUI.skin.settings.doubleClickSelectsWord)
{
editor.SelectCurrentWord();
editor.DblClickSnap(TextEditorUnstrip.DblClickSnapping.WORDS);
editor.MouseDragSelectsWholeWords(true);
}
if (Event.current.clickCount == 3 && GUI.skin.settings.tripleClickSelectsLine)
{
editor.SelectCurrentParagraph();
editor.MouseDragSelectsWholeWords(true);
editor.DblClickSnap(TextEditorUnstrip.DblClickSnapping.PARAGRAPHS);
}
evt.Use();
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl == id)
{
if (evt.shift)
editor.MoveCursorToPosition(Event.current.mousePosition);
else
editor.SelectToPosition(Event.current.mousePosition);
evt.Use();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == id)
{
editor.MouseDragSelectsWholeWords(false);
GUIUtility.hotControl = 0;
evt.Use();
}
break;
case EventType.KeyDown:
if (GUIUtility.keyboardControl != id)
return;
if (editor.HandleKeyEvent(evt))
{
evt.Use();
change = true;
content.text = editor.text;
break;
}
// Ignore tab & shift-tab in textfields
if (evt.keyCode == KeyCode.Tab || evt.character == '\t')
return;
char c = evt.character;
if (c == '\n' && !multiline && !evt.alt)
return;
// Simplest test: only allow the character if the display font supports it.
Font font = style.font;
if (!font)
font = GUI.skin.font;
if (font.HasCharacter(c) || c == '\n')
{
editor.Insert(c);
change = true;
break;
}
// On windows, keypresses also send events with keycode but no character. Eat them up here.
if (c == 0)
{
// if we have a composition string, make sure we clear the previous selection.
if (InputManager.compositionString.Length > 0)
{
editor.ReplaceSelection("");
change = true;
}
evt.Use();
}
// else {
// REALLY USEFUL:
// Debug.Log ("unhandled " +evt);
// evt.Use ();
// }
break;
case EventType.Repaint:
// If we have keyboard focus, draw the cursor
// TODO: check if this OpenGL view has keyboard focus
if (GUIUtility.keyboardControl != id)
{
style.Draw(position, content, id, false);
}
else
{
editor.DrawCursor(content.text);
}
break;
}
if (GUIUtility.keyboardControl == id)
GUIUtility.textFieldInput = true;
if (change)
{
GUI.changed = true;
content.text = editor.text;
if (maxLength >= 0 && content.text.Length > maxLength)
content.text = content.text.Substring(0, maxLength);
evt.Use();
}
}
public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options) public static bool DoRepeatButton(GUIContent content, GUIStyle style, GUILayoutOption[] options)
{ {
return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive); return GUI.DoRepeatButton(LayoutUtilityUnstrip.GetRect(content, style, options), content, style, FocusType.Passive);
} }
public static void Space(float pixels) public static void Space(float pixels)
{ {
if (GUILayoutUtility.current.topLevel.isVertical) if (GUILayoutUtility.current.topLevel.isVertical)
Internal_LayoutUtility.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) }); LayoutUtilityUnstrip.GetRect(0, pixels, SpaceStyle, new GUILayoutOption[] { GUILayout.Height(pixels) });
else else
Internal_LayoutUtility.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) }); LayoutUtilityUnstrip.GetRect(pixels, 0, SpaceStyle, new GUILayoutOption[] { GUILayout.Width(pixels) });
if (Event.current.type == EventType.Layout) if (Event.current.type == EventType.Layout)
{ {
@ -234,7 +373,7 @@ namespace Explorer.UnstripInternals
{ {
guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType); guilayoutGroup = (GUILayoutGroup)Activator.CreateInstance(layoutType);
guilayoutGroup.style = style; guilayoutGroup.style = style;
GUILayoutUtility.current.windows.Add(guilayoutGroup); GUILayoutUtility.current.windows.entries.Add(guilayoutGroup);
} }
GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup); GUILayoutUtility.current.layoutGroups.Push(guilayoutGroup);
GUILayoutUtility.current.topLevel = guilayoutGroup; GUILayoutUtility.current.topLevel = guilayoutGroup;
@ -279,22 +418,6 @@ namespace Explorer.UnstripInternals
#region Scrolling #region Scrolling
private static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID)
{
Il2CppSystem.Object obj;
if (StateCache.ContainsKey(controlID))
{
obj = StateCache[controlID];
}
else
{
obj = Il2CppSystem.Activator.CreateInstance(type);
StateCache.Add(controlID, obj);
}
return obj;
}
public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options)
{ {
// First, just try normal way, may not have been stripped or was unstripped successfully. // First, just try normal way, may not have been stripped or was unstripped successfully.
@ -348,10 +471,12 @@ namespace Explorer.UnstripInternals
if (ScrollStack.Count <= 0) return; if (ScrollStack.Count <= 0) return;
var state = ScrollStack.Peek().TryCast<ScrollViewState>(); var scrollExt = ScrollStack.Peek() as ScrollViewStateUnstrip;
var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
if (scrollExt == null) throw new Exception("Could not get scrollExt!"); //var state = ScrollStack.Peek().TryCast<ScrollViewState>();
//var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
//if (scrollExt == null) throw new Exception("Could not get scrollExt!");
GUIClip.Pop(); GUIClip.Pop();
@ -419,16 +544,15 @@ namespace Explorer.UnstripInternals
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive); int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
var scrollViewState = GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID) ScrollViewStateUnstrip scrollExt;
.TryCast<ScrollViewState>(); try
{
if (scrollViewState == null) scrollExt = (ScrollViewStateUnstrip)GUIUtilityUnstrip.GetMonoStateObject(typeof(ScrollViewStateUnstrip), controlID);
return scrollPosition; }
catch
var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer); {
return Vector2.zero;
if (scrollExt == null) }
return scrollPosition;
bool apply = scrollExt.apply; bool apply = scrollExt.apply;
if (apply) if (apply)
@ -446,7 +570,7 @@ namespace Explorer.UnstripInternals
rect.width = position.width; rect.width = position.width;
rect.height = position.height; rect.height = position.height;
ScrollStack.Push(scrollViewState); ScrollStack.Push(scrollExt);
Rect screenRect = new Rect(position.x, position.y, position.width, position.height); Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
EventType type = Event.current.type; EventType type = Event.current.type;
@ -630,7 +754,7 @@ namespace Explorer.UnstripInternals
{ {
id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position); id = GUIUtility.GetControlID(GUI.s_SliderHash, FocusType.Passive, position);
} }
var sliderHandler = new Internal_SliderHandler(position, value, size, start, end, slider, thumb, horiz, id); var sliderHandler = new SliderHandlerUnstrip(position, value, size, start, end, slider, thumb, horiz, id);
return sliderHandler.Handle(); return sliderHandler.Handle();
} }

View File

@ -0,0 +1,67 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Explorer.Helpers;
namespace Explorer.Unstrip.IMGUI
{
public class GUIUtilityUnstrip
{
public static Dictionary<int, object> MonoStateCache = new Dictionary<int, object>();
public static object GetMonoStateObject(Type type, int controlID)
{
if (!MonoStateCache.ContainsKey(controlID))
{
MonoStateCache.Add(controlID, Activator.CreateInstance(type));
}
return MonoStateCache[controlID];
}
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
public static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID)
{
Il2CppSystem.Object obj;
if (StateCache.ContainsKey(controlID))
{
obj = StateCache[controlID];
}
else
{
obj = Il2CppSystem.Activator.CreateInstance(type);
StateCache.Add(controlID, obj);
}
return obj;
}
private static Dictionary<int, Il2CppSystem.Object> GetStateCacheDict()
{
if (m_stateCacheDict == null)
{
try
{
m_stateCacheDict = ReflectionHelpers.GetTypeByName("UnityEngine.GUIStateObjects")
.GetProperty("s_StateCache")
.GetValue(null, null)
as Dictionary<int, Il2CppSystem.Object>;
if (m_stateCacheDict == null) throw new Exception();
}
catch
{
m_stateCacheDict = new Dictionary<int, Il2CppSystem.Object>();
}
}
return m_stateCacheDict;
}
}
}
#endif

View File

@ -1,9 +1,9 @@
#if CPP #if CPP
using UnityEngine; using UnityEngine;
namespace Explorer.UnstripInternals namespace Explorer.Unstrip.IMGUI
{ {
public class Internal_LayoutUtility public class LayoutUtilityUnstrip
{ {
public static Rect GetRect(float width, float height, GUIStyle style, params GUILayoutOption[] options) public static Rect GetRect(float width, float height, GUIStyle style, params GUILayoutOption[] options)
{ {

View File

@ -0,0 +1,89 @@
#if CPP
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Explorer.Unstrip.IMGUI
{
public class ScrollViewStateUnstrip
{
public Rect position;
public Rect visibleRect;
public Rect viewRect;
public Vector2 scrollPosition;
public bool apply;
public void ScrollTo(Rect pos)
{
this.ScrollTowards(pos, float.PositiveInfinity);
}
public bool ScrollTowards(Rect pos, float maxDelta)
{
Vector2 b = this.ScrollNeeded(pos);
bool result;
if (b.sqrMagnitude < 0.0001f)
{
result = false;
}
else if (maxDelta == 0f)
{
result = true;
}
else
{
if (b.magnitude > maxDelta)
{
b = b.normalized * maxDelta;
}
this.scrollPosition += b;
this.apply = true;
result = true;
}
return result;
}
private Vector2 ScrollNeeded(Rect pos)
{
Rect rect = this.visibleRect;
rect.x += this.scrollPosition.x;
rect.y += this.scrollPosition.y;
float num = pos.width - this.visibleRect.width;
if (num > 0f)
{
pos.width -= num;
pos.x += num * 0.5f;
}
num = pos.height - this.visibleRect.height;
if (num > 0f)
{
pos.height -= num;
pos.y += num * 0.5f;
}
Vector2 zero = Vector2.zero;
if (pos.xMax > rect.xMax)
{
zero.x += pos.xMax - rect.xMax;
}
else if (pos.xMin < rect.xMin)
{
zero.x -= rect.xMin - pos.xMin;
}
if (pos.yMax > rect.yMax)
{
zero.y += pos.yMax - rect.yMax;
}
else if (pos.yMin < rect.yMin)
{
zero.y -= rect.yMin - pos.yMin;
}
Rect rect2 = this.viewRect;
rect2.width = Mathf.Max(rect2.width, this.visibleRect.width);
rect2.height = Mathf.Max(rect2.height, this.visibleRect.height);
zero.x = Mathf.Clamp(zero.x, rect2.xMin - this.scrollPosition.x, rect2.xMax - this.visibleRect.width - this.scrollPosition.x);
zero.y = Mathf.Clamp(zero.y, rect2.yMin - this.scrollPosition.y, rect2.yMax - this.visibleRect.height - this.scrollPosition.y);
return zero;
}
}
}
#endif

View File

@ -0,0 +1,411 @@
#if CPP
using System;
using UnhollowerRuntimeLib;
using UnityEngine;
namespace Explorer.Unstrip.IMGUI
{
public struct SliderHandlerUnstrip
{
public static int ScrollTroughSide
{
get
{
if (!m_getScrollTroughSideFailed)
{
try
{
return GUI.scrollTroughSide;
}
catch
{
m_getScrollTroughSideFailed = true;
}
}
return m_manualScrollTrough;
}
set
{
if (!m_setScrollTroughSideFailed)
{
try
{
GUI.scrollTroughSide = value;
return;
}
catch
{
m_setScrollTroughSideFailed = true;
}
}
m_manualScrollTrough = value;
}
}
private static bool m_getScrollTroughSideFailed;
private static bool m_setScrollTroughSideFailed;
private static int m_manualScrollTrough;
private readonly Rect position;
private readonly float currentValue;
private readonly float size;
private readonly float start;
private readonly float end;
private readonly GUIStyle slider;
private readonly GUIStyle thumb;
private readonly bool horiz;
private readonly int id;
public SliderHandlerUnstrip(Rect position, float currentValue, float size, float start,
float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
{
this.position = position;
this.currentValue = currentValue;
this.size = size;
this.start = start;
this.end = end;
this.slider = slider;
this.thumb = thumb;
this.horiz = horiz;
this.id = id;
}
public float Handle()
{
float result;
if (this.slider == null || this.thumb == null)
{
result = this.currentValue;
}
else
{
switch (this.CurrentEventType())
{
case EventType.MouseDown:
return this.OnMouseDown();
case EventType.MouseUp:
return this.OnMouseUp();
case EventType.MouseDrag:
return this.OnMouseDrag();
case EventType.Repaint:
return this.OnRepaint();
}
result = this.currentValue;
}
return result;
}
private float OnMouseDown()
{
float result;
if (!this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
{
result = this.currentValue;
}
else
{
ScrollTroughSide = 0;
GUIUtility.hotControl = this.id;
this.CurrentEvent().Use();
if (this.ThumbSelectionRect().Contains(this.CurrentEvent().mousePosition))
{
this.StartDraggingWithValue(this.ClampedCurrentValue());
result = this.currentValue;
}
else
{
GUI.changed = true;
if (this.SupportsPageMovements())
{
var state = GetSliderState();
state.isDragging = false;
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
ScrollTroughSide = this.CurrentScrollTroughSide();
result = this.PageMovementValue();
}
else
{
float num = this.ValueForCurrentMousePosition();
this.StartDraggingWithValue(num);
result = this.Clamp(num);
}
}
}
return result;
}
private float OnMouseDrag()
{
float result;
if (GUIUtility.hotControl != this.id)
{
result = this.currentValue;
}
else
{
var state = GetSliderState();
if (!state.isDragging)
{
result = this.currentValue;
}
else
{
GUI.changed = true;
this.CurrentEvent().Use();
float num = this.MousePosition() - state.dragStartPos;
float value = state.dragStartValue + num / this.ValuesPerPixel();
result = this.Clamp(value);
}
}
return result;
}
private float OnMouseUp()
{
if (GUIUtility.hotControl == this.id)
{
this.CurrentEvent().Use();
GUIUtility.hotControl = 0;
}
return this.currentValue;
}
private float OnRepaint()
{
this.slider.Draw(this.position, GUIContent.none, this.id);
if (!this.IsEmptySlider() && this.currentValue >= this.MinValue() && this.currentValue <= this.MaxValue())
{
this.thumb.Draw(this.ThumbRect(), GUIContent.none, this.id);
}
float result;
if (GUIUtility.hotControl != this.id || !this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
{
result = this.currentValue;
}
else if (this.ThumbRect().Contains(this.CurrentEvent().mousePosition))
{
if (ScrollTroughSide != 0)
{
GUIUtility.hotControl = 0;
}
result = this.currentValue;
}
else
{
GUI.InternalRepaintEditorWindow();
if (DateTime.Now < GUIUnstrip.nextScrollStepTime)
{
result = this.currentValue;
}
else if (this.CurrentScrollTroughSide() != ScrollTroughSide)
{
result = this.currentValue;
}
else
{
GUIUnstrip.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
if (this.SupportsPageMovements())
{
GetSliderState().isDragging = false;
GUI.changed = true;
result = this.PageMovementValue();
}
else
{
result = this.ClampedCurrentValue();
}
}
}
return result;
}
private EventType CurrentEventType()
{
return this.CurrentEvent().GetTypeForControl(this.id);
}
private int CurrentScrollTroughSide()
{
float num = (!this.horiz) ? this.CurrentEvent().mousePosition.y : this.CurrentEvent().mousePosition.x;
float num2 = (!this.horiz) ? this.ThumbRect().y : this.ThumbRect().x;
return (num <= num2) ? -1 : 1;
}
private bool IsEmptySlider()
{
return this.start == this.end;
}
private bool SupportsPageMovements()
{
return this.size != 0f && GUI.usePageScrollbars;
}
private float PageMovementValue()
{
float num = this.currentValue;
int num2 = (this.start <= this.end) ? 1 : -1;
if (this.MousePosition() > this.PageUpMovementBound())
{
num += this.size * (float)num2 * 0.9f;
}
else
{
num -= this.size * (float)num2 * 0.9f;
}
return this.Clamp(num);
}
private float PageUpMovementBound()
{
float result;
if (this.horiz)
{
result = this.ThumbRect().xMax - this.position.x;
}
else
{
result = this.ThumbRect().yMax - this.position.y;
}
return result;
}
private Event CurrentEvent()
{
return Event.current;
}
private float ValueForCurrentMousePosition()
{
float result;
if (this.horiz)
{
result = (this.MousePosition() - this.ThumbRect().width * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
}
else
{
result = (this.MousePosition() - this.ThumbRect().height * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
}
return result;
}
private float Clamp(float value)
{
return Mathf.Clamp(value, this.MinValue(), this.MaxValue());
}
private Rect ThumbSelectionRect()
{
return this.ThumbRect();
}
private void StartDraggingWithValue(float dragStartValue)
{
var state = GetSliderState();
state.dragStartPos = this.MousePosition();
state.dragStartValue = dragStartValue;
state.isDragging = true;
}
private SliderStateUnstrip GetSliderState()
{
return (SliderStateUnstrip)GUIUtilityUnstrip.GetMonoStateObject(typeof(SliderStateUnstrip), this.id);
}
private Rect ThumbRect()
{
return (!this.horiz) ? this.VerticalThumbRect() : this.HorizontalThumbRect();
}
private Rect VerticalThumbRect()
{
float num = this.ValuesPerPixel();
Rect result;
if (this.start < this.end)
{
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * num + this.ThumbSize());
}
else
{
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() + this.size - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * -num + this.ThumbSize());
}
return result;
}
private Rect HorizontalThumbRect()
{
float num = this.ValuesPerPixel();
Rect result;
if (this.start < this.end)
{
result = new Rect((this.ClampedCurrentValue() - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y + (float)this.slider.padding.top, this.size * num + this.ThumbSize(), this.position.height - (float)this.slider.padding.vertical);
}
else
{
result = new Rect((this.ClampedCurrentValue() + this.size - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y, this.size * -num + this.ThumbSize(), this.position.height);
}
return result;
}
private float ClampedCurrentValue()
{
return this.Clamp(this.currentValue);
}
private float MousePosition()
{
float result;
if (this.horiz)
{
result = this.CurrentEvent().mousePosition.x - this.position.x;
}
else
{
result = this.CurrentEvent().mousePosition.y - this.position.y;
}
return result;
}
private float ValuesPerPixel()
{
float result;
if (this.horiz)
{
result = (this.position.width - (float)this.slider.padding.horizontal - this.ThumbSize()) / (this.end - this.start);
}
else
{
result = (this.position.height - (float)this.slider.padding.vertical - this.ThumbSize()) / (this.end - this.start);
}
return result;
}
private float ThumbSize()
{
float result;
if (this.horiz)
{
result = ((this.thumb.fixedWidth == 0f) ? ((float)this.thumb.padding.horizontal) : this.thumb.fixedWidth);
}
else
{
result = ((this.thumb.fixedHeight == 0f) ? ((float)this.thumb.padding.vertical) : this.thumb.fixedHeight);
}
return result;
}
private float MaxValue()
{
return Mathf.Max(this.start, this.end) - this.size;
}
private float MinValue()
{
return Mathf.Min(this.start, this.end);
}
}
}
#endif

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Explorer.Unstrip.IMGUI
{
public class SliderStateUnstrip
{
public float dragStartPos;
public float dragStartValue;
public bool isDragging;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnhollowerBaseLib;
using UnityEngine;
using System.IO;
using Explorer.Helpers;
using System.Runtime.InteropServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace Explorer.Unstrip.ImageConversion
{
public static class ImageConversionUnstrip
{
// byte[] ImageConversion.EncodeToPNG(this Texture2D image);
internal delegate byte[] d_EncodeToPNG(IntPtr tex);
public static byte[] EncodeToPNG(this Texture2D tex)
{
var data = ICallHelper.GetICall<d_EncodeToPNG>("UnityEngine.ImageConversion::EncodeToPNG")
.Invoke(tex.Pointer);
// The Il2Cpp EncodeToPNG() method does return System.Byte[],
// but for some reason it is not recognized or valid.
// Simple fix is iterating into a new array manually.
byte[] safeData = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
safeData[i] = (byte)data[i];
}
return safeData;
}
// bool ImageConversion.LoadImage(this Texture2D tex, byte[] data, bool markNonReadable);
internal delegate bool d_LoadImage(IntPtr tex, IntPtr data, bool markNonReadable);
public static bool LoadImage(this Texture2D tex, byte[] data, bool markNonReadable)
{
var il2cppArray = new Il2CppStructArray<byte>(data.Length);
for (int i = 0; i < data.Length; i++)
{
il2cppArray[i] = data[i];
}
var ret = ICallHelper.GetICall<d_LoadImage>("UnityEngine.ImageConversion::LoadImage")
.Invoke(tex.Pointer, il2cppArray.Pointer, markNonReadable);
return ret;
}
// Helper for LoadImage from filepath
public static bool LoadImage(Texture2D tex, string filePath, bool markNonReadable)
{
if (!File.Exists(filePath))
{
return false;
}
var data = File.ReadAllBytes(filePath);
return tex.LoadImage(data, markNonReadable);
}
}
}
#endif

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Explorer.Helpers;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.Unstrip.LayerMasks
{
public static class LayerMaskUnstrip
{
#if CPP
internal delegate IntPtr d_LayerToName(int layer);
public static string LayerToName(int layer)
{
var iCall = ICallHelper.GetICall<d_LayerToName>("UnityEngine.LayerMask::LayerToName");
return IL2CPP.Il2CppStringToManaged(iCall.Invoke(layer));
}
#else
public static string LayerToName(int layer) => LayerMask.LayerToName(layer);
#endif
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Explorer.Helpers;
using UnityEngine;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.Unstrip.Resources
{
public class ResourcesUnstrip
{
#if CPP
internal delegate IntPtr d_FindObjectsOfTypeAll(IntPtr type);
public static UnityEngine.Object[] FindObjectsOfTypeAll(Il2CppSystem.Type type)
{
var arrayPtr = ICallHelper.GetICall<d_FindObjectsOfTypeAll>("UnityEngine.Resources::FindObjectsOfTypeAll")
.Invoke(type.Pointer);
var array = new Il2CppReferenceArray<UnityEngine.Object>(arrayPtr);
var ret = new UnityEngine.Object[array.Length];
for (int i = 0; i < array.Length; i++)
{
ret[i] = array[i];
}
return ret;
}
#else
public static UnityEngine.Object[] FindObjectsOfTypeAll(Type type) => UnityEngine.Resources.FindObjectsOfTypeAll(type);
#endif
}
}

View File

@ -0,0 +1,41 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Explorer.Helpers;
using UnhollowerBaseLib;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Explorer.Unstrip.Scenes
{
public class SceneUnstrip
{
//Scene.GetRootGameObjects();
internal delegate void d_GetRootGameObjects(int handle, IntPtr list);
public static GameObject[] GetRootGameObjects(Scene scene)
{
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(scene));
var iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
iCall.Invoke(scene.handle, list.Pointer);
return list.ToArray();
}
//Scene.rootCount;
internal delegate int GetRootCountInternal_delegate(int handle);
public static int GetRootCount(Scene scene)
{
var iCall = ICallHelper.GetICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
return iCall.Invoke(scene.handle);
}
}
}
#endif

View File

@ -1,29 +0,0 @@
#if CPP
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Explorer.UnstripInternals
{
public class Internal_ScrollViewState
{
public Rect position;
public Rect visibleRect;
public Rect viewRect;
public Vector2 scrollPosition;
public bool apply;
public static Dictionary<IntPtr, Internal_ScrollViewState> Dict = new Dictionary<IntPtr, Internal_ScrollViewState>();
public static Internal_ScrollViewState FromPointer(IntPtr ptr)
{
if (!Dict.ContainsKey(ptr))
{
Dict.Add(ptr, new Internal_ScrollViewState());
}
return Dict[ptr];
}
}
}
#endif

View File

@ -1,413 +0,0 @@
#if CPP
using System;
using UnhollowerRuntimeLib;
using UnityEngine;
using Explorer.UnstripInternals;
using Il2CppSystem.Reflection;
namespace Explorer.UnstripInternals
{
public struct Internal_SliderHandler
{
public static int ScrollTroughSide
{
get
{
if (!m_getScrollTroughSideFailed)
{
try
{
return GUI.scrollTroughSide;
}
catch
{
m_getScrollTroughSideFailed = true;
}
}
return m_manualScrollTrough;
}
set
{
if (!m_setScrollTroughSideFailed)
{
try
{
GUI.scrollTroughSide = value;
return;
}
catch
{
m_setScrollTroughSideFailed = true;
}
}
m_manualScrollTrough = value;
}
}
private static bool m_getScrollTroughSideFailed;
private static bool m_setScrollTroughSideFailed;
private static int m_manualScrollTrough;
private readonly Rect position;
private readonly float currentValue;
private readonly float size;
private readonly float start;
private readonly float end;
private readonly GUIStyle slider;
private readonly GUIStyle thumb;
private readonly bool horiz;
private readonly int id;
public Internal_SliderHandler(Rect position, float currentValue, float size, float start,
float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id)
{
this.position = position;
this.currentValue = currentValue;
this.size = size;
this.start = start;
this.end = end;
this.slider = slider;
this.thumb = thumb;
this.horiz = horiz;
this.id = id;
}
public float Handle()
{
float result;
if (this.slider == null || this.thumb == null)
{
result = this.currentValue;
}
else
{
switch (this.CurrentEventType())
{
case EventType.MouseDown:
return this.OnMouseDown();
case EventType.MouseUp:
return this.OnMouseUp();
case EventType.MouseDrag:
return this.OnMouseDrag();
case EventType.Repaint:
return this.OnRepaint();
}
result = this.currentValue;
}
return result;
}
private float OnMouseDown()
{
float result;
if (!this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
{
result = this.currentValue;
}
else
{
ScrollTroughSide = 0;
GUIUtility.hotControl = this.id;
this.CurrentEvent().Use();
if (this.ThumbSelectionRect().Contains(this.CurrentEvent().mousePosition))
{
this.StartDraggingWithValue(this.ClampedCurrentValue());
result = this.currentValue;
}
else
{
GUI.changed = true;
if (this.SupportsPageMovements())
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
ext.isDragging = false;
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
ScrollTroughSide = this.CurrentScrollTroughSide();
result = this.PageMovementValue();
}
else
{
float num = this.ValueForCurrentMousePosition();
this.StartDraggingWithValue(num);
result = this.Clamp(num);
}
}
}
return result;
}
private float OnMouseDrag()
{
float result;
if (GUIUtility.hotControl != this.id)
{
result = this.currentValue;
}
else
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
if (!ext.isDragging)
{
result = this.currentValue;
}
else
{
GUI.changed = true;
this.CurrentEvent().Use();
float num = this.MousePosition() - ext.dragStartPos;
float value = ext.dragStartValue + num / this.ValuesPerPixel();
result = this.Clamp(value);
}
}
return result;
}
private float OnMouseUp()
{
if (GUIUtility.hotControl == this.id)
{
this.CurrentEvent().Use();
GUIUtility.hotControl = 0;
}
return this.currentValue;
}
private float OnRepaint()
{
this.slider.Draw(this.position, GUIContent.none, this.id);
if (!this.IsEmptySlider() && this.currentValue >= this.MinValue() && this.currentValue <= this.MaxValue())
{
this.thumb.Draw(this.ThumbRect(), GUIContent.none, this.id);
}
float result;
if (GUIUtility.hotControl != this.id || !this.position.Contains(this.CurrentEvent().mousePosition) || this.IsEmptySlider())
{
result = this.currentValue;
}
else if (this.ThumbRect().Contains(this.CurrentEvent().mousePosition))
{
if (ScrollTroughSide != 0)
{
GUIUtility.hotControl = 0;
}
result = this.currentValue;
}
else
{
GUI.InternalRepaintEditorWindow();
if (DateTime.Now < Internal.nextScrollStepTime)
{
result = this.currentValue;
}
else if (this.CurrentScrollTroughSide() != ScrollTroughSide)
{
result = this.currentValue;
}
else
{
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
if (this.SupportsPageMovements())
{
Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false;
GUI.changed = true;
result = this.PageMovementValue();
}
else
{
result = this.ClampedCurrentValue();
}
}
}
return result;
}
private EventType CurrentEventType()
{
return this.CurrentEvent().GetTypeForControl(this.id);
}
private int CurrentScrollTroughSide()
{
float num = (!this.horiz) ? this.CurrentEvent().mousePosition.y : this.CurrentEvent().mousePosition.x;
float num2 = (!this.horiz) ? this.ThumbRect().y : this.ThumbRect().x;
return (num <= num2) ? -1 : 1;
}
private bool IsEmptySlider()
{
return this.start == this.end;
}
private bool SupportsPageMovements()
{
return this.size != 0f && GUI.usePageScrollbars;
}
private float PageMovementValue()
{
float num = this.currentValue;
int num2 = (this.start <= this.end) ? 1 : -1;
if (this.MousePosition() > this.PageUpMovementBound())
{
num += this.size * (float)num2 * 0.9f;
}
else
{
num -= this.size * (float)num2 * 0.9f;
}
return this.Clamp(num);
}
private float PageUpMovementBound()
{
float result;
if (this.horiz)
{
result = this.ThumbRect().xMax - this.position.x;
}
else
{
result = this.ThumbRect().yMax - this.position.y;
}
return result;
}
private Event CurrentEvent()
{
return Event.current;
}
private float ValueForCurrentMousePosition()
{
float result;
if (this.horiz)
{
result = (this.MousePosition() - this.ThumbRect().width * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
}
else
{
result = (this.MousePosition() - this.ThumbRect().height * 0.5f) / this.ValuesPerPixel() + this.start - this.size * 0.5f;
}
return result;
}
private float Clamp(float value)
{
return Mathf.Clamp(value, this.MinValue(), this.MaxValue());
}
private Rect ThumbSelectionRect()
{
return this.ThumbRect();
}
private void StartDraggingWithValue(float dragStartValue)
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
ext.dragStartPos = this.MousePosition();
ext.dragStartValue = dragStartValue;
ext.isDragging = true;
}
private SliderState GetSliderState()
{
return GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>();
}
private Rect ThumbRect()
{
return (!this.horiz) ? this.VerticalThumbRect() : this.HorizontalThumbRect();
}
private Rect VerticalThumbRect()
{
float num = this.ValuesPerPixel();
Rect result;
if (this.start < this.end)
{
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * num + this.ThumbSize());
}
else
{
result = new Rect(this.position.x + (float)this.slider.padding.left, (this.ClampedCurrentValue() + this.size - this.start) * num + this.position.y + (float)this.slider.padding.top, this.position.width - (float)this.slider.padding.horizontal, this.size * -num + this.ThumbSize());
}
return result;
}
private Rect HorizontalThumbRect()
{
float num = this.ValuesPerPixel();
Rect result;
if (this.start < this.end)
{
result = new Rect((this.ClampedCurrentValue() - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y + (float)this.slider.padding.top, this.size * num + this.ThumbSize(), this.position.height - (float)this.slider.padding.vertical);
}
else
{
result = new Rect((this.ClampedCurrentValue() + this.size - this.start) * num + this.position.x + (float)this.slider.padding.left, this.position.y, this.size * -num + this.ThumbSize(), this.position.height);
}
return result;
}
private float ClampedCurrentValue()
{
return this.Clamp(this.currentValue);
}
private float MousePosition()
{
float result;
if (this.horiz)
{
result = this.CurrentEvent().mousePosition.x - this.position.x;
}
else
{
result = this.CurrentEvent().mousePosition.y - this.position.y;
}
return result;
}
private float ValuesPerPixel()
{
float result;
if (this.horiz)
{
result = (this.position.width - (float)this.slider.padding.horizontal - this.ThumbSize()) / (this.end - this.start);
}
else
{
result = (this.position.height - (float)this.slider.padding.vertical - this.ThumbSize()) / (this.end - this.start);
}
return result;
}
private float ThumbSize()
{
float result;
if (this.horiz)
{
result = ((this.thumb.fixedWidth == 0f) ? ((float)this.thumb.padding.horizontal) : this.thumb.fixedWidth);
}
else
{
result = ((this.thumb.fixedHeight == 0f) ? ((float)this.thumb.padding.vertical) : this.thumb.fixedHeight);
}
return result;
}
private float MaxValue()
{
return Mathf.Max(this.start, this.end) - this.size;
}
private float MinValue()
{
return Mathf.Min(this.start, this.end);
}
}
}
#endif

View File

@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Explorer.UnstripInternals
{
public class Internal_SliderState
{
public float dragStartPos;
public float dragStartValue;
public bool isDragging;
public static Dictionary<IntPtr, Internal_SliderState> Dict = new Dictionary<IntPtr, Internal_SliderState>();
public static Internal_SliderState FromPointer(IntPtr ptr)
{
if (!Dict.ContainsKey(ptr))
{
Dict.Add(ptr, new Internal_SliderState());
}
return Dict[ptr];
}
}
}