[C#][Harmony Lib]Harmony dosen't hook constructors

Started by smarrazzo, January 30, 2018, 10:28:35 AM

Previous topic - Next topic

smarrazzo

After dozens of trials i noticed that harmony can't hook constructors,the standard harmony syntax just don't work:

[HarmonyPatch(typeof(Zone_Growing))]
[HarmonyPatch(".ctor")]
[HarmonyPatch(new Type[] { typeof(ZoneManager) })]
internal static class Patch_Zone_Growing_Default
{
   
static void Postfix(Zone_Growing __instance,ZoneManager z)
{
Log.Message("hooked");
}
}

or even
[HarmonyPatch(typeof(Zone_Growing), ".ctor", new Type[] { typeof(ZoneManager)})]
it keeps throwing method not found exception and its really frustrating.
Someone knows an alternative way to hook constructors with harmony ?
Btw this bug should be fixed or documented properly

BrokenValkyrie


smarrazzo

#2
yeah, but my class is not abstract and i need to access it only 1 time when the object is created, accessing a with  [HarmonyPatch(typeof(BuildableDef))]  is not the same because harmony will hook the class everytime the given variable is modified and it's not my case of need.

jamaicancastle

You can tell Harmony to look up a specific method that's passed to it by a variable, using code like so:

using System.Reflection //add this to your using block at the top

    [HarmonyPatch]
    public static class YourPatchClassName
    {
        static MethodInfo TargetMethod()
        {
            var methods = typeof(foo).GetMethods(); // where "foo" is the class you're trying to patch

            foreach (var method in methods)
            {
                if(method.Name == "bar") // where "bar" is the name of the method, or you can change the statement to look up another attribute, like the properties or return type
                {
                    return method;
                }
            }
            throw new Exception("Tried to patch [whatever you're doing] but couldn't find it.");
        }
        // your prefix or postfix or transpiler goes here
    }

(Thanks to some folks on the community Discord and I think ultimately erdelf for this code.)

However in this case I wonder if it might be simpler to hook into whatever it is that's constructing the object in the first place? For instance if you're trying to set the properties of a newly-created growing zone, it might be easier to do so by hooking the designator that creates them.