Mixinとは
MixinはSpongePoweredによって開発された既存のソースコードを動的に変更することができるものである。
@Mixinについて
1.20になってforgeに追加された。
簡単な使い方
package examplemod;
import net.minecraft.client.player.LocalPlayer;
import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LocalPlayer.class)
public class LocalPlayerMixin {
@Shadow @Final public static Logger LOGGER;
@Inject(method = "getPermissionLevel", at = @At(value = "HEAD"))
public void getPermissionLevelMixin(CallbackInfoReturnable<Integer> cir) {
LOGGER.info("INJECT TO HEAD @ `getPermissionLevel`");
}
}
@Mixin
@Mixin(ターゲットクラス.class)
挿入したいメソッドのあるクラス(この記事ではターゲットクラス
とする)をvalue
に置く
@Shadow
@Shadow
: ターゲットクラスのフィールド(同じ名前である必要がある)
LocalPlayer
クラスでは1行目に
public static final Logger LOGGER = LogUtils.getLogger();
と既に定義されているため、それを使うためにShadowアノテーションを置く
@Final
@Final
: フィールドにfinalがついていた時のみつける
先ほどのLOGGER
フィールドにはfinal
がついているため、ターゲットクラスではfinalがついているということを記す。
@Inject
@Inject(method = "メソッド名", at = @At(value = "挿入場所"))
: このmixinの醍醐味
ただし、指定が少し難しい
メソッド名:挿入したいメソッド名の名前。今回はLocalPlayer#getPermissionLevel()
挿入場所:(空白部分は自分はよくわかっていない)
value | 自分の認識 |
---|---|
HEAD | メソッドの一番初めに実行 |
RETURN | |
TAIL | 指定したメソッドの最後のreturn の直前で実行 |
INVOKE | |
INVOKE_ASSIGN | |
FIELD | |
NEW | |
INVOKE_STRING |
INVOKE とほぼ同じ |
CONSTANT |
最後に
忘れないようにメモの感覚で残しています。間違っていたところがあれば指摘していただけると助かります。