Minecraft Fabric 1.21.1客户端向服务器发送数据方法咨询
Fabric 1.21.1 客户端向服务器发送数据包实现方案
核心类与方法说明
Fabric 1.21.1中实现客户端向服务器发数据,核心依赖以下类/方法:
TypedCustomPayload:替代旧版CustomPayload,作为数据包的标识与内容载体(1.21+版本旧版已过时)PacketByteBuf:数据序列化/反序列化容器,通过PacketByteBufs.create()创建实例ClientPlayNetworking:客户端发送数据包的入口类,调用send()方法发送TypedCustomPayload实例
完整实现步骤与示例
1. 定义并注册自定义Payload类型
先创建常量定义数据包唯一标识,同时完成客户端与服务器的接收器注册:
public class MyModNetworking { // 格式:modid:packet_name,确保唯一 public static final Identifier EXAMPLE_PACKET_ID = new Identifier("mymod", "player_action"); // 定义Payload的编解码器,负责数据读写 public static final TypedCustomPayload.Codec<PlayerActionPayload> ACTION_CODEC = TypedCustomPayload.codecOf( PlayerActionPayload::write, PlayerActionPayload::new ); // 注册接收器,需在Mod初始化阶段调用 public static void registerPackets() { // 服务器端接收器:处理客户端发来的数据包 ServerPlayNetworking.registerGlobalReceiver(EXAMPLE_PACKET_ID, ACTION_CODEC, (payload, context) -> { // 切换到服务器主线程执行逻辑 context.server().execute(() -> { ServerPlayerEntity player = context.player(); String action = payload.getAction(); // 这里写服务器端处理逻辑,比如记录操作、修改玩家状态 player.sendMessage(Text.literal("收到客户端操作:" + action), false); }); }); // 客户端接收器(可选):处理服务器返回的响应 ClientPlayNetworking.registerGlobalReceiver(EXAMPLE_PACKET_ID, ACTION_CODEC, (payload, context) -> { context.client().execute(() -> { MinecraftClient.getInstance().player.sendMessage(Text.literal("服务器响应:" + payload.getAction()), false); }); }); } }
2. 实现自定义Payload类
创建继承自TypedCustomPayload的类,实现数据读写逻辑:
public record PlayerActionPayload(String action) implements TypedCustomPayload { // 返回对应的数据包标识 @Override public Id<? extends TypedCustomPayload> getId() { return MyModNetworking.EXAMPLE_PACKET_ID; } // 将数据写入PacketByteBuf public void write(PacketByteBuf buf) { buf.writeString(this.action); } // 从PacketByteBuf读取数据构造实例 public PlayerActionPayload(PacketByteBuf buf) { this(buf.readString()); } }
3. 客户端发送数据包的调用示例
在客户端触发逻辑(比如按键事件、GUI按钮点击)中发送数据包:
// 构造Payload实例 PlayerActionPayload payload = new PlayerActionPayload("打开背包"); // 发送到服务器 ClientPlayNetworking.send(payload);
常见问题解决
类型不匹配错误
- 确认使用
TypedCustomPayload而非旧版CustomPayload,1.21+版本ClientPlayNetworking.send()仅接受前者 - 确保Payload类的
getId()返回的Identifier与注册时完全一致
Payload创建错误
- 禁止直接实例化旧版
CustomPayload,必须通过自定义类继承TypedCustomPayload实现 - 注册时必须使用对应的编解码器,保证序列化/反序列化逻辑匹配
初始化注意事项
在Mod的初始化类中调用注册方法:
public class MyMod implements ModInitializer { @Override public void onInitialize() { MyModNetworking.registerPackets(); } }
内容的提问来源于stack exchange,提问作者mybom
相关产品推荐
相关产品推荐

