-
Notifications
You must be signed in to change notification settings - Fork 45
Patching
Inside the class Harmony searches for methods with the specific names TargetMethod()
, Prepare()
, Prefix()
or Postfix()
. Instead of relying on those names, you can also use the method annoations [HarmonyTargetMethod]
, [HarmonyPrepare]
, [HarmonyPrefix]
or [HarmonyPostfix]
.
TargetMethod (Optional)
Most of the times, you will use a combination of HarmonyPatch()
annotations on the class to define the method you want to patch. Sometimes though, it is necessary to calculate the method with code. For this, Harmony searches for a method called
static MethodInfo TargetMethod()
static MethodInfo TargetMethod(Harmony instance)
// or
[HarmonyTargetMethod]
static MethodInfo CalculateMethod(...)
That method, if it exists, is expected to return a MethodInfo
of the method to be patched. You can optionally receive the harmony instance if you want to run other Harmony methods inside your code.
Prepare (Optional)
Before the patching, Harmony gives you a chance to prepare your state. For this, Harmony searches for a method called
static bool Prepare()
static bool Prepare(Harmony instance)
// or
[HarmonyPrepare]
static bool MyInitializer(...)
That method, if it exists, is expected to return a boolean that controls if patching will happen. You can optionally receive the harmony instance if you want to run other Harmony methods inside your code.
Prefix (Optional)
static bool Prefix(...)
// or
[HarmonyPrefix]
static bool MyPrefix(...)
This method defines the code that is executed before the original method. It follows the guidelines defined in [Patching]
Postfix (Optional)
static bool Postfix(...)
// or
[HarmonyPostfix]
static bool MyPostfix(...)
This method defines the code that is executed after the original method. It follows the guidelines defined in Patching.
Each prefix and postfix can get all the parameters of the original method as well as the instance (if original method is not static) and the return value. In order to patch a method your patches need to follow the following principles when defining them:
- A patch must be a static method
- A prefix patch has a return signature of void or bool
- A postfix patch has a return signature of void
- Patches can use a parameter named __instance to access the instance value if original method is not static
- Patches can use a parameter named __result to access the returned value (prefixes get default value)
- Patches can define only those parameters they want to access (no need to define all)
- Patch parameters must use the exact same name and type as the original method
- Patches can either get parameters normally or by declaring any parameter ref (for manipulation)
- Prefix will not be able to get any out parameters
Example:
// original method in class Customer
private List<string> getNames(int count, out Error error)
// prefix
// - wants instance, result and count
// - wants to change count
// - returns a boolean that controls if original is executed (true) or not (false)
static bool Prefix(Customer __instance, List<string> result, ref int count)
// postfix
// - wants result and error
// - does not change any of those
static void Postfix(List<string> result, Error error)
- 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