网络包
基本信息
| 属性 | 值 |
|---|---|
| 管道 | 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)
- 建立
FMLEventChannel并register(this)(:64-65) - 反射取
FMLEventChannel.channels字段得到EnumMap<Side, FMLEmbeddedChannel>(:68-70) - 按运行形态二选一发现类名(
: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)
- 开发态(
Collections.sort(classes)按全限定类名排序 ——…packets.client.X的c字典序小于…packets.server.X的s,所以 C 开头全部排在 S 开头之前(:106)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) 抽象实现 |