diff options
7 files changed, 68 insertions, 2 deletions
diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index 3e35c9dd..7668e8a9 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -336,6 +336,13 @@ namespace StardewModdingAPI.Framework.ModLoading IInstructionHandler[] handlers = new InstructionMetadata().GetHandlers(this.ParanoidMode, platformChanged, this.RewriteMods).ToArray(); RecursiveRewriter rewriter = new RecursiveRewriter( module: module, + rewriteModule: curModule => + { + bool rewritten = false; + foreach (IInstructionHandler handler in handlers) + rewritten |= handler.Handle(curModule); + return rewritten; + }, rewriteType: (type, replaceWith) => { bool rewritten = false; diff --git a/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs b/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs index 624113b3..d5d1b38e 100644 --- a/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs +++ b/src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs @@ -25,6 +25,12 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework ** Public methods *********/ /// <inheritdoc /> + public virtual bool Handle(ModuleDefinition module) + { + return false; + } + + /// <inheritdoc /> public virtual bool Handle(ModuleDefinition module, TypeReference type, Action<TypeReference> replaceWith) { return false; diff --git a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs index 10f68f0d..4f14a579 100644 --- a/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs @@ -13,6 +13,11 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework /********* ** Delegates *********/ + /// <summary>Rewrite a module definition in the assembly code.</summary> + /// <param name="module">The current module definition.</param> + /// <returns>Returns whether the module was changed.</returns> + public delegate bool RewriteModuleDelegate(ModuleDefinition module); + /// <summary>Rewrite a type reference in the assembly code.</summary> /// <param name="type">The current type reference.</param> /// <param name="replaceWith">Replaces the type reference with the given type.</param> @@ -32,6 +37,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework /// <summary>The module to rewrite.</summary> public ModuleDefinition Module { get; } + /// <summary>Handle or rewrite a module definition if needed.</summary> + public RewriteModuleDelegate RewriteModuleImpl { get; } + /// <summary>Handle or rewrite a type reference if needed.</summary> public RewriteTypeDelegate RewriteTypeImpl { get; } @@ -44,11 +52,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework *********/ /// <summary>Construct an instance.</summary> /// <param name="module">The module to rewrite.</param> + /// <param name="rewriteModule">Handle or rewrite a module if needed.</param> /// <param name="rewriteType">Handle or rewrite a type reference if needed.</param> /// <param name="rewriteInstruction">Handle or rewrite a CIL instruction if needed.</param> - public RecursiveRewriter(ModuleDefinition module, RewriteTypeDelegate rewriteType, RewriteInstructionDelegate rewriteInstruction) + public RecursiveRewriter(ModuleDefinition module, RewriteModuleDelegate rewriteModule, RewriteTypeDelegate rewriteType, RewriteInstructionDelegate rewriteInstruction) { this.Module = module; + this.RewriteModuleImpl = rewriteModule; this.RewriteTypeImpl = rewriteType; this.RewriteInstructionImpl = rewriteInstruction; } @@ -63,6 +73,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework try { + changed |= this.RewriteModuleImpl(this.Module); + foreach (var type in types) changed |= this.RewriteTypeDefinition(type); } diff --git a/src/SMAPI/Framework/ModLoading/IInstructionHandler.cs b/src/SMAPI/Framework/ModLoading/IInstructionHandler.cs index 17c9ba68..d41732f8 100644 --- a/src/SMAPI/Framework/ModLoading/IInstructionHandler.cs +++ b/src/SMAPI/Framework/ModLoading/IInstructionHandler.cs @@ -24,6 +24,11 @@ namespace StardewModdingAPI.Framework.ModLoading /********* ** Methods *********/ + /// <summary>Rewrite a module definition if needed.</summary> + /// <param name="module">The assembly module.</param> + /// <returns>Returns whether the module was changed.</returns> + bool Handle(ModuleDefinition module); + /// <summary>Rewrite a type reference if needed.</summary> /// <param name="module">The assembly module containing the instruction.</param> /// <param name="type">The type definition to handle.</param> diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/ArchitectureAssemblyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/ArchitectureAssemblyRewriter.cs new file mode 100644 index 00000000..cc830216 --- /dev/null +++ b/src/SMAPI/Framework/ModLoading/Rewriters/ArchitectureAssemblyRewriter.cs @@ -0,0 +1,31 @@ +using Mono.Cecil; +using StardewModdingAPI.Framework.ModLoading.Framework; + +namespace StardewModdingAPI.Framework.ModLoading.Rewriters +{ + /// <summary>Removes the 32-bit-only from loaded assemblies.</summary> + internal class ArchitectureAssemblyRewriter : BaseInstructionHandler + { + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + public ArchitectureAssemblyRewriter() + : base(defaultPhrase: "32-bit architecture") { } + + + /// <inheritdoc /> + public override bool Handle(ModuleDefinition module) + { + if (module.Attributes.HasFlag(ModuleAttributes.Required32Bit)) + { + module.Attributes &= ~ModuleAttributes.Required32Bit; + this.MarkRewritten(); + return true; + } + + return false; + } + + } +} diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index c1aa3721..61fb77b2 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1732,7 +1732,7 @@ namespace StardewModdingAPI.Framework { errorReasonPhrase = "its DLL couldn't be loaded."; #if SMAPI_FOR_WINDOWS_64BIT_HACK - if (!EnvironmentUtility.Is64BitAssembly(assemblyPath)) + if (ex is BadImageFormatException && !EnvironmentUtility.Is64BitAssembly(assemblyPath)) errorReasonPhrase = "it needs to be updated for 64-bit mode."; #endif errorDetails = $"Error: {ex.GetLogSummary()}"; diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index a787993a..9f537c92 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -50,6 +50,11 @@ namespace StardewModdingAPI.Metadata // rewrite for SMAPI 3.12 (Harmony 1.x => 2.0 update) yield return new Harmony1AssemblyRewriter(); + + // rewrite for 64-bit mode +#if SMAPI_FOR_WINDOWS_64BIT_HACK + yield return new ArchitectureAssemblyRewriter(); +#endif } /**** |