summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs7
-rw-r--r--src/SMAPI/Framework/ModLoading/Framework/BaseInstructionHandler.cs6
-rw-r--r--src/SMAPI/Framework/ModLoading/Framework/RecursiveRewriter.cs14
-rw-r--r--src/SMAPI/Framework/ModLoading/IInstructionHandler.cs5
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/ArchitectureAssemblyRewriter.cs31
-rw-r--r--src/SMAPI/Framework/SCore.cs2
-rw-r--r--src/SMAPI/Metadata/InstructionMetadata.cs5
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
}
/****