From 2adaaeb973f9391e5a3a11c6cdbc7c4cf00639a4 Mon Sep 17 00:00:00 2001 From: Andreas Pardeike Date: Sat, 4 Feb 2017 11:48:53 +0100 Subject: [PATCH] Bug fixes; v1.0.6 --- Harmony/PatchFunctions.cs | 5 +-- Harmony/PatchProcessor.cs | 4 +-- Harmony/Properties/AssemblyInfo.cs | 4 +-- Harmony/Tools/PatchTools.cs | 51 +++++------------------------- 4 files changed, 14 insertions(+), 50 deletions(-) diff --git a/Harmony/PatchFunctions.cs b/Harmony/PatchFunctions.cs index 0d42a131..ccfaeff9 100644 --- a/Harmony/PatchFunctions.cs +++ b/Harmony/PatchFunctions.cs @@ -67,13 +67,14 @@ public static void UpdateWrapper(MethodBase original, PatchInfo patchInfo) var sortedPostfixes = GetSortedPatchMethods(patchInfo.postfixes); var sortedProcessors = GetSortedProcessors(patchInfo.processors); - var replacement = MethodPatcher.CreatePatchedMethod(original, sortedPostfixes, sortedPostfixes, sortedProcessors); + var replacement = MethodPatcher.CreatePatchedMethod(original, sortedPrefixes, sortedPostfixes, sortedProcessors); if (replacement == null) throw new MissingMethodException("Cannot create dynamic replacement for " + original); - PatchTools.KeepAliveForever(replacement); var originalCodeStart = Memory.GetMethodStart(original); var patchCodeStart = Memory.GetMethodStart(replacement); Memory.WriteJump(originalCodeStart, patchCodeStart); + + PatchTools.RememberObject(original, replacement); // no gc for new value + release old value to gc } } } \ No newline at end of file diff --git a/Harmony/PatchProcessor.cs b/Harmony/PatchProcessor.cs index 3d66d537..6c0fb7e7 100644 --- a/Harmony/PatchProcessor.cs +++ b/Harmony/PatchProcessor.cs @@ -1,7 +1,5 @@ -using Harmony.ILCopying; -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; namespace Harmony diff --git a/Harmony/Properties/AssemblyInfo.cs b/Harmony/Properties/AssemblyInfo.cs index 60be43ba..b788b046 100644 --- a/Harmony/Properties/AssemblyInfo.cs +++ b/Harmony/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.5.0")] -[assembly: AssemblyFileVersion("1.0.5.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.0.6.0")] +[assembly: AssemblyFileVersion("1.0.6.0")] \ No newline at end of file diff --git a/Harmony/Tools/PatchTools.cs b/Harmony/Tools/PatchTools.cs index af6235c2..4fdc4a66 100644 --- a/Harmony/Tools/PatchTools.cs +++ b/Harmony/Tools/PatchTools.cs @@ -9,21 +9,18 @@ namespace Harmony public static class PatchTools { // this holds all the objects we want to keep alive so they don't get garbage-collected - static object[] objectReferences; - [MethodImpl(MethodImplOptions.Synchronized)] - public static void KeepAliveForever(object obj) + static Dictionary objectReferences = new Dictionary(); + public static void RememberObject(object key, object value) { - if (objectReferences == null) - objectReferences = new object[0]; - objectReferences.Add(obj); + objectReferences[key] = value; } - public static MethodInfo GetPatchMethod(Type patchType, string name, Type[] parameter) + public static MethodInfo GetPatchMethod(Type patchType, string name, Type[] parameters = null) { var method = patchType.GetMethods(AccessTools.all) .FirstOrDefault(m => m.GetCustomAttributes(typeof(T), true).Count() > 0); if (method == null) - method = patchType.GetMethod(name, AccessTools.all, null, parameter, null); + method = AccessTools.Method(patchType, name, parameters); return method; } @@ -32,42 +29,10 @@ public static void GetPatches(Type patchType, MethodBase original, out MethodInf var type = original.DeclaringType; var methodName = original.Name; - var parameters = original.GetParameters(); - var prefixParams = new List(); - var postfixParams = new List(); - if (original.IsStatic == false) - { - prefixParams.Add(type); - postfixParams.Add(type); - } - var returnedType = AccessTools.GetReturnedType(original); - if (returnedType != typeof(void)) - { - var retRef = returnedType.MakeByRefType(); - prefixParams.Add(retRef); - postfixParams.Add(retRef); - } - parameters.Do(pi => - { - var paramRef = pi.ParameterType.MakeByRefType(); - if (pi.IsOut == false) // prefix patches should not get out-parameters - prefixParams.Add(paramRef); - postfixParams.Add(paramRef); - }); - - prefix = GetPatchMethod(patchType, "Prefix", prefixParams.ToArray()); - postfix = GetPatchMethod(patchType, "Postfix", postfixParams.ToArray()); + prefix = GetPatchMethod(patchType, "Prefix"); + postfix = GetPatchMethod(patchType, "Postfix"); if (prefix == null && postfix == null) - { - var prefixMethod = "Prefix(" + string.Join(", ", prefixParams.Select(p => p.FullName).ToArray()) + ")"; - var postfixMethod = "Postfix(" + string.Join(", ", postfixParams.Select(p => p.FullName).ToArray()) + ")"; - throw new MissingMethodException("No prefix/postfix patch for " + type.FullName + "." + methodName + "() found that matches " + prefixMethod + " or " + postfixMethod); - } - - if (prefix != null && prefix.ReturnType != typeof(bool)) - throw new MissingMethodException("Prefix() must return bool (return true to execute original method)"); - if (postfix != null && postfix.ReturnType != typeof(void)) - throw new MissingMethodException("Postfix() must not return anything"); + throw new MissingMethodException("No prefix/postfix patch for " + type.FullName + "." + methodName + "() found"); } } } \ No newline at end of file