Indexed Codec

基本信息

net.glease.tc4tweak.network.IndexedCodec extends MessageToMessageCodec<FMLProxyPacket, IMessage> —— MyNet 的底层编解码器,把 Forge 的 FMLProxyPacket 解成 IMessage。

方法

方法 行 说明
handlerAdded(ChannelHandlerContext) 46 加入 Netty pipeline
addDiscriminator(int, Class<? extends IMessage>) 51 登记 discriminator → 类型
exceptionCaught(ChannelHandlerContext, Throwable) 90 异常兜底

双向映射表

字段 类型 用途
discriminators TByteObjectMap<Class<? extends IMessage>> byte discriminator → 类型
types TObjectByteMap<Class<? extends IMessage>> 类型 → byte discriminator

addDiscriminator(int, Class) 双向写入并 return this(支持链式)。

discriminator 被 (byte) discriminator 强转 —— 上限 127, 当前只用 0/1/2。

「未知消息不崩」的确切实现

decode() 第 77-82 行:

Class<? extends IMessage> clazz = discriminators.get(discriminator);
if (clazz == null) {
    // TC4Tweaks modification: don't just panic about this. this is fine
    log.warn("Undefined message: {}. Is server running a newer TC4Tweaks?", discriminator);
    return;
}

注释直接标注 TC4Tweaks modification —— 相对 FML 原生实现, 遇到未注册 discriminator 时打一条 warn 后静默 return, 而不是抛异常。这正是 MyNet 类注释所述的行为。

依赖 FML 内部 API

ctx.attr(INBOUNDPACKETTRACKER).set(new ThreadLocal<>());   // handlerAdded
ctx.attr(INBOUNDPACKETTRACKER).get().set(new WeakReference<>(msg));  // decode

直接使用 FML 的包级常量 FMLIndexedMessageToMessageCodec.INBOUNDPACKETTRACKER (静态 import),并用 ThreadLocal<WeakReference<FMLProxyPacket>> 保存原包, 以便 encode 时把 dispatcher 拷给新的 FMLProxyPacket(第 65-69 行)—— 这是对 FML 内部实现的硬耦合,FML 改包结构即编译失败。

相关条目

源码

  • src/main/java/net/glease/tc4tweak/network/IndexedCodec.java