Skip to content

Target Method Annotations

Andreas Pardeike edited this page Mar 12, 2017 · 16 revisions

When you use the PatchAll(Assembly assembly) call, Harmony will search through all classes and methods inside the given assembly looking for specific Harmony annotations.

Example

A typical patch consists of a class with annotations that looks like this:

[HarmonyPatch(typeof(SomeTypeHere))]
[HarmonyPatch("SomeMethodName")]
class MyPatchClass
{
	static void Postfix(...)
	{
		//...
	}
}

This will annotate the class with enough information to identify the method to patch. Usually, you will have one class for each method that you want to patch. Inside that class, you define a Prefix and/or a Postfix method. Harmony will find them by their name. If you annotate those methods you can even have different names.

Annotation types

To indicate that a class contains patch methods it needs to be annotated with at lease one of the following class annotations:

  • [HarmonyPatch(Type, Type[])] Defines the type that contains the method to be patched (optional Type[] for generics)

  • [HarmonyPatch(String)] Defines the method to be patched by name

  • [HarmonyPatch(Type[])] Defines the attributes of the method to be patched (only necessary if multiple methods with the same name exist)

Additionally to repeating the basic annotations, the following shortcut can be used:

  • [HarmonyPatch(Type, String, Type[])] Defines the type and method to be patched in a single annotation

Combining annotations

The combination of those annotations defines the target method. Examples:

To patch method String.ToUpper() :

[HarmonyPatch(typeof(String))]
[HarmonyPatch("ToUpper")]

To patch property Account in class MyClass :

[HarmonyPatch(typeof(MyClass))]
[HarmonyPatch("get_Account")]

To patch method String.IndexOf(char, int) :

[HarmonyPatch(typeof(String))]
[HarmonyPatch("IndexOf")]
[HarmonyPatch(new Type[] { typeof(char), typeof(int) })]

//or

[HarmonyPatch(typeof(String), "IndexOf", new Type[] { typeof(char), typeof(int) })]

Patch classes can be public or private, static or not. Patch methods can be public or private but must be static since the patched original method does not have any reference to an instance of your patch class. If you use the manual way to specify the patch methods, your patch methods can even be DynamicMethod's.

Generic Methods

To patch methods with generic signatures, you need to patch specific versions of the method. It is impossible to patch a method in a generic way. Example: AddItem(T item) cannot be patched directly but you can define one patch for i.e. AddItem(string item) and one for AddItem(int item). Pro tip: to patch a large number of variations, create your patches dynamically.

Next: Execution flow

Clone this wiki locally