封包编解码
基本信息
| 属性 | 值 |
|---|---|
| 编解码器 | net.bdew.lib.network.SerializedMessageCodec[T <: NetChannel] |
| Netty 基类 | MessageToMessageCodec[FMLProxyPacket, BaseMessage[T]] |
| 通道封装 | net.bdew.lib.network.NetChannel |
| 消息基类 | net.bdew.lib.network.BaseMessage |
| 序列化格式 | Java 原生序列化(ObjectOutputStream / ObjectInputStream) |
| 载体封包 | cpw.mods.fml.common.network.internal.FMLProxyPacket |
network/ Scala 文件数 |
7 |
功能
BD lib 的网络层允许下游模组用普通的 Scala case class 定义封包,无需手写字节读写。它把消息用 Java 原生序列化写入一个 Netty ByteBuf,再包进 FML 的 FMLProxyPacket 发出。
编解码流程
SerializedMessageCodec(network/SerializedMessageCodec.scala:35)标注了 Netty 的 @Sharable,同时实现 encode 与 decode:
- encode(
:37-51)— 分配Unpooled.buffer(),包一层ObjectOutputStream(new ByteBufOutputStream(buff)),writeObject(msg)后连同ctx.channel.attr(NetworkRegistry.FML_CHANNEL).get构造FMLProxyPacket发出。 - decode(
:53-)— 包一层ObjectInputStream(new ByteBufInputStream(msg.payload())),并覆写resolveClass加入白名单校验(见 封包白名单)。
NetChannel
NetChannel(name)(network/NetChannel.scala:29)封装了 FML 的 FMLEmbeddedChannel,按 Side 维护一份通道表。它定义了两个内部 Netty handler:
ServerHandler(SimpleChannelInboundHandler[Message])— 从NetworkRegistry.NET_HANDLER取出EntityPlayerMP,在serverChain中查找处理器;找不到时只记一条警告(Unable to handle message from user %s)而不抛异常;整个处理体包在 try/catch 中,异常记为Error handling packet。ClientHandler— 客户端对应实现。
内置通道
本模组自身只注册了一条通道:
| 通道名 | 类 | 用途 |
|---|---|---|
bdew.multiblock |
multiblock/network/NetHandler.scala:16 |
多方块输出面配置(MsgOutputCfg、MsgOutputCfgSlot) |
预注册的封包类
preInit 阶段向 SerializedMessageCodec 登记 4 个允许反序列化的类(BdLib.scala:65-68):BaseMessage、MsgOutputCfgRSMode、MsgOutputCfg、MsgOutputCfgSlot。
数值
| 数值名 | 值 |
|---|---|
network/ Scala 文件数 |
7 |
| 本模组自建网络通道数 | 1(bdew.multiblock) |
| 预初始化登记的封包类数 | 4 |
| 序列化方式 | Java 原生序列化(writeObject / readObject) |
| 内部 Netty handler 数 | 2(ServerHandler / ClientHandler) |
交互
玩家无法直接触发封包。以下为框架对使用者的可见行为:
| 触发 | 行为 |
|---|---|
| 下游模组发送封包 | 消息被序列化为字节并以 FMLProxyPacket 走 FML 通道 |
| 客户端发来未注册类型的封包 | decode 中 resolveClass 拒绝该类,记录 Received disallowed message component class 警告并中止反序列化 |
| 消息类型已注册但无处理器 | 服务端记 Unable to handle message from user %s 警告,游戏不崩 |
| 消息处理器抛出异常 | 记为 Error handling packet 错误日志,不影响服务端继续运行 |