网络管线
基本信息
| 属性 | 值 |
|---|---|
| 管线类 | PacketPipeline(MessageToMessageCodec<FMLProxyPacket, AbstractPacket>) |
| 通道名 | TMechWorks(大写 W,与 modid TMechworks 大小写不一致) |
| 基类 | mantle.common.network.AbstractPacket |
| 已注册包 | 1(PacketDrawbridge) |
| discriminator | 0(自动分配,逻辑排序) |
| 数据格式 | 13 字节(3×writeInt + writeByte) |
| 初始化 | TMechworks.preInit → packetPipeline.initalise()(TMechworks.java:74) |
| 后初始化 | TMechworks.postInit → packetPipeline.postInitialise() |
| 编码风格 | NIO(ByteBuf),非 1.7.10 常见的 Packet250CustomPayload |
PacketDrawbridge
network/packet/PacketDrawbridge.java —— 唯一的数据包,单向 S2C→C2S,用于在 GUI 中设置 Drawbridge 的放置方向。
| 字段 | 类型 | 编码 | 字节 |
|---|---|---|---|
x |
int | buffer.writeInt(x) |
4 |
y |
int | buffer.writeInt(y) |
4 |
z |
int | buffer.writeInt(z) |
4 |
direction |
byte | buffer.writeByte(direction) |
1 |
| 合计 | 13 |
处理
handleServerSide(EntityPlayer)(:53-66):
World world = player.worldObj;
TileEntity te = world.getTileEntity(x, y, z);
if (te instanceof DrawbridgeLogic) {
((DrawbridgeLogic) te).setPlacementDirection(direction);
te.markDirty();
} else if (te instanceof AdvancedDrawbridgeLogic) {
((AdvancedDrawbridgeLogic) te).setPlacementDirection(direction);
}
handleClientSide(EntityPlayer) 是空方法 —— 该包纯上行(C2S),客户端不发也不处理。
发送方:DrawbridgeGui.updateServer(byte) / AdvDrawbridgeGui.updateServer(byte) → TMechworks.packetPipeline.sendToServer(new PacketDrawbridge(...))(client/gui/DrawbridgeGui.java:91-92)。
数值
| 数值 | 值 |
|---|---|
| 通道名 | TMechWorks(大写 W,非 modid TMechworks) |
| 包数量 | 1 |
| discriminator | 0 |
| 数据长度 | 13 字节 |
| 方向 | C2S 单向(handleClientSide 空) |
| 容量上限 | 256(registerPacket 的 size() > 256 检查) |
| 重复注册检查 | 有(packets.contains(clazz)) |
| postInit 后注册 | 拒绝(isPostInitialised) |
源码缺陷
- 通道名与 modid 大小写不一致:modid 是
TMechworks,而NetworkRegistry.INSTANCE.newChannel传入"TMechWorks"(network/packet/PacketPipeline.java:119)。FML 会把通道名转小写做内部匹配,当前可用;但若与其他 mod 的通道名仅大小写不同会发生冲突。源码无注释说明。 registerPacket的 3 处失败路径全部不记日志(:49-65):三段// You should log here!!注释后直接return false。若注册失败,discriminator 会错位导致客户端与服务端解码错包,但无任何日志可查。这是从 CPW 模板复制来的已知缺陷。- 容量检查是
> 256而非>= 256(:50):允许注册到 257 个包,此时第 257 个包的 discriminator 会溢出 byte。边界 off-by-one。 handleServerSide的两个分支重复代码(:58-65):DrawbridgeLogic与AdvancedDrawbridgeLogic各写一遍setPlacementDirection,可用共同父接口IDrawbridgeLogicBase消除(该接口确实存在)。AdvancedDrawbridgeLogic分支缺markDirty():DrawbridgeLogic分支调了te.markDirty(),Advanced 分支没有 —— 改方向后服务端可能不及时持久化该 TE。- 两个
updateServer内保留 8 行注释掉的Packet250CustomPayload旧实现(client/gui/DrawbridgeGui.java:81-89、client/gui/AdvDrawbridgeGui.java:145-153):两处完全相同的 9 行死代码。 PacketDrawbridge有两个构造器但只有 1 个包:PacketDrawbridge()无参(供解码用)+PacketDrawbridge(x, y, z, direction)(供编码用),这是标准做法,非缺陷。packets是LinkedList而非ArrayList:包数量为 1,无性能影响。- 无任何包用于同步 Drawbridge 的
extension/active状态:GUI 界面不显示伸展进度,玩家只能靠观察方块判断。
相关条目
- Drawbridge GUI - 本管线的唯一调用方
- Drawbridge -
setPlacementDirection的接收方 - Advanced Drawbridge - 第二个接收方
- tinkersconstruct - Mantle 作为本管线基类的来源(TCon 依赖链)