Fixed the issue where the smart block placer couldn't obtain blueprint previews in a server environment. 修复了26.1服务器环境下智能方块放置器获取不到蓝图预览的问题#3809
Conversation
- 调整物品栏加载顺序,先加载磁盘物品确保结构加载不被误判清空 - 在 loadFromTag 中重置无效结构标志,避免错误状态残留 - 在载入NBT时同步结构缓存数据,支持客户端蓝图预览功能 - 处理缓存结构UUID的解析,提升结构识别准确性 - 保证hasStructureDisk和hasInvalidStructure状态正确设置
Reason: delete in root path Reply |
|
现在我有足够的上下文来完成审查。以下是我的分析: PR #3809 代码审查仓库: Anvil-Dev/AnvilCraft ✅ 看起来不错1. 物品栏加载顺序调整( 逻辑正确。原来 2. 无效结构标志重置( this.hasStructureDisk = true;
+this.hasInvalidStructure = false;在成功加载结构后重置错误状态,防止先前失败的状态残留误锁后续操作。与原有的 3. 客户端蓝图预览同步( 4. 无遗留调试语句、无密钥泄露、无合并冲突标记。 💡 建议建议 1(中等)— this.loadedStructure = this.loadStructureData(tag.getCompoundOrEmpty("cachedStructure"));
try {
this.loadedStructure = this.loadStructureData(tag.getCompoundOrEmpty("cachedStructure"));
this.loadedStructureName = tag.getStringOr("cachedStructureName", "");
// ... UUID 解析 ...
} catch (Exception e) {
LOGGER.warn("Failed to load cached structure from sync data", e);
this.loadedStructure = null;
this.loadedStructureName = "";
this.loadedStructureUuid = null;
}建议 2(低)— this.loadedStructureUuid = UUIDUtil.CODEC.parse(
NbtOps.INSTANCE, tag.getCompoundOrEmpty("cachedStructureUuid")
).result().orElse(null);
📝 总结PR 的 5 个变更目标全部正确实现,逻辑清晰、改动精准。修复了服务器环境下蓝图预览失效的问题,是高质量的热修复。仅有的建议涉及异常鲁棒性,非阻塞性问题。 |
|
我现在已经掌握了完整的变更信息。以下是审查报告。 🔍 PR #3809 代码审查摘要状态:评论(小的注意事项,不阻塞合并) 文件: 🟢 主要变更(正确)1. 物品栏加载顺序调整( ✅ 这是此 PR 的核心修复。 2. 重置失效结构标志( this.hasStructureDisk = true;
this.hasInvalidStructure = false; // 新增✅ 当找到有效的结构磁盘时,显式清除失效标志。逻辑正确,防止状态残留。 3. 同步包中结构缓存数据加载( ✅ 从菜单同步包中读取
|
代码审查摘要 — PR #3809仓库: Anvil-Dev/AnvilCraft 🔍 变更总览
✅ Change 1:加载顺序修复(核心改动)位置: 旧逻辑: 新逻辑: 👍 正确且解释清晰。 这是服务端环境下面板预览丢失的根因—— if (nowHasDisk == this.hasStructureDisk && currentUuid != null
&& currentUuid.equals(this.loadedStructureUuid)) return;当 ✅ Change 2:重置无效结构标志位置: this.hasStructureDisk = true;
this.hasInvalidStructure = false; // ← 新增👍 合理的保险措施。如果 BE 在保存时 ✅ Change 3:菜单同步数据中的结构缓存位置: if (tag.contains("cachedStructure")) {
this.loadedStructure = this.loadStructureData(...);
this.loadedStructureName = ...;
this.loadedStructureUuid = ...;
this.hasStructureDisk = true;
this.hasInvalidStructure = false;
}👍 逻辑与 这个新增块是客户端预览的核心:当菜单打开(客户端侧),服务端发送的 sync data 中包含 💡 建议
✅ 看起来不错
📋 总结
建议操作: 批准合并。 |
- 新增客户端向服务端请求结构预览数据的网络包 StructurePreviewRequestPacket - 服务端读取结构文件,提取调色板和方块列表数据返回给客户端 - 客户端通过 StructurePreviewResponsePacket 接收并缓存原始NBT数据 - 在预览渲染时解析NBT数据为结构信息,构建并缓存LevelLike对象 - 实现本地文件加载及缓存淘汰策略,防止内存泄漏 - 优化缓存管理,避免重复请求,支持请求超时重试机制 - 增加路径和文件名校验功能,防止路径穿越攻击
Reason: Security scan — [MEDIUM] Variation selector characters detected: Content contains Unicode variation selectors (VS1-256). These are commonly used in emoji sequences but may indicate steganographic encoding or obfuscation Reply |
|
以下是 PR #3809 的完整代码审查。 代码审查摘要结论:评论(3 条建议,无阻塞性问题) 概述此 PR 修复了 26.1 服务器环境下智能方块放置器无法获取蓝图预览的核心问题——客户端无法直接访问服务端文件系统上的结构文件。架构上引入了 C2S 请求 → S2C 响应 的网络通信模式,配合三级缓存策略实现蓝图预览。 文件变更统计
🟠 警告1.
|
|
所有检查完成。以下是完整的审查意见: 代码审查摘要结论:建议修改(2 个警告,2 条建议) 🟢 主要变更概述该 PR 通过引入客户端-服务端网络预览协议修复了 26.1 服务器环境下智能方块放置器无法获取蓝图预览的问题:
|
- 删除了 StructureDiskPreviewSupport 中的@SuppressWarnings注解及多余空检查 - 结构数据接收逻辑中移除空检查,避免重复判断 - StructurePreviewRequestPacket 中校验 previewData 的 palette 和 blocks 非空,避免解析失败重试 - StructureLoadUtil 中添加最大预览方块限制(4096),超出时截断并打印警告日志 - 优化结构文件加载时 palette 和 blocks 的复制逻辑及异常处理
|
好的,我已经完整分析了 PR #3809 的所有 6 个文件的变更。以下是审查。 代码审查摘要结论:评论(1 个警告,3 条建议,无阻塞性问题) 🟢 主要改动概述该 PR 修复了智能方块放置器在服务器环境下无法获取蓝图预览的问题。核心思路是引入 C2S/S2C 网络协议,让客户端在无法直接读取服务端结构文件时,通过请求-响应机制获取预览数据。涉及 6 个文件,±386 行净变更。
|
- 调整NbtAccounter内存限制为128MB,避免无限堆内存消耗 - 改进结构文件读取的稳定性和性能 - 防止因内存无限制占用导致的潜在崩溃风险
|
现在我已掌握所有更改的全貌。以下是审查结果: 代码审查摘要 — PR #3809结论:评论(无阻塞性问题,有一些建议) 范围: 6 个文件,+369/−97 行。修复 26.1 服务端环境下智能方块放置器的蓝图预览缺失问题。 🔵 主要逻辑分析1.
✅ 正确性:修复逻辑正确。旧代码先调 2. this.hasStructureDisk = true;
this.hasInvalidStructure = false; // 新增✅ 在 3. 菜单同步包中包含
4. 服务端读取结构 ✅ 设计合理——不发送 5. 将缓存架构从"5秒过期"改为会话级永不过期(仅条目超过 100 时淘汰最旧),并新增三阶段缓存策略:
获取预览的新降级链:① 本地缓存 → ② 服务端待处理数据 → ③ 本地文件加载 → ④ 向服务端发网络请求 ✅ 去重机制防止大量 6. 标准的 C2S/S2C 请求-响应模式。服务端收到请求后调用 ✅ 使用标准的 NeoForge StreamCodec 编码。
|
|
好的,所有变更已看完,以下是完整的审查意见。 代码审查摘要PR #3809 — Fixed server environment blueprint preview for SmartBlockPlacer
🟢 主要更改1. SmartBlockPlacerBlockEntity.java — 加载顺序修复(+18/-2)
2. StructureDiskPreviewSupport.java — 缓存策略重构(+147/-75) 预览系统从单人模式扩展为 CS 架构:
3. 新网络包:StructurePreviewRequestPacket(+77,C2S)
4. 新网络包:StructurePreviewResponsePacket(+43,S2C)
5. StructureLoadUtil.java — 新增预览数据加载(+78/-14)
6. StructureSaveUtil.java — 一致性调整(+6/-6)
💡 建议(非阻塞性)
✅ 看起来不错
结论建议:评论(Comment)— 无阻塞问题,可以合并。 该 PR 正确地解决了服务器环境下智能方块放置器无法获取蓝图预览的核心问题。关键修复(加载顺序调整)简单有效,同时通过新增 C2S/S2C 网络包构建了完整的客户端-服务端预览数据同步体系。缓存架构重构干净,安全措施到位,代码质量良好。以上建议均为可选的优化方向,不阻塞合并。 由 Hermes Agent 审查 |
- 调整UUID解析的代码换行,提升可读性 - 保持原有逻辑不变 - 符合代码风格规范
- 使用 PropertyDispatch 优化 SmartBlockPlacerBlock 和 StructureScannerBlock 的方块状态渲染 - 增加倒挂(upside_down)属性,完善模型旋转逻辑,支持水平方向和上下翻转 - 修正 SmartBlockPlacerBlock 中倒挂状态的碰撞盒形状计算 - 优化 SmartBlockPlacerBlockEntity 的前置扫描逻辑,停止模式下缺少物品时停止扫描 - SmartBlockPlacerScreen 中预览结构时添加倒挂方向渲染及结构数据翻转处理 - 更新 smart_block_placer.json 和 structure_scanner.json 增加倒挂相关方块状态配置
Reason: Security scan — [MEDIUM] Variation selector characters detected: Content contains Unicode variation selectors (VS1-256). These are commonly used in emoji sequences but may indicate steganographic encoding or obfuscation Reply |
代码审查摘要结论:评论(发现若干建议,无阻塞性问题) 📋 变更总览本 PR 修复了 26.1 服务端环境下智能方块放置器无法获取蓝图预览 的问题,涉及 11 个文件 约 1,108 行差异。核心变更:
💡 建议1. 蓝图模式"停止"行为变更可能影响用户体验
2. 预览数据截断缺乏客户端感知
这属于优化建议——当前实现对预览功能无功能性问题,只是大结构用户可能感到困惑。 3. 请求去重超时期间无 loading 状态
4. 生成 JSON 缺少末尾换行符 两个 ✅ 值得肯定的设计
📊 文件变更统计
由 Hermes Agent 审查 |
Reason: Security scan — [MEDIUM] Variation selector characters detected: Content contains Unicode variation selectors (VS1-256). These are commonly used in emoji sequences but may indicate steganographic encoding or obfuscation Reply |
代码审查摘要结论:评论(观察到 2 条建议,无阻塞性问题) PR 概览: 新增 C2S/S2C 网络包体系,解决服务端环境下智能方块放置器的蓝图预览无法获取的问题。核心变更包括:新增 📋 变更总览
💡 建议1.
|
| 项目 | 旧版 | 新版 |
|---|---|---|
| 缓存键 | String (UUID 或 hash) | UUID (直接从 diskData) |
| 过期策略 | TTL 5秒 + 间隔清理 | 会话级永不过期 + LRU淘汰 |
| 请求去重 | 无 | UUID去重 + 30秒超时重试 |
| 对象 | PreviewCache (class) | PreviewCache (record) |
- UUID 作为缓存键消除了 hash 碰撞风险
- 会话级永不过期避免了 tooltip 渲染时的重复请求
MAX_CACHE_SIZE = 100防内存泄漏- 请求去重 + 超时机制合理
安全方法重构评估:✅ 逻辑正确
isValidStructureFile → isInvalidStructureFile,isPathWithinBaseDirectory → isPathOutsideBaseDirectory,所有调用点的取反关系已正确更新:
旧: if (!isValidStructureFile(name)) → error
新: if (isInvalidStructureFile(name)) → error
✓ 等价
旧: if (!isPathWithinBaseDirectory(path, base)) → error
新: if (isPathOutsideBaseDirectory(path, base)) → error
✓ 等价
StructureSaveUtil 中也同步更新了同样的命名转换。
SmartBlockPlacerBlock 形状修正:✅ 正确
旧: SHAPE_NORTH_UPSIDE = rotate(X, 180, SHAPE_NORTH) ❌
SHAPE_SOUTH_UPSIDE = rotate(X, 180, SHAPE_SOUTH) ❌
新: SHAPE_NORTH_UPSIDE = rotate(X, 180, SHAPE_SOUTH) ✅
SHAPE_SOUTH_UPSIDE = rotate(X, 180, SHAPE_NORTH) ✅
绕 X 轴旋转 180 度时,NORTH ↔ SOUTH 自动互换,旧值导致 NORTH_UPSIDE 和 SOUTH_UPSIDE 形状交换了位置。
NBT 加载顺序修复:✅ 正确
旧: loadFromTag(tag) → loadItemsFromTag(...)
→ loadFromTag 中 tryLoadStructure 可能在物品尚未加载时
误判"磁盘槽位为空"而清空 cachedStructure
新: loadItemsFromTag(...) → loadFromTag(tag)
→ 先加载物品确保 tryLoadStructure 能正确识别磁盘物品
同时 loadFromTag 中增加了 this.hasInvalidStructure = false; 的显式重置,防止旧状态残留。
applySyncDataFromMenu 新增结构缓存同步:✅ 正确
菜单同步包现在携带 cachedStructure/cachedStructureName/cachedStructureUuid,客户端收到后更新到结构缓存中,使蓝图预览能直接从本地缓存命中,减少网络请求。
SmartBlockPlacerScreen 预览渲染改进:✅
- 倒挂状态下 X/Z/Y 坐标正确翻转
- 方块状态
rotate(Rotation.CLOCKWISE_180)+flipHalfPropertyStatic - placer 自身不再设置 UPSIDE_DOWN 属性(预览渲染仅在结构旋转层面处理正倒挂,更简洁)
新网络包 StreamCodec 设计:✅
StructurePreviewRequestPacket 使用 UUIDUtil.STREAM_CODEC + ByteBufCodecs.STRING_UTF8,StructurePreviewResponsePacket 使用 ByteBufCodecs.COMPOUND_TAG。编解码简洁高效。服务端对空结构文件和空 palette/blocks 的日志警告策略合理。
loadPreviewData 安全截断:✅
MAX_PREVIEW_BLOCKS = 4096 限制了单个预览包的大小,超过时截断并记录日志。这防止了超大结构导致网络包超过 Minecraft 的 2MB 包大小限制。
Java 21 未命名模式变量:✅
case BedBlock _ -> // 替代旧的 case BedBlock bedBlock ->
case DoorBlock _ -> // 替代旧的 case DoorBlock doorBlock ->JEP 443 (JDK 21 final) 语法,清理未使用变量警告,无行为变化。
🔎 审查清单检查结果
| 类别 | 结果 |
|---|---|
| ✅ 正确性 | NBT加载顺序修复方案合理;缓存策略正确;网络包设计合理 |
| ✅ 安全性 | 路径遍历防护已保留(仅重命名),文件名白名单验证未放宽 |
| ✅ 代码质量 | 结构清晰,注释充分(中/双语),命名改善 |
| 缓存策略大幅提升(去除了 TTL 重计算),但并发映射可优化 | |
| diff 中未见新增测试代码(模组项目常见,建议确认手动测试覆盖) | |
| ✅ 文档 | JavaDoc 注释完整,缓存策略用 ul 标签详细说明 |
| ✅ 向后兼容 | NBT 加载兼容旧路径(保留 loadFromTag 调用) |
✨ 总结亮点
- 核心问题定位准确:服务端无本地文件 → 网络同步是唯一正确方案
- 缓存策略设计合理:会话级永不过期 + 去重 + 超时重试的三层保障
- 变更范围控制良好:仅涉及预览相关逻辑,未引入不必要的重构
- 安全防护保留:路径遍历和文件名验证在原语义下完整保留
建议: 确认网络包在 NeoForge PayloadRegistrar 中的注册代码是否存在,并评估 HashMap 是否需要升级为 ConcurrentHashMap。
由 Hermes Agent 审查 · PR #3809 · synchronize · 26.1 服务器环境蓝图预览修复
|
现在我已经审查了所有文件,以下是完整的审查意见。 代码审查摘要 — PR #3809结论:评论(无阻塞性问题,2 条建议) PR 范围: 修复智能方块放置器在 26.1 服务器环境下无法获取蓝图预览的问题 + 添加倒挂模型支持 🟢 主要变更架构该 PR 引入了 C2S/S2C 网络协议 来解决服务器环境下磁盘预览的问题: 三层缓存策略:
核心修复:
✅ 代码质量
|
|
PR #3809 已被关闭(action: 根据
因此我不会下载 diff 或执行任何审查。PR 已合并/关闭,无需进一步操作。 |
Uh oh!
There was an error while loading. Please reload this page.