diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-05-21 23:50:34 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2020-05-21 23:50:34 -0400 |
commit | 33da29b3e56a56c29ed6f36196d00881fa2aecfe (patch) | |
tree | a805b6856fb8542279fd751de02efd9eb89187fa /src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs | |
parent | db0a46cb688ac47a06067b07dfe30bc2b65ec369 (diff) | |
download | SMAPI-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/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs')
-rw-r--r-- | src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs | 56 |
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"; + } } } |