消息协议
[!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)。