Skip to content
Kiooeht edited this page Jul 25, 2024 · 3 revisions

If you have not read the SpirePatch documentation, read that before continuing. This page does not cover how to use SpirePatch/SpirePatch2, it only covers the differences between SpirePatch and SpirePatch2.

Differences

  • Instead of the @SpirePatch annotation, use the @SpirePatch2 annotation on the patch class.
  • Patch methods are not passed all arguments of the original method (as well as the instance if the original method is not static). Instead, patch methods are passed arguments of the original method by name.
    • If the patch method has a parameter with the same as a parameter of the original method, that parameter will be passed the value of that original parameter.
    • If the original method is not static, the patch method may include a parameter with the name __instance to receive the instance.
  • Because parameters are matched by name, you may choose to exclude any parameters you do not with to use and those you do include may be in any order you wish.
  • __args By naming a parameter __args your patch will be passed all of the original parameters as an array. The type of the parameter is Object[].

Postfix

  • To receive the original return value, include a parameter to your patch method with the name __result.

Insert

  • localvars are also passed by name. If you use localvars you must include a parameter with a name matching the localvar name. (See: Insert localvars Example).

Examples

For all these examples, we will be patching the foo method of this example class.

public class Foobar
{
	private boolean b;

	public String foo(int i, float f, String s)
	{
		String a = "a";
		int foo = 4;
		if (i > 7) {
			foo = 9;
			a += s;
		}
		return foo + f;
	}
}

Parameter Exclusion

In this example, we do not include the i or f parameters, only including the instance and s parameter.

public static void Prefix(Foobar __instance, String s)
{
	//
}

Parameter Ordering

In this example, we include all parameters, the instance, as well as the result (See: Postfix result). However, we include the parameters in a different order than they appear in the original method's parameter list and intersperse the __instance and __result parameters.

public static void Postfix(int i, Foobar __instance, String s, String __result, float f)
{
	//
}

Private Field Captures

Again, the parameters are out of order and some are missing (notably the instance parameter is missing). However we have also included the private variable b using Private Field Captures, which may also appear in any position in the parameter list.

public static void Postfix(float f, boolean ___b, int i)
{
	//
}

Insert localvars Example

As with normal parameters, localvars paramters may be included in any order or even interspersed with the normal parameters.

@SpireInsertPatch(
	rloc=4,
	localvars={"foo", "a"}
)
public static void Insert(String a, float q, @ByRef int[] foo)
{
	if (q > 0) {
		foo[0] = 3;
		System.out.println(a);
	}
}

__args Example

__args is an array of Objects containing all the original arguments in their original order. In this example, __args will be [Integer, Float, String] (the primitive types are boxed into their object types).

public static void Postfix(Foobar __instance, Object[] __args)
{
	//
}