Compare commits

...

10 Commits
2.0.1 ... 2.0.6

Author SHA1 Message Date
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
45 changed files with 3093 additions and 701 deletions

View File

@ -78,11 +78,16 @@ There is a simple Mod Config for the Explorer. You can access the settings via t
* Whether or not to show the Bitwise Editing helper when inspecting integers
`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
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 Hellpoint, use [HPExplorerMouseControl](https://github.com/sinai-dev/Hellpoint-Mods/tree/master/HPExplorerMouseControl/HPExplorerMouseControl)
@ -93,8 +98,9 @@ For example:
using Explorer;
using Harmony; // or 'using HarmonyLib;' for BepInEx
// ...
[HarmonyPatch(typeof(MyGame.MenuClass), nameof(MyGame.MenuClass.CursorUpdate)]
public class MenuClass_CursorUpdate
// You will need to figure out the relevant Class and Method for your game using dnSpy.
[HarmonyPatch(typeof(MyGame.InputManager), nameof(MyGame.InputManager.Update))]
public class InputManager_Update
{
[HarmonyPrefix]
public static bool Prefix()

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Explorer.UI;
namespace Explorer.CacheObject
{
@ -21,6 +22,15 @@ namespace Explorer.CacheObject
public override void UpdateValue()
{
if (IValue is InteractiveDictionary iDict)
{
if (!iDict.EnsureDictionaryIsSupported())
{
ReflectionException = "Not supported due to TypeInitializationException";
return;
}
}
try
{
var fi = MemInfo as FieldInfo;

View File

@ -129,7 +129,7 @@ namespace Explorer.CacheObject
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(15) });
GUILayout.Label(label, new GUILayoutOption[] { GUILayout.ExpandWidth(false) });
this.m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
this.m_argumentInput[i] = GUIUnstrip.TextField(input, new GUILayoutOption[] { GUILayout.ExpandWidth(true) });
GUI.skin.label.alignment = TextAnchor.MiddleLeft;

View File

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

View File

@ -25,12 +25,26 @@ namespace Explorer.CacheObject
return;
}
//ExplorerCore.Log("Initializing InteractiveValue of type " + valueType.FullName);
InteractiveValue interactive;
if (valueType == typeof(GameObject) || valueType == typeof(Transform))
{
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))
{
interactive = new InteractivePrimitive();

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Explorer.UI;
namespace Explorer.CacheObject
{
@ -32,14 +33,38 @@ namespace Explorer.CacheObject
return;
}
if (IValue is InteractiveDictionary iDict)
{
if (!iDict.EnsureDictionaryIsSupported())
{
ReflectionException = "Not supported due to TypeInitializationException";
return;
}
}
try
{
var pi = MemInfo as PropertyInfo;
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
IValue.Value = pi.GetValue(target, ParseArguments());
if (pi.CanRead)
{
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
base.UpdateValue();
IValue.Value = pi.GetValue(target, ParseArguments());
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)
{

View File

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

View File

@ -208,10 +208,14 @@
<Compile Include="CacheObject\CacheMethod.cs" />
<Compile Include="CacheObject\CacheProperty.cs" />
<Compile Include="CacheObject\CacheObjectBase.cs" />
<Compile Include="Helpers\Texture2DHelpers.cs" />
<Compile Include="UI\InteractiveValue\InteractiveValue.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveDictionary.cs" />
<Compile Include="UI\InteractiveValue\Object\InteractiveEnumerable.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\InteractiveRect.cs" />
<Compile Include="UI\InteractiveValue\Struct\InteractiveVector.cs" />
@ -227,7 +231,7 @@
<Compile Include="Extensions\UnityExtensions.cs" />
<Compile Include="Helpers\ReflectionHelpers.cs" />
<Compile Include="Helpers\UnityHelpers.cs" />
<Compile Include="Input\AbstractInput.cs" />
<Compile Include="Input\IAbstractInput.cs" />
<Compile Include="Tests\TestClass.cs" />
<Compile Include="UI\ForceUnlockCursor.cs" />
<Compile Include="Input\InputManager.cs" />
@ -257,6 +261,10 @@
<Compile Include="UI\TabViewWindow.cs" />
<Compile Include="UI\WindowBase.cs" />
<Compile Include="UI\WindowManager.cs" />
<Compile Include="Unstrip\ImageConversion\ImageConversionUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\Internal_GUIUtility.cs" />
<Compile Include="Unstrip\IMGUI\Internal_TextEditor.cs" />
<Compile Include="Unstrip\LayerMask\LayerMaskUnstrip.cs" />
<Compile Include="Unstrip\Scene\SceneUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\GUIUnstrip.cs" />
<Compile Include="Unstrip\IMGUI\Internal_LayoutUtility.cs" />

View File

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

View File

@ -0,0 +1,192 @@
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
{
#if CPP
// 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]; // not sure if cast is needed
}
File.WriteAllBytes(savepath, safeData);
#else
File.WriteAllBytes(savepath, data);
#endif
}
}
// 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,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

@ -10,65 +10,77 @@ namespace Explorer
{
public static class InputManager
{
private static AbstractInput inputModule;
private static IAbstractInput m_inputModule;
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.InputLegacyModule", 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!");
inputModule = new NoInput();
m_inputModule = new NoInput();
}
inputModule.Init();
bool TryLoadModule(string dll, Type check) => ReflectionHelpers.LoadModule(dll) && check != null;
m_inputModule.Init();
}
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 GetKey(KeyCode key) => inputModule.GetKey(key);
public static bool GetKeyDown(KeyCode key) => m_inputModule.GetKeyDown(key);
public static bool GetKey(KeyCode key) => m_inputModule.GetKey(key);
public static bool GetMouseButtonDown(int btn) => inputModule.GetMouseButtonDown(btn);
public static bool GetMouseButton(int btn) => inputModule.GetMouseButton(btn);
public static bool GetMouseButtonDown(int btn) => m_inputModule.GetMouseButtonDown(btn);
public static bool GetMouseButton(int btn) => m_inputModule.GetMouseButton(btn);
//#if CPP
//#pragma warning disable IDE1006
// // public extern static string compositionString { get; }
#if CPP
internal delegate void d_ResetInputAxes();
internal static d_ResetInputAxes ResetInputAxes_iCall =
IL2CPP.ResolveICall<d_ResetInputAxes>("UnityEngine.Input::ResetInputAxes");
// internal delegate string get_compositionString_delegate();
// internal static get_compositionString_delegate get_compositionString_iCall =
// IL2CPP.ResolveICall<get_compositionString_delegate>("UnityEngine.Input::get_compositionString");
public static void ResetInputAxes() => ResetInputAxes_iCall();
#else
public static void ResetInputAxes() => UnityEngine.Input.ResetInputAxes();
#endif
// public static string compositionString => get_compositionString_iCall();
#if CPP
#pragma warning disable IDE1006
// public extern static string compositionString { get; }
// // public extern static Vector2 compositionCursorPos { get; set; }
internal delegate IntPtr d_get_compositionString();
internal static d_get_compositionString get_compositionString_iCall =
IL2CPP.ResolveICall<d_get_compositionString>("UnityEngine.Input::get_compositionString");
// internal delegate Vector2 get_compositionCursorPos_delegate();
// internal static get_compositionCursorPos_delegate get_compositionCursorPos_iCall =
// IL2CPP.ResolveICall<get_compositionCursorPos_delegate>("UnityEngine.Input::get_compositionCursorPos");
public static string compositionString => IL2CPP.Il2CppStringToManaged(get_compositionString_iCall());
// internal delegate void set_compositionCursorPos_delegate(Vector2 value);
// internal static set_compositionCursorPos_delegate set_compositionCursorPos_iCall =
// IL2CPP.ResolveICall<set_compositionCursorPos_delegate>("UnityEngine.Input::set_compositionCursorPos");
// public extern static Vector2 compositionCursorPos { get; set; }
// public static Vector2 compositionCursorPos
// {
// get => get_compositionCursorPos_iCall();
// set => set_compositionCursorPos_iCall(value);
// }
internal delegate void d_get_compositionCursorPos(out Vector2 ret);
internal static d_get_compositionCursorPos get_compositionCursorPos_iCall =
IL2CPP.ResolveICall<d_get_compositionCursorPos>("UnityEngine.Input::get_compositionCursorPos_Injected");
//#pragma warning restore IDE1006
//#endif
internal delegate void set_compositionCursorPos_delegate(ref Vector2 value);
internal static set_compositionCursorPos_delegate set_compositionCursorPos_iCall =
IL2CPP.ResolveICall<set_compositionCursorPos_delegate>("UnityEngine.Input::set_compositionCursorPos_Injected");
public static Vector2 compositionCursorPos
{
get
{
get_compositionCursorPos_iCall(out Vector2 ret);
return ret;
}
set => set_compositionCursorPos_iCall(ref value);
}
#pragma warning restore IDE1006
#endif
}
}

View File

@ -7,7 +7,7 @@ using UnityEngine;
namespace Explorer.Input
{
public class InputSystem : AbstractInput
public class InputSystem : IAbstractInput
{
public static Type TKeyboard => _keyboard ?? (_keyboard = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard"));
private static Type _keyboard;
@ -43,9 +43,9 @@ namespace Explorer.Input
private static PropertyInfo _positionProp;
private static MethodInfo _readVector2InputMethod;
public override Vector2 MousePosition => (Vector2)_readVector2InputMethod.Invoke(MousePositionInfo, new object[0]);
public Vector2 MousePosition => (Vector2)_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 actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsedKey });
@ -53,7 +53,7 @@ namespace Explorer.Input
return (bool)_btnWasPressedProp.GetValue(actualKey, null);
}
public override bool GetKey(KeyCode key)
public bool GetKey(KeyCode key)
{
var parsed = Enum.Parse(TKey, key.ToString());
var actualKey = _kbIndexer.GetValue(CurrentKeyboard, new object[] { parsed });
@ -61,7 +61,7 @@ namespace Explorer.Input
return (bool)_btnIsPressedProp.GetValue(actualKey, null);
}
public override bool GetMouseButtonDown(int btn)
public bool GetMouseButtonDown(int btn)
{
switch (btn)
{
@ -72,7 +72,7 @@ namespace Explorer.Input
}
}
public override bool GetMouseButton(int btn)
public bool GetMouseButton(int btn)
{
switch (btn)
{
@ -83,7 +83,7 @@ namespace Explorer.Input
}
}
public override void Init()
public void Init()
{
ExplorerCore.Log("Initializing new InputSystem support...");

View File

@ -7,7 +7,7 @@ using UnityEngine;
namespace Explorer.Input
{
public class LegacyInput : AbstractInput
public class LegacyInput : IAbstractInput
{
public static Type TInput => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input"));
private static Type _input;
@ -18,17 +18,17 @@ namespace Explorer.Input
private static MethodInfo _getMouseButtonMethod;
private static MethodInfo _getMouseButtonDownMethod;
public override Vector2 MousePosition => (Vector3)_mousePositionProp.GetValue(null, null);
public Vector2 MousePosition => (Vector3)_mousePositionProp.GetValue(null, null);
public override bool GetKey(KeyCode key) => (bool)_getKeyMethod.Invoke(null, new object[] { key });
public bool GetKey(KeyCode key) => (bool)_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)_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)_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)_getMouseButtonDownMethod.Invoke(null, new object[] { btn });
public override void Init()
public void Init()
{
ExplorerCore.Log("Initializing Legacy Input support...");

View File

@ -8,18 +8,16 @@ namespace Explorer.Input
{
// 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 override bool GetMouseButtonDown(int btn) => false;
public override void Init() { }
public void Init() { }
}
}

View File

@ -4,6 +4,7 @@ using System;
using UnityEngine;
using System.Reflection;
using System.Runtime.InteropServices;
using Explorer.UI.Shared;
#if CPP
using UnhollowerBaseLib;
using UnityEngine.SceneManagement;
@ -14,16 +15,13 @@ namespace Explorer.Tests
public static class StaticTestClass
{
public static int StaticProperty => 5;
public static int StaticField = 69;
public static List<string> StaticList = new List<string>
{
"one",
"two",
"three",
};
public static void StaticMethod() { }
}
@ -33,6 +31,17 @@ namespace Explorer.Tests
public static TestClass Instance => m_instance ?? (m_instance = new TestClass());
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 StaticField = 5;
public int NonStaticField;
@ -52,6 +61,16 @@ namespace Explorer.Tests
public TestClass()
{
#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);
ILHashSetTest = new Il2CppSystem.Collections.Generic.HashSet<string>();
ILHashSetTest.Add("1");
ILHashSetTest.Add("2");

View File

@ -17,32 +17,25 @@ namespace Explorer.UI
}
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;
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;
public static void Init()
{
try
{
// Check if Cursor class is loaded
if (CursorType == null)
{
ExplorerCore.Log("Trying to manually load Cursor module...");
if (ReflectionHelpers.LoadModule("UnityEngine.CoreModule") && CursorType != null)
{
ExplorerCore.Log("Ok!");
}
else
{
throw new Exception("Could not load UnityEngine.Cursor module!");
}
throw new Exception("Could not find Type 'UnityEngine.Cursor'!");
}
// Get current cursor state and enable cursor
@ -91,7 +84,8 @@ namespace Explorer.UI
}
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,7 @@ using System.Collections.Generic;
using UnityEngine;
using Explorer.UI.Shared;
using Explorer.UI.Main;
using Explorer.Unstrip.LayerMasks;
#if CPP
using UnhollowerRuntimeLib;
#endif
@ -17,6 +18,8 @@ namespace Explorer.UI.Inspectors
public GameObject TargetGO;
public bool pendingDestroy;
private static bool m_hideControls;
// gui element holders
@ -43,6 +46,8 @@ namespace Explorer.UI.Inspectors
private bool m_autoUpdateTransform;
private bool m_localContext;
private int m_layer;
private readonly List<Component> m_cachedDestroyList = new List<Component>();
private string m_addComponentInput = "";
@ -104,16 +109,16 @@ namespace Explorer.UI.Inspectors
{
try
{
if (pendingDestroy) return;
if (Target == null)
{
ExplorerCore.Log("Target is null!");
DestroyWindow();
DestroyOnException(new Exception("Target was destroyed."));
return;
}
if (!TargetGO && !GetObjectAsGameObject())
{
ExplorerCore.Log("Target was destroyed!");
DestroyWindow();
DestroyOnException(new Exception("Target was destroyed."));
return;
}
@ -132,6 +137,8 @@ namespace Explorer.UI.Inspectors
TargetGO.transform.localScale = m_frozenScale;
}
m_layer = TargetGO.layer;
// update child objects
var childList = new List<Transform>();
for (int i = 0; i < TargetGO.transform.childCount; i++)
@ -162,7 +169,10 @@ namespace Explorer.UI.Inspectors
private void DestroyOnException(Exception e)
{
if (pendingDestroy) return;
ExplorerCore.Log($"Exception drawing GameObject Window: {e.GetType()}, {e.Message}");
pendingDestroy = true;
DestroyWindow();
}
@ -204,6 +214,8 @@ namespace Explorer.UI.Inspectors
public override void WindowFunction(int windowID)
{
if (pendingDestroy) return;
try
{
var rect = WindowManager.TabView ? TabViewWindow.Instance.m_rect : this.m_rect;
@ -250,6 +262,8 @@ namespace Explorer.UI.Inspectors
GUIUnstrip.TextArea(m_name, new GUILayoutOption[0]);
GUILayout.EndHorizontal();
LayerControls();
// --- Horizontal Columns section ---
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
@ -280,6 +294,34 @@ namespace Explorer.UI.Inspectors
}
}
private void LayerControls()
{
GUIUnstrip.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)
{
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);

View File

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

View File

@ -160,7 +160,7 @@ namespace Explorer.UI.Inspectors
{
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;
if (m < 4 || m > 16)
continue;
@ -208,16 +208,19 @@ namespace Explorer.UI.Inspectors
continue;
}
//ExplorerCore.Log($"Trying to cache member {sig}...");
try
{
var cached = CacheFactory.GetCacheObject(member, target);
if (cached != null)
{
cachedSigs.Add(sig);
list.Add(cached);
cached.ReflectionException = exception;
if (string.IsNullOrEmpty(cached.ReflectionException))
{
cached.ReflectionException = exception;
}
}
}
catch (Exception e)
@ -260,15 +263,12 @@ namespace Explorer.UI.Inspectors
? new GUILayoutOption[] { GUILayout.Width(245f) }
: new GUILayoutOption[0];
GUILayout.Label("<b>Type:</b> <color=cyan>" + TargetType.FullName + "</color>", labelWidth);
GUILayout.EndHorizontal();
if (asInstance != null)
{
asInstance.DrawInstanceControls(rect);
}
else
{
GUILayout.EndHorizontal();
}
UIStyles.HorizontalLine(Color.grey);

View File

@ -146,7 +146,7 @@ namespace Explorer.UI
{
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]);
}
@ -198,31 +198,51 @@ namespace Explorer.UI
return m_toStringMethod;
}
private string GetButtonLabel()
public string GetButtonLabel()
{
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
? Syntax.Class_Static
: Syntax.Class_Instance;
string label;
string typeLabel = $"<color={classColor}>{ValueType.FullName}</color>";
if (Value is UnityEngine.Object)
if (valueType == typeof(TextAsset))
{
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
{
if (!label.Contains(ValueType.FullName))
label = (string)ToStringMethod?.Invoke(Value, null) ?? Value.ToString();
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 += $" ({typeLabel})";
label = label.Replace($"({valueType.FullName})", $"({typeLabel})");
}
else
{
label = label.Replace(ValueType.FullName, typeLabel);
if (!label.Contains(valueType.FullName))
{
label += $" ({typeLabel})";
}
else
{
label = label.Replace(valueType.FullName, typeLabel);
}
}
}

View File

@ -10,6 +10,9 @@ using Explorer.CacheObject;
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 bool IsExpanded { get; set; }
@ -158,7 +161,7 @@ namespace Explorer.UI
m_cachedValues = values.ToArray();
}
private bool EnsureDictionaryIsSupported()
public bool EnsureDictionaryIsSupported()
{
if (typeof(IDictionary).IsAssignableFrom(ValueType))
{
@ -177,6 +180,11 @@ namespace Explorer.UI
.GetField("NativeClassPtr")
.GetValue(null);
if (ptr == IntPtr.Zero)
{
return false;
}
return Il2CppSystem.Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(ptr)) is Il2CppSystem.Type;
}
}

View File

@ -6,6 +6,10 @@ using System.Reflection;
using UnityEngine;
using Explorer.UI.Shared;
using Explorer.CacheObject;
using System.Linq;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.UI
{
@ -173,38 +177,20 @@ namespace Explorer.UI
private Type GetEntryType()
{
if (m_entryType == null)
if (ValueType.IsGenericType)
{
if (OwnerCacheObject is CacheMember cacheMember && cacheMember.MemInfo != null)
{
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;
}
var gArgs = ValueType.GetGenericArguments();
if (memberType != null && memberType.IsGenericType)
{
m_entryType = memberType.GetGenericArguments()[0];
}
}
else if (Value != null)
if (ValueType.FullName.Contains("ValueCollection"))
{
var type = Value.GetType();
if (type.IsGenericType)
{
m_entryType = type.GetGenericArguments()[0];
}
m_entryType = gArgs[gArgs.Length - 1];
}
else
{
m_entryType = gArgs[0];
}
}
// use System.Object for non-generic.
if (m_entryType == null)
else
{
m_entryType = typeof(object);
}
@ -255,18 +241,11 @@ namespace Explorer.UI
}
#endif
//ExplorerCore.Log("Caching enumeration entry " + obj.ToString() + " as " + EntryType.FullName);
var cached = new CacheEnumerated() { Index = index, RefIList = Value as IList, ParentEnumeration = this };
cached.Init(obj, EntryType);
list.Add(cached);
//if (CacheFactory.GetCacheObject(obj, t) is CacheObjectBase cached)
//{
// list.Add(cached);
//}
//else
//{
// list.Add(null);
//}
}
else
{

View File

@ -0,0 +1,51 @@
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 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)
{
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)
{
GUIUnstrip.BeginVertical();
GUIUnstrip.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()
{
GUIUnstrip.BeginHorizontal();
GUILayout.Label("Save folder:", new GUILayoutOption[] { GUILayout.Width(80f) });
saveFolder = GUIUnstrip.TextField(saveFolder, new GUILayoutOption[0]);
GUIUnstrip.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

@ -80,12 +80,13 @@ namespace Explorer.UI
if (OwnerCacheObject.CanWrite)
{
b = GUILayout.Toggle(b, label, new GUILayoutOption[0]);
if (b != (bool)Value)
{
Value = b;
OwnerCacheObject.SetValue();
}
Value = GUILayout.Toggle(b, label, new GUILayoutOption[] { GUILayout.Width(60) });
DrawApplyButton();
//if (b != (bool)Value)
//{
// Value = b;
// OwnerCacheObject.SetValue();
//}
}
else
{
@ -104,13 +105,8 @@ namespace Explorer.UI
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) });
if (OwnerCacheObject.CanWrite)
{
if (GUILayout.Button("<color=#00FF00>Apply</color>", new GUILayoutOption[] { GUILayout.Width(60) }))
{
SetValueFromInput();
}
}
DrawApplyButton();
if (ModConfig.Instance.Bitwise_Support && m_canBitwiseOperate)
{
@ -129,6 +125,24 @@ namespace Explorer.UI
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()
{
if (OwnerCacheObject.CanWrite)

View File

@ -33,7 +33,7 @@ namespace Explorer.UI.Main
public static TextEditor textEditor;
private bool shouldRefocus;
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetCompletionStyle();
public static GUIStyle AutocompleteStyle => autocompleteStyle ?? GetAutocompleteStyle();
private static GUIStyle autocompleteStyle;
public static readonly string[] DefaultUsing = new string[]
@ -342,9 +342,9 @@ Help();";
}
// 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),
margin = new RectOffset(0, 0, 0, 0),
@ -353,8 +353,10 @@ Help();";
normal = { background = null },
focused = { 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

View File

@ -18,12 +18,14 @@ namespace Explorer.UI.Main
public int defaultPageLimit;
public bool bitwiseSupport;
public bool tabView;
public string defaultOutputPath;
private CacheObjectBase toggleKeyInput;
private CacheObjectBase defaultSizeInput;
private CacheObjectBase defaultPageLimitInput;
private CacheObjectBase bitwiseSupportInput;
private CacheObjectBase tabViewInput;
private CacheObjectBase defaultOutputPathInput;
public override void Init()
{
@ -41,6 +43,9 @@ namespace Explorer.UI.Main
tabView = ModConfig.Instance.Tab_View;
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() { }
@ -58,26 +63,41 @@ namespace Explorer.UI.Main
toggleKeyInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Default Window Size:", new GUILayoutOption[] { GUILayout.Width(215f) });
defaultSizeInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Default Items per Page:", new GUILayoutOption[] { GUILayout.Width(215f) });
defaultPageLimitInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Enable Bitwise Editing:", new GUILayoutOption[] { GUILayout.Width(215f) });
bitwiseSupportInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
GUILayout.Label($"Enable Tab View:", new GUILayoutOption[] { GUILayout.Width(215f) });
tabViewInput.IValue.DrawValue(MainMenu.MainRect, MainMenu.MainRect.width - 215f);
GUILayout.EndHorizontal();
UIStyles.HorizontalLine(Color.black, true);
GUIUnstrip.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]))
{
ApplyAndSave();

View File

@ -19,8 +19,6 @@ namespace Explorer.UI.Main
private float m_timeOfLastUpdate = -1f;
private const int PASSIVE_UPDATE_INTERVAL = 1;
private static bool m_getRootObjectsFailed;
private static string m_currentScene = "";
// gameobject list
@ -50,7 +48,7 @@ namespace Explorer.UI.Main
if (m_searching)
CancelSearch();
Update_Impl(true);
Update_Impl();
}
public void TraverseUp()
@ -75,11 +73,6 @@ namespace Explorer.UI.Main
public void CancelSearch()
{
m_searching = false;
if (m_getRootObjectsFailed && !m_currentTransform)
{
GetRootObjectsManual_Impl();
}
}
public List<CacheObjectBase> SearchSceneObjects(string _search)
@ -112,7 +105,7 @@ namespace Explorer.UI.Main
Update_Impl();
}
private void Update_Impl(bool manual = false)
private void Update_Impl()
{
List<Transform> allTransforms = new List<Transform>();
@ -126,39 +119,23 @@ namespace Explorer.UI.Main
}
else
{
if (!m_getRootObjectsFailed)
for (int i = 0; i < SceneManager.sceneCount; i++)
{
try
var scene = SceneManager.GetSceneAt(i);
if (scene.name == m_currentScene)
{
for (int i = 0; i < SceneManager.sceneCount; i++)
{
var scene = SceneManager.GetSceneAt(i);
var rootObjects =
#if CPP
Unstrip.Scenes.SceneUnstrip.GetRootGameObjects(scene)
.Select(it => it.transform);
#else
scene.GetRootGameObjects().Select(it => it.transform);
#endif
allTransforms.AddRange(rootObjects);
if (scene.name == m_currentScene)
{
allTransforms.AddRange(scene.GetRootGameObjects()
.Select(it => it.transform));
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());
}
}
@ -178,36 +155,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 --------- //
public override void DrawWindow()
@ -292,15 +239,12 @@ namespace Explorer.UI.Main
{
int index = names.IndexOf(m_currentScene);
index += changeWanted;
if (index > scenes.Count - 1)
if (index >= 0 && index < SceneManager.sceneCount)
{
index = 0;
m_currentScene = scenes[index].name;
Update_Impl();
}
else if (index < 0)
{
index = scenes.Count - 1;
}
m_currentScene = scenes[index].name;
}
}
}
@ -317,7 +261,7 @@ namespace Explorer.UI.Main
{
Pages.TurnPage(Turn.Left, ref this.scroll);
Update_Impl(true);
Update_Impl();
}
Pages.CurrentPageLabel();
@ -326,7 +270,7 @@ namespace Explorer.UI.Main
{
Pages.TurnPage(Turn.Right, ref this.scroll);
Update_Impl(true);
Update_Impl();
}
}
@ -356,14 +300,6 @@ namespace Explorer.UI.Main
else
{
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)

View File

@ -6,6 +6,7 @@ using System.Reflection;
using UnityEngine;
using Explorer.UI.Shared;
using Explorer.CacheObject;
using System.Threading;
namespace Explorer.UI.Main
{
@ -15,9 +16,13 @@ namespace Explorer.UI.Main
public override string Name { get => "Search"; }
private int MaxSearchResults = 5000;
private string m_searchInput = "";
private string m_typeInput = "";
//private bool m_cachingResults;
private Vector2 resultsScroll = Vector2.zero;
public PageHelper Pages = new PageHelper();
@ -58,6 +63,8 @@ namespace Explorer.UI.Main
private void CacheResults(IEnumerable results, bool isStaticClasses = false)
{
//m_cachingResults = true;
m_searchResults = new List<CacheObjectBase>();
foreach (var obj in results)
@ -67,6 +74,9 @@ namespace Explorer.UI.Main
#if CPP
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;
}
#else
@ -76,6 +86,14 @@ namespace Explorer.UI.Main
}
#endif
if (toCache is TextAsset textAsset)
{
if (string.IsNullOrEmpty(textAsset.text))
{
continue;
}
}
var cache = CacheFactory.GetCacheObject(toCache);
cache.IsStaticClassSearchResult = isStaticClasses;
m_searchResults.Add(cache);
@ -83,187 +101,22 @@ namespace Explorer.UI.Main
Pages.ItemCount = m_searchResults.Count;
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()
{
Pages.PageOffset = 0;
CacheResults(FindAllObjectsOfType(m_searchInput, m_typeInput));
}
//if (m_cachingResults)
//{
// ExplorerCore.Log("Cannot search now, we are already caching results...");
// return;
//}
Pages.PageOffset = 0;
private List<object> FindAllObjectsOfType(string searchQuery, string typeName)
{
#if CPP
Il2CppSystem.Type searchType = null;
@ -272,24 +125,18 @@ namespace Explorer.UI.Main
#endif
if (TypeMode == TypeFilter.Custom)
{
try
if (ReflectionHelpers.GetTypeByName(m_typeInput) is Type t)
{
if (ReflectionHelpers.GetTypeByName(typeName) is Type t)
{
#if CPP
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
searchType = Il2CppSystem.Type.GetType(t.AssemblyQualifiedName);
#else
searchType = t;
searchType = t;
#endif
}
else
{
throw new Exception($"Could not find a Type by the name of '{typeName}'!");
}
}
catch (Exception e)
else
{
ExplorerCore.Log("Exception getting Search Type: " + e.GetType() + ", " + e.Message);
ExplorerCore.Log($"Could not find a Type by the name of '{m_typeInput}'!");
return;
}
}
else if (TypeMode == TypeFilter.Object)
@ -311,7 +158,7 @@ namespace Explorer.UI.Main
{
ExplorerCore.LogWarning("Your Custom Class Type must inherit from UnityEngine.Object!");
}
return new List<object>();
return;
}
var matches = new List<object>();
@ -323,9 +170,9 @@ namespace Explorer.UI.Main
int i = 0;
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;
}
@ -355,7 +202,7 @@ namespace Explorer.UI.Main
i++;
}
return matches;
CacheResults(matches);
}
public static bool FilterScene(object obj, SceneFilter filter)
@ -394,8 +241,6 @@ namespace Explorer.UI.Main
return false;
}
// ====== other ========
private static bool FilterName(string name)
{
// Don't really want these instances.
@ -497,5 +342,202 @@ namespace Explorer.UI.Main
return list;
}
// =========== GUI DRAW ============= //
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++)
{
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]);
}
GUIUnstrip.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()
{
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.Label("Max Results:", new GUILayoutOption[] { GUILayout.Width(100) });
var s = MaxSearchResults.ToString();
s = GUIUnstrip.TextField(s, new GUILayoutOption[] { GUILayout.Width(80) });
if (int.TryParse(s, out int i))
{
MaxSearchResults = i;
}
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();
}
//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

@ -8,18 +8,17 @@ namespace Explorer.UI.Shared
{
public class ResizeDrag
{
#if CPP
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 bool isResizing = false;
private static Rect m_currentResize;
private static int m_currentWindow;
public static Rect ResizeWindow(Rect _rect, int ID)
{
#if CPP
if (!RESIZE_FAILED)
{
var origRect = _rect;
@ -29,31 +28,40 @@ namespace Explorer.UI.Shared
GUIUnstrip.BeginHorizontal(GUIContent.none, GUI.skin.box, null);
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
#if ML
GUILayout.Button(gcDrag, GUI.skin.label, new GUILayoutOption[] { GUILayout.Height(15) });
#if BIE
#if CPP // Temporary for BepInEx IL2CPP
GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) });
#else
GUILayout.Button("<-- Drag to resize -->", new GUILayoutOption[] { GUILayout.Height(15) });
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
var r = GUIUnstrip.GetLastRect();
var resizeDragArea = GUIUnstrip.GetLastRect();
var mousePos = InputManager.MousePosition;
try
{
var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y));
if (r.Contains(mouse) && InputManager.GetMouseButtonDown(0))
if (resizeDragArea.Contains(mouse))
{
isResizing = true;
m_currentWindow = ID;
m_currentResize = new Rect(mouse.x, mouse.y, _rect.width, _rect.height);
IsMouseInResizeArea = true;
if (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;
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.height = Mathf.Max(100, m_currentResize.height + (mouse.y - m_currentResize.y));
@ -81,8 +89,6 @@ namespace Explorer.UI.Shared
//ExplorerCore.Log(e.StackTrace);
return origRect;
}
GUI.skin.label.alignment = TextAnchor.UpperLeft;
}
else
{
@ -111,44 +117,8 @@ namespace Explorer.UI.Shared
}
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;
return _rect;

View File

@ -66,10 +66,19 @@ namespace Explorer.UI
GUIUnstrip.BeginVertical(GUIContent.none, GUI.skin.box, null);
GUIUnstrip.BeginHorizontal(new GUILayoutOption[0]);
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;
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)
{
rowCount = 0;
@ -82,7 +91,6 @@ namespace Explorer.UI
string color = focused ? "<color=lime>" : "<color=orange>";
GUI.color = focused ? Color.green : Color.white;
var window = WindowManager.Windows[i];
if (GUILayout.Button(color + window.Title + "</color>", new GUILayoutOption[] { GUILayout.Width(200) }))
{
TargetTabID = i;

View File

@ -11,6 +11,26 @@ namespace Explorer.UI
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 int CurrentWindowID { get; set; } = 500000;
private static Rect m_lastWindowRect;
@ -123,26 +143,6 @@ namespace Explorer.UI
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)
{
var mousePos = InputManager.MousePosition;

View File

@ -53,12 +53,21 @@ namespace Explorer
public static string TextField(string text, GUILayoutOption[] options)
{
#if CPP
return Internal.TextField(text, options);
return Internal.TextField(text, options, false);
#else
return GUILayout.TextField(text, options);
#endif
}
public static string TextArea(string text, params GUILayoutOption[] options)
{
#if CPP
return Internal.TextField(text, options, true);
#else
return GUILayout.TextArea(text, options);
#endif
}
public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title)
{
#if CPP
@ -77,15 +86,6 @@ namespace Explorer
#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)
{
#if CPP

View File

@ -16,12 +16,9 @@ namespace Explorer.Unstrip.IMGUI
public static bool ScrollFailed = false;
public static bool ManualUnstripFailed = false;
public static GenericStack ScrollStack => m_scrollStack ?? GetScrollStack();
public static PropertyInfo m_scrollViewStatesInfo;
public static GenericStack m_scrollStack;
public static Dictionary<int, Il2CppSystem.Object> StateCache => m_stateCacheDict ?? GetStateCacheDict();
public static Dictionary<int, Il2CppSystem.Object> m_stateCacheDict;
public static Stack<object> ScrollStack => m_scrollStack ?? GetScrollStack();
public static Stack<object> m_scrollStack;
//public static PropertyInfo m_scrollViewStatesInfo;
public static GUIStyle SpaceStyle => m_spaceStyle ?? GetSpaceStyle();
public static GUIStyle m_spaceStyle;
@ -34,53 +31,13 @@ namespace Explorer.Unstrip.IMGUI
public static MethodInfo m_bringWindowToFrontMethod;
public static bool m_bringWindowFrontAttempted;
private static GenericStack GetScrollStack()
private static Stack<object> GetScrollStack()
{
if (m_scrollViewStatesInfo == null)
{
if (typeof(GUI).GetProperty("scrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo scrollStatesInfo)
{
m_scrollViewStatesInfo = scrollStatesInfo;
}
else if (typeof(GUI).GetProperty("s_ScrollViewStates", ReflectionHelpers.CommonFlags) is PropertyInfo s_scrollStatesInfo)
{
m_scrollViewStatesInfo = s_scrollStatesInfo;
}
}
if (m_scrollViewStatesInfo?.GetValue(null, null) is GenericStack stack)
{
m_scrollStack = stack;
}
else
{
m_scrollStack = new GenericStack();
}
m_scrollStack = new Stack<object>();
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()
{
try
@ -115,10 +72,12 @@ namespace Explorer.Unstrip.IMGUI
GUI.Box(g.rect, content, style);
}
public static string TextField(string text, GUILayoutOption[] options)
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);
GUIContent guicontent = GUIContent.Temp(text);
bool flag = GUIUtility.keyboardControl != controlID;
@ -131,19 +90,19 @@ namespace Explorer.Unstrip.IMGUI
guicontent = GUIContent.Temp(text);
// guicontent = GUIContent.Temp(text + GUIUtility.compositionString);
}
Rect rect = Internal_LayoutUtility.GetRect(guicontent, GUI.skin.textField, options);
Rect rect = Internal_LayoutUtility.GetRect(guicontent, skin, options);
bool flag2 = GUIUtility.keyboardControl == controlID;
if (flag2)
{
guicontent = GUIContent.Temp(text);
}
DoTextField(rect, controlID, guicontent, false, -1, GUI.skin.textField);
DoTextField(rect, controlID, guicontent, multiLine, -1, skin);
return guicontent.text;
}
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 (Internal_GUIUtility.GetMonoStateObject(typeof(Internal_TextEditor), id) is Internal_TextEditor textEditor)
{
if (maxLength >= 0 && content.text.Length > maxLength)
{
@ -156,11 +115,138 @@ namespace Explorer.Unstrip.IMGUI
textEditor.multiline = multiline;
textEditor.controlID = id;
textEditor.DetectFocusChange();
GUI.HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
HandleTextFieldEventForDesktop(position, id, content, multiline, maxLength, style, textEditor);
textEditor.UpdateScrollOffsetIfNeeded(Event.current);
}
}
private static void HandleTextFieldEventForDesktop(Rect position, int id, GUIContent content, bool multiline, int maxLength,
GUIStyle style, Internal_TextEditor 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(Internal_TextEditor.DblClickSnapping.WORDS);
editor.MouseDragSelectsWholeWords(true);
}
if (Event.current.clickCount == 3 && GUI.skin.settings.tripleClickSelectsLine)
{
editor.SelectCurrentParagraph();
editor.MouseDragSelectsWholeWords(true);
editor.DblClickSnap(Internal_TextEditor.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)
{
return GUI.DoRepeatButton(Internal_LayoutUtility.GetRect(content, style, options), content, style, FocusType.Passive);
@ -279,22 +365,6 @@ namespace Explorer.Unstrip.IMGUI
#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)
{
// First, just try normal way, may not have been stripped or was unstripped successfully.
@ -348,10 +418,12 @@ namespace Explorer.Unstrip.IMGUI
if (ScrollStack.Count <= 0) return;
var state = ScrollStack.Peek().TryCast<ScrollViewState>();
var scrollExt = Internal_ScrollViewState.FromPointer(state.Pointer);
var scrollExt = ScrollStack.Peek() as Internal_ScrollViewState;
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();
@ -419,16 +491,18 @@ namespace Explorer.Unstrip.IMGUI
int controlID = GUIUtility.GetControlID(GUI.s_ScrollviewHash, FocusType.Passive);
var scrollViewState = GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID)
.TryCast<ScrollViewState>();
var scrollExt = (Internal_ScrollViewState)Internal_GUIUtility.GetMonoStateObject(typeof(Internal_ScrollViewState), controlID);
if (scrollViewState == null)
return scrollPosition;
//var scrollViewState = Internal_GUIUtility.GetStateObject(Il2CppType.Of<ScrollViewState>(), controlID)
// .TryCast<ScrollViewState>();
var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer);
//if (scrollViewState == null)
// return scrollPosition;
if (scrollExt == null)
return scrollPosition;
//var scrollExt = Internal_ScrollViewState.FromPointer(scrollViewState.Pointer);
//if (scrollExt == null)
// return scrollPosition;
bool apply = scrollExt.apply;
if (apply)
@ -446,7 +520,7 @@ namespace Explorer.Unstrip.IMGUI
rect.width = position.width;
rect.height = position.height;
ScrollStack.Push(scrollViewState);
ScrollStack.Push(scrollExt);
Rect screenRect = new Rect(position.x, position.y, position.width, position.height);
EventType type = Event.current.type;

View File

@ -0,0 +1,66 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Explorer.Unstrip.IMGUI
{
public class Internal_GUIUtility
{
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

@ -13,17 +13,77 @@ namespace Explorer.Unstrip.IMGUI
public Vector2 scrollPosition;
public bool apply;
public static Dictionary<IntPtr, Internal_ScrollViewState> Dict = new Dictionary<IntPtr, Internal_ScrollViewState>();
public void ScrollTo(Rect pos)
{
this.ScrollTowards(pos, float.PositiveInfinity);
}
public static Internal_ScrollViewState FromPointer(IntPtr ptr)
{
if (!Dict.ContainsKey(ptr))
{
Dict.Add(ptr, new Internal_ScrollViewState());
}
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;
}
return Dict[ptr];
}
}
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

@ -118,8 +118,8 @@ namespace Explorer.Unstrip.IMGUI
GUI.changed = true;
if (this.SupportsPageMovements())
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
ext.isDragging = false;
var state = GetSliderState();
state.isDragging = false;
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(250.0);
ScrollTroughSide = this.CurrentScrollTroughSide();
result = this.PageMovementValue();
@ -144,8 +144,8 @@ namespace Explorer.Unstrip.IMGUI
}
else
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
if (!ext.isDragging)
var state = GetSliderState();
if (!state.isDragging)
{
result = this.currentValue;
}
@ -153,8 +153,8 @@ namespace Explorer.Unstrip.IMGUI
{
GUI.changed = true;
this.CurrentEvent().Use();
float num = this.MousePosition() - ext.dragStartPos;
float value = ext.dragStartValue + num / this.ValuesPerPixel();
float num = this.MousePosition() - state.dragStartPos;
float value = state.dragStartValue + num / this.ValuesPerPixel();
result = this.Clamp(value);
}
}
@ -207,7 +207,7 @@ namespace Explorer.Unstrip.IMGUI
Internal.nextScrollStepTime = DateTime.Now.AddMilliseconds(30.0);
if (this.SupportsPageMovements())
{
Internal_SliderState.FromPointer(GetSliderState().Pointer).isDragging = false;
GetSliderState().isDragging = false;
GUI.changed = true;
result = this.PageMovementValue();
}
@ -303,15 +303,15 @@ namespace Explorer.Unstrip.IMGUI
private void StartDraggingWithValue(float dragStartValue)
{
var ext = Internal_SliderState.FromPointer(GetSliderState().Pointer);
ext.dragStartPos = this.MousePosition();
ext.dragStartValue = dragStartValue;
ext.isDragging = true;
var state = GetSliderState();
state.dragStartPos = this.MousePosition();
state.dragStartValue = dragStartValue;
state.isDragging = true;
}
private SliderState GetSliderState()
private Internal_SliderState GetSliderState()
{
return GUIUtility.GetStateObject(Il2CppType.Of<SliderState>(), this.id).TryCast<SliderState>();
return (Internal_SliderState)Internal_GUIUtility.GetMonoStateObject(typeof(Internal_SliderState), this.id);
}
private Rect ThumbRect()

View File

@ -10,17 +10,5 @@ namespace Explorer.Unstrip.IMGUI
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];
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
#if CPP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnhollowerBaseLib;
using UnityEngine;
using System.IO;
namespace Explorer.Unstrip.ImageConversion
{
public static class ImageConversionUnstrip
{
// byte[] ImageConversion.EncodeToPNG(this Texture2D image);
public static byte[] EncodeToPNG(this Texture2D tex)
{
return EncodeToPNG_iCall(tex.Pointer);
}
internal delegate byte[] EncodeToPNG_delegate(IntPtr tex);
internal static EncodeToPNG_delegate EncodeToPNG_iCall =
IL2CPP.ResolveICall<EncodeToPNG_delegate>("UnityEngine.ImageConversion::EncodeToPNG");
// bool ImageConversion.LoadImage(this Texture2D tex, byte[] data, bool markNonReadable);
public static bool LoadImage(this Texture2D tex, byte[] data, bool markNonReadable)
{
return LoadImage_iCall(tex.Pointer, data, markNonReadable);
}
internal delegate bool LoadImage_delegate(IntPtr tex, byte[] data, bool markNonReadable);
internal static LoadImage_delegate LoadImage_iCall =
IL2CPP.ResolveICall<LoadImage_delegate>("UnityEngine.ImageConversion::LoadImage");
// Helper for LoadImage
public static bool LoadImage(this 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,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
#if CPP
using UnhollowerBaseLib;
#endif
namespace Explorer.Unstrip.LayerMasks
{
public static class LayerMaskUnstrip
{
#if CPP
internal delegate IntPtr d_LayerToName(int layer);
internal static d_LayerToName LayerToName_iCall =
IL2CPP.ResolveICall<d_LayerToName>("UnityEngine.LayerMask::LayerToName");
public static string LayerToName(int layer)
{
var ptr = LayerToName_iCall(layer);
return IL2CPP.Il2CppStringToManaged(ptr);
}
#else
public static string LayerToName(int layer)
{
return LayerMask.LayerToName(layer);
}
#endif
}
}

View File

@ -5,37 +5,35 @@ using System.Linq;
using System.Text;
using UnhollowerBaseLib;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Explorer.Unstrip.Scene
namespace Explorer.Unstrip.Scenes
{
public class SceneUnstrip
{
internal delegate void getRootSceneObjects(int handle, IntPtr list);
internal static getRootSceneObjects getRootSceneObjects_iCall =
IL2CPP.ResolveICall<getRootSceneObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
public static void GetRootGameObjects_Internal(UnityEngine.SceneManagement.Scene scene, IntPtr list)
{
getRootSceneObjects_iCall(scene.handle, list);
}
public static GameObject[] GetRootSceneObjects(UnityEngine.SceneManagement.Scene scene)
//Scene.GetRootGameObjects();
public static GameObject[] GetRootGameObjects(Scene scene)
{
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount_Internal(scene));
GetRootGameObjects_Internal(scene, list.Pointer);
GetRootGameObjectsInternal_iCall(scene.handle, list.Pointer);
return list.ToArray();
}
internal delegate int getRootCount(int handle);
internal static getRootCount getRootCount_iCall =
IL2CPP.ResolveICall<getRootCount>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
internal delegate void GetRootGameObjectsInternal_delegate(int handle, IntPtr list);
internal static GetRootGameObjectsInternal_delegate GetRootGameObjectsInternal_iCall =
IL2CPP.ResolveICall<GetRootGameObjectsInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
public static int GetRootCount_Internal(UnityEngine.SceneManagement.Scene scene)
//Scene.rootCount;
public static int GetRootCount_Internal(Scene scene)
{
return getRootCount_iCall(scene.handle);
return GetRootCountInternal_iCall(scene.handle);
}
internal delegate int GetRootCountInternal_delegate(int handle);
internal static GetRootCountInternal_delegate GetRootCountInternal_iCall =
IL2CPP.ResolveICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal");
}
}
#endif