From b4b5f1ec93ef0f422b077e10069749b13ba05147 Mon Sep 17 00:00:00 2001 From: sinaioutlander <49360850+sinaioutlander@users.noreply.github.com> Date: Thu, 1 Oct 2020 18:57:28 +1000 Subject: [PATCH] 1.8.2 * Added support for games which use the new InputSystem module and have disabled LegacyInputModule --- src/Config/ModConfig.cs | 8 +- src/Explorer.csproj | 1 + src/ExplorerBepInPlugin.cs | 2 +- src/ExplorerCore.cs | 19 ++- src/Helpers/InputHelper.cs | 186 +++++++++++++++++++++++++----- src/Menu/InspectUnderMouse.cs | 4 +- src/Menu/ResizeDrag.cs | 4 +- src/Menu/Windows/WindowManager.cs | 2 +- src/UnstripFixes/GUIUnstrip.cs | 51 +++----- src/UnstripFixes/Internal.cs | 8 +- 10 files changed, 200 insertions(+), 85 deletions(-) diff --git a/src/Config/ModConfig.cs b/src/Config/ModConfig.cs index 21332478..341059cf 100644 --- a/src/Config/ModConfig.cs +++ b/src/Config/ModConfig.cs @@ -30,9 +30,9 @@ public static void OnLoad() } // returns true if settings successfully loaded - public static bool LoadSettings(bool checkExist = true) + public static bool LoadSettings() { - if (checkExist && !File.Exists(SETTINGS_PATH)) + if (!File.Exists(SETTINGS_PATH)) return false; try @@ -50,9 +50,9 @@ public static bool LoadSettings(bool checkExist = true) return Instance != null; } - public static void SaveSettings(bool checkExist = true) + public static void SaveSettings() { - if (checkExist && File.Exists(SETTINGS_PATH)) + if (File.Exists(SETTINGS_PATH)) File.Delete(SETTINGS_PATH); using (var file = File.Create(SETTINGS_PATH)) diff --git a/src/Explorer.csproj b/src/Explorer.csproj index 7a8ffc67..57d37fb5 100644 --- a/src/Explorer.csproj +++ b/src/Explorer.csproj @@ -34,6 +34,7 @@ D:\Steam\steamapps\common\Outward - Il2Cpp D:\Steam\steamapps\common\Outward + v4.7.2 diff --git a/src/ExplorerBepInPlugin.cs b/src/ExplorerBepInPlugin.cs index cceb9c40..847cb614 100644 --- a/src/ExplorerBepInPlugin.cs +++ b/src/ExplorerBepInPlugin.cs @@ -66,7 +66,7 @@ internal void Awake() new ExplorerCore(); - HarmonyInstance.PatchAll(); + //HarmonyInstance.PatchAll(); } void LoadMCS() diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs index 496db894..de2983a4 100644 --- a/src/ExplorerCore.cs +++ b/src/ExplorerCore.cs @@ -4,23 +4,23 @@ namespace Explorer { public class ExplorerCore { - public const string NAME = "Explorer (" + PLATFORM + ", " + MODLOADER + ")"; - public const string VERSION = "1.8.1"; + public const string NAME = "Explorer (" + PLATFORM + ", " + MODLOADER + ")"; + public const string VERSION = "1.8.2"; public const string AUTHOR = "Sinai"; public const string GUID = "com.sinai.explorer"; - public const string MODLOADER = -#if ML - "MelonLoader"; -#else - "BepInEx"; -#endif public const string PLATFORM = #if CPP "Il2Cpp"; #else "Mono"; #endif + public const string MODLOADER = +#if ML + "MelonLoader"; +#else + "BepInEx"; +#endif public static ExplorerCore Instance { get; private set; } @@ -30,11 +30,10 @@ public ExplorerCore() ModConfig.OnLoad(); - InputHelper.Init(); - new MainMenu(); new WindowManager(); + InputHelper.Init(); CursorControl.Init(); Log($"{NAME} {VERSION} initialized."); diff --git a/src/Helpers/InputHelper.cs b/src/Helpers/InputHelper.cs index 47c5f9dc..db8810dd 100644 --- a/src/Helpers/InputHelper.cs +++ b/src/Helpers/InputHelper.cs @@ -5,18 +5,41 @@ namespace Explorer { /// - /// Version-agnostic UnityEngine Input module using Reflection. + /// Version-agnostic Input module using Reflection. /// public static class InputHelper { // If Input module failed to load at all public static bool NO_INPUT; - // Base UnityEngine.Input class - private static Type Input => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input")); + // If using new InputSystem module + public static bool USING_NEW_INPUT; + + // Cached Types + private static Type TInput => _input ?? (_input = ReflectionHelpers.GetTypeByName("UnityEngine.Input")); private static Type _input; - // Cached member infos + private static Type TKeyboard => _keyboardSys ?? (_keyboardSys = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Keyboard")); + private static Type _keyboardSys; + + private static Type TMouse => _mouseSys ?? (_mouseSys = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Mouse")); + private static Type _mouseSys; + + private static Type TKey => _key ?? (_key = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Key")); + private static Type _key; + + // Cached member infos (new system) + private static PropertyInfo _keyboardCurrent; + private static PropertyInfo _kbItemProp; + private static PropertyInfo _isPressed; + private static PropertyInfo _wasPressedThisFrame; + private static PropertyInfo _mouseCurrent; + private static PropertyInfo _leftButton; + private static PropertyInfo _rightButton; + private static PropertyInfo _position; + private static MethodInfo _readValueMethod; + + // Cached member infos (legacy) private static PropertyInfo _mousePosition; private static MethodInfo _getKey; private static MethodInfo _getKeyDown; @@ -25,49 +48,153 @@ public static class InputHelper public static void Init() { - if (Input == null && !TryManuallyLoadInput()) + if (TKeyboard != null || TryManuallyLoadNewInput()) { - NO_INPUT = true; + InitNewInput(); return; } - // Cache reflection now that we know Input is loaded + if (TInput != null || TryManuallyLoadLegacyInput()) + { + InitLegacyInput(); + return; + } + + ExplorerCore.LogWarning("Could not find any Input module!"); + NO_INPUT = true; + } + + private static void InitNewInput() + { + ExplorerCore.Log("Initializing new InputSystem support..."); + + USING_NEW_INPUT = true; + + _keyboardCurrent = TKeyboard.GetProperty("current"); + _kbItemProp = TKeyboard.GetProperty("Item", new Type[] { TKey }); + + var btnControl = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Controls.ButtonControl"); + _isPressed = btnControl.GetProperty("isPressed"); + _wasPressedThisFrame = btnControl.GetProperty("wasPressedThisFrame"); + + _mouseCurrent = TMouse.GetProperty("current"); + _leftButton = TMouse.GetProperty("leftButton"); + _rightButton = TMouse.GetProperty("rightButton"); + + _position = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.Pointer") + .GetProperty("position"); + + _readValueMethod = ReflectionHelpers.GetTypeByName("UnityEngine.InputSystem.InputControl`1") + .MakeGenericType(typeof(Vector2)) + .GetMethod("ReadValue"); + } + + private static void InitLegacyInput() + { + ExplorerCore.Log("Initializing Legacy Input support..."); - _mousePosition = Input.GetProperty("mousePosition"); + _mousePosition = TInput.GetProperty("mousePosition"); + _getKey = TInput.GetMethod("GetKey", new Type[] { typeof(KeyCode) }); + _getKeyDown = TInput.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) }); + _getMouseButton = TInput.GetMethod("GetMouseButton", new Type[] { typeof(int) }); + _getMouseButtonDown = TInput.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) }); + } - _getKey = Input.GetMethod("GetKey", new Type[] { typeof(KeyCode) }); - _getKeyDown = Input.GetMethod("GetKeyDown", new Type[] { typeof(KeyCode) }); - _getMouseButton = Input.GetMethod("GetMouseButton", new Type[] { typeof(int) }); - _getMouseButtonDown = Input.GetMethod("GetMouseButtonDown", new Type[] { typeof(int) }); + private static bool TryManuallyLoadNewInput() + { + if (ReflectionHelpers.LoadModule("Unity.InputSystem") && TKeyboard != null) + { + ExplorerCore.Log("Loaded new InputSystem module!"); + return true; + } + else + { + return false; + } } -#pragma warning disable IDE1006 // Camel-case property (Unity style) - public static Vector3 mousePosition + private static bool TryManuallyLoadLegacyInput() + { + if ((ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") || ReflectionHelpers.LoadModule("UnityEngine.CoreModule")) + && TInput != null) + { + ExplorerCore.Log("Loaded legacy InputModule!"); + return true; + } + else + { + return false; + } + } + + public static Vector3 MousePosition { get { if (NO_INPUT) return Vector3.zero; + + if (USING_NEW_INPUT) + { + var mouse = _mouseCurrent.GetValue(null, null); + var pos = _position.GetValue(mouse, null); + + return (Vector2)_readValueMethod.Invoke(pos, new object[0]); + } + return (Vector3)_mousePosition.GetValue(null, null); } } -#pragma warning restore IDE1006 public static bool GetKeyDown(KeyCode key) { if (NO_INPUT) return false; + + if (USING_NEW_INPUT) + { + var parsed = Enum.Parse(TKey, key.ToString()); + var currentKB = _keyboardCurrent.GetValue(null, null); + var actualKey = _kbItemProp.GetValue(currentKB, new object[] { parsed }); + + return (bool)_wasPressedThisFrame.GetValue(actualKey, null); + } + return (bool)_getKeyDown.Invoke(null, new object[] { key }); } public static bool GetKey(KeyCode key) { if (NO_INPUT) return false; + + if (USING_NEW_INPUT) + { + var parsed = Enum.Parse(TKey, key.ToString()); + var currentKB = _keyboardCurrent.GetValue(null, null); + var actualKey = _kbItemProp.GetValue(currentKB, new object[] { parsed }); + + return (bool)_isPressed.GetValue(actualKey, null); + } + return (bool)_getKey.Invoke(null, new object[] { key }); } - /// 1 = left, 2 = middle, 3 = right, etc + /// 0/1 = left, 2 = middle, 3 = right, etc public static bool GetMouseButtonDown(int btn) { if (NO_INPUT) return false; + + if (USING_NEW_INPUT) + { + var mouse = _mouseCurrent.GetValue(null, null); + + PropertyInfo btnProp; + if (btn < 2) btnProp = _leftButton; + else btnProp = _rightButton; + + var actualBtn = btnProp.GetValue(mouse, null); + + return (bool)_wasPressedThisFrame.GetValue(actualBtn, null); + } + return (bool)_getMouseButtonDown.Invoke(null, new object[] { btn }); } @@ -75,24 +202,21 @@ public static bool GetMouseButtonDown(int btn) public static bool GetMouseButton(int btn) { if (NO_INPUT) return false; - return (bool)_getMouseButton.Invoke(null, new object[] { btn }); - } - - private static bool TryManuallyLoadInput() - { - ExplorerCore.Log("UnityEngine.Input is null, trying to load manually...."); - if ((ReflectionHelpers.LoadModule("UnityEngine.InputLegacyModule") || ReflectionHelpers.LoadModule("UnityEngine.CoreModule")) - && Input != null) - { - ExplorerCore.Log("Ok!"); - return true; - } - else + if (USING_NEW_INPUT) { - ExplorerCore.Log("Could not load Input module!"); - return false; + var mouse = _mouseCurrent.GetValue(null, null); + + PropertyInfo btnProp; + if (btn < 2) btnProp = _leftButton; + else btnProp = _rightButton; + + var actualBtn = btnProp.GetValue(mouse, null); + + return (bool)_isPressed.GetValue(actualBtn, null); } + + return (bool)_getMouseButton.Invoke(null, new object[] { btn }); } } } diff --git a/src/Menu/InspectUnderMouse.cs b/src/Menu/InspectUnderMouse.cs index 777b1bb6..c5b9b373 100644 --- a/src/Menu/InspectUnderMouse.cs +++ b/src/Menu/InspectUnderMouse.cs @@ -33,7 +33,7 @@ public static void InspectRaycast() if (!UnityHelpers.MainCamera) return; - var ray = UnityHelpers.MainCamera.ScreenPointToRay(InputHelper.mousePosition); + var ray = UnityHelpers.MainCamera.ScreenPointToRay(InputHelper.MousePosition); if (Physics.Raycast(ray, out RaycastHit hit, 1000f)) { @@ -61,7 +61,7 @@ public static void OnGUI() { if (m_objUnderMouseName != "") { - var pos = InputHelper.mousePosition; + var pos = InputHelper.MousePosition; var rect = new Rect( pos.x - (Screen.width / 2), // x Screen.height - pos.y - 50, // y diff --git a/src/Menu/ResizeDrag.cs b/src/Menu/ResizeDrag.cs index bb8f6d23..423ed4b0 100644 --- a/src/Menu/ResizeDrag.cs +++ b/src/Menu/ResizeDrag.cs @@ -38,7 +38,7 @@ public static Rect ResizeWindow(Rect _rect, int ID) //var r = GUILayoutUtility.GetLastRect(); var r = Internal_LayoutUtility.GetLastRect(); - var mousePos = InputHelper.mousePosition; + var mousePos = InputHelper.MousePosition; try { @@ -125,7 +125,7 @@ public static Rect ResizeWindow(Rect _rect, int ID) //var r = GUILayoutUtility.GetLastRect(); var r = GUILayoutUtility.GetLastRect(); - var mousePos = InputHelper.mousePosition; + var mousePos = InputHelper.MousePosition; var mouse = GUIUnstrip.ScreenToGUIPoint(new Vector2(mousePos.x, Screen.height - mousePos.y)); if (r.Contains(mouse) && InputHelper.GetMouseButtonDown(0)) diff --git a/src/Menu/Windows/WindowManager.cs b/src/Menu/Windows/WindowManager.cs index ab26bb6d..5a8afa3a 100644 --- a/src/Menu/Windows/WindowManager.cs +++ b/src/Menu/Windows/WindowManager.cs @@ -189,7 +189,7 @@ public static bool IsMouseInWindow private static bool RectContainsMouse(Rect rect) { - var mousePos = InputHelper.mousePosition; + var mousePos = InputHelper.MousePosition; return rect.Contains(new Vector2(mousePos.x, Screen.height - mousePos.y)); } diff --git a/src/UnstripFixes/GUIUnstrip.cs b/src/UnstripFixes/GUIUnstrip.cs index 8eebbe7c..9f4407fe 100644 --- a/src/UnstripFixes/GUIUnstrip.cs +++ b/src/UnstripFixes/GUIUnstrip.cs @@ -19,7 +19,7 @@ public static string TextField(string text, GUILayoutOption[] options) #else return GUILayout.TextField(text, options); #endif - } + } public static Rect Window(int id, Rect rect, GUI.WindowFunction windowFunc, string title) { @@ -75,63 +75,50 @@ public static void Space(float pixels) #endif } + public static bool RepeatButton(string text, params GUILayoutOption[] options) + { #if CPP - public static bool RepeatButton(string text, params GUILayoutOption[] options) - { - return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); - } + return Internal.DoRepeatButton(GUIContent.Temp(text), GUI.skin.button, options); #else - public static bool RepeatButton(string text, params GUILayoutOption[] args) - { - return GUILayout.RepeatButton(text, args); - } + return GUILayout.RepeatButton(text, options); #endif + } -#if CPP - public static void BeginArea(Rect screenRect, GUIStyle style) + public static void BeginArea(Rect screenRect, GUIStyle style) { - Internal.BeginArea(screenRect, GUIContent.none, style); - } +#if CPP + Internal.BeginArea(screenRect, GUIContent.none, style); #else - public static void BeginArea(Rect rect, GUIStyle skin) - { - GUILayout.BeginArea(rect, skin); - } + GUILayout.BeginArea(screenRect, style); #endif + } -#if CPP static public void EndArea() { +#if CPP Internal.EndArea(); - } #else - public static void EndArea() - { GUILayout.EndArea(); - } #endif + } -#if CPP public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) { +#if CPP return Internal.BeginScrollView(scroll, options); +#else + return GUILayout.BeginScrollView(scroll, options); +#endif } public static void EndScrollView(bool handleScrollWheel = true) { +#if CPP Internal.EndScrollView(handleScrollWheel); - } #else - public static Vector2 BeginScrollView(Vector2 scroll, params GUILayoutOption[] options) - { - return GUILayout.BeginScrollView(scroll, options); - } - - public static void EndScrollView() - { GUILayout.EndScrollView(); - } #endif + } } } \ No newline at end of file diff --git a/src/UnstripFixes/Internal.cs b/src/UnstripFixes/Internal.cs index ba33e348..da6ac3ec 100644 --- a/src/UnstripFixes/Internal.cs +++ b/src/UnstripFixes/Internal.cs @@ -267,7 +267,7 @@ public static void EndArea() #endregion -#region Scrolling + #region Scrolling private static Il2CppSystem.Object GetStateObject(Il2CppSystem.Type type, int controlID) { @@ -653,7 +653,9 @@ private static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle sty #endregion } - public static class UnstripExtensions + #region Extensions + + public static class Extensions { public static Rect Unstripped_GetLast(this GUILayoutGroup group) { @@ -670,5 +672,7 @@ public static Rect Unstripped_GetLast(this GUILayoutGroup group) return result; } } + + #endregion } #endif