跳到正文
烈焰甘蔗Wiki

PacketHandler(网络通道与注册表)

事实基准:harvestcraft-1.3.14-GTNH.jar(MC 1.7.10 / Forge 10.13.4.1614)CFR 0.152 反编译源码。

概览

Pam’s HarvestCraft 的整个网络层是 FML SimpleNetworkWrapper(cpw.mods.fml.common.network.simpleimpl),没有使用旧版 FMLEmbeddedChannel / 自定义 payload。

属性 值 来源
通道实现 NetworkRegistry.INSTANCE.newSimpleChannel(...) → SimpleNetworkWrapper PacketHandler.java:14
通道名 "harvestcraft" PacketHandler.java:14
字段 PacketHandler.INSTANCE(public static final) PacketHandler.java:14
初始化时机 HarvestCraft.preInit() 第 92 行调用 PacketHandler.init() HarvestCraft.java:92
已注册包数 3 PacketHandler.java:17-19
判别器占用 0、1、2(连续,无空洞) PacketHandler.java:17-19

注册表(权威来源:PacketHandler.init())

init() 的全部内容就是下面三行 registerMessage 调用——PacketHandler.java:17-19:

判别器 包类 目标侧 Handler
0 MessageMarketBrowse Side.SERVER 自身(IMessageHandler<MessageMarketBrowse, IMessage>)
1 MessageMarketBuy Side.SERVER 自身
2 MessageMarketClosed Side.SERVER 自身

三个包全部是客户端 → 服务端(Side.SERVER 表示"在服务端处理")。本模组没有任何注册为 Side.CLIENT 的包:服务端从不主动向客户端推送本模组自定义数据,市场 UI 的同步完全靠原版方块实体 / GUI 同步机制。

三个包都使用自处理模式(implements IMessage, IMessageHandler<自身, IMessage>),不经过 SimpleNetworkWrapper.registerMessage(handler, requestMessageType, discriminator, side) 的四参分离写法。

方向与调用点

方向 触发点 来源
客户端 → 服务端 GuiMarket.java:80、:82、:85 发送 MessageMarketBuy PacketHandler.INSTANCE.sendToServer(...)
客户端 → 服务端 GuiMarket.java:93 发送 MessageMarketClosed PacketHandler.INSTANCE.sendToServer(...)

全部 4 个发送点都在 GuiMarket 里,即只有打开市场 GUI 时才会产生本模组的网络流量。

缺陷:注册了但没有发送方的包

MessageMarketBrowse(判别器 0)在 PacketHandler 里注册、在自身 onMessage 里实现了完整的服务端处理逻辑,但客户端没有任何一处构造并发送它——全模组对 MessageMarketBrowse 的引用只有 PacketHandler.java:6(import)、PacketHandler.java:17(注册)和它自己的类定义。

  • 处理器逻辑:MessageMarketBrowse.java:46-55(定位 TileEntityMarket → setBrowsingInfo(itemNum) → 刷新 GUI)。
  • 实际可达性:不可达。市场翻页功能实际由 TileEntityMarket 自身的方块实体同步承担。

详见 MessageMarketBrowse。

缺陷:同名通道被创建了两次

位置 代码 后果
PacketHandler.java:14 NetworkRegistry.INSTANCE.newSimpleChannel("harvestcraft") → PacketHandler.INSTANCE 承载全部 3 个包注册
HarvestCraft.java:162 NetworkRegistry.INSTANCE.newSimpleChannel(modid) → HarvestCraft.INSTANCE 完全未被使用

HarvestCraft.java:59 声明了 public static final SimpleNetworkWrapper INSTANCE,静态初始化块 HarvestCraft.java:162 用同一个 modid(= "harvestcraft",见 HarvestCraft.java:59)又建了一个通道。

  • HarvestCraft.INSTANCE 在全模组没有任何读取点(除声明与赋值外无引用),因此没有包注册到它上面。
  • 两个 wrapper 用了相同的通道名字符串。本机没有 FML 1.7.10 的源码,无法从本仓库判定 NetworkRegistry.INSTANCE.newSameChannel 对重名通道的处理(是复用、覆盖还是抛异常),因此不断言这会在运行时抛错;只记录"同名通道被创建两次"这一源码事实。

另一套未使用的抽象:AbstractPacket

AbstractPacket(encodeInto / decodeInto / handleClientSide / handleServerSide)是旧版自定义 payload 方案的基类,共有 5 个子类,全部是空方法。详见 AbstractPacket 与 旧版空壳包。

相关条目

浏览全部模组