diff --git a/README.md b/README.md
index 640d71a..6f7b28d 100644
--- a/README.md
+++ b/README.md
@@ -19,24 +19,24 @@
### BepInEx
-0. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game. For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
-1. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
-2. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
-3. In IL2CPP, you will need to download the [Unity libs](https://github.com/LavaGang/Unity-Runtime-Libraries) for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
+1. Install [BepInEx](https://github.com/BepInEx/BepInEx) for your game. For IL2CPP you should use [BepInEx 6 (Bleeding Edge)](https://builds.bepis.io/projects/bepinex_be), for Mono you should use [BepInEx 5](https://github.com/BepInEx/BepInEx/releases) (until Mono support stabilizes in BepInEx 6).
+2. Download the UnityExplorer release for BepInEx IL2CPP or Mono above.
+3. Take the `UnityExplorer.BIE.___.dll` file and put it in `[GameFolder]\BepInEx\plugins\`
+4. In IL2CPP, you will need to download the [Unity libs](https://github.com/LavaGang/Unity-Runtime-Libraries) for the game's Unity version and put them in the `BepInEx\unity-libs\` folder.
### MelonLoader
-0. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3+ for your game. Version 0.3 is currently in pre-release, so you must "Enable ALPHA Releases" in your MelonLoader Installer settings to see the option for it.
-1. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
-2. Take the `UnityExplorer.ML.___.dll` file and put it in the `[GameFolder]\Mods\` folder.
+1. Install [MelonLoader](https://github.com/HerpDerpinstine/MelonLoader) 0.3+ for your game. Version 0.3 is currently in pre-release, so you must "Enable ALPHA Releases" in your MelonLoader Installer settings to see the option for it.
+2. Download the UnityExplorer release for MelonLoader IL2CPP or Mono above.
+3. Take the `UnityExplorer.ML.___.dll` file and put it in the `[GameFolder]\Mods\` folder.
### Standalone
-The standalone release is based on the BepInEx build, so it requires Harmony 2.0 (or HarmonyX) to function properly.
+The standalone release requires you to also load `0Harmony.dll` (HarmonyX, from the `lib\` folder) to function properly, and the IL2CPP also requires `UnhollowerBaseLib.dll` as well. The Mono release should be fairly easy to use with any loader, but the IL2CPP one may be tricky, I'd recommend just using BepInEx or MelonLoader for IL2CPP.
-0. Load the DLL from your mod or inject it. You must also make sure `0Harmony.dll` is loaded, and `UnhollowerBaseLib.dll` for IL2CPP as well.
-1. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`
-2. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
+1. Load the UnityExplorer DLL from your mod or inject it, as well as `0Harmony.dll` and `UnhollowerBaseLib.dll` as required.
+2. Create an instance of Unity Explorer with `UnityExplorer.ExplorerStandalone.CreateInstance();`
+3. Optionally subscribe to the `ExplorerStandalone.OnLog` event to handle logging if you wish.
## Issues and contributions
@@ -124,31 +124,6 @@ Depending on the release you are using, the config file will be found at:
* MelonLoader: `UserData\MelonPreferences.cfg`
* Standalone `{DLL_location}\UnityExplorer\config.ini`
-`Main Menu Toggle` (KeyCode)
-* Default: `F7`
-* See [this article](https://docs.unity3d.com/ScriptReference/KeyCode.html) for a full list of all accepted KeyCodes.
-
-`Force Unlock Mouse` (bool)
-* Default: `true`
-* Forces the cursor to be unlocked and visible while the UnityExplorer menu is open, and prevents anything else taking control.
-
-`Default Page Limit` (int)
-* Default: `25`
-* Sets the default items per page when viewing lists or search results.
-* Requires a restart to take effect, apart from Reflection Inspector tabs.
-
-`Default Output Path` (string)
-* Default: `Mods\UnityExplorer`
-* Where output is generated to, by default (for Texture PNG saving, etc).
-
-`Log Unity Debug` (bool)
-* Default: `false`
-* Listens for Unity `Debug.Log` messages and prints them to UnityExplorer's log.
-
-`Hide on Startup` (bool)
-* Default: `false`
-* If true, UnityExplorer will be hidden when you start the game, you must open it via the keybind.
-
## Building
Building the project should be straight-forward, the references are all inside the `lib\` folder.
diff --git a/lib/BepInEx.dll b/lib/BepInEx.dll
index 6bd8fc3..4f11349 100644
Binary files a/lib/BepInEx.dll and b/lib/BepInEx.dll differ
diff --git a/src/Core/Config/ConfigElement.cs b/src/Core/Config/ConfigElement.cs
index 7795752..b3510cc 100644
--- a/src/Core/Config/ConfigElement.cs
+++ b/src/Core/Config/ConfigElement.cs
@@ -46,7 +46,7 @@ namespace UnityExplorer.Core.Config
private void SetValue(T value)
{
- if ((m_value == null && value == null) || m_value.Equals(value))
+ if ((m_value == null && value == null) || (m_value != null && m_value.Equals(value)))
return;
m_value = value;
diff --git a/src/Core/Input/CursorUnlocker.cs b/src/Core/Input/CursorUnlocker.cs
index 5027955..419912f 100644
--- a/src/Core/Input/CursorUnlocker.cs
+++ b/src/Core/Input/CursorUnlocker.cs
@@ -46,86 +46,21 @@ namespace UnityExplorer.Core.Input
UpdateCursorControl();
- Unlock = true;
+ Unlock = ConfigManager.Force_Unlock_Mouse.Value;
ConfigManager.Force_Unlock_Mouse.OnValueChanged += (bool val) => { Unlock = val; };
}
- private static void SetupPatches()
- {
- try
- {
- if (CursorType == null)
- {
- throw new Exception("Could not find Type 'UnityEngine.Cursor'!");
- }
-
- // Get current cursor state and enable cursor
- try
- {
- m_lastLockMode = (CursorLockMode?)typeof(Cursor).GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null)
- ?? CursorLockMode.None;
-
- m_lastVisibleState = (bool?)typeof(Cursor).GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null)
- ?? false;
- }
- catch { }
-
- // Setup Harmony Patches
- TryPatch(typeof(Cursor),
- "lockState",
- new HarmonyMethod(typeof(CursorUnlocker).GetMethod(nameof(Prefix_set_lockState))),
- true);
-
- TryPatch(typeof(Cursor),
- "visible",
- new HarmonyMethod(typeof(CursorUnlocker).GetMethod(nameof(Prefix_set_visible))),
- true);
-
- TryPatch(typeof(EventSystem),
- "current",
- new HarmonyMethod(typeof(CursorUnlocker).GetMethod(nameof(Prefix_EventSystem_set_current))),
- true);
- }
- catch (Exception e)
- {
- ExplorerCore.Log($"Exception on ForceUnlockCursor.Init! {e.GetType()}, {e.Message}");
- }
- }
-
- private static void TryPatch(Type type, string property, HarmonyMethod patch, bool setter)
- {
- try
- {
- var harmony = ExplorerCore.Loader.HarmonyInstance;
-
- var prop = type.GetProperty(property);
-
- if (setter) // setter is prefix
- {
- harmony.Patch(prop.GetSetMethod(), prefix: patch);
- }
- else // getter is postfix
- {
- harmony.Patch(prop.GetGetMethod(), postfix: patch);
- }
- }
- catch (Exception e)
- {
- string suf = setter ? "set_" : "get_";
- ExplorerCore.Log($"Unable to patch {type.Name}.{suf}{property}: {e.Message}");
- }
- }
-
public static void UpdateCursorControl()
{
try
{
m_currentlySettingCursor = true;
+
if (ShouldActuallyUnlock)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
-
+
if (UIManager.EventSys)
SetEventSystem();
}
@@ -137,6 +72,7 @@ namespace UnityExplorer.Core.Input
if (UIManager.EventSys)
ReleaseEventSystem();
}
+
m_currentlySettingCursor = false;
}
catch (Exception e)
@@ -163,9 +99,7 @@ namespace UnityExplorer.Core.Input
if (!m_lastEventSystem)
m_lastEventSystem = EventSystem.current;
- //ExplorerCore.Log("Disabling current event system...");
m_lastEventSystem.enabled = false;
- //m_lastEventSystem.gameObject.SetActive(false);
}
// Set to our current system
@@ -184,7 +118,6 @@ namespace UnityExplorer.Core.Input
if (m_lastEventSystem)
{
m_lastEventSystem.enabled = true;
- //m_lastEventSystem.gameObject.SetActive(true);
m_settingEventSystem = true;
EventSystem.current = m_lastEventSystem;
@@ -193,7 +126,30 @@ namespace UnityExplorer.Core.Input
}
}
- [HarmonyPrefix]
+ // Patches
+
+ private static void SetupPatches()
+ {
+ try
+ {
+ if (CursorType == null)
+ throw new Exception("Could not load Type 'UnityEngine.Cursor'!");
+
+ // Get current cursor state and enable cursor
+ m_lastLockMode = (CursorLockMode?)CursorType.GetProperty("lockState", BF.Public | BF.Static)?.GetValue(null, null)
+ ?? CursorLockMode.None;
+
+ m_lastVisibleState = (bool?)CursorType.GetProperty("visible", BF.Public | BF.Static)?.GetValue(null, null)
+ ?? false;
+
+ ExplorerCore.Loader.SetupPatches();
+ }
+ catch (Exception e)
+ {
+ ExplorerCore.Log($"Error on CursorUnlocker.Init! {e.GetType()}, {e.Message}");
+ }
+ }
+
public static void Prefix_EventSystem_set_current(ref EventSystem value)
{
if (!m_settingEventSystem)
@@ -210,7 +166,6 @@ namespace UnityExplorer.Core.Input
// Also keep track of when anything else tries to set Cursor state, this will be the
// value that we set back to when we close the menu or disable force-unlock.
- [HarmonyPrefix]
public static void Prefix_set_lockState(ref CursorLockMode value)
{
if (!m_currentlySettingCursor)
@@ -222,7 +177,6 @@ namespace UnityExplorer.Core.Input
}
}
- [HarmonyPrefix]
public static void Prefix_set_visible(ref bool value)
{
if (!m_currentlySettingCursor)
diff --git a/src/ExplorerCore.cs b/src/ExplorerCore.cs
index a039828..76e4d19 100644
--- a/src/ExplorerCore.cs
+++ b/src/ExplorerCore.cs
@@ -12,7 +12,7 @@ namespace UnityExplorer
public class ExplorerCore
{
public const string NAME = "UnityExplorer";
- public const string VERSION = "3.3.3";
+ public const string VERSION = "3.3.4";
public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer";
diff --git a/src/Loader/BIE/ExplorerBepInPlugin.cs b/src/Loader/BIE/ExplorerBepInPlugin.cs
index cc56a8f..82082b2 100644
--- a/src/Loader/BIE/ExplorerBepInPlugin.cs
+++ b/src/Loader/BIE/ExplorerBepInPlugin.cs
@@ -10,6 +10,9 @@ using System.Text;
using UnityExplorer.Core.Config;
using UnityExplorer.Loader.BIE;
using UnityEngine;
+using UnityExplorer.Core;
+using UnityEngine.EventSystems;
+using UnityExplorer.Core.Input;
#if CPP
using BepInEx.IL2CPP;
using UnhollowerRuntimeLib;
@@ -75,10 +78,8 @@ namespace UnityExplorer
ClassInjector.RegisterTypeInIl2Cpp();
- var obj = new GameObject(
- "ExplorerBehaviour",
- new Il2CppSystem.Type[] { Il2CppType.Of() }
- );
+ var obj = new GameObject("ExplorerBehaviour");
+ obj.AddComponent();
obj.hideFlags = HideFlags.HideAndDontSave;
GameObject.DontDestroyOnLoad(obj);
@@ -101,6 +102,48 @@ namespace UnityExplorer
}
}
#endif
+
+ public void SetupPatches()
+ {
+ try
+ {
+ this.HarmonyInstance.PatchAll();
+ }
+ catch (Exception ex)
+ {
+ ExplorerCore.Log($"Exception setting up Harmony patches:\r\n{ex.ReflectionExToString()}");
+ }
+ }
+
+ [HarmonyPatch(typeof(EventSystem), "current", MethodType.Setter)]
+ public class PATCH_EventSystem_current
+ {
+ [HarmonyPrefix]
+ public static void Prefix_EventSystem_set_current(ref EventSystem value)
+ {
+ CursorUnlocker.Prefix_EventSystem_set_current(ref value);
+ }
+ }
+
+ [HarmonyPatch(typeof(Cursor), "lockState", MethodType.Setter)]
+ public class PATCH_Cursor_lockState
+ {
+ [HarmonyPrefix]
+ public static void Prefix_set_lockState(ref CursorLockMode value)
+ {
+ CursorUnlocker.Prefix_set_lockState(ref value);
+ }
+ }
+
+ [HarmonyPatch(typeof(Cursor), "visible", MethodType.Setter)]
+ public class PATCH_Cursor_visible
+ {
+ [HarmonyPrefix]
+ public static void Prefix_set_visible(ref bool value)
+ {
+ CursorUnlocker.Prefix_set_visible(ref value);
+ }
+ }
}
}
#endif
\ No newline at end of file
diff --git a/src/Loader/IExplorerLoader.cs b/src/Loader/IExplorerLoader.cs
index f8b8e18..78a17b4 100644
--- a/src/Loader/IExplorerLoader.cs
+++ b/src/Loader/IExplorerLoader.cs
@@ -17,10 +17,6 @@ namespace UnityExplorer
Action