Mixin中的Inject points

Leawsic 发布于 2025-11-10 49 次阅读


在Minecraft的Mod开发中,Mixin是一个非常强大的工具,它允许开发者在不修改原始代码的情况下修改游戏的行为。Mixin提供了多种注入点(Inject Point),每种都有其特定的作用和使用场景。

Mixin官方文档 注入点Wiki

常见的注入点类型

1. HEAD

  • 作用: 在目标方法的开头注入代码
  • 使用场景: 需要在方法执行前进行某些操作,如参数检查、初始化等
  • 示例:
@Inject(at = @At("HEAD"), method = "targetMethod")
private void injectAtHead(CallbackInfo ci) {
    // 在目标方法开始前执行的代码
}

2. RETURN

  • 作用: 在目标方法的所有返回点之前注入代码
  • 使用场景: 需要在方法返回前执行清理工作或修改返回值
  • 示例:
@Inject(at = @At("RETURN"), method = "targetMethod")
private void injectAtReturn(CallbackInfo ci) {
    // 在方法每个return语句前执行的代码
}

3. TAIL

  • 作用: 在目标方法的最后一个返回语句之前注入代码
  • 使用场景: 只需要在方法正常结束时执行代码,而不是在每个返回点都执行
  • 示例:
@Inject(at = @At("TAIL"), method = "targetMethod")
private void injectAtTail(CallbackInfo ci) {
    // 在方法最后return语句前执行的代码
}

4. INVOKE

  • 作用: 在调用其他方法之前注入代码
  • 使用场景: 需要在特定方法调用前后执行代码
  • 示例:
@Inject(at = @At(value = "INVOKE", target = "Lsome/Class;methodName()V"), method = "targetMethod")
private void injectAtInvoke(CallbackInfo ci) {
    // 在调用some.Class.methodName()之前执行的代码
}

5. FIELD

  • 作用: 在读取或写入字段之前注入代码
  • 使用场景: 需要监控或修改字段访问
  • 示例:
@Inject(at = @At(value = "FIELD", target = "Lsome/Class;fieldName:I"), method = "targetMethod")
private void injectAtField(CallbackInfo ci) {
    // 在访问some.Class.fieldName字段之前执行的代码
}

6. NEW

  • 作用: 在创建新对象(new操作符)之前注入代码
  • 使用场景: 需要监控或替换对象创建过程
  • 示例:
@Inject(at = @At(value = "NEW", target = "java/lang/StringBuilder"), method = "targetMethod")
private void injectAtNew(CallbackInfo ci) {
    // 在创建StringBuilder对象之前执行的代码
}

7. JUMP

  • 作用: 在跳转操作(如if、for、while等)之前注入代码
  • 使用场景: 需要监控控制流变化

8. INVOKE_STRING

  • 作用: 在调用接受单个字符串参数并返回void的方法之前注入代码
  • 使用场景: 特别适用于监控性能分析调用,如Profiler.startSection()
  • 示例:
@Inject(at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;startSection(Ljava/lang/String;)V"), method = "targetMethod")
private void injectAtInvokeString(CallbackInfo ci) {
    // 在调用Profiler.startSection(String)之前执行的代码
}

区别总结

  1. 执行时机不同: HEAD在方法开始执行,TAIL在方法正常结束前,RETURN在所有返回点前
  2. 执行次数不同: HEAD和TAIL只执行一次,RETURN可能执行多次(如果方法有多个返回点)
  3. 适用场景不同:
  • HEAD适用于初始化或前置检查
  • TAIL/RETURN适用于清理或后置处理
  • INVOKE适用于拦截特定方法调用
  • FIELD适用于监控字段访问

根据你的具体需求选择合适的注入点,可以让代码更加精确和高效。

江畔何人初见月?江月何年初照人?灯火葳蕤处……
最后更新于 2026-04-12