Skip to content

1.21 Fix cross-version concrete blueprints 修复跨版本钢筋混凝土蓝图导入 - #6079

Merged
PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-6058-concrete-blueprint
Nov 13, 2026
Merged

PigeonNian merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-6058-concrete-blueprint

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

fix(blueprint): 兼容跨版本钢筋混凝土方块名称

- 导入时识别新版十六种颜色钢筋混凝土及台阶、楼梯、墙的名称
- 保留方块属性与原始蓝图数据,并继续拒绝未知方块
Copilot AI balanced review requested due to automatic review settings November 12, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@Gugle2308 Gugle2308 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查意见 — PR #6079

结论:APPROVE(可以合并)。0 个阻塞项,2 条非阻塞建议与 1 条范围说明。

概览

  • head 2bdae381a9ce / base 0ea57be70033(dev/1.21/1.6 是默认分支 ⇒ 合并即关闭 issue #6058);state=open、draft=false、mergeable_state=clean。
  • 改动:1 个文件 / +28 −2(building/StructureSnapshotCodec.java,4 个 hunk,下载的 patch diff 含 1 个 diff --git 头和 4 个 @@ 标记)。
  • CI(head 与本次一致):build ✅、checkstyle ✅。
  • 本次审查的 diff 覆盖范围不完整:下面所有关于「哪些方块名在两条线之间发生了变化」的判断,都不在这 30 行 diff 里——它们分别来自两条线的 ModBlocks 注册代码、两侧 419 条 blockstate id 的全集差集、NeoForge MappedRegistry 打补丁后的语义,以及对 HALF 属性的逐字段对账。上述内容都是静态核对,未在实机上验证导入。diff 本身只覆盖 parsePaletteStates 与新增的 helper 一行,未触及 parse、write、CODEC、错误路径。

✅ 已核实正确

  1. 改名方向与范围都准确(未依据 PR 描述,而是从注册代码反查):
    • 1.21:ModBlocks.java:4217/4259/4287/4311 拼 "reinforced_concrete_" + color(分别是基础方块、slab、stair、wall)。
    • 26.1:ModBlocks.java:4461/4520/4546/4572 拼 color + "_reinforced_concrete"(含 _slab、_stair、_wall 后缀)。
    • 两侧 Color 都是 16 个值,序列化名逐一相同(white…pink);blockstate id 全集差集 419 对 419,唯一差异是 64 和 64 条且全部是钢筋混凝土(comm 差集:non-concrete diffs: [])。因此归一化范围既没有遗漏,也没有误改:1.21 侧不存在任何以 <color>_reinforced_concrete 开头的 id,namespace == anvilcraft + 精确前缀 + {"", "_slab", "_stair", "_wall"} 白名单三重收窄后,本地的合法 id 不可能被该逻辑改写。
  2. issue 里「21→26 方向不确定」有确定答案:不需要 26.1 侧再改。26.1 为每种颜色给了 4 条 .aliasFrom(...)(ModBlocks.java:4464/4522/4550/4574,16 色 = 64 条别名);NeoForge 的 MappedRegistry.java.patch 把 resolve(...) 接进了 getValue、get(Identifier)、get(ResourceKey)、getOrCreateHolderOrThrow,而 parsePaletteStates 的校验与 NbtUtils.readBlockState 走的正是 HolderGetter.get(ResourceKey) 这一条 ⇒ 26.1 侧对旧名(1.21 名)进行解析时会经过别名解析,因此 1.21 保存的钢筋混凝土蓝图在 26.1 上可以解析。同时 26.1 的 codec 没有做任何名称归一化,说明那边本来就依靠别名。
  3. 方块属性语义等价,改名不会导致 readBlockState 结果变化:两侧都是 EnumProperty.create("half", ReinforcedConcreteHalf.class)(single/top/bottom);blockstate JSON 属性键集合逐项相同——基础方块 half=bottom/single/top、slab type=bottom/double/top、stair facing/half/shape、wall 无变体键。因此归一化后的 tag 会解析到同一个状态。
  4. 只复制被改名的条目(stateTag.copy() + putString("Name", …)),Properties 及其他键原样保留,未命中的方块不产生拷贝。
  5. 未放宽校验:unknownIds.add(id.toString()) 仍用原始 id,抛出的仍是 unknown_block —— 玩家看到的是蓝图里真正写着的名字,而不是归一化后的名字;若归一化目标在本地不存在,也会落回这条路径。PR 描述的「继续拒绝未知方块」成立。
  6. 所有入口都覆盖:BlueprintNormalizer.load:44 → StructureSnapshotCodec.parse,磁盘文件、扫描仪、Litematica 导入、上传全部走同一处;LitematicaImporter 产出的也是普通 Name 字符串。编码侧(write 的 NbtUtils.writeBlockState)未改 ⇒ 无存档或协议格式变化。
  7. 新增代码的导入依赖已齐(AnvilCraft、Color 原本就在 import 列表里,ArrayList 和 List 亦然),无新增注解,最长新增行 91 字符 < style.xml 的 140。

💡 建议(非阻塞)

  1. 归一化表与注册名分处两处,将来容易发生无提示的遗漏:normalizeConcreteId 硬编码 "_slab" / "_stair" / "_wall" 白名单,而拼法定义在 ModBlocks 的四个构造器里。26.1 若再加一个变体(例如 _fence),本方法会静默把它归到「未知方块」,表现成导入失败但报的原名看起来完全正常。建议在 ModBlocks 的四个注册处各留一行注释指向本方法,或把四个后缀抽成常量供两边共用。
  2. 范围说明(不建议在本 PR 处理):本 PR 只规范化 palette。同一方块 id 还有三个载体——实体 NBT 的 BlockState、CauldronState、SlidingBlocks[].state,以及计划刻的 BlueprintTicks.type。其中 1.21 BuildingEntityTransform.transform:67-69 用 readBlockState 解析未知名会静默得到 AIR(例如蓝图里的下落方块实体),而 MagnetizedNodeBuildAdapter.support:30-34 的严格字符串相等 + throw 会让整份结构作废。再加上这些载荷在两条线之间本来就有 BlockState ↔ block_state、BlockPos ↔ block_pos 的键名漂移,跨版本蓝图中带下落方块/附着实体的场景已超出本 PR 的修复范围。建议在 PR 描述或后续 issue 里记一笔,避免后续被当成这个修复的回归。

📋 声称验证

描述中的说法 判定 依据
导入时识别新版十六色钢筋混凝土及台阶/楼梯/墙 ✅ 两侧 ModBlocks 拼法 + 64 与 64 的全集差集,无遗漏无越界
保留方块属性与原始蓝图数据 ✅ stateTag.copy() 只改 Name;HALF 与 blockstate 属性键集合两侧一致
继续拒绝未知方块 ✅ unknownIds.add(id.toString()) 用原名、抛 unknown_block
fixed #6058 ✅ issue 仍 open,目标是默认分支 dev/1.21/1.6,合并后自动关闭

🧪 建议测试

  1. 26.1 保存、内含 16 色钢筋混凝土(基础方块 + slab/stair/wall)的蓝图,在 1.21 导入并放置,逐色确认方块与 half/type 状态正确。
  2. 反向:1.21 保存的同类蓝图在 26.1 导入(验证 alias 解析链路,issue 里未确认的那一半)。
  3. 蓝图中混入一个真的不存在的方块 id,确认报错文案显示的是原始名、且未被静默跳过。
  4. 同一蓝图连着导入两次(归一化结果幂等性检查)。

标题已准确且为中英双语,本次未修改标题。

@PigeonNian PigeonNian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@PigeonNian
PigeonNian merged commit 9d0302a into Anvil-Dev:dev/1.21/1.6 Nov 13, 2026
2 checks passed
@WhereisFff
WhereisFff deleted the dev/1.21/fix-6058-concrete-blueprint branch November 13, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 26.1保存的带钢筋混凝土的蓝图无法在1.21导入

4 participants