消息协议

[!INFO] 注册真源:PacketHandlerBackpack.initialise()(de.eydamos.backpack.network) 通道名:Constants.CHANNEL 无关,实际用的是 Constants.MOD_ID = "Backpack"

基本信息

属性 值
通道创建 NetworkRegistry.INSTANCE.newSimpleChannel(Constants.MOD_ID)
通道名 Backpack(modid 原样,大写开头)
消息总数 10(6 个 C→S,4 个 S→C)
判别号 C→S 使用 0…5,S→C 使用 10…13

编号刻意留出 6…9 的空档,便于日后插入新的 S→C 消息而不与既有 ID 冲突。

完整消息表

客户端 → 服务端(Side.SERVER)

判别号 消息类 用途
0 MessageRenameBackpack 提交背包重命名
1 MessageOpenGui 请求打开某个 GUI
2 MessageGuiCommand GUI 内命令(Constants.GuiCommands)
3 MessagePersonalBackpack 个人背包数据同步
4 MessageRecipe 提交 / 推送合成配方
5 MessageBackpackInfoRequest 请求背包槽位占用信息

服务端 → 客户端(Side.CLIENT)

判别号 消息类 用途
10 MessageOpenPersonalSlot 打开个人穿戴槽界面
11 MessageOpenBackpack 打开背包容器界面
12 MessagePersonalBackpack 下发个人背包存档
13 MessageBackpackInfo 下发背包槽位占用统计

MessagePersonalBackpack 双向复用

MessagePersonalBackpack 是唯一在两个方向都注册的消息类 (判别号 3 与 12)。其 onMessage(:51)用世界/连接侧的 BackpackUtil.isServerSide() 分派到两套逻辑,而不是 ctx.sideForSideInteraction():

  • 收到包的接收端是服务端时:用 ctx 里的 playerUUID 经 resolveOnlinePlayer 定位在线玩家,取出其 PlayerSave 中的 个人背包栈,并按请求者身份裁剪返回内容(源码注释: Only the requester needs their own backpack UUID)。
  • 接收端是客户端时:把个人背包栈写入本地背包存档用于渲染。

MessageOpenBackpack:81 在构造时写入 NBT:

NBTUtil.setBoolean(nbtTagCompound, Constants.NBT.INTELLIGENT, message.intelligent);

即打开背包的请求里顺带携带了 intelligent 标记, 由服务端在 BackpackSave 中落盘 —— 这与 智能工作台背包配方 描述的 标记机制是同一套 NBT 键。

Constants.GuiCommands 子命令

MessageGuiCommand 承载的 GUI 内命令由 Constants.GuiCommands 定义:

常量 值 含义
CLEAR 1 清空当前容器
SAVE 2 立即保存背包
PREV 3 切换到上一页/上一页签
NEXT 4 切换到下一页/下一页签

PREV / NEXT 对应背包 GUI 内的标签页切换(见 高级容器界面 的标签系统)。

Constants.Guis 界面常量

MessageOpenGui 的判别参数由 Constants.Guis 定义:

常量 值 对应界面
OPEN_PERSONAL_BACKPACK 0 个人背包本体
OPEN_PERSONAL_SLOT 1 个人穿戴槽

与 个人背包快捷键 发送的常量一致。

初始化时机

PacketHandlerBackpack 在字段初始化时就创建了通道:

public static PacketHandlerBackpack packetHandler = new PacketHandlerBackpack();   // Backpack.java 静态字段
public final SimpleNetworkWrapper networkWrapper =
        NetworkRegistry.INSTANCE.newSimpleChannel(Constants.MOD_ID);

initialise() 单独调用以注册各消息。通道对象在类加载期即建立, Backpack 类的静态字段 packetHandler 保证在任何 @Mod 方法之前完成初始化。

版本检查

preInit 末尾通过 IMC 通道注册版本检查:

FMLInterModComms.sendRuntimeMessage(Constants.MOD_ID, "VersionChecker",
        "addVersionCheck", Constants.UPDATE_FILE);

UPDATE_FILE 为 http://www.eydamos.de/minecraft/backpack/version.json(HTTP 而非 HTTPS)。

相关条目