-
Notifications
You must be signed in to change notification settings - Fork 44
Method patches
Method patches work by applying HarmonyPatch
attribute to specific methods.
Here's an example of a class patch:
public class OriginalType
{
public static void TargetMethod()
{
Console.WriteLine("Target method!");
}
}
public class MyPatch
{
// Specifies the method to be a patch that targets OriginalType.TargetMethod
[HarmonyPatch(typeof(OriginalType), "TargetMethod")]
[HarmonyPrefix]
public static void Prefix()
{
// Code to run at the start of the original method
Console.WriteLine("Hello");
}
// Specifies the method to be a patch that targets OriginalType.TargetMethod
[HarmonyPatch(typeof(OriginalType), "TargetMethod")]
[HarmonyPostfix]
public static void Postfix()
{
// Code to run after the original method
Console.WriteLine("Bye");
}
}
Class patches are applied by calling Harmony.PatchAll(Type)
to which you pass the type that contains your patch methods. After you apply the patch, calling OriginalType.TargetMethod
will print
Hello
Target method!
Bye
To specify multiple targets, you can apply multiple HarmonyPatch
attributes on a single patch:
// Patches both TargetMethod and TargetMethod2
[HarmonyPatch(typeof(OriginalType), "TargetMethod")]
[HarmonyPatch(typeof(OriginalType), "TargetMethod2")]
[HarmonyPrefix]
public static void Prefix()
Method patches work on a per-method basis and only with attributes. As such, no lifetime methods are available in method patches.
Here is a list of all methods supported by class patches.
Note about syntax: the []
brackets inside the method arguments denote optional arguments.
[HarmonyPrefix]
static (void|bool) MyPrefix([...])
This method defines the code that is executed before the original method. Prefixes can optionally return a boolean: if prefix returns true
, the original method code is executed; if prefix returns false
, the original method code is skipped.
Difference between Harmony and HarmonyX: HarmonyX will run all prefixes even if one of them returns false
. Refer to differences from Harmony for more info.
Prefixes can accept various parameters. Refer to Patch parameters for a list of all supported patch parameters.
[HarmonyPostfix]
static void MyPostfix([...])
// Passthrough prefix (receives return value as first parameter, returns new return value)
[HarmonyPostfix]
static T MyPostfix([T result, ...])
This method defines the code that is executed after the original method. All postfixes always get executed even if the original method code was skipped.
There are two types of postfixes: normal and passthrough. Normal postfixes have return type void
and behave like prefixes.
Passthrough postfixes have a return value and an optional return
argument the types of which are the same target method return value. Passthrough postfixes receive the return value of the original method and must return either the same value or a modified one.
Postfixes can accept various parameters. Refer to Patch parameters for a list of all supported patch parameters.
// Rethrowing finalizer
[HarmonyFinalizer]
static void MyFinalizer([...])
// Throwing finalizer
[HarmonyFinalizer]
static Exception MyFinalizer([...])
Finalizers allow you to catch, throw and suppress exceptions in a method. Finalizers run before postfixes and only if original method wasn't skipped. Finalizers also run immediately if an exception occurs inside the original method.
Finalizers can accept various parameters. Refer to Patch parameters for a list of all supported patch parameters.
Finalizers are an advanced topic. Refer to Finalizers guide for more info.
[HarmonyTranspiler]
static IEnumerable<CodeInstruction> MyTranspiler(IEnumerable<CodeInstruction> instr[, ...])
This method defines the transpiler that modifies the code of the original method. Use this in the advanced case where you want to modify the original methods IL codes.
This method must always have at least one parameter of type IEnumerable<CodeInstruction>
that will receive a list of IL instructions of the original methods. The transpiler must return a new IEnumerable<CodeInstruction>
that will be used as the modified code of the original method.
Transpilers are an advanced topic. Refer to Transpilers guide for more info.
- Basic usage
-
HarmonyX extensions
1.1. Patching and unpatching
1.2. Prefixes are flowthrough
1.3. Targeting multiple methods with one patch
1.4. Patching enumerators
1.5. Transpiler helpers
1.6. ILManipulators
1.7. Extended patch targets
1.8. New patch attributes -
Extending HarmonyX
2.1. Custom patcher backends -
Misc
4.1. Patch parameters - Implementation differences from Harmony