summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-05-21 23:50:34 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-05-21 23:50:34 -0400
commit33da29b3e56a56c29ed6f36196d00881fa2aecfe (patch)
treea805b6856fb8542279fd751de02efd9eb89187fa /src/SMAPI/Framework
parentdb0a46cb688ac47a06067b07dfe30bc2b65ec369 (diff)
downloadSMAPI-33da29b3e56a56c29ed6f36196d00881fa2aecfe.tar.gz
SMAPI-33da29b3e56a56c29ed6f36196d00881fa2aecfe.tar.bz2
SMAPI-33da29b3e56a56c29ed6f36196d00881fa2aecfe.zip
rewrite Harmony.Patch method to allow non-implemented virtual methods (#711)
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs56
1 files changed, 41 insertions, 15 deletions
diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs
index fa340781..54b91679 100644
--- a/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs
+++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs
@@ -28,6 +28,13 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
public DynamicMethod Patch(MethodBase original, HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
{
+ // In Harmony 1.x you could target a virtual method that's not implemented by the
+ // target type, but in Harmony 2.0 you need to target the concrete implementation.
+ // This just resolves the method to the concrete implementation if needed.
+ if (original != null)
+ original = original.GetDeclaredMember();
+
+ // call Harmony 2.0 and show a detailed exception if it fails
try
{
MethodInfo method = base.Patch(original: original, prefix: prefix, postfix: postfix, transpiler: transpiler);
@@ -35,22 +42,41 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades
}
catch (Exception ex)
{
- // get patch types
- var patchTypes = new List<string>();
- if (prefix != null)
- patchTypes.Add("prefix");
- if (postfix != null)
- patchTypes.Add("postfix");
- if (transpiler != null)
- patchTypes.Add("transpiler");
-
- // get original method label
- string methodLabel = original != null
- ? $"method {original.DeclaringType?.FullName}.{original.Name}"
- : "null method";
-
- throw new Exception($"Harmony instance {this.Id} failed applying {string.Join("/", patchTypes)} to {methodLabel}.", ex);
+ string patchTypes = this.GetPatchTypesLabel(prefix, postfix, transpiler);
+ string methodLabel = this.GetMethodLabel(original);
+ throw new Exception($"Harmony instance {this.Id} failed applying {patchTypes} to {methodLabel}.", ex);
}
}
+
+
+ /*********
+ ** Private methods
+ *********/
+ /// <summary>Get a human-readable label for the patch types being applies.</summary>
+ /// <param name="prefix">The prefix method, if any.</param>
+ /// <param name="postfix">The postfix method, if any.</param>
+ /// <param name="transpiler">The transpiler method, if any.</param>
+ private string GetPatchTypesLabel(HarmonyMethod prefix = null, HarmonyMethod postfix = null, HarmonyMethod transpiler = null)
+ {
+ var patchTypes = new List<string>();
+
+ if (prefix != null)
+ patchTypes.Add("prefix");
+ if (postfix != null)
+ patchTypes.Add("postfix");
+ if (transpiler != null)
+ patchTypes.Add("transpiler");
+
+ return string.Join("/", patchTypes);
+ }
+
+ /// <summary>Get a human-readable label for the method being patched.</summary>
+ /// <param name="method">The method being patched.</param>
+ private string GetMethodLabel(MethodBase method)
+ {
+ return method != null
+ ? $"method {method.DeclaringType?.FullName}.{method.Name}"
+ : "null method";
+ }
}
}