summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/ModLoading/Framework/RewriteHelper.cs11
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyMethodFacade.cs45
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs4
3 files changed, 58 insertions, 2 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Framework/RewriteHelper.cs b/src/SMAPI/Framework/ModLoading/Framework/RewriteHelper.cs
index 91c9dec3..36058b86 100644
--- a/src/SMAPI/Framework/ModLoading/Framework/RewriteHelper.cs
+++ b/src/SMAPI/Framework/ModLoading/Framework/RewriteHelper.cs
@@ -137,7 +137,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
/// <summary>Get whether a method definition matches the signature expected by a method reference.</summary>
/// <param name="definition">The method definition.</param>
/// <param name="reference">The method reference.</param>
- public static bool HasMatchingSignature(MethodInfo definition, MethodReference reference)
+ public static bool HasMatchingSignature(MethodBase definition, MethodReference reference)
{
//
// duplicated by HasMatchingSignature(MethodDefinition, MethodReference) below
@@ -166,7 +166,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
public static bool HasMatchingSignature(MethodDefinition definition, MethodReference reference)
{
//
- // duplicated by HasMatchingSignature(MethodInfo, MethodReference) above
+ // duplicated by HasMatchingSignature(MethodBase, MethodReference) above
//
// same name
@@ -191,6 +191,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Framework
/// <param name="reference">The method reference.</param>
public static bool HasMatchingSignature(Type type, MethodReference reference)
{
+ if (reference.Name == ".ctor")
+ {
+ return type
+ .GetConstructors(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
+ .Any(method => RewriteHelper.HasMatchingSignature(method, reference));
+ }
+
return type
.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly | BindingFlags.Public)
.Any(method => RewriteHelper.HasMatchingSignature(method, reference));
diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyMethodFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyMethodFacade.cs
new file mode 100644
index 00000000..44c97401
--- /dev/null
+++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyMethodFacade.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using HarmonyLib;
+
+namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
+{
+ /// <summary>Maps Harmony 1.x <see cref="HarmonyMethod"/> methods to Harmony 2.x to avoid breaking older mods.</summary>
+ /// <remarks>This is public to support SMAPI rewriting and should not be referenced directly by mods.</remarks>
+ [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Used via assembly rewriting")]
+ [SuppressMessage("ReSharper", "CS1591", Justification = "Documentation not needed for facade classes.")]
+ public class HarmonyMethodFacade : HarmonyMethod
+ {
+ /*********
+ ** Public methods
+ *********/
+ public HarmonyMethodFacade(MethodInfo method)
+ {
+ this.ImportMethodImpl(method);
+ }
+
+ public HarmonyMethodFacade(Type type, string name, Type[] parameters = null)
+ {
+ this.ImportMethodImpl(AccessTools.Method(type, name, parameters));
+ }
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Import a method directly using the internal HarmonyMethod code.</summary>
+ /// <param name="methodInfo">The method to import.</param>
+ private void ImportMethodImpl(MethodInfo methodInfo)
+ {
+ // A null method is no longer allowed in the constructor with Harmony 2.0, but the
+ // internal code still handles null fine. For backwards compatibility, this bypasses
+ // the new restriction when the mod hasn't been updated for Harmony 2.0 yet.
+
+ MethodInfo importMethod = typeof(HarmonyMethod).GetMethod("ImportMethod", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (importMethod == null)
+ throw new InvalidOperationException("Can't find 'HarmonyMethod.ImportMethod' method");
+ importMethod.Invoke(this, new object[] { methodInfo });
+ }
+ }
+}
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs
index ce6417a8..8fed170a 100644
--- a/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs
+++ b/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs
@@ -92,6 +92,10 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters
toType = typeof(AccessToolsFacade);
break;
+ case "HarmonyLib.HarmonyMethod":
+ toType = typeof(HarmonyMethodFacade);
+ break;
+
default:
return false;
}