网络包

基本信息

属性 值
管道 PacketPipeline(packets/PacketPipeline.java)
频道名 hee(private static final String channelName = "hee",:45)
通道类型 FMLEventChannel + 按 Side 分的 FMLEmbeddedChannel(:53-54、:64)
包类总数 25 个(20 个 C 开头 + 5 个 S 开头)
ID 分配方式 无显式注册:扫描类文件后按类名排序依次编号 0..N(:106-108)
单例 private static PacketPipeline instance,由 initializePipeline() 创建

功能

initializePipeline() 是静态入口:若 instance != null 直接抛 RuntimeException("Packet pipeline has already been registered!")(:47-51)。创建后调 load()。

load() 的包发现逻辑(PacketPipeline.java:61-115)

  1. 建立 FMLEventChannel 并 register(this)(:64-65)
  2. 反射取 FMLEventChannel.channels 字段得到 EnumMap<Side, FMLEmbeddedChannel>(:68-70)
  3. 按运行形态二选一发现类名(:77-104):
    • 开发态(HardcoreEnderExpansion.sourceFile.isDirectory()):列 chylex/hee/packets/client 与 …/server 下的文件,只看文件名前缀 C / S(:80-88)
    • 打包态:用 ZipFile 遍历条目,匹配 chylex/hee/packets/client/C 与 chylex/hee/packets/server/S(:90-100)
  4. Collections.sort(classes) 按全限定类名排序 —— …packets.client.X 的 c 字典序小于 …packets.server.X 的 s,所以 C 开头全部排在 S 开头之前(:106)
  5. for (String cls : classes) registerPacket(++id, …),id 从 −1 起自增,序号与文件名中的数字无关(:108)

registerPacket 把 (byte) id 双向存进 idToPacket / packetToId 两张 trove 哈希表(:117-120)。writePacket 写出 1 字节 ID 再写包体(:124-125)。

由此产生的 ID 映射与文件名数字不一致(第 108 行的计数结果,见下方两张表)。文件名的数字只起排序作用。仓库无注释说明这一设计,故仅记录。

失败处理:捕获 NoSuchFieldException | IllegalArgumentException | IllegalAccessException | IOException | ClassNotFoundException 后包装为 RuntimeException("Unable to load the Packet system!", e)(:109-112)—— 记录了异常本体,不是空 catch。

数值

20 个 C 开头包(服务端 → 客户端,运行期 ID 0–19)

运行期 ID 类 用途
0 C00ClearInventorySlot 清空指定 GUI 槽位
1 C01ParticleEndPortalCreation 末影传送门创建粒子
2 C02PlayRecord 播放音乐唱片
3 C03KnowledgeNotification 知识解锁通知
4 C04OpenAdventurersDiary 打开冒险家日记
5 C05CustomWeather 自定义天气
6 C06SetPlayerVelocity 设定玩家速度
7 C07AddPlayerVelocity 叠加玩家速度
8 C08PlaySound 播放音效
9 C09SimpleEvent 通用事件
10 C10ParticleEnergyTransfer 能量传输粒子(见能量系统)
11 C11ParticleAltarOrb 祭坛宝珠粒子(见精华祭坛)
12 C12FiendFireballExplosion 火焰恶魔火球爆炸
13 C13TransportBeaconData 运输信标数据(见虚空箱与运输信标)
14 C14FiendFireball 火焰恶魔火球
15 C17AltarRuneItemEffect 祭坛符文物品效果
16 C19CompendiumData 知识书数据
17 C20Effect 效果
18 C21EffectEntity 实体效果(末影传送用)
19 C22EffectLine 线条效果(诅咒传送用)

5 个 S 开头包(客户端 → 服务端,运行期 ID 20–24)

运行期 ID 类 用途
20 S00DeathFlowerPot 死亡之花盆栽交互
21 S01GuiEnhancementsClick 强化 GUI 点击
22 S02CompendiumPurchase 知识书购买
23 S03SimpleEvent 通用事件
24 S04TransportBeaconTravel 运输信标传送

计数核对(两种表述):git ls-files 'src/main/java/chylex/hee/packets/client' | xargs -n1 basename | grep -c '^C' → 20;…/server … | grep -c '^S' → 5;合计 25。packets/ 目录共 31 个 .java 文件 = 25 个包 + 4 个基类(AbstractPacket / AbstractClientPacket / AbstractServerPacket)+ PacketPipeline + 2 个占位 __.java。

交互

触发 行为
preInit PacketPipeline.initializePipeline() 建立 hee 事件通道(HardcoreEnderExpansion.java:168)
发包 S 开头包走 FMLEmbeddedChannel 的 sendToServer;C 开头包走 sendToAllAround / sendToPlayer(channels.get(side),:53-54)
收包 AbstractClientPacket / AbstractServerPacket 的 processPacket(EntityPlayer player, IMessage message) 抽象实现

相关条目