diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-08-31 01:13:22 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-09-01 20:02:58 -0400 |
commit | 8bfab94213e86c4245961150bd3423ee85213c5d (patch) | |
tree | 69fb8ceab3a0c21a27a2ac28eb6c42333b1bcf9b /src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs | |
parent | c6cc1513c5ab5544094fe30b13ee0d73e1e04109 (diff) | |
download | SMAPI-8bfab94213e86c4245961150bd3423ee85213c5d.tar.gz SMAPI-8bfab94213e86c4245961150bd3423ee85213c5d.tar.bz2 SMAPI-8bfab94213e86c4245961150bd3423ee85213c5d.zip |
reduce unneeded operations when scanning/rewriting mod DLLs
Diffstat (limited to 'src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs')
-rw-r--r-- | src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs deleted file mode 100644 index 7a3b428d..00000000 --- a/src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using HarmonyLib; -using Mono.Cecil; -using Mono.Cecil.Cil; -using StardewModdingAPI.Framework.ModLoading.Framework; -using StardewModdingAPI.Framework.ModLoading.RewriteFacades; - -namespace StardewModdingAPI.Framework.ModLoading.Rewriters -{ - /// <summary>Rewrites Harmony 1.x assembly references to work with Harmony 2.x.</summary> - internal class Harmony1AssemblyRewriter : BaseInstructionHandler - { - /********* - ** Fields - *********/ - /// <summary>Whether any Harmony 1.x types were replaced.</summary> - private bool ReplacedTypes; - - - /********* - ** Public methods - *********/ - /// <summary>Construct an instance.</summary> - public Harmony1AssemblyRewriter() - : base(defaultPhrase: "Harmony 1.x") { } - - /// <inheritdoc /> - public override bool Handle(ModuleDefinition module, TypeReference type, Action<TypeReference> replaceWith) - { - // rewrite Harmony 1.x type to Harmony 2.0 type - if (type.Scope is AssemblyNameReference { Name: "0Harmony" } scope && scope.Version.Major == 1) - { - Type targetType = this.GetMappedType(type); - replaceWith(module.ImportReference(targetType)); - this.OnChanged(); - this.ReplacedTypes = true; - return true; - } - - return false; - } - - /// <inheritdoc /> - public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction) - { - // rewrite Harmony 1.x methods to Harmony 2.0 - MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); - if (this.TryRewriteMethodsToFacade(module, methodRef)) - { - this.OnChanged(); - return true; - } - - // rewrite renamed fields - FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); - if (fieldRef != null) - { - if (fieldRef.DeclaringType.FullName == "HarmonyLib.HarmonyMethod" && fieldRef.Name == "prioritiy") - { - fieldRef.Name = nameof(HarmonyMethod.priority); - this.OnChanged(); - } - } - - return false; - } - - - /********* - ** Private methods - *********/ - /// <summary>Update the mod metadata when any Harmony 1.x code is migrated.</summary> - private void OnChanged() - { - this.MarkRewritten(); - this.MarkFlag(InstructionHandleResult.DetectedGamePatch); - } - - /// <summary>Rewrite methods to use Harmony facades if needed.</summary> - /// <param name="module">The assembly module containing the method reference.</param> - /// <param name="methodRef">The method reference to map.</param> - private bool TryRewriteMethodsToFacade(ModuleDefinition module, MethodReference methodRef) - { - if (!this.ReplacedTypes) - return false; // not Harmony (or already using Harmony 2.0) - - // get facade type - Type toType = methodRef?.DeclaringType.FullName switch - { - "HarmonyLib.Harmony" => typeof(HarmonyInstanceFacade), - "HarmonyLib.AccessTools" => typeof(AccessToolsFacade), - "HarmonyLib.HarmonyMethod" => typeof(HarmonyMethodFacade), - _ => null - }; - if (toType == null) - return false; - - // map if there's a matching method - if (RewriteHelper.HasMatchingSignature(toType, methodRef)) - { - methodRef.DeclaringType = module.ImportReference(toType); - return true; - } - - return false; - } - - /// <summary>Get an equivalent Harmony 2.x type.</summary> - /// <param name="type">The Harmony 1.x type.</param> - private Type GetMappedType(TypeReference type) - { - return type.FullName switch - { - "Harmony.HarmonyInstance" => typeof(Harmony), - "Harmony.ILCopying.ExceptionBlock" => typeof(ExceptionBlock), - _ => this.GetMappedTypeByConvention(type) - }; - } - - /// <summary>Get an equivalent Harmony 2.x type using the convention expected for most types.</summary> - /// <param name="type">The Harmony 1.x type.</param> - private Type GetMappedTypeByConvention(TypeReference type) - { - string fullName = type.FullName.Replace("Harmony.", "HarmonyLib."); - string targetName = typeof(Harmony).AssemblyQualifiedName!.Replace(typeof(Harmony).FullName!, fullName); - return Type.GetType(targetName, throwOnError: true); - } - } -} |