Fabric模组开发:如何修改PlayerMoveC2SPacket变量赋值逻辑?
修改PlayerMoveC2SPacket构造函数坐标赋值的可行方案
针对你想修改net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket构造函数中x、y、z坐标赋值逻辑的需求,不推荐使用@Overwrite(构造函数重载多、易冲突且匹配难度高),推荐用Mixin的@Redirect注解实现精准拦截修改,具体步骤如下:
1. 编写Mixin类
创建一个Mixin类,拦截构造函数中对x、y、z字段的赋值操作,替换为取整后的数值:
@Mixin(PlayerMoveC2SPacket.class) public class PlayerMoveC2SPacketMixin { // 拦截x字段的赋值 @Redirect( method = "<init>(DDDZ)V", at = @At(value = "FIELD", target = "Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;x:D", ordinal = 0) ) private double redirectX(PlayerMoveC2SPacket instance, double originalValue) { return (double) Math.round(originalValue); } // 拦截y字段的赋值 @Redirect( method = "<init>(DDDZ)V", at = @At(value = "FIELD", target = "Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;y:D", ordinal = 0) ) private double redirectY(PlayerMoveC2SPacket instance, double originalValue) { return (double) Math.round(originalValue); } // 拦截z字段的赋值 @Redirect( method = "<init>(DDDZ)V", at = @At(value = "FIELD", target = "Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;z:D", ordinal = 0) ) private double redirectZ(PlayerMoveC2SPacket instance, double originalValue) { return (double) Math.round(originalValue); } }
- 说明:
method = "<init>(DDDZ)V"指定拦截的是接收三个double坐标和一个boolean落地状态的构造函数,对应原版中直接赋值x/y/z的构造函数;若你需要修改其他重载构造函数,可替换对应的方法签名。@Redirect会拦截对目标字段的赋值操作,将原本的赋值参数替换为我们处理后的取整数值,其余变量的赋值逻辑不受影响。
2. 注册Mixin
在你的模组fabric.mod.json文件中添加Mixin配置:
{ "schemaVersion": 1, "id": "your_mod_id", "version": "1.0.0", // 其他配置项... "mixins": [ "mixins.your_mod_id.json" ] }
然后创建mixins.your_mod_id.json文件(放在resources目录下),指定要加载的Mixin类:
{ "required": true, "package": "com.your_package_path.mixin", // 替换为你的Mixin类所在包路径 "compatibilityLevel": "JAVA_17", "mixins": [ "PlayerMoveC2SPacketMixin" ], "injectors": { "defaultRequire": 1 } }
为什么@Overwrite会出错?
@Overwrite是直接覆盖整个方法/构造函数,但构造函数存在多个重载,容易出现签名匹配错误;同时这种方式会完全替换原构造函数逻辑,不仅容易和其他模组的Mixin冲突,还会丢失原构造函数中你不需要修改的变量赋值逻辑,风险较高。而@Redirect是精准拦截局部赋值操作,对原代码侵入性更低,兼容性更好。
内容的提问来源于stack exchange,提问作者Codemob
相关产品推荐
相关产品推荐

