Table of Contents

Перенаправления методов

Редиректоры методов могут использовать Точки внедрения:

INVOKE

Точка внедрения INVOKE используется для вызовов “target” в “method”, что означает, что его можно использовать для перенаправления метода непосредственно перед его вызовом.

Перенаправление статического метода

Редиректоры статических методов должен иметь те же параметры, что и target.

Перенаправление вызова ItemStack::fromTag(ListTag) в SimpleInventory::readTags возращает null:

  1. @Mixin(SimpleInventory.class)
  2. abstract class SimpleInventoryMixin {
  3. @Redirect(method = "readTags",
  4. at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/item/ItemStack;fromTag(Lnet/minecraft/nbt/ListTag;)Lnet/minecraft/item/ItemStack;"))
  5. private static ItemStack returnNull(ListTag tag) {
  6. return null;
  7. }
  8. }

Перенаправление метода экземпляра

Редиректоры методов экземпляра аналогичны редиректорам статических методов, но они должны иметь дополнительный параметр в начале своих списков параметров для объектов, для которых вызываются их “целевые” объекты.

Перенаправление вызова Entity::dropItem(ItemConvertible, int) в Entity::dropItem(ItemConvertible) делает так, что при выкидывании алмазы будут заменяться на воздух:

  1. @Mixin(Entity.class)
  2. abstract class EntityMixin {
  3. @Redirect(method = "dropItem",
  4. at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;dropItem(Lnet/minecraft/item/ItemConvertible;I)Lnet/minecraft/entity/ItemEntity;"))
  5. private ItemEntity replaceDroppedItem(Entity droppingEntity, ItemConvertible item, int yOffset) {
  6. return droppingEntity.dropItem(item == Items.DIAMOND ? Items.AIR : item, yOffset);
  7. }
  8. }

INVOKE_STRING

Точка внедрения “INVOKE_STRING” используется для сопоставления вызовов “target” в “method”, если “target” является методом с одним параметром “String” и ему передается литерал “String”. Литерал “String” для захвата должен быть указан в свойстве “args” для “At”.

Перенаправление вызова Profiler::push с помощью “tick”, переданного ему в MinecraftClient::render изменяет location, переданное в указанном вызове:

  1. @Mixin(MinecraftClient.class)
  2. abstract class MinecraftClientMixin {
  3. @Redirect(method = "render",
  4. at = @At(value = "INVOKE_STRING",
  5. target = "Lnet/minecraft/util/profiler/Profiler;push(Ljava/lang/String;)V",
  6. args = "ldc=tick"))
  7. private void redirectPush(Profiler profiler, String location) {
  8. profiler.push("modified tick");
  9. System.out.println(location);
  10. }
  11. }