Support repeated projection of blueprints and improve runtime status and entity restoration 支持蓝图重复投影并完善运行状态与实体恢复 - #4971
Conversation
- 支持拖拽平铺蓝图投影、松开锁定并再次右键批量粘贴,统一预览与放置范围限制 - 完善选区距离锁定、方向调整和尺寸显示,同步更新操作提示与中英文翻译 - 统一结构扫描快照采集,保存并恢复方块运行进度、计划刻与时间基准,兼容 Litematica 计划刻导入 - 完善建造后的红石、流体与邻居更新,避免恢复结构时误触发侦测器 - 扩展生物、掉落物、投射物、移动方块及模组实体的蓝图建造,恢复运动状态、乘骑关系和实体引用 - 支持树脂封存生物供料,补全实体装备、库存、流体及特殊方块材料需求 - 增加磁铁、铁砧锤与点火工具需求校验,并显示不支持建造的具体对象 - 将实体纳入建造撤销,仅撤销状态未变化且允许修改的建造组 - 蓝图导出遇到同名文件时自动添加序号,并反馈实际导出文件名
Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection. Reply |
Reason: shell execution via heredoc Reply |
|
I have everything I need. Writing the review now. 代码审查摘要 — PR #4971操作: opened( ✅ 已核对的编译面(无问题)用官方 1.21.1
📋 声称验证表
🔴 关键
|
| 被测目标 | 建议场景 | 优先级 |
|---|---|---|
BlueprintPlacement.tile |
锚点=last(单份)、±X/Z 平铺、Y 向堆叠、count*entries 刚好越界、跨 4000 上限 |
🔴 |
planBlueprint 实体分支 |
范围内放风弹/烟花火箭/凋灵之首,确认是“跳过”还是“整盘失败”(当前实现验证 🔴1) | 🔴 |
BlueprintEntities.flatten/link |
三阶乘骑(船→马→玩家)、自引用/循环乘骑、>32 层嵌套、缺 UUID 的实体、同锚点重复粘贴的 UUID 复用 | 🔴 |
BlueprintTicks.capture/restore |
边界跨区块的计划刻、delay=0、流体/方块双类、还原后立即 tick 的行为、被 cells 过滤掉的方块上的计划刻 |
🟡 |
BlueprintRuntimeData.restoreClock |
capturedAt=0(Litematica 导入)与有捕获时间的两种路径、RemainingWaitingTime>0、熔炉 BurnTime/CookTime 经“库存插入后”不被清零 |
🟡 |
BuildingCommit.activate |
侦测器相邻放置不翻转、红石线网络恢复、含水方块不流水、计划刻不被重复调度 | 🟡 |
StructureBlueprintFiles.write |
同名连续导出 3 次 → _1/_2 序号与回显文件名、超长名截断到 128、并发同名 |
🟢 |
结论: REQUEST_CHANGES
功能覆盖与 PR 声称一致,坐标系/时序这类最容易出错的点做得相当扎实。但 🔴1(个别不支持实体会让整份蓝图静默失败,且触发面因 isTransient 放宽而扩大) 与
PR 标题「Support repeated projection of blueprints and improve runtime status and entity restoration 支持蓝图重复投影并完善运行状态与实体恢复」与变更内容相符,无需修改。
由 Hermes Agent 审查
代码审查摘要 — PR #4971操作: edited(标题/分支变更 → 全量复审)
🔴 关键未发现确定性阻断缺陷(未发现必然崩溃/数据丢失的硬 bug)。
|
| 声称 | 状态 | 对应实现 |
|---|---|---|
| 拖拽平铺投影、松开锁定再右键批量粘贴、统一预览与范围限制 | ✅ | BlueprintPlacement.tile、BuildingRodClient.beginBlueprintSelection/confirmSelection/blueprintPlacements、BuildingRodPacket.PLACE_BLUEPRINTS、BuildingRodService.blueprints |
| 选区距离锁定、方向调整、尺寸显示 | ✅ | canAdjustDistance/controlAvailable/selectionOffset、selection_size 三参数文案 |
| 同步更新中英文翻译 | en_us/en_ud/生成器 ✅;zh_cn 未更新(见 |
|
| 统一结构扫描快照采集 | BlueprintCapture.capture 接入服务端保存;客户端预览仍走缓存(见 |
|
| 保存/恢复运行进度、计划刻、时间基准,兼容 Litematica 计划刻导入 | ✅ | BlueprintRuntimeData、BlueprintTicks、LitematicaImporter(PendingBlockTicks/PendingFluidTicks)、StructureSnapshot.capturedAt |
| 建造后红石/流体/邻居更新,避免误触发侦测器 | ✅(性能见 💡) | BuildingCommit.activate/activatePlaced、BlueprintLevelMixin#neighborShapeChanged |
| 扩展生物/掉落物/投射物/移动方块/模组实体建造,恢复运动状态/乘骑/引用 | DynamicBuildingEntities、BuildingEntityTransform(Motion/BlockPos/SlidingBlocks/记忆);语义变化见 |
|
| 树脂封存生物供料,补全装备/库存/流体/特殊方块材料 | ✅ | reserveCreature、BlueprintSpecialBlocks、Mob 装备/InventoryCarrier 剥离与回填、FluidTankMinecartEntity 储罐 |
| 磁铁/铁砧锤/点火工具校验 + 显示不支持对象 | ✅ | requiredTool/requiresHammer、reserveIgnitions、unsupported_type |
| 实体纳入建造撤销(仅未变化且可修改的组) | 已实现 recordEntity/SavedEntity,但状态门使实体组实际不可撤销(见 |
|
| 导出同名自动加序号并反馈实际文件名 | ✅ | StructureBlueprintFiles.write 返回候选名、BlueprintClientFiles.receive 校验并回显 |
| resolved #4963/#4964/#4966、fixed #4968、resolved #4970 | 未校验 | 无 gh 凭据,无法查询 issue 状态与关闭链 |
结论: COMMENT(建议处理
🧪 测试建议
| 被测目标 | 推荐测试场景 | 优先级 |
|---|---|---|
BuildingRodUndo.SavedEntity.matches() |
放置含生物/掉落物的蓝图 → 等 1 tick → 撤销;验证方块是否应还原、材料是否应返还 | 🔴 |
StructureSaveUtil.buildSnapshot(BlueprintCapture 分支) |
扫描区内含磁铁节点但支撑方块被破坏 → SAVE 各入口(GUI 保存 / 自动保存 / action 包)逐一验证不抛异常 | 🔴 |
BlueprintPlacement.tile × commit 上限 |
含门/床/活塞头的多方块蓝图拖拽平铺 → 统计实际放置格数与材料扣减是否一致 | 🟡 |
BlueprintTicks.capture/restore |
含红石计划刻/流体计划刻的结构导出再投影,验证 tick 时刻与 priority 保持 | 🟡 |
BuildingMaterials.reserveCreature |
背包树脂块 + 刷怪蛋混放、无蛋生物(仅树脂)、蛋跨两栈拆分 → 计量与撤销返还 | 🟡 |
BlueprintEntities.link |
生物乘骑载具(含嵌套乘客)蓝图投影,验证乘骑关系与记忆引用指向新 UUID | 🟡 |
标题
建议标题(本次 gh 未认证,未能自动修改):
Support tiled blueprint projection, block/entity runtime restoration and material requirements 支持蓝图平铺重复投影、方块/实体运行状态恢复与材料需求补全
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched references/blueprint-repetition-and-runtime-entity-restore-review.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched SKILL.md in skill 'building-rod-blueprint-review' (1 replacement). |
|
💾 Self-improvement review: Patched SKILL.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched SKILL.md in skill 'mixin-injection-verification' (1 replacement). |
|
已完成审查。以下是审查意见(gh token 已失效,未能自动改标题,建议标题附在末尾)。 代码审查摘要 — PR #4971操作: opened(synchronize 后 head 🔴 关键
|
| 声称 | 状态 | 对应文件 |
|---|---|---|
| 拖拽平铺投影 / 松开锁定 / 再右键批量粘贴 | ✅ | BlueprintPlacement.tile, BuildingRodClient(blueprintOffset/press/release/confirm/PLACE_BLUEPRINTS), BuildingRodPacket |
| 统一预览与放置范围限制 | ✅( |
BlueprintPlacement.tile ← 客户端/服务端共用, BuildingRodRenderer |
| 选区距离锁定 / 方向调整 / 尺寸显示 | ✅ | BuildingRodClient.selectionBounds, applyControl(4 方向), handleKeyboardInput, selection_size |
| 统一结构扫描快照采集 | ✅( |
StructureSaveUtil.buildSnapshot → BlueprintCapture |
| 保存/恢复运行进度、计划刻、时间基准 | ✅( |
BlueprintRuntimeData, BlueprintTicks, StructureSnapshot(+Codec), BlueprintBlockConfiguration |
| Litematica 计划刻导入 | Time 语义待确认) |
LitematicaImporter |
| 建造后红石/流体/邻居更新,避免误触侦测器 | ✅ | BuildingCommit.activate/activatePlaced/isRestoredObserverUpdate, BlueprintLevelMixin |
| 生物/掉落物/投射物/移动方块/模组实体建造 | ✅(🔴 第 1 条信任边界) | DynamicBuildingEntities, BlueprintEntities, MagnetizedNodeBuildAdapter, EntityBuildAdapters, BuildingEntityTransform |
| 恢复运动状态/乘骑/实体引用 | ✅ | BuildingEntityTransform(Motion 旋转/SlidingBlocks/Relative*), BlueprintEntities.link |
| 树脂封存生物供料,补全装备/库存/流体/特殊方块材料 | ✅ | BuildingMaterials.reserveCreature, DynamicBuildingEntities(contents), VanillaBuildingEntities.VehicleAdapter(fluids), BlueprintSpecialBlocks |
| 磁铁/铁砧锤/点火工具需求校验 + 显示不支持对象 | ✅ | EntityBuildAdapter.requiredTool/requiresHammer, BuildingMaterials.reserveTool/reserveHammer/reserveIgnitions, unsupported_type |
| 实体纳入撤销(仅状态未变且可修改的组) | ✅( |
BuildingRodUndo |
| 导出同名自动编号 + 反馈实际文件名 | ✅ | StructureBlueprintFiles.write, BlueprintClientFiles.receive |
结论: REQUEST_CHANGES(建议先处理 🔴 第 1、2 条,
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
BlueprintPlacement.tile() |
offset 恰好 = / 略小于 / 为 0 / 为负;count*entries 刚好越界;MAX_BLOCKS 边界 |
🔴 |
BuildingRodService.blueprints() + planBlueprint() |
平铺多份时的 declared/portalCores 归属;第二份失败时不得留下半成品 |
🔴 |
BlueprintTicks.read/restore |
缺 pos/未知 type/>32768 条 → 期望可捕获的 IAE 而非 NSEE;capturedAt=0 回退分支;RESTORE 时 placed 过滤 |
🔴 |
BuildingEntityTransform.sanitize() |
恶意 NBT(1e9 Attributes/ActiveEffects/Invulnerable)不得生效;Passengers/UUID 必须被剥离 | 🔴 |
BuildingRodUndo |
实体 NBT 自然漂移(Age/Motion)后撤销行为;节点/出口实体与方块同组时的跳过语义 | 🟡 |
BuildingMaterials 工具/生物/点火预留 |
铁砧锤被 retainedTool 占用后不能当材料消耗;树脂封存生物匹配;火焰计数(多扇传送门/多处火) |
🟡 |
BuildingCommit.activate() |
侦测器朝向不被邻居更新改写、且恢复后仍能被真实邻居触发;计划刻/流体刻数量与蓝图一致 | 🟡 |
StructureSaveUtil.buildSnapshot() / ScannerDiskNormalizer |
扫描区域被改动后导出内容;magnetized_node 支撑缺失时不得整体失败 |
🟡 |
StructureBlueprintFiles.write() |
目录内已存在 a.nbt、a_1.nbt、…;名称长度接近 128 的截断 |
🟢 |
建议标题(gh auth status 显示 token 已失效,故未自动修改):
Support blueprint tiling, runtime-tick restoration and entity building 支持蓝图平铺投影、运行状态/计划刻恢复与实体建造
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). · Patched references/pr-class-routing.md in skill 'github-webhook-pr-review' (1 replacement). |
- 将撤销改为恢复建造前的区域快照,涵盖方块、方块实体、原有实体、计划刻与方块事件 - 跟踪建造实体及区域变化产生的掉落物、下落方块和 TNT,撤销时清理关联实体 - 按实际消耗记录物品与流体账单,扣除随区域快照恢复的库存,避免重复返还材料 - 支持向原仓储退还流体,保留未完成的实体回收与退款记录,并增加部分撤销提示 - 补全拴绳结的扫描、预览与放置,恢复实体间及栅栏上的拴绳关系,兼容旧版拴绳数据 - 将拴绳纳入材料消耗与缺料清单,校验栅栏支撑和修改权限,并在撤销时清理闲置绳结
Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection. Reply |
Reason: script execution via -e/-c flag Reply |
Reason: script execution via -e/-c flag Reply |
代码审查摘要 — PR #4971操作: synchronize(重审当前 head 🔴 关键1. 无适配器的实体会让「整份蓝图(含全部平铺副本)」无法建造 —— 相对 base 的行为回归 实测(1.21.1 客户端字节码,常量池键名): 扫描区域里只要残留一个凋灵之首 / 潜影贝导弹 / 风弹 / 烟花火箭 / 羊驼口水, 建议:
|
| PR 声称 | 状态 | 对应实现 |
|---|---|---|
| 拖拽平铺投影、松开锁定、再右键批量粘贴,统一预览与放置范围 | ✅ | BlueprintPlacement.tile / BuildingRodClient.blueprintPlacements·selectionBounds·beginBlueprintSelection / BuildingRodPacket.Action.PLACE_BLUEPRINTS / BuildingRodService.blueprints / BuildingRodRenderer.renderCopy |
| 选区距离锁定、方向调整、尺寸显示 | ✅ | canAdjustDistance/controlAvailable/applyControl(index≥2 → selectionOffset) + screen.anvilcraft.building_rod.selection_size |
| 同步更新操作提示与中英文翻译 | 英文(en_us/en_ud,数据生成)✅;zh_cn/zh_hk/zh_tw/zh_meme 缺 3 个新键且旧提示未更新 | |
| 统一扫描快照采集,保存/恢复运行进度、计划刻与时间基准 | ✅ | BlueprintCapture(服务端统一入口,StructureSaveUtil.buildSnapshot 改走它)、BlueprintTicks.capture/restore、BlueprintRuntimeData.rebase/restoreClock、StructureSnapshotCodec 写入 anvilcraft:captured_at |
| 兼容 Litematica 计划刻导入 | LitematicaImporter 读 PendingBlockTicks/PendingFluidTicks + x/y/z/Block·Fluid/Time/Priority/SubTick(离线无法核对 Litematica 实际写出键名,建议贴一份真实 .litematic 验证;另见警告 2 的 ResourceLocation.parse) |
|
| 建造后红石/流体/邻居更新,避免误触发侦测器 | ✅ | BuildingCommit.activate/activatePlaced、set() 补 onBlockStateChange、isRestoredObserverUpdate + BlueprintLevelMixin |
| 扩展生物/掉落物/投射物/移动方块/模组实体,恢复运动、乘骑、实体引用 | DynamicBuildingEntities、BlueprintEntities.flatten/identities/scope/link/remap、BuildingEntityTransform(Motion/TileX/SlidingBlocks/Anvilcraft 实体)、SlidingBlockEntity/AnimateAscendingBlockEntity/CauldronOutletEntity 补存档 — 但见警告 1 |
|
| 树脂封存生物供料,补全装备/库存/流体/特殊方块材料 | ✅ | BuildingMaterials.reserveCreature(树脂优先,退化为刷怪蛋)、DynamicBuildingEntities Mob 装备+InventoryCarrier、VanillaBuildingEntities 坦克流体、BlueprintSpecialBlocks.material/extra、BuildingBlockMaterial:31 |
| 磁铁/铁砧锤/点火工具需求校验,显示不支持对象 | ✅ | requiredTool/requiresHammer/ignitions → reserveTool/reserveHammer/reserveConsumable + unsupported_type 消息 |
| 实体纳入撤销,仅撤销状态未变化且允许修改的组 | ✅ | BuildingRegionSnapshot + Receipt + canRestore/canRemove(详见警告 4) |
| 导出重名自动加序号并反馈实际文件名 | ✅ | StructureBlueprintFiles.write 返回文件名 → StructureScannerFiles.sendFile → BlueprintClientFiles 校验/显示 |
关联 issue(#4963/#4964/#4966/#4968/#4970):5 个均仍为 open(PR 未合并,符合预期),标题主题与本次改动逐条对应:空中取点放方块 ✅、区域范围显示 ✅、蓝图批量放置 ✅、磁化节点导致无法粘贴(MagnetizedNodeBuildAdapter.support 按碰撞高度反查支撑方块)✅、背包有打火石/火焰弹可放火 ✅。
🧪 测试建议
| 被测目标 | 场景 | 优先级 |
|---|---|---|
BlueprintPlacement.tile |
last == anchor(count=1);单轴反向拖拽;count*entries > MAX_BLOCKS 返回空;尺寸 1×1×1(不除零) |
🔴 |
BuildingRodService.planBlueprint 实体循环 |
区域含 凋灵之首/潜影贝导弹/风弹(无适配器)时应跳过而非中止;含箭/掉落物应正常 | 🔴 |
BlueprintTicks.read |
缺 pos、非法 type、条目 > 32768 —— 断言抛 IllegalArgumentException 并被 blueprints() 捕获 |
🔴 |
BuildingMaterials.reserve |
工具保留(retainedTool 不消耗、材料让位一格);树脂优先于刷怪蛋;失败后 reserved/retainedTool/returned/fluidPayments 完全回滚 |
🟡 |
BlueprintRuntimeData.rebase/restoreClock |
capturedAt=0 与 >0;RemainingWaitingTime/PhaseDuration 分支;PhaseStartGameTime 仍为 long |
🟡 |
BuildingRodUndo.undo |
二次调用(restored=true 后不重复恢复区域);实体被玩家拒绝交互 → undo_partial;栓绳结辅助实体被回收 |
🟡 |
StructureBlueprintFiles.write |
连续同名 _1/_2;超长名截断至 128;目标已存在为目录时不死循环 |
🟢 |
结论: COMMENT(倾向修复后合并) — 主体设计与实现质量高(平铺上界、工具保留语义、激活窗口内的观察者抑制、区域快照式撤销都经得起推敲),但 🔴1「无适配器实体导致整份蓝图无法建造」是相对 base 的功能回归且修复成本极低,
说明:PR 标题
Support repeated projection of blueprints and improve runtime status and entity restoration 支持蓝图重复投影并完善运行状态与实体恢复准确清晰,未改标题(本环境的gh凭据已失效,gh auth status报 token invalid,符合流程中的回退约定)。
由 Hermes Agent 审查
|
审查完成。以下是审查意见(Webhook 会自动发布为 PR 评论;未执行任何 代码审查摘要 — PR #4971范围: 46 个文件(43 Java,13 新增,0 删除)/ +2284 −363 先说结论:整体质量很高——材料账单/退款记账、实体快照与引用重建、静默提交后的统一激活,都是相当讲究的实现。下面按严重程度列出问题。 ✅ 已交叉验证的运行时前提(高风险点,均通过)用 官方 1.21.1 client_mappings 逐条核对,这几处若写错会是启动崩溃级问题,实测无误:
🔴 关键(需修复或明确答复)1.
2. 撤销快照区域 = 平铺副本的并集包围盒(含空洞),且无体积上限 —
|
| 声称 | 状态 | 对应实现 |
|---|---|---|
| 拖拽平铺投影、松开锁定后再次右键批量粘贴,统一预览与放置范围 | ✅ | BuildingRodClient.beginBlueprintSelection/blueprintOffset/blueprintPlacements、BlueprintPlacement.tile、BuildingRodPacket.PLACE_BLUEPRINTS、BuildingRodService.blueprints、BuildingRodRenderer 多副本 |
| 选区距离锁定、方向调整、尺寸显示 + 中英文翻译 | ✅ | selectionBounds + selection_size overlay、applyControl 方向偏移、en_us/en_ud/BuildingRodLang |
| 统一结构扫描快照采集(运行进度/计划刻/时间基准,兼容 Litematica 计划刻) | BlueprintCapture、BlueprintTicks、BlueprintRuntimeData、LitematicaImporter 计划刻导入;但服务端/客户端采集路径分裂( |
|
| 建造后红石/流体/邻居更新,避免误触发侦测器 | ✅ | BuildingCommit.activate/activatePlaced、isRestoredObserverUpdate + BlueprintLevelMixin |
| 生物/掉落物/投射物/移动方块/模组实体可建造,恢复运动、乘骑与实体引用 | ✅ | DynamicBuildingEntities、BlueprintEntities、isTransient 放宽、Motion/Rotation 变换、VanillaBuildingEntities |
| 树脂封存生物供料,补全实体装备/库存/流体与特殊方块材料 | ✅ | BuildingMaterials.reserveCreature、DynamicBuildingEntities.plan(Mob)、insertContents(EquipmentSlot/InventoryCarrier)、BlueprintSpecialBlocks |
| 磁铁/铁砧锤/点火工具校验,并显示不支持的具体对象 | ✅ | MagnetizedNodeBuildAdapter.requiredTool、Outlet.requiresHammer、ignitions + 打火石/火焰弹回退、unsupported_type |
| 实体纳入撤销,仅撤销状态未变化且允许修改的建造组 | 实体纳入撤销 ✅;"仅撤销状态未变化"未实现(见 |
|
| 导出重名自动加序号并反馈实际文件名 | ✅ | StructureBlueprintFiles.write 返回实际名 + StructureScannerFiles/BlueprintClientFiles 校验回传 |
| resolved #4963 / #4964 / #4966、fixed #4968、resolved #4970 | 5 个 issue 均仍 open(未合并,属预期)。#4964(范围显示)/#4966(蓝图批量放置)/#4968(磁化节点导致无法粘贴)/#4970(打火石/火焰弹放火)映射明确 ✅;#4963"在空中找点凭空放置"仅由 Ctrl 悬浮 + selectionOffset 间接覆盖,且 ClipContext.Block.COLLIDER 反而要求起点必须命中碰撞方块,请确认是否真正解决 |
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
BuildingRegionSnapshot.restore() |
建造后挖掉方块→拾取→撤销(校验物品/材料是否重复);另一玩家在区域内挖掘后撤销(掉落物是否被误删) | 🔴 |
BuildingRodService.blueprints() + BlueprintPlacement.tile() |
稀疏大尺寸蓝图 × 2×2×2 平铺:盒体积/耗时、undoBounds 是否含空隙、空隙落在保护区内时的报错文案 |
🔴 |
BlueprintTicks / BlueprintRuntimeData.restoreClock |
计划刻与 PhaseStartGameTime/RollStart 在跨维度/长时间后放置与撤销的时钟重建;capturedAt==0(Litematica 导入)分支 |
🟡 |
BuildingMaterials.reserve* |
工具被同时当作材料、多组共用单一磁铁/铁砧锤、拴绳/点火消耗不足时的 missing() 清单 |
🟡 |
StructureBlueprintFiles.write |
同名连续导出 N 次(foo.nbt→foo_1.nbt),临时文件重名/移动失败后的重试 |
🟢 |
结论: REQUEST_CHANGES
两项需先明确处理:(1) 区域快照撤销带来的物品复制 / 连带删除他人掉落物,以及 (2) 平铺副本并集包围盒导致的撤销快照体量(含空洞)无上限。其余为警告与改进建议;API/Mixin/访问器层面的高风险点已用官方映射逐条验证通过,未发现编译或启动级问题。
标题建议(gh token 失效,本次未自动修改):
Support tiled blueprint projection, region-snapshot undo and runtime/entity restoration 支持蓝图平铺投影、区域快照撤销与运行状态/实体恢复
(现标题未涵盖"区域快照撤销/计划刻与运行状态恢复"这两块主要工作。)
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched references/blueprint-repetition-and-runtime-entity-restore-review.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched SKILL.md in skill 'mixin-injection-verification' (1 replacement). |
Reason: script execution via -e/-c flag Reply |
|
已完成核对。以下是审查意见(webhook 会自动发布,我没有执行任何 代码审查摘要 — PR #4971操作: synchronize 🔴 关键1. 区域快照无条件恢复 ⇒ 「挖走方块并拾取」可稳定复制物品(
复现:建造 → 挖掉建造出的方块并立刻拾取掉落 → 撤销 ⇒ 区域回到建造前状态,玩家净得该方块物品 + 材料全额返还。 建议:撤销退款前校验"该 receipt 对应的建造格是否仍为建造结果"(或 2.
|
| 声称 | 状态 | 证据 |
|---|---|---|
| 拖拽平铺蓝图投影、松开锁定、再次右键批量粘贴 | ✅ | BlueprintPlacement.tile、Action.PLACE_BLUEPRINTS、BuildingRodClient.beginBlueprintSelection/confirmSelection/blueprintPlacements |
| 统一预览与放置范围限制 | 客户端 blueprintPlacements().isEmpty() 与 MAX_BLOCKS 校验齐备,但 reach 只查首尾锚点(见 |
|
| 选区距离锁定、方向调整、尺寸显示、中英文翻译 | selection_size 已加 + HUD 改造完成;zh_cn 未同步(见 |
|
| 统一结构扫描快照采集 | ✅ | BlueprintCapture.capture 直采世界帧 + StructureSaveUtil.buildSnapshot 改走它;客户端预览仍走旧缓存的"导出/预览分叉"请确认(见待确认) |
| 保存并恢复方块运行进度、计划刻与时间基准 | BlueprintRuntimeData/BlueprintTicks 机制完整,但 take 时机使按类型清洗变死码(见 |
|
| 兼容 Litematica 计划刻导入 | LitematicaImporter 有对应改动;delay 语义(相对剩余 vs 绝对)与测试用例建议在描述中补一句 |
|
| 完善建造后红石/流体/邻居更新,避免误触发侦测器 | ✅ | BuildingCommit.activate + isRestoredObserverUpdate + RedstoneWireNetworkManager.restoreBlueprint |
| 扩展生物/掉落物/投射物/移动方块/模组实体建造,恢复运动/乘骑/引用 | 覆盖到位,但"不支持的类型会 abort 整份建造"(见 |
|
| 树脂封存生物供料、补全装备/库存/流体/特殊方块材料 | ✅ | reserveCreature(树脂优先 2 轮)、EntityBuildAdapters.insertContents 的 Mob 槽位映射、BlueprintSpecialBlocks.extra、limitMotion |
| 磁铁、铁砧锤与点火工具需求校验 + 显示不支持建造的对象 | ✅ | requiredTool/requiresHammer/group.tools/reserveTool/ignitions/leads + unsupported_type 提示 |
| 实体纳入建造撤销,仅撤销状态未变化且允许修改的建造组 | ❌ | 实现已改为无条件区域恢复(canRestore 只做权限/破坏事件校验),且会复制物品(见 🔴1);描述未同步 |
| 蓝图导出同名自动加序号并反馈实际文件名 | ✅ | StructureBlueprintFiles.write 返回 candidate + StructureScannerFiles.handle 回传(序号循环无上界见 |
| resolved #4963/#4964/#4966、fixed #4968、resolved #4970 | 未逐条核 | 本轮未拉取 issue 状态做交叉验证(webhook 匿名 API 限额),仅按代码面核对 |
❓ 待确认(未能实测,需作者确认)
reserveCreature的树脂返还只写进了本次调用的allocated.returned,而 reserve 末尾有allocated.returned.clear()+ 从this.returned切片重建。若中间没有allocated.returned → this.returned的拷贝,则撤销账单(group.returned)不含树脂 ⇒ 撤销不收回,等于白送 1~4 个树脂。请确认该拷贝仍在reserveCreature之后执行。- 服务端导出改读实时世界(
scannedBlocks被忽略)而客户端预览仍走缓存 ⇒ 预览 ≠ 文件内容;BlueprintTicks.capture的level.getChunkAt会强制加载(必要时生成)扫描区内区块,请确认rangeX/Y/Z上限下的最坏区块数可接受。 BuildingCommit.set新增的serverLevel.onBlockStateChange(pos, previous, state)/state.onBlockStateChange(level, pos, previous)在 1.21.1 侧的可用性我只做了源码面观察(本地无 1.21.1 反混淆环境),若 CI 未覆盖请留意。
结论: REQUEST_CHANGES — 核心机制(平铺、运行状态/计划刻恢复、实体引用恢复、材料账目重建)设计成体系且多数细节经得起推敲,但 🔴1(区域恢复 + 全额退款 ⇒ 复制物品)与 🔴2(consumed() 抵扣 no-op)直接影响玩家物品守恒,且 PR 描述仍写着"仅撤销状态未变化的建造组"与实现不符;另有 zh_cn 漏翻、实体 abort 整份建造、Iris/电网改动混入范围等需处理。
由 Hermes Agent 审查(本轮已核实项均以代码/目标分支文件为准;未实测项已在"待确认"中标明)
|
💾 Self-improvement review: Patched references/blueprint-repetition-and-runtime-entity-restore-review.md in skill 'building-rod-blueprint-review' (1 replacement). · Patched SKILL.md in skill 'building-rod-blueprint-review' (1 replacement). |
代码审查摘要 — PR #4971操作: review_requested(state=open, mergeable=true) 🔴 需合并前处理1. 撤销改为「整区域快照回滚」——与描述不符,且存在刷物品 / 丢物品路径
建议:恢复粒度收敛到 cells(或 2.
|
| 声称 | 状态 | 对应实现 |
|---|---|---|
| 拖拽平铺投影 / 松开锁定 / 再右键批量粘贴 (resolved #4966) | ✅ | BlueprintPlacement.tile、BuildingRodService.blueprints/planBlueprint、BuildingRodPacket.PLACE_BLUEPRINTS、BuildingRodClient.beginBlueprintSelection/blueprintPlacements/confirm |
| 选区距离锁定 + 方向调整 + 尺寸显示 (resolved #4963 / #4964) | ✅ | canAdjustDistance/selectionOffset/applyControl(index≥2)、selectionBounds() + setOverlayMessage(selection_size)、BuildingRodRenderer |
| 统一快照采集 + 运行进度/计划刻/时间基准 + Litematica 计划刻 | BlueprintCapture/BlueprintTicks/BlueprintRuntimeData/LitematicaImporter 均到位,但客户端预览仍是旧路径( |
|
| 建造后红石/流体/邻居更新、避免误触发侦测器 | ✅ | BuildingCommit.activate/activatePlaced/isRestoredObserverUpdate + BlueprintLevelMixin |
| 扩展生物/掉落物/投射物/移动方块/模组实体 + 运动/乘骑/实体引用 | ✅ | DynamicBuildingEntities、BlueprintEntities.flatten/link、BuildingEntityTransform、VanillaBuildingEntities |
| 树脂封存生物供料 + 装备/库存/流体需求 | ✅(生存下生物装备按设计不继承) | fromMaterial、reserveCreature、EntityBuildAdapters.insertContents(Mob) |
| 磁铁/铁砧锤/点火工具校验 + 不支持对象提示 (fixed #4968 / resolved #4970) | ✅ | MagnetizedNodeBuildAdapter.requiredTool、DynamicBuildingEntities.Outlet.requiresHammer、group.ignitions → 打火石/火焰弹、unsupported_type |
| 实体纳入撤销 | 已纳入(receipt.entities/drops/derived),但区域级回滚带来复制/丢失风险(🔴1、🔴2) | |
| 蓝图导出同名自动加序号 + 反馈实际文件名 | ✅ | StructureBlueprintFiles.write → StructureScannerFiles/BlueprintClientFiles 回传名称(含 isSafeName + .nbt 校验) |
(#4963/#4964/#4966/#4968/#4970 仍为 open,随本 PR 合并关闭,映射均能在 diff 中找到落点。)
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
BuildingRodUndo.undo + BuildingRegionSnapshot.restore |
建造后在区域内取走容器物品 / 放置方块 / 击杀实体 → 断言无复制、无未授权回滚 | 🔴 |
BuildingRodUndo.blockDrops/fallingBlock |
区域内挖矿留下掉落物 + 建造后撤销 → 断言无关掉落物保留 | 🔴 |
BuildingRodUndo.consumed |
容器内容 + 回执对账(去重是否生效/是否多扣) | 🔴 |
BlueprintEntities.fromMaterial |
生存用刷怪蛋/树脂建造带装备生物 → 断言装备来自材料而非蓝图 | 🟡 |
BlueprintEntities.limitMotion/restoreMotion |
Motion 极大值 (1e6,0,0)、NaN、非 3 元素 → 断言 ≤15.9 且有限,load 后速度保持 |
🟡 |
BlueprintPlacement.tile |
last 与 anchor 同点 / 反向 / 超大 → 空列表 + too_many;平铺包围盒与 cells 数量一致 |
🟡 |
BlueprintTicks read/write |
未知类型、>32768、负 delay、capturedAt=0(Litematica)→ 拒绝/clamp/回环相等 |
🟡 |
StructureSnapshotCodec |
write→parse 回环含 ticks/capturedAt;旧文件(缺这两个键)兼容 | 🟡 |
BuildingMaterials.reserve |
工具(锤/磁铁/打火石)保留 1 个不被消耗、restoreSources 回滚、缺料清单含工具与 ×N 数量 |
🟡 |
StructureBlueprintFiles.write |
连续同名导出 → _1/_2 后缀、名称 ≤128、返回名称可被客户端校验通过 |
🟢 |
IrisState/CelestialIrisRenderer |
无 Iris、Iris 加载失败、shader reload 后 reset() 无残留缓冲 |
🟢 |
PowerGrid.flush |
多玩家 + 离线/跨维度组件 → 需求分配不重复计费、getRemaining() 不为负 |
🟢 |
结论: REQUEST_CHANGES — 功能面实现完整、覆盖面好(15 个新类、工具/生物/拴绳/实体引用/计划刻都接上了,生存经济漏洞也堵住了),但**撤销语义从「按组校验」改成「整区域回滚」**带来刷物品与误删掉落物两条实际风险,且与 PR 描述不一致;另有 1 处(consumed() 去重)实际未生效、1 处预览/导出采集路径不一致待确认。建议至少修掉 🔴1、🔴2 与
由 Hermes Agent 审查
|
操作类型为 closed(该 PR 已于 2026-09-21T12:30:37Z 合并, 本轮未做任何代码审查分析、未执行任何 gh 评论/修改命令,也未改动 PR 标题。 建议:如需对已合并的 #4971 做事后审查(post-merge review),请以新的同步事件(例如后续 |
Uh oh!
There was an error while loading. Please reload this page.