PamBeeGenerator(野生蜂巢生成)
事实基准:
harvestcraft-1.3.14-GTNH.jar(MC 1.7.10 / Forge 10.13.4.1614)CFR 0.152 反编译源码。 本条目的switch结论已用 class 字节码复核。
基本信息
| 属性 | 值 | 来源 |
|---|---|---|
| 类 | com.pam.harvestcraft.PamBeeGenerator |
PamBeeGenerator.java:13 |
| 实现 | IWorldGenerator |
PamBeeGenerator.java:14 |
| 注册条件 | BlockRegistry.enablebeehiveGeneration(默认 true) |
HarvestCraft.java:120-122 |
| 注册权重 | 0 | HarvestCraft.java:121 |
| 产出方块 | BlockRegistry.pamBeehive |
PamBeeGenerator.java:32 |
字节码级 switch 复核(关键)
generate 方法(PamBeeGenerator.java:15-24)的 CFR 输出没有 break:
switch (world.field_73011_w.field_76574_g) {
case -1: { this.generateNether(world, random, chunkX * 16, chunkZ * 16); }
case 0: { this.generateSurface(world, random, chunkX * 16, chunkZ * 16); }
}
这不是反编译伪影。 class 字节码(PamBeeGenerator.class,generate 方法 code_len=67)的实际布局:
| 偏移 | 指令 |
|---|---|
| 0 | aload 4 |
| 2 | getfield #21 |
| 5 | getfield #27 |
| 8 | lookupswitch → default 相对 +58、(-1, +28)、(0, +43) |
| 36 | aload_0 ← case -1 起点 |
| 37–47 | aload 4 / aload_1 / iload_2 / bipush 16 / imul / iload_3 / bipush 16 / imul |
| 48 | invokevirtual #31(generateNether) |
| 51 | aload_0 ← case 0 起点,与上一条指令首尾相接 |
| 52–62 | 同上参数序列 |
| 63 | invokevirtual #34(generateSurface) |
| 66 | return ← default 落点 |
case -1 的最后一条指令是 @48 的 invokevirtual(占 48–50),其后没有任何 goto(0xa7);下一条指令 @51 正是 case 0 的入口。
结论:case -1 真的落穿进 case 0。这是源码级缺失 break 的真实缺陷,不是 CFR 伪影。
(switch 的跳转偏移以操作码所在偏移为基准,不是填充后的操作数区起点——这也是为什么 default 落在 66 而非 70。)
运行时后果
在下界(维度 -1)中,生成流程是:
generateNether(world, rand, chunkX*16, chunkZ*16)—— 空方法,一条指令都没有(PamBeeGenerator.java:36-37)- 紧接着(落穿)执行
generateSurface(world, rand, chunkX*16, chunkZ*16)
所以 brief 中"因 generateNether 是空方法故无后果"只对了一半:generateNether 确实是空方法,但落穿导致下界也会跑一遍主世界的蜂巢逻辑。
generateSurface(PamBeeGenerator.java:26-34)的做法是:
for (int k = 0; k < BlockRegistry.beehiveRarity; ++k) {
int l = rand.nextInt(128);
int i1 = i + rand.nextInt(16);
if (world.func_147439_a(i1, l - 1, j1 = j + rand.nextInt(16)) != Blocks.field_150362_t
&& world.func_147439_a(i1, l - 1, j1) != Blocks.field_150364_r) continue;
world.func_147449_b(i1, l - 1, j1, BlockRegistry.pamBeehive);
}
- 尝试次数 =
BlockRegistry.beehiveRarity,默认 5(BlockRegistry.java:341,beekeeping分类)。 - 高度
rand.nextInt(128),即 Y ∈ [0, 128)。 - 地表判定只接受两种方块:
Blocks.field_150362_t与Blocks.field_150364_r(SRG 名 → 未解析;语义佐证:二者在WorldGenPamFruitTree.java:75用作"放树叶"的方块、在WorldGenPamFruitTree.java:84用作"放树干"的方块,在WorldGenPamMushroomGarden.java:28-30用作铺地面 —— 即树叶与原木)。 - 放置高度是
l - 1,即地表那一格(蜂巢替换掉脚下的树叶/原木)。
下界通常不存在树叶/原木,所以落穿的实际表现通常是"什么也不发生";但只要下界里出现树叶或原木(例如其它模组搬入、或玩家放置),就会在下界 Y<128 处生成野生蜂巢。
复现条件
- 默认配置(
enablebeehiveGeneration = true)下即存在。 - 在下界(维度
-1)放置一片树叶或原木作为地表,然后加载新区块。
源码缺陷
| 位置 | 问题 |
|---|---|
PamBeeGenerator.java:17-22 |
switch 的 case -1 缺 break,落穿进 case 0。字节码 @48→@51 无 goto 可证。 |
PamBeeGenerator.java:36-37 |
generateNether 是完全空的方法体(下界不生成任何东西),与 case -1 分支不匹配。 |
相关条目
- 世界生成器注册总表 —— 注册条件与权重
- PamTreeGenerator · PamGardenGenerator —— 同样存在落穿,但见各条目的"编译期落穿 vs 真实落穿"区分
- 兄弟维度:网络包 · 配置 · 兼容层