@Target(value=METHOD)
@Retention(value=RUNTIME)
public @interface ModifyArg
method(). This type of injection
provides a lightweight mechanism for changing a single argument of a target
method invocation. To affect multiple arguments at once, use ModifyArgs instead.
Consider the following method call:
// x, y and z are of type float someObject.setLocation(x, y, z, true);
Let us assume that we wish to modify the y value in the method call. We know that the arguments are floats and that the y value is the second (index = 1) float argument. Thus our injector requires the following signature:
@ModifyArg(method = "...", at = ..., index = 1)
private float adjustYCoord(float y) {
return y + 64.0F;
}
The callback consumes the original value of y and returns the adjusted value.
@ModifyArg can also consume all of the target method's arguments if required, to provide additional context for the callback. In this case the arguments of the callback should match the target method:
@ModifyArg(method = "...", at = ..., index = 1)
private float adjustYCoord(float x, float y, float z, boolean interpolate) {
return (x == 0 && y == 0) ? 0 : y;
}| Modifier and Type | Required Element and Description |
|---|---|
At |
at
An
At annotation which describes the InjectionPoint in
the target method. |
java.lang.String[] |
method
String representation of one or more
target selectors which identify the target
methods. |
| Modifier and Type | Optional Element and Description |
|---|---|
int |
allow
Injection points are in general expected to match every candidate
instruction in the target method or slice, except in cases where options
such as
At.ordinal() are specified which naturally limit the number
of results. |
java.lang.String |
constraints
Returns constraints which must be validated for this injector to
succeed.
|
int |
expect
Like
require() but only enabled if the
mixin.debug.countInjections option is set
to true and defaults to 1. |
int |
index
Gets the argument index on the target to set.
|
boolean |
remap
|
int |
require
In general, injectors are intended to "fail soft" in that a failure to
locate the injection point in the target method is not considered an
error condition.
|
Slice |
slice
|
public abstract java.lang.String[] method
target selectors which identify the target
methods.public abstract At at
At annotation which describes the InjectionPoint in
the target method. The specified InjectionPoint must only
return MethodInsnNode instances
and an exception will be thrown if this is not the case.At which identifies the target method invocationpublic abstract Slice slice
public abstract int index
Gets the argument index on the target to set. It is not necessary to set this value if there is only one argument of the modifier type in the hooked method's signature. For example if the target method accepts a boolean, an integer and a String, and the modifier method accepts and returns an integer, then the integer parameter will be automatically selected.
The index is zero-based.
public abstract boolean remap
ModifyArg methods since it is
anticipated that in general the target of a ModifyArg annotation
will be an obfuscated method in the target class. However since it is
possible to also apply mixins to non-obfuscated targets (or non-
obfuscated methods in obfuscated targets, such as methods added by Forge)
it may be necessary to suppress the compiler error which would otherwise
be generated. Setting this value to false will cause the
annotation processor to skip this annotation when attempting to build the
obfuscation table for the mixin.public abstract int require
However, this behaviour is not always desirable. For example, if your
application depends on a particular injection succeeding you may wish to
detect the injection failure as an error condition. This argument is thus
provided to allow you to stipulate a minimum number of successful
injections for this callback handler. If the number of injections
specified is not achieved then an InjectionError is thrown at
application time. Use this option with care.
public abstract int expect
require() but only enabled if the
mixin.debug.countInjections option is set
to true and defaults to 1. Use this option during debugging to
perform simple checking of your injectors. Causes the injector to throw
a InvalidInjectionException if the expected number of injections
is not realised.public abstract int allow
At.ordinal() are specified which naturally limit the number
of results.
This option allows for sanity-checking to be performed on the results
of an injection point by specifying a maximum allowed number of matches,
similar to that afforded by Group.max(). For example if your
injection is expected to match 4 invocations of a target method, but
instead matches 5, this can become a detectable tamper condition by
setting this value to 4.
Setting any value 1 or greater is allowed. Values less than 1 or less
than require() are ignored. require() supercedes this
argument such that if allow is less than require the
value of require is always used.
Note that this option is not a limit on the query behaviour of this injection point. It is only a sanity check used to ensure that the number of matches is not too high
public abstract java.lang.String constraints
ConstraintParser.Constraint for details of constraint formats.