Forge或NeoForge开发过程记录

Forge或NeoForge开发过程记录

mohuangNPC
2025-12-22 / 0 评论 / 1 阅读 / 正在检测是否收录...

@Mixin 注解

重要的注解,写在类名上,用来表示注入到哪个类

@Mixin(TeleportCommand.class)

@Shadow 注解

当你mixin一个类的时候,然后要用该类的某个内部字段,或者某个方法签名的时候

    //    @Invoker("teleportToPos")
    @Shadow
    private static int teleportToPos(CommandSourceStack p_139026_, Collection<? extends Entity> p_139027_, ServerLevel p_139028_, Coordinates p_139029_, @Nullable Coordinates p_139030_, @Nullable TeleportCommand.LookAt p_139031_) throws CommandSyntaxException {
        throw new AssertionError();
    }

//    @Invoker("teleportToEntity")
    @Shadow
    private static int teleportToEntity(CommandSourceStack source, Collection<? extends Entity> targets, Entity destination) throws CommandSyntaxException {
        throw new AssertionError();
    }

如果有某些无语的问题,比如私有方法中还调用了注入类的内部接口或者各种奇葩方法,那干脆直接方法全部复制一遍也可以

@Inject注解

该注解是直接注入方法

@Inject(method = "register", at = @At("HEAD"),cancellable = true)

method 代表需要注入的方法

at 参数详解

at代表注入位置
HEAD 代表方法头插入
RETURN 代表方法RETURN之前插入
TAIL 在方法的最后一条指令之前注入(在return之前)。
INVOKE 方法调用相关的注入点

@At(value = "INVOKE", target = "目标方法签名")
// 在调用特定方法时注入。
@At(value = "INVOKE", 
    target = "Lnet/minecraft/world/entity/Entity;getX()D")

INVOKE_ASSIGN 在调用方法并将结果赋值给变量时注入。

@At(value = "INVOKE_ASSIGN", target = "目标方法签名")

INVOKE_STRING 在调用方法且栈顶有特定字符串常量时注入。

@At(value = "INVOKE_STRING", 
    target = "目标方法签名",
    args = "ldc=要匹配的字符串")

FIELD 字段访问相关的注入点

@At(value = "FIELD", target = "字段签名")
//在访问(读取或写入)字段时注入。
@At(value = "FIELD", 
    target = "Lnet/minecraft/world/entity/Entity;x:D")

GETFIELD

@At(value = "GETFIELD", target = "字段签名")
在读取字段值时注入。

PUTFIELD

@At(value = "PUTFIELD", target = "字段签名")
在写入字段值时注入。

FIELD_GET

@At(value = "FIELD_GET", target = "字段签名")
同GETFIELD。

FIELD_SET

@At(value = "FIELD_SET", target = "字段签名")
同PUTFIELD。
  1. 数组访问相关的注入点
    ARRAY

    @At(value = "ARRAY")
    在数组访问时注入。

ARRAY_GET

@At(value = "ARRAY_GET")
在读取数组元素时注入。

ARRAY_SET

@At(value = "ARRAY_SET")
在写入数组元素时注入。
  1. 局部变量相关的注入点
    STORE
@At(value = "STORE", ordinal = 0)
在存储到局部变量时注入。

LOAD

@At(value = "LOAD", ordinal = 0)
在从局部变量加载时注入。

JUMP 条件判断相关的注入点

@At(value = "JUMP", opcode = Opcodes.IFNE)
  在条件跳转指令处注入。

IFNULL

@At(value = "IFNULL")
在ifnull指令处注入。

IFNONNULL

@At(value = "IFNONNULL")
在ifnonnull指令处注入。

IF_ACMPEQ, IF_ACMPNE

@At(value = "IF_ACMPEQ")
在对象引用比较时注入。

IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT等

@At(value = "IF_ICMPEQ")
在整数比较时注入。
  1. 常量相关的注入点
    CONSTANT
@At(value = "CONSTANT", args = "doubleValue=0.0")
在加载常量时注入。
  1. 新建对象相关的注入点
    NEW
@At(value = "NEW", target = "类签名")
在创建新对象时注入。
@At(value = "NEW", 
    target = "net/minecraft/world/item/ItemStack")
  1. 异常处理相关的注入点
    THROW
@At(value = "THROW")
在抛出异常时注入。
  1. 特殊注入点
    INVOKE_SPECIAL
@At(value = "INVOKE_SPECIAL", target = "方法签名")
在调用私有方法或构造方法时注入。

INVOKE_VIRTUAL

@At(value = "INVOKE_VIRTUAL", target = "方法签名")
在调用虚方法时注入。

INVOKE_STATIC

@At(value = "INVOKE_STATIC", target = "方法签名")
在调用静态方法时注入。

INVOKE_INTERFACE

@At(value = "INVOKE_INTERFACE", target = "方法签名")
在调用接口方法时注入。
  1. 字节码指令相关的注入点
    INVOKE_DYNAMIC
@At(value = "INVOKE_DYNAMIC")
在invokedynamic指令处注入。

INSTANCEOF

@At(value = "INSTANCEOF")
在instanceof检查时注入。

常用的组合参数
ordinal参数
指定第几次出现的位置:

@At(value = "INVOKE", target = "...", ordinal = 0)
shift参数
调整注入位置:

Shift.BEFORE: 在目标指令之前

Shift.AFTER: 在目标指令之后

Shift.BY: 偏移指定数量

@At(value = "INVOKE", target = "...", shift = Shift.BEFORE)

by参数
与Shift.BY一起使用:

@At(value = "INVOKE", target = "...", shift = Shift.BY, by = 2)

cancellable 参数

它控制是否允许取消(跳过)原始方法的执行

@Inject(method = "register", at = @At("HEAD"),cancellable = true)
    private static void modifyCommandPermissions(CommandDispatcher<CommandSourceStack> dispatcher, CallbackInfo ci) {
      ci.cancel();
    }
0

评论 (0)

取消

Warning: file_put_contents(/var/www/html/rss.xml): failed to open stream: Permission denied in /var/www/html/usr/plugins/CustomRSS/Plugin.php on line 149