5 | Injections
How to use and apply the @Inject annotation to your code. Also tells you how to read and write all the parameters housed inside the annotation.
What is Inject?
The @Inject annotation injects code into a specified target method.
Parameters, in order:
All target method parameters
CallbackInfo(forvoidreturn type on target) orCallbackInfoReturnable<R>
Return type: void
Consider the following code:
public void target() {
Dummy.getInstance().dummy("foo");
}If we were to inject into it, we would use something like this:
@Inject(method = "target()V", at = @At(value = "INVOKE", target = "Lnet/example/Dummy;dummy(Ljava/lang/String;)V"))
private void mixin(CallbackInfo ci) {
injectedCode();
}It might be a little hard to understand at first, so lets break it down.
@Inject(
method = "target()V",
at = @At(value = "INVOKE", target = "Lnet/example/Dummy;dummy(Ljava/lang/String;)V")
)The first parameter is method , it tells the mixin what method we're going to modify
Now for the @At statement:
value = "INVOKE"This tells the mixin that we're looking for the invocation of the method.
target = "Lnet/example/Dummy;dummy()V")This tells the mixin where the method we're modifying is located
Now, lets break down the syntax of "Lnet/example/Dummy;dummy()V"
The L represents a class name, so Lnet/example/Dummy; is the path to the class where the method dummy , is located.
The dummy represents the method name inside the Dummy class.
Inside the brackets, we see another class (Ljava/lang/String;), this is the path to the String class, as String is actually a class, just one in the standard library, which doesn't need to be imported, everything inside these brackets are the parameters for dummy
Just after the brackets there is a V, which simply means void specifying that the println function doesn't return any value
The table below shows the different characters with their different meanings.
FieldType term
Type
Interpretation
B
byte
signed byte
C
char
Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16
D
double
double-precision floating-point value
F
float
single-precision floating-point value
I
int
integer
J
long
long integer
L
ClassName;
reference an instance of class ClassName
S
short
signed short
Z
boolean
true or false
[
reference
one array dimension
Inject, cancelable
Consider the following code:
Example mixin:
Lets dissect this; First, we start off with defining our method, in this case, it's target() then we define the @At statement, which houses our value and our target.
Oh, but what's that? It's the cancellable statement!
The cancellable statement, can only be used at TAIL or RETURN . It's job is to inject code into a target method, and if ci.cancel is called, it returns after the mixin is done executing.
So, if we were to apply our mixin to our target() function, we would have a result similar, if not exactly like this:
Congrats! Now you hold the power of injecting code to your heart's content!
Last updated
Was this helpful?