From 506e75c5feaabac504c2ca879cc1c8eeaae041fa Mon Sep 17 00:00:00 2001 From: Sinai <49360850+sinai-dev@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:20:25 +1000 Subject: [PATCH] Handle Unhollowed modules path through IExplorerLoader. Allow Standalone release to specify manually. --- src/Core/Reflection/Il2CppReflection.cs | 19 ++++-------- src/Loader/BepInEx/ExplorerBepInPlugin.cs | 2 ++ src/Loader/IExplorerLoader.cs | 1 + src/Loader/MelonLoader/ExplorerMelonMod.cs | 4 +++ src/Loader/Standalone/ExplorerStandalone.cs | 32 +++++++++++++++++---- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/Core/Reflection/Il2CppReflection.cs b/src/Core/Reflection/Il2CppReflection.cs index 06dc57b..103e6bb 100644 --- a/src/Core/Reflection/Il2CppReflection.cs +++ b/src/Core/Reflection/Il2CppReflection.cs @@ -481,29 +481,21 @@ namespace UnityExplorer #region Force-loading game modules - internal static string UnhollowedFolderPath => Path.GetFullPath( -#if ML - Path.Combine("MelonLoader", "Managed") -#elif BIE - Path.Combine(BepInEx.Paths.BepInExRootPath, "unhollowed") -#else - Path.Combine(ExplorerCore.Loader.ExplorerFolder, "Modules") -#endif - ); - // Helper for IL2CPP to try to make sure the Unhollowed game assemblies are actually loaded. // Force loading all il2cpp modules internal void TryLoadGameModules() { - if (Directory.Exists(UnhollowedFolderPath)) + var dir = ExplorerCore.Loader.UnhollowedModulesFolder; + if (Directory.Exists(dir)) { - foreach (var filePath in Directory.GetFiles(UnhollowedFolderPath, "*.dll")) + foreach (var filePath in Directory.GetFiles(dir, "*.dll")) DoLoadModule(filePath); } else - ExplorerCore.LogWarning($"Expected Unhollowed folder path does not exist: '{UnhollowedFolderPath}'"); + ExplorerCore.LogWarning($"Expected Unhollowed folder path does not exist: '{dir}'. " + + $"If you are using the standalone release, you can specify the Unhollowed modules path when you call CreateInstance()."); } internal bool DoLoadModule(string fullPath) @@ -514,7 +506,6 @@ namespace UnityExplorer try { Assembly.LoadFile(fullPath); - //Assembly.Load(File.ReadAllBytes(fullPath)); return true; } catch //(Exception e) diff --git a/src/Loader/BepInEx/ExplorerBepInPlugin.cs b/src/Loader/BepInEx/ExplorerBepInPlugin.cs index 36295ad..18dd77e 100644 --- a/src/Loader/BepInEx/ExplorerBepInPlugin.cs +++ b/src/Loader/BepInEx/ExplorerBepInPlugin.cs @@ -39,6 +39,8 @@ namespace UnityExplorer => Log; #endif + public string UnhollowedModulesFolder => Path.Combine(Paths.BepInExRootPath, "unhollowed"); + public ConfigHandler ConfigHandler => _configHandler; private BepInExConfigHandler _configHandler; diff --git a/src/Loader/IExplorerLoader.cs b/src/Loader/IExplorerLoader.cs index 5a4d074..9a51826 100644 --- a/src/Loader/IExplorerLoader.cs +++ b/src/Loader/IExplorerLoader.cs @@ -9,6 +9,7 @@ namespace UnityExplorer public interface IExplorerLoader { string ExplorerFolder { get; } + string UnhollowedModulesFolder { get; } ConfigHandler ConfigHandler { get; } diff --git a/src/Loader/MelonLoader/ExplorerMelonMod.cs b/src/Loader/MelonLoader/ExplorerMelonMod.cs index 61d82c1..1819a7a 100644 --- a/src/Loader/MelonLoader/ExplorerMelonMod.cs +++ b/src/Loader/MelonLoader/ExplorerMelonMod.cs @@ -24,6 +24,10 @@ namespace UnityExplorer public string ExplorerFolder => Path.Combine("Mods", ExplorerCore.NAME); + public string UnhollowedModulesFolder => Path.Combine( + Path.GetDirectoryName(MelonHandler.ModsDirectory), + Path.Combine("MelonLoader", "Managed")); + public ConfigHandler ConfigHandler => _configHandler; public MelonLoaderConfigHandler _configHandler; diff --git a/src/Loader/Standalone/ExplorerStandalone.cs b/src/Loader/Standalone/ExplorerStandalone.cs index 9097f50..cf5d787 100644 --- a/src/Loader/Standalone/ExplorerStandalone.cs +++ b/src/Loader/Standalone/ExplorerStandalone.cs @@ -18,26 +18,43 @@ namespace UnityExplorer public class ExplorerStandalone : IExplorerLoader { /// - /// Call this to initialize UnityExplorer without adding a log listener. + /// Call this to initialize UnityExplorer without adding a log listener or Unhollowed modules path. + /// The default Unhollowed path "UnityExplorer\Modules\" will be used. /// /// The new (or active, if one exists) instance of ExplorerStandalone. - public static ExplorerStandalone CreateInstance() => CreateInstance(null); + public static ExplorerStandalone CreateInstance() => CreateInstance(null, null); /// - /// Call this to initialize UnityExplorer and add a listener for UnityExplorer's log messages. + /// Call this to initialize UnityExplorer and add a listener for UnityExplorer's log messages, without specifying an Unhollowed modules path. + /// The default Unhollowed path "UnityExplorer\Modules\" will be used. /// /// Your log listener to handle UnityExplorer logs. /// The new (or active, if one exists) instance of ExplorerStandalone. - public static ExplorerStandalone CreateInstance(Action logListener) + public static ExplorerStandalone CreateInstance(Action logListener) => CreateInstance(logListener, null); + + /// + /// Call this to initialize UnityExplorer with the provided log listener and Unhollowed modules path. + /// + /// Your log listener to handle UnityExplorer logs. + /// The path of the Unhollowed modules, either relative or absolute. + /// The new (or active, if one exists) instance of ExplorerStandalone. + public static ExplorerStandalone CreateInstance(Action logListener, string unhollowedModulesPath) { if (Instance != null) return Instance; + var instance = new ExplorerStandalone(); + instance.Init(); + instance.CheckExplorerFolder(); + if (logListener != null) OnLog += logListener; - var instance = new ExplorerStandalone(); - instance.Init(); + if (string.IsNullOrEmpty(unhollowedModulesPath) || !Directory.Exists(unhollowedModulesPath)) + instance._unhollowedPath = Path.Combine(instance.ExplorerFolder, "Modules"); + else + instance._unhollowedPath = unhollowedModulesPath; + return instance; } @@ -48,6 +65,9 @@ namespace UnityExplorer /// public static event Action OnLog; + public string UnhollowedModulesFolder => _unhollowedPath; + private string _unhollowedPath; + public ConfigHandler ConfigHandler => _configHandler; private StandaloneConfigHandler _configHandler;