diff --git a/Dependencies/BZ.EXP/BepInEx.cfg b/Dependencies/BZ.EXP/BepInEx.cfg new file mode 100644 index 00000000..e15c9378 --- /dev/null +++ b/Dependencies/BZ.EXP/BepInEx.cfg @@ -0,0 +1,16 @@ +[Preloader.Entrypoint] + +## The local filename of the assembly to target. +# Setting type: String +# Default value: UnityEngine.CoreModule.dll +Assembly = Assembly-CSharp.dll + +## The name of the type in the entrypoint assembly to search for the entrypoint method. +# Setting type: String +# Default value: Application +Type = PreStartScreen + +## The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from. +# Setting type: String +# Default value: .cctor +Method = Start diff --git a/Dependencies/BZ.STABLE/BepInEx.cfg b/Dependencies/BZ.STABLE/BepInEx.cfg new file mode 100644 index 00000000..e15c9378 --- /dev/null +++ b/Dependencies/BZ.STABLE/BepInEx.cfg @@ -0,0 +1,16 @@ +[Preloader.Entrypoint] + +## The local filename of the assembly to target. +# Setting type: String +# Default value: UnityEngine.CoreModule.dll +Assembly = Assembly-CSharp.dll + +## The name of the type in the entrypoint assembly to search for the entrypoint method. +# Setting type: String +# Default value: Application +Type = PreStartScreen + +## The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from. +# Setting type: String +# Default value: .cctor +Method = Start diff --git a/Dependencies/SN.EXP/BepInEx.cfg b/Dependencies/SN.EXP/BepInEx.cfg new file mode 100644 index 00000000..e15c9378 --- /dev/null +++ b/Dependencies/SN.EXP/BepInEx.cfg @@ -0,0 +1,16 @@ +[Preloader.Entrypoint] + +## The local filename of the assembly to target. +# Setting type: String +# Default value: UnityEngine.CoreModule.dll +Assembly = Assembly-CSharp.dll + +## The name of the type in the entrypoint assembly to search for the entrypoint method. +# Setting type: String +# Default value: Application +Type = PreStartScreen + +## The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from. +# Setting type: String +# Default value: .cctor +Method = Start diff --git a/Dependencies/SN.STABLE/BepInEx.cfg b/Dependencies/SN.STABLE/BepInEx.cfg new file mode 100644 index 00000000..40ed9366 --- /dev/null +++ b/Dependencies/SN.STABLE/BepInEx.cfg @@ -0,0 +1,16 @@ +[Preloader.Entrypoint] + +## The local filename of the assembly to target. +# Setting type: String +# Default value: UnityEngine.CoreModule.dll +Assembly = Assembly-CSharp.dll + +## The name of the type in the entrypoint assembly to search for the entrypoint method. +# Setting type: String +# Default value: Application +Type = SystemsSpawner + +## The name of the method in the specified entrypoint assembly and type to hook and load Chainloader from. +# Setting type: String +# Default value: .cctor +Method = Awake diff --git a/Installer/BZ.EXP.iss b/Installer/BZ.EXP.iss index 8e53f360..ff6d05b5 100644 --- a/Installer/BZ.EXP.iss +++ b/Installer/BZ.EXP.iss @@ -76,6 +76,7 @@ Source: "QModManager.UnityAudioFixer.xml"; DestDir: "{app}\BepInEx\patchers\QMod ; BepInEx Source: "..\..\Dependencies\BepInEx\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs replacesameversion sharedfile uninsnosharedfileprompt; +Source: "..\..\Dependencies\BZ.EXP\BepInEx.cfg"; DestDir: "{app}\BepInEx\config"; Flags: ignoreversion sharedfile uninsnosharedfileprompt; [Dirs] Name: "{app}\QMods" diff --git a/Installer/BZ.STABLE.iss b/Installer/BZ.STABLE.iss index 21ffb3ea..f84ff133 100644 --- a/Installer/BZ.STABLE.iss +++ b/Installer/BZ.STABLE.iss @@ -76,6 +76,7 @@ Source: "QModManager.UnityAudioFixer.xml"; DestDir: "{app}\BepInEx\patchers\QMod ; BepInEx Source: "..\..\Dependencies\BepInEx\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs replacesameversion sharedfile uninsnosharedfileprompt; +Source: "..\..\Dependencies\BZ.STABLE\BepInEx.cfg"; DestDir: "{app}\BepInEx\config"; Flags: ignoreversion sharedfile uninsnosharedfileprompt; [Dirs] Name: "{app}\QMods" diff --git a/Installer/SN.EXP.iss b/Installer/SN.EXP.iss index 4abd8e00..5f3070ea 100644 --- a/Installer/SN.EXP.iss +++ b/Installer/SN.EXP.iss @@ -76,6 +76,7 @@ Source: "QModManager.UnityAudioFixer.xml"; DestDir: "{app}\BepInEx\patchers\QMod ; BepInEx Source: "..\..\Dependencies\BepInEx\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs replacesameversion sharedfile uninsnosharedfileprompt; +Source: "..\..\Dependencies\SN.EXP\BepInEx.cfg"; DestDir: "{app}\BepInEx\config"; Flags: ignoreversion sharedfile uninsnosharedfileprompt; [Dirs] Name: "{app}\QMods" diff --git a/Installer/SN.STABLE.iss b/Installer/SN.STABLE.iss index 9639659b..92ca5343 100644 --- a/Installer/SN.STABLE.iss +++ b/Installer/SN.STABLE.iss @@ -74,6 +74,7 @@ Source: "QModManager.UnityAudioFixer.xml"; DestDir: "{app}\BepInEx\patchers\QMod ; BepInEx Source: "..\..\Dependencies\BepInEx\*"; DestDir: "{app}"; Flags: recursesubdirs createallsubdirs replacesameversion sharedfile uninsnosharedfileprompt; +Source: "..\..\Dependencies\SN.STABLE\BepInEx.cfg"; DestDir: "{app}\BepInEx\config"; Flags: ignoreversion sharedfile uninsnosharedfileprompt; [Dirs] Name: "{app}\QMods" diff --git a/QModManager/BepInex/Plugins/QMMLoader.cs b/QModManager/BepInex/Plugins/QMMLoader.cs index 2935d6b8..66864c8e 100644 --- a/QModManager/BepInex/Plugins/QMMLoader.cs +++ b/QModManager/BepInex/Plugins/QMMLoader.cs @@ -1,9 +1,19 @@ using BepInEx; -using System; +#if !SUBNAUTICA_STABLE +using HarmonyLib; +#if !BELOWZERO +using System.Collections; +#endif +#endif +using System.Collections.Generic; using UnityEngine; namespace QModInstaller.BepInEx.Plugins { + using QModManager.API.ModLoading; + using QModManager.Patching; + using QModManager.Utility; + /// /// QMMLoader - simply fires up the QModManager entry point. /// @@ -15,6 +25,9 @@ public class QMMLoader : BaseUnityPlugin internal const string PluginName = "QMMLoader"; internal const string PluginVersion = "4.1.4"; + internal static List QModsToLoad; + private static Initializer Initializer; + /// /// Prevents a default instance of the class from being created /// Also ensures the root bepinex object does not get destroyed if the game reloads for steam. @@ -24,10 +37,87 @@ private void Awake() GameObject obj = gameObject; while (obj.transform.parent?.gameObject != null) + { obj = obj.transform.parent.gameObject; + } obj.EnsureComponent(); DontDestroyOnLoad(obj); + + PreInitializeQMods(); + } + + private void PreInitializeQMods() + { + Patcher.Patch(); // Run QModManager patch + + if (QModsToLoad is null) + { + Logger.LogWarning("QModsToLoad is null!"); + return; + } + + Initializer = new Initializer(Patcher.CurrentlyRunningGame); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.MetaPreInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.PreInitialize); + +#if SUBNAUTICA_STABLE + Initializer.InitializeMods(QModsToLoad, PatchingOrder.NormalInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.PostInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.MetaPostInitialize); + + SummaryLogger.ReportIssues(QModsToLoad); + SummaryLogger.LogSummaries(QModsToLoad); + foreach (Dialog dialog in Patcher.Dialogs) + { + dialog.Show(); + } +#else + var harmony = new Harmony(PluginGuid); + harmony.Patch( + AccessTools.Method( +#if SUBNAUTICA + typeof(PlatformUtils), nameof(PlatformUtils.PlatformInitAsync) +#elif BELOWZERO + typeof(SpriteManager), nameof(SpriteManager.OnLoadedSpriteAtlases) +#endif + ), + postfix: new HarmonyMethod(AccessTools.Method(typeof(QMMLoader), nameof(QMMLoader.InitializeQMods))) + ); +#endif + } + +#if SUBNAUTICA_EXP + private static IEnumerator InitializeQMods(IEnumerator result) + { + yield return result; + + Initializer.InitializeMods(QModsToLoad, PatchingOrder.NormalInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.PostInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.MetaPostInitialize); + + SummaryLogger.ReportIssues(QModsToLoad); + SummaryLogger.LogSummaries(QModsToLoad); + foreach (Dialog dialog in Patcher.Dialogs) + { + dialog.Show(); + } + } +#elif BELOWZERO + private static void InitializeQMods() + { + Initializer.InitializeMods(QModsToLoad, PatchingOrder.NormalInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.PostInitialize); + Initializer.InitializeMods(QModsToLoad, PatchingOrder.MetaPostInitialize); + + SummaryLogger.ReportIssues(QModsToLoad); + SummaryLogger.LogSummaries(QModsToLoad); + + foreach (Dialog dialog in Patcher.Dialogs) + { + dialog.Show(); + } } +#endif } } \ No newline at end of file diff --git a/QModManager/QModManager.csproj b/QModManager/QModManager.csproj index 37436a7c..9c85c1d1 100644 --- a/QModManager/QModManager.csproj +++ b/QModManager/QModManager.csproj @@ -78,10 +78,6 @@ ..\Dependencies\$(Configuration)\Newtonsoft.Json.dll False - - ..\Dependencies\$(Configuration)\Sentry.dll - False - ..\Dependencies\$(Configuration)\UnityEngine.dll @@ -112,6 +108,12 @@ False + + + ..\Dependencies\$(Configuration)\Sentry.dll + False + + diff --git a/QModPluginEmulator/QModManager.QModPluginGenerator.csproj b/QModPluginEmulator/QModManager.QModPluginGenerator.csproj index 4ec31582..70a26f2b 100644 --- a/QModPluginEmulator/QModManager.QModPluginGenerator.csproj +++ b/QModPluginEmulator/QModManager.QModPluginGenerator.csproj @@ -89,6 +89,8 @@ rmdir "$(SolutionDir)VortexBuild\$(Configuration)" /q /s xcopy "$(SolutionDir)Dependencies\BepInEx" "$(SolutionDir)VortexBuild\$(Configuration)" /E /H /I /Q /Y +xcopy "$(SolutionDir)Dependencies\$(Configuration)\BepInEx.cfg" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\config\" /I /Q /Y +mkdir "$(SolutionDir)VortexBuild\$(Configuration)\QMods" xcopy "$(SolutionDir)Dependencies\cldb.dat" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y xcopy "$(SolutionDir)packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y xcopy "$(TargetDir)QModManager.exe" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y @@ -105,7 +107,7 @@ xcopy "$(TargetDir)QModManager.OculusNewtonsoftRedirect.dll" "$(SolutionDir)Vort xcopy "$(TargetDir)QModInstaller.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\plugins\QModManager\" /I /Q /Y xcopy "$(TargetDir)QModInstaller.xml" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\plugins\QModManager\" /I /Q /Y -powershell Compress-Archive -Path '$(SolutionDir)VortexBuild\$(Configuration)\Bepinex' -DestinationPath '$(SolutionDir)VortexBuild\QModManager_$(Configuration).zip' -Force +powershell Compress-Archive -Path '$(SolutionDir)VortexBuild\$(Configuration)\BepInEx' -DestinationPath '$(SolutionDir)VortexBuild\QModManager_$(Configuration).zip' -Force powershell Compress-Archive -LiteralPath '$(SolutionDir)VortexBuild\$(Configuration)\doorstop_config.ini', '$(SolutionDir)VortexBuild\$(Configuration)\winhttp.dll' -DestinationPath '$(SolutionDir)VortexBuild\QModManager_$(Configuration).zip' -Update echo F|xcopy /S /Q /Y /F "$(SolutionDir)Installer\$(Configuration).iss" "$(TargetDir)\QModsInstallerScript.iss" diff --git a/QModPluginEmulator/QModPluginGenerator.cs b/QModPluginEmulator/QModPluginGenerator.cs index 1da806af..caa4ebc4 100644 --- a/QModPluginEmulator/QModPluginGenerator.cs +++ b/QModPluginEmulator/QModPluginGenerator.cs @@ -4,6 +4,7 @@ using HarmonyLib; using Mono.Cecil; #if SUBNAUTICA_STABLE +using System.Collections; using Oculus.Newtonsoft.Json; #else using Newtonsoft.Json; @@ -12,18 +13,18 @@ using QModManager.Patching; using QModManager.Utility; using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; -using QModManager.API.ModLoading; using TypeloaderCache = System.Collections.Generic.Dictionary>; using QMMAssemblyCache = System.Collections.Generic.Dictionary; namespace QModManager { + using QModInstaller.BepInEx.Plugins; + public static class QModPluginGenerator { internal static readonly string QModsPath = Path.Combine(Paths.GameRootPath, "QMods"); @@ -43,15 +44,13 @@ public static class QModPluginGenerator internal static Dictionary QModsToLoadById; internal static Dictionary QModPluginInfos; internal static List InitialisedQModPlugins; - private static Initializer Initializer; - private static List ModsToLoad; private static Harmony Harmony; internal static IVersionParser VersionParserService { get; set; } = new VersionParser(); private static TypeloaderCache PluginCache; [Obsolete("Should not be used!", true)] - public static void Finish() + public static void Initialize() { try { @@ -61,6 +60,9 @@ public static void Finish() typeof(TypeLoader).GetMethod(nameof(TypeLoader.FindPluginTypes)).MakeGenericMethod(typeof(PluginInfo)), postfix: new HarmonyMethod(typeof(QModPluginGenerator).GetMethod(nameof(TypeLoaderFindPluginTypesPostfix)))); + Harmony.Patch( + typeof(MetadataHelper).GetMethod(nameof(MetadataHelper.GetMetadata), new Type[] { typeof(object) }), + prefix: new HarmonyMethod(AccessTools.Method(typeof(QModPluginGenerator), nameof(QModPluginGenerator.MetadataHelperGetMetadataPrefix)))); } catch (Exception ex) { @@ -70,93 +72,6 @@ public static void Finish() } } -#if SUBNAUTICA_STABLE - [HarmonyPatch(typeof(SystemsSpawner), nameof(SystemsSpawner.Awake))] - [HarmonyPrefix] - private static void PreInitializeQMM() - { - Patcher.Patch(); // Run QModManager patch - - ModsToLoad = QModsToLoad.ToList(); - Initializer = new Initializer(Patcher.CurrentlyRunningGame); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.MetaPreInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.PreInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.NormalInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.PostInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.MetaPostInitialize); - - SummaryLogger.ReportIssues(ModsToLoad); - SummaryLogger.LogSummaries(ModsToLoad); - foreach(Dialog dialog in Patcher.Dialogs) - { - dialog.Show(); - } - - } -#else - [HarmonyPatch(typeof(PreStartScreen), nameof(PreStartScreen.Start))] - [HarmonyPrefix] - private static void PreInitializeQMM() - { - - - Patcher.Patch(); // Run QModManager patch - - ModsToLoad = QModsToLoad.ToList(); - Initializer = new Initializer(Patcher.CurrentlyRunningGame); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.MetaPreInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.PreInitialize); - - Harmony.Patch( - AccessTools.Method( -#if SUBNAUTICA - typeof(PlatformUtils), nameof(PlatformUtils.PlatformInitAsync) -#elif BELOWZERO - typeof(SpriteManager), nameof(SpriteManager.OnLoadedSpriteAtlases) -#endif - ), postfix: new HarmonyMethod(AccessTools.Method(typeof(QModPluginGenerator), nameof(QModPluginGenerator.InitializeQMM)))); - } - -#if SUBNAUTICA_EXP - private static IEnumerator InitializeQMM(IEnumerator result) - { - if (ModsToLoad != null) - { - yield return result; - - Initializer.InitializeMods(ModsToLoad, PatchingOrder.NormalInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.PostInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.MetaPostInitialize); - - SummaryLogger.ReportIssues(ModsToLoad); - SummaryLogger.LogSummaries(ModsToLoad); - foreach (Dialog dialog in Patcher.Dialogs) - { - dialog.Show(); - } - } - yield break; - } -#elif BELOWZERO - private static void InitializeQMM() - { - if (ModsToLoad != null) - { - Initializer.InitializeMods(ModsToLoad, PatchingOrder.NormalInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.PostInitialize); - Initializer.InitializeMods(ModsToLoad, PatchingOrder.MetaPostInitialize); - - SummaryLogger.ReportIssues(ModsToLoad); - SummaryLogger.LogSummaries(ModsToLoad); - - foreach (Dialog dialog in Patcher.Dialogs) - { - dialog.Show(); - } - } - } -#endif -#endif private static string[] QMMKnownAssemblyPaths = new[] { #if !SUBNAUTICA_STABLE @@ -295,7 +210,6 @@ private static TypeloaderCache GetPluginCache() [Obsolete("Should not be used!", true)] public static void TypeLoaderFindPluginTypesPostfix(ref Dictionary> __result, string directory) { - Harmony.PatchAll(typeof(QModPluginGenerator)); if (directory != Paths.PluginPath) return; @@ -385,17 +299,18 @@ public static void TypeLoaderFindPluginTypesPostfix(ref Dictionary