diff --git a/Data/latest-version.txt b/Data/latest-version.txt index fc931ed3..094c9526 100644 --- a/Data/latest-version.txt +++ b/Data/latest-version.txt @@ -1 +1 @@ -4.1.4.0 \ No newline at end of file +4.2.0.0 \ No newline at end of file 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/BepInEx/BepInEx/patchers/BepInEx.MultiFolderLoader.dll b/Dependencies/BepInEx/BepInEx/patchers/BepInEx.MultiFolderLoader.dll new file mode 100644 index 00000000..138e5768 Binary files /dev/null and b/Dependencies/BepInEx/BepInEx/patchers/BepInEx.MultiFolderLoader.dll differ diff --git a/Dependencies/BepInEx/doorstop_config.ini b/Dependencies/BepInEx/doorstop_config.ini index a68f30f1..2e860502 100644 --- a/Dependencies/BepInEx/doorstop_config.ini +++ b/Dependencies/BepInEx/doorstop_config.ini @@ -13,4 +13,7 @@ ignoreDisableSwitch=false # (e.g. mscorlib is stripped in original game) # This option causes Mono to seek mscorlib and core libraries from a different folder before Managed # Original Managed folder is added as a secondary folder in the search path -dllSearchPathOverride= \ No newline at end of file +dllSearchPathOverride= + +[MultiFolderLoader] +baseDir=.\QMods \ No newline at end of file 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/Executable/Properties/AssemblyInfo.cs b/Executable/Properties/AssemblyInfo.cs index d74be537..d9e46dd6 100644 --- a/Executable/Properties/AssemblyInfo.cs +++ b/Executable/Properties/AssemblyInfo.cs @@ -12,5 +12,5 @@ [assembly: ComVisible(false)] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] diff --git a/Installer/BZ.EXP.iss b/Installer/BZ.EXP.iss index 8e53f360..3fa94a28 100644 --- a/Installer/BZ.EXP.iss +++ b/Installer/BZ.EXP.iss @@ -5,7 +5,7 @@ #endif #define Name "QModManager" ; The name of the game will be added after it -#define Version "4.1.4" +#define Version "4.2" #define Author "QModManager" #define URL "https://github.com/QModManager/QModManager" #define SupportURL "https://discord.gg/UpWuWwq" @@ -59,7 +59,7 @@ Source: "InstallerExtensions.dll"; Flags: DontCopy ; Files required by QModManager itself ; Dependencies -Source: "..\..\packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; +Source: "..\..\packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\cldb.dat"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\Oculus.Newtonsoft.Json.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; @@ -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..64fcb3e8 100644 --- a/Installer/BZ.STABLE.iss +++ b/Installer/BZ.STABLE.iss @@ -5,7 +5,7 @@ #endif #define Name "QModManager" ; The name of the game will be added after it -#define Version "4.1.4" +#define Version "4.2" #define Author "QModManager" #define URL "https://github.com/QModManager/QModManager" #define SupportURL "https://discord.gg/UpWuWwq" @@ -59,7 +59,7 @@ Source: "InstallerExtensions.dll"; Flags: DontCopy ; Files required by QModManager itself ; Dependencies -Source: "..\..\packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; +Source: "..\..\packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\cldb.dat"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\Oculus.Newtonsoft.Json.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; @@ -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/Properties/AssemblyInfo.cs b/Installer/Properties/AssemblyInfo.cs index 7d03deec..842baa71 100644 --- a/Installer/Properties/AssemblyInfo.cs +++ b/Installer/Properties/AssemblyInfo.cs @@ -14,5 +14,5 @@ [assembly: Guid("8c6c9a0b-80c4-43d2-89f2-749e6f09fdda")] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] diff --git a/Installer/SN.EXP.iss b/Installer/SN.EXP.iss index 4abd8e00..5ff504b7 100644 --- a/Installer/SN.EXP.iss +++ b/Installer/SN.EXP.iss @@ -5,7 +5,7 @@ #endif #define Name "QModManager" ; The name of the game will be added after it -#define Version "4.1.4" +#define Version "4.2" #define Author "QModManager" #define URL "https://github.com/QModManager/QModManager" #define SupportURL "https://discord.gg/UpWuWwq" @@ -59,7 +59,7 @@ Source: "InstallerExtensions.dll"; Flags: DontCopy ; Files required by QModManager itself ; Dependencies -Source: "..\..\packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; +Source: "..\..\packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\cldb.dat"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\Oculus.Newtonsoft.Json.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; @@ -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..c8a57150 100644 --- a/Installer/SN.STABLE.iss +++ b/Installer/SN.STABLE.iss @@ -5,7 +5,7 @@ #endif #define Name "QModManager" ; The name of the game will be added after it -#define Version "4.1.4" +#define Version "4.2" #define Author "QModManager" #define URL "https://github.com/QModManager/QModManager" #define SupportURL "https://discord.gg/UpWuWwq" @@ -59,7 +59,7 @@ Source: "InstallerExtensions.dll"; Flags: DontCopy ; Files required by QModManager itself ; Dependencies -Source: "..\..\packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; +Source: "..\..\packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; Source: "..\..\Dependencies\cldb.dat"; DestDir: "{app}\BepInEx\patchers\QModManager"; Flags: ignoreversion; ; QMM @@ -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/OculusNewtonsoftRedirect/Properties/AssemblyInfo.cs b/OculusNewtonsoftRedirect/Properties/AssemblyInfo.cs index 308f449b..ddd3cc07 100644 --- a/OculusNewtonsoftRedirect/Properties/AssemblyInfo.cs +++ b/OculusNewtonsoftRedirect/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] diff --git a/QModManager.sln b/QModManager.sln index d4623aec..bb32a167 100644 --- a/QModManager.sln +++ b/QModManager.sln @@ -36,6 +36,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QModManager.QModPluginGener EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QModManager.OculusNewtonsoftRedirect", "OculusNewtonsoftRedirect\QModManager.OculusNewtonsoftRedirect.csproj", "{25558450-FF33-4FDF-91C7-0C5C00A94A57}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Scripts", "Build Scripts", "{075884D3-CC6F-4B56-B050-C31A8E11FA52}" + ProjectSection(SolutionItems) = preProject + Scripts\QModPluginGenerator-post-build.cmd = Scripts\QModPluginGenerator-post-build.cmd + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution BZ.EXP|Any CPU = BZ.EXP|Any CPU @@ -224,6 +229,9 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {075884D3-CC6F-4B56-B050-C31A8E11FA52} = {5A8D179E-C749-4346-AD81-05F11C082A1C} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {54A73C4F-4981-48CC-AD91-27D3D090D5D4} EndGlobalSection diff --git a/QModManager/BepInex/Plugins/LogFilter.cs b/QModManager/BepInex/Plugins/LogFilter.cs new file mode 100644 index 00000000..9281deef --- /dev/null +++ b/QModManager/BepInex/Plugins/LogFilter.cs @@ -0,0 +1,54 @@ +using BepInEx; +using HarmonyLib; +using System.Text.RegularExpressions; + +namespace QModInstaller.BepInEx.Plugins +{ + /// + /// Handles filtering noisy logs from the QModManager logs. + /// + [BepInPlugin(PluginGuid, PluginName, PluginVersion)] + [BepInProcess("Subnautica"), BepInProcess("SubnauticaZero")] + internal class LogFilter : BaseUnityPlugin + { + internal const string PluginGuid = "QModManager.LogFilter"; + internal const string PluginName = PluginGuid; + internal const string PluginVersion = "4.2"; + + private void Awake() + { + var harmony = new Harmony(PluginGuid); + harmony.Patch(AccessTools.Method("MirrorInternalLogs.Util.LibcHelper:Format"), + postfix: new HarmonyMethod(AccessTools.Method(typeof(LogFilter), nameof(LogFilter.LibcHelper_Format_Postfix)))); + } + + private readonly static Regex[] DirtyRegexPatterns = new Regex[] { + new Regex(@"([\r\n]+)?(\(Filename: .*\))", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(Replacing cell.*)", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(Resetting cell with.*)", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(Fallback handler could not load.*)", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(Heartbeat CSV.*,[0-9])", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(L[0-9]: .*)", RegexOptions.Compiled), + new Regex(@"([\r\n]+)?(Kinematic body only supports Speculative Continuous collision detection)", RegexOptions.Compiled) + }; + + private static void LibcHelper_Format_Postfix(ref string __result) + { + bool match = false; + foreach (Regex pattern in DirtyRegexPatterns) + { + if (pattern.IsMatch(__result)) + { + __result = pattern.Replace(__result, string.Empty).Trim(); + match = true; + } + } + + // if our filtering resulted in an empty string, return null so that MirrorInternalLogs will skip the line + if (match && string.IsNullOrWhiteSpace(__result)) + { + __result = null; + } + } + } +} diff --git a/QModManager/BepInex/Plugins/QMMLoader.cs b/QModManager/BepInex/Plugins/QMMLoader.cs new file mode 100644 index 00000000..7e3e57bd --- /dev/null +++ b/QModManager/BepInex/Plugins/QMMLoader.cs @@ -0,0 +1,123 @@ +using BepInEx; +#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. + /// + [BepInPlugin(PluginGuid, PluginName, PluginVersion)] + [BepInProcess("Subnautica"), BepInProcess("SubnauticaZero")] + public class QMMLoader : BaseUnityPlugin + { + internal const string PluginGuid = "QModManager.QMMLoader"; + internal const string PluginName = "QMMLoader"; + internal const string PluginVersion = "4.2"; + + 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. + /// + 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/Properties/AssemblyInfo.cs b/QModManager/Properties/AssemblyInfo.cs index 911d7312..6396d299 100644 --- a/QModManager/Properties/AssemblyInfo.cs +++ b/QModManager/Properties/AssemblyInfo.cs @@ -13,8 +13,8 @@ [assembly: ComVisible(false)] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] [assembly: InternalsVisibleTo("QMMTests")] [assembly: InternalsVisibleTo("QModManager")] diff --git a/QModManager/QMMLoader.cs b/QModManager/QMMLoader.cs deleted file mode 100644 index 737d483c..00000000 --- a/QModManager/QMMLoader.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace QModInstaller -{ - using BepInEx; - using System; - using UnityEngine; - - /// - /// QMMLoader - simply fires up the QModManager entry point. - /// - [BepInPlugin(PluginGuid, PluginName, PluginVersion)] - [BepInProcess(SubnauticaProcessName)] - [BepInProcess(SubnauticaZeroProcessName)] - public class QMMLoader: BaseUnityPlugin - { - internal const string PluginGuid = "QModManager.QMMLoader"; - internal const string PluginName = "QMMLoader"; - internal const string PluginVersion = "1.0.2"; - - internal const string SubnauticaProcessName = "Subnautica"; - internal const string SubnauticaZeroProcessName = "SubnauticaZero"; - - /// - /// 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. - /// - [Obsolete("DO NOT USE!", true)] - private QMMLoader() - { - GameObject obj = gameObject; - - while(obj.transform.parent?.gameObject != null) - obj = obj.transform.parent.gameObject; - - obj.EnsureComponent(); - DontDestroyOnLoad(obj); - } - } -} \ No newline at end of file diff --git a/QModManager/QModManager.csproj b/QModManager/QModManager.csproj index 697fdd42..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,10 +108,17 @@ False + + + ..\Dependencies\$(Configuration)\Sentry.dll + False + + + @@ -131,7 +134,7 @@ - + @@ -167,6 +170,7 @@ + diff --git a/QModPluginEmulator/Properties/AssemblyInfo.cs b/QModPluginEmulator/Properties/AssemblyInfo.cs index f9692a53..65db3109 100644 --- a/QModPluginEmulator/Properties/AssemblyInfo.cs +++ b/QModPluginEmulator/Properties/AssemblyInfo.cs @@ -33,8 +33,8 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] [assembly: NeutralResourcesLanguage("en")] [assembly: InternalsVisibleTo("QModManager.QMMLoader")] diff --git a/QModPluginEmulator/QModManager.QModPluginGenerator.csproj b/QModPluginEmulator/QModManager.QModPluginGenerator.csproj index ce9c8d23..91da93a4 100644 --- a/QModPluginEmulator/QModManager.QModPluginGenerator.csproj +++ b/QModPluginEmulator/QModManager.QModPluginGenerator.csproj @@ -13,42 +13,27 @@ 512 true - - - ..\Build\$(Configuration)\ - SUBNAUTICA;SUBNAUTICA_STABLE true pdbonly AnyCPU 7.3 prompt + + ..\Build\$(Configuration)\ + SUBNAUTICA;SUBNAUTICA_STABLE + ..\Build\$(Configuration)\ SUBNAUTICA;SUBNAUTICA_EXP - true - pdbonly - AnyCPU - 7.3 - prompt ..\Build\$(Configuration)\ BELOWZERO;BELOWZERO_STABLE - true - pdbonly - AnyCPU - 7.3 - prompt ..\Build\$(Configuration)\ BELOWZERO;BELOWZERO_EXP - true - pdbonly - AnyCPU - 7.3 - prompt OnBuildSuccess @@ -100,30 +85,11 @@ QModManager + + + - rmdir "$(SolutionDir)VortexBuild\$(Configuration)" /q /s -xcopy "$(SolutionDir)Dependencies\BepInEx" "$(SolutionDir)VortexBuild\$(Configuration)" /E /H /I /Q /Y -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 -xcopy "$(TargetDir)QModManager.QModPluginGenerator.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y -xcopy "$(TargetDir)QModManager.UnityAudioFixer.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y -xcopy "$(TargetDir)QModManager.UnityAudioFixer.xml" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y - -if NOT "$(ConfigurationName)" =="SN.STABLE" ( - -xcopy "$(SolutionDir)Dependencies\Oculus.Newtonsoft.Json.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y -xcopy "$(TargetDir)QModManager.OculusNewtonsoftRedirect.dll" "$(SolutionDir)VortexBuild\$(Configuration)\BepInEx\patchers\QModManager\" /I /Q /Y -) - -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 -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" -"$(SolutionDir)Dependencies\Inno\ISCC.exe" "$(TargetDir)QModsInstallerScript.iss" + call "$(SolutionDir)\Scripts\QModPluginGenerator-post-build.cmd" "$(SolutionDir)" "$(TargetDir)" "$(ConfigurationName)" \ No newline at end of file diff --git a/QModPluginEmulator/QModPluginGenerator.cs b/QModPluginEmulator/QModPluginGenerator.cs index 3ea1978b..283596d3 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,19 +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 System.Text.RegularExpressions; -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"); @@ -44,36 +44,25 @@ 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 { PluginCache = GetPluginCache(); Harmony = new Harmony("QModManager.QModPluginGenerator"); - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) - { - if (assembly?.GetName()?.Name?.Contains("MirrorInternalLogs") ?? false) - { - Type type = AccessTools.TypeByName("MirrorInternalLogs.Util.LibcHelper"); - var method = type?.GetMethod("Format"); - - if (method != null) - Harmony.Patch(method, postfix: new HarmonyMethod(typeof(QModPluginGenerator), nameof(QModPluginGenerator.LibcHelper_Format_Postfix))); - break; - } - } Harmony.Patch( 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) { @@ -83,115 +72,8 @@ public static void Finish() } } - private readonly static List DirtyRegexPatterns = new List() { - new Regex(@"([\r\n]+)?(\(Filename: .*\))$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(Replacing cell.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(Resetting cell with.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(PerformGarbage.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(Fallback handler could not load.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(Heartbeat CSV.*,[0-9])$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(L0: PerformGarbageCollection ->.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(L0: CellManager::EstimateBytes.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - new Regex(@"^(Kinematic body only supports Speculative Continuous collision detection.*)$", RegexOptions.Compiled | RegexOptions.Multiline), - }; - - private static void LibcHelper_Format_Postfix(ref string __result) - { - foreach (Regex pattern in DirtyRegexPatterns) - { - __result = pattern.Replace(__result, string.Empty).Trim(); - } - } - -#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[] { + private readonly static string[] QMMKnownAssemblyPaths = new[] { #if !SUBNAUTICA_STABLE Path.Combine(QMMPatchersPath, "QModManager.OculusNewtonsoftRedirect.dll"), #endif @@ -328,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; @@ -418,17 +299,18 @@ public static void TypeLoaderFindPluginTypesPostfix(ref Dictionary + + + \ No newline at end of file diff --git a/Scripts/QModPluginGenerator-post-build.cmd b/Scripts/QModPluginGenerator-post-build.cmd new file mode 100644 index 00000000..e9e22b18 --- /dev/null +++ b/Scripts/QModPluginGenerator-post-build.cmd @@ -0,0 +1,27 @@ +set solutionDir=%~f1 +set targetDir=%~f2 +set configName=%3 + +rmdir "%solutionDir%VortexBuild\%configName%" /q /s +xcopy "%solutionDir%Dependencies\BepInEx" "%solutionDir%VortexBuild\%configName%" /E /H /I /Q /Y +xcopy "%solutionDir%Dependencies\%configName%\BepInEx.cfg" "%solutionDir%VortexBuild\%configName%\BepInEx\config\" /I /Q /Y +mkdir "%solutionDir%VortexBuild\%configName%\QMods" +xcopy "%solutionDir%Dependencies\cldb.dat" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +xcopy "%solutionDir%packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +xcopy "%targetDir%QModManager.exe" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +xcopy "%targetDir%QModManager.QModPluginGenerator.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +xcopy "%targetDir%QModManager.UnityAudioFixer.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +xcopy "%targetDir%QModManager.UnityAudioFixer.xml" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y + +if NOT "%configName%" =="SN.STABLE" ( + xcopy "%solutionDir%Dependencies\Oculus.Newtonsoft.Json.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y + xcopy "%targetDir%QModManager.OculusNewtonsoftRedirect.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\patchers\QModManager\" /I /Q /Y +) + +xcopy "%targetDir%QModInstaller.dll" "%solutionDir%VortexBuild\%configName%\BepInEx\plugins\QModManager\" /I /Q /Y +xcopy "%targetDir%QModInstaller.xml" "%solutionDir%VortexBuild\%configName%\BepInEx\plugins\QModManager\" /I /Q /Y + +%solutionDir%packages\7-Zip.CommandLine.18.1.0\tools\7za.exe a "%solutionDir%VortexBuild\QModManager_%configName%.zip" "%solutionDir%VortexBuild\%configName%\*" + +echo F|xcopy /S /Q /Y /F "%solutionDir%Installer\%configName%.iss" "%targetDir%\QModsInstallerScript.iss" +"%solutionDir%Dependencies\Inno\ISCC.exe" "%targetDir%QModsInstallerScript.iss" \ No newline at end of file diff --git a/UnityAudioFixer/Properties/AssemblyInfo.cs b/UnityAudioFixer/Properties/AssemblyInfo.cs index 3572587f..8ac3042a 100644 --- a/UnityAudioFixer/Properties/AssemblyInfo.cs +++ b/UnityAudioFixer/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("4.1.4")] -[assembly: AssemblyFileVersion("4.1.4")] +[assembly: AssemblyVersion("4.2")] +[assembly: AssemblyFileVersion("4.2")] diff --git a/UnityAudioFixer/QModManager.UnityAudioFixer.csproj b/UnityAudioFixer/QModManager.UnityAudioFixer.csproj index bf5eb61e..004ccd32 100644 --- a/UnityAudioFixer/QModManager.UnityAudioFixer.csproj +++ b/UnityAudioFixer/QModManager.UnityAudioFixer.csproj @@ -55,9 +55,8 @@ prompt - - ..\packages\AssetsTools.NET.2.0.3\lib\net35\AssetsTools.NET.dll - False + + ..\packages\AssetsTools.NET.2.0.9\lib\net40\AssetsTools.NET.dll ..\Dependencies\BepInEx\BepInEx\core\BepInEx.dll diff --git a/UnityAudioFixer/UnityAudioFixer.cs b/UnityAudioFixer/UnityAudioFixer.cs index 6ec0e4c2..c9fa666d 100644 --- a/UnityAudioFixer/UnityAudioFixer.cs +++ b/UnityAudioFixer/UnityAudioFixer.cs @@ -90,7 +90,7 @@ private static void ChangeDisableUnityAudio(string path, bool newValue, QModGame AssetsFileInstance afi = am.LoadAssetsFile(path, false); am.LoadClassDatabase(Path.Combine(UnityAudioFixerPath, "cldb.dat")); AssetFileInfoEx audioInfo = afi.table.GetAssetInfo(4); - AssetTypeInstance audioAti = am.GetATI(afi.file, audioInfo); + AssetTypeInstance audioAti = am.GetTypeInstance(afi.file, audioInfo); AssetTypeValueField audioBaseField = audioAti.GetBaseField(); audioBaseField.Get("m_DisableAudio").GetValue().Set(newValue); byte[] audioAsset; diff --git a/UnityAudioFixer/packages.config b/UnityAudioFixer/packages.config index 76f7717a..e70d9e05 100644 --- a/UnityAudioFixer/packages.config +++ b/UnityAudioFixer/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file