Fix wrong behaviour in storage systems 修复存储系统中的错误行为#4190
Conversation
…port custom category and player inventory display
|
现在我拥有所有必要信息来提供全面的审查。 代码审查:PR #4190 — 修复存储系统中的错误行为作者: QiuShui1012 架构概览本次 PR 是一次重大的存储系统 UI 重构,将界面从原版 Minecraft 的
1. 修复:三种大型多方块无法打开界面 ✅根因定位正确。 大型储箱(LargeCrate)、超维存储站(HyperdimensionStorageStation)和潜影贝容器(ShulkerContainer)在获取 BlockEntity 时使用了点击位置的原始 // ❌ 旧代码(错误):直接使用点击位置 pos
BlockEntity blockEntity = level.getBlockEntity(pos);
// ✅ 新代码(正确):获取主块坐标再查 BE
BlockEntity blockEntity = level.getBlockEntity(this.getMainPartPos(pos, state));这解释了为何只有大型多方块无法打开界面——小型 CrateBlock 是单方块结构,不受此影响(CrateBlock 未使用 所有四个存储方块统一采用了 2.
|
| 类别 | 结果 | 备注 |
|---|---|---|
| 正确性 | 多方块修复正确;reorder 空方法、死代码需清理 | |
| 安全性 | ✅ | 无硬编码密钥;spectator 检查正确 |
| 序列化兼容 | PlayerSetting.storageSettings → storage 需迁移路径 |
|
| 代码质量 | ✅ | 整体重构清晰,职责分离好 |
| 死代码 | 注释掉的 checkHotbarKeyPressed 应删除 |
|
| 测试 | ❓ | 未看到测试文件变更(RPC stub 功能建议添加 unit test) |
| 语言 | ✅ | 中/英同步,无残留 |
| 删除完整性 | ✅ | 旧类完全移除,无残留引用 |
结论
基本通过,建议修复以上 3 个
- 删除
StorageScreen.java中注释掉的checkHotbarKeyPressed死代码块 - 填充或标记
StorageServerStub.reorder()的空方法体(至少加// TODO注释) - 评估
PlayerSetting.storageSettings→storage序列化变更的向后兼容性影响,必要时添加迁移码
…when outputting them into storage blocks
|
现在我对整个 PR 有了全面的了解,让我生成审查报告。 代码审查摘要 — PR #4190操作: synchronize 概览本 PR 对存储系统 GUI 进行了重大重构:
🔴 关键问题1. StorageServerStub 静态 STUBS 映射可能泄漏
2. 界面关闭时携带物品可能掉落(低风险)
|
| 声称 | 状态 | 对应文件 |
|---|---|---|
| #3582 主界面 — 玩家物品栏 | ✅ | StorageScreen.java — Screen 化重构,直接渲染 Inventory 槽位并处理输入 |
| #3582 类别设置 — 添加自定义类别 | ✅ | CategorySettingsScreen.java — 独立 Screen,管理 FilterCategory 的 listed/alternate |
| 拆分主界面和类别设置界面 | ✅ | 旧 CategorySetting widget 删除 + StorageScreen 中将设置打开改为跳转 CategorySettingsScreen |
| 修复三种大型多方块无法打开界面 | ✅ | HyperdimensionStorageStationBlock.java、LargeCrateBlock.java、ShulkerContainerBlock.java — 全部使用 getMainPartPos() |
| 架构迁移:Menu → Screen + RPC | ✅ | 新建 4 个 RPC stub 文件 + 删除 StorageMenu.java + 移除 MenuProvider 实现 + 移除 ModMenuTypes.STORAGE 注册 |
✅ 看起来不错
- 四类方块(CrateBlock + 三个多方块)的
useItemOn统一实现了新模式,代码结构一致 DistExecutor.run(Dist.CLIENT, ...)正确限制了客户端侧的屏幕打开OwnSettingValidator和StorageAccessValidator提供了合理的 RPC 安全检查- 删除
StorageMenu时同步删除了ModMenuTypes.STORAGE注册和StorageScreen的AbstractContainerScreen继承,清理完整 - Gradle 依赖
anvillib升级到2.0.0+snapshot.492(支持新 RPC 功能) - 所有 lang key 变更与 ScreenLang.java 中的更新一致
- 旧网络包
StoragePackets.sync的引用已被完全移除
结论: COMMENT — PR 代码质量较高,架构迁移设计合理,多方块 bug 修复正确。主要问题 STUBS 映射泄漏和 removed() 中物品掉落风险当前影响有限,建议在后续迭代中处理。无阻塞性问题。
Reason: script execution via -e/-c flag Reply |
|
现在我已全面理解了所有变更。以下是完整审查报告。 代码审查摘要 — PR #4190操作: 变更分类
🔴 关键1.
2.
3.
|
Reason: script execution via -e/-c flag Reply |
|
我现在已经有了对本次 PR 的全面了解。让我输出审查意见。 代码审查摘要 — PR #4190操作: edited 架构变更概览本次 PR 对存储系统做了重大的架构重构:
✅ 关键问题修复验证🔴 1. 存储方块"吞物品" — 已修复 public ItemStack quickMoveStack(Player player, int slotIndex) {
return this.getSlot(slotIndex).getItem(); // ← 经典"吞物品"存根!
}此实现违反 🔴 2. 大型多方块无法打开界面 — 已修复 // 旧(使用点击位置)→ 对于子方块,getBlockEntity(pos) 返回 null
BlockEntity blockEntity = level.getBlockEntity(pos);
// 新(归一到主块位置)
BlockEntity blockEntity = level.getBlockEntity(this.getMainPartPos(pos, state));涉及: 🔍 新增代码审查3.
4.
5. private static final Map<UUID, StorageServerStub> STUBS = new HashMap<>();
6.
📋 声称验证表
🟢 看起来不错
|
Reason: script execution via -e/-c flag Reply |
|
以下是 PR #4190 的代码审查。 PR #4190 — 审查:存储系统行为修复总览: 44 个文件变更,4364 行 diff。这是一次重大的存储系统架构重构,从 ✅ 核心问题修复1. 多方块 UI 无法打开 ✅涉及文件: 旧代码使用 修复: 改为 - BlockEntity blockEntity = level.getBlockEntity(pos);
+ BlockEntity blockEntity = level.getBlockEntity(this.getMainPartPos(pos, state));
2. 存储方块吞物品 ✅涉及文件: 旧代码的 public ItemStack quickMoveStack(Player player, int slotIndex) {
return this.getSlot(slotIndex).getItem(); // ← 经典吞物品 bug!
}这是 Shift+点击吞物品的经典 bug—— 3. 主界面与类别设置界面拆分 ✅
🔄 架构变更RPC 迁移(从自定义网络包 → anvilcraft-lib RPC)
优点: 类型安全、
类别系统重构
关键的架构决策:
|
| 项目 | 状态 | 备注 |
|---|---|---|
| 正确性 | ✅ | 多方块 BE 定位已修复;quickMoveStack 吞物品 bug 已消除 |
| 安全性 | ✅ | 携带物品清空、RPC 验证器、玩家 ID 校验 |
| 代码质量 | ✅ | 干净的架构迁移,IClientCategory → ICategory,FilterContent 更精确 |
| 测试 | 无法从 diff 确认测试覆盖。removed() 中的携带物品清空逻辑值得写测试 |
|
| 性能 | 排序缓存清除策略可能在大存储/高更新频率下成为瓶颈 | |
| 文档 | ✅ | 新增 lang 键完整;PlayerSettings.getSetting(UUID) 的 Javadoc 提示了参数类型 |
| 数据兼容性 | PlayerSetting 存格式破坏性变更——确认旧存档是否有迁移方案 |
总结
这是一个设计良好的架构重构,正确解决了所有三个目标问题:
- 多方块 UI —
getMainPartPos修复 ✅ - 吞物品 — 删除有缺陷的
StorageMenu.quickMoveStack✅ - UI 拆分 —
StorageScreen+CategorySettingsScreen独立 ✅
…display in CategoryList
PR #4190 代码审查文件变更: 46 个文件(+2160 / -1437),无 EOF 换行符缺失、无合并冲突 总体架构变更 —— 从 AbstractContainerScreen/Menu 迁移到 Screen + RPC这是本 PR 最核心的变化,解决了存储系统大量的行为错误根源:
1. ✅ 大型多方块无法打开界面的修复四种存储方块( // 旧代码(只取点击位置的BE,对于多方块非主体部位会拿到错误的BE)
BlockEntity blockEntity = level.getBlockEntity(pos);
// 新代码(从任意部位正确找到主方块)
BlockEntity blockEntity = level.getBlockEntity(this.getMainPartPos(pos, state));✅ 关键修复: 另外去掉了 server 端的 2. ✅ FilterContainer 过滤内容校验// 旧
this.content = stack.getOrDefault(ModComponents.FILTER_CONTENT, new FilterContent());
// 新
this.content = Optional.ofNullable(stack.get(ModComponents.FILTER_CONTENT))
.filter(filter -> {
for (ItemStack content : filter.list()) {
if (!content.isEmpty()) return true;
}
return false;
})
.orElse(new FilterContent());✅ 修复了空白过滤器的边缘情况:如果 filter 物品有 3. ✅ FilterContent 增加 equals/hashCode
4. ✅ ICategory 接口简化(删除 HolderHolder + IClientCategory)
5. ✅ PlayerSetting 存储设置变更// 旧: Map<UUID, StorageSetting> storageSettings — 每个存储箱都有自己的设置
// 新: StorageSetting storage — 每个玩家只有一份统一的设置✅ 简化为每个玩家只有一个 6. ✅ StorageSetting 增加 searchContent
7. ✅ RPC 校验器安全
8.
|
| 问题 | 修复方式 | 严重程度 |
|---|---|---|
| 存储方块吞物品(Shift+点击) | 删除 StorageMenu 假槽位,改为纯 Screen + RPC | 🔴 关键 |
| 大型多方块无法打开界面 | getMainPartPos() 取代直接 getBlockEntity(pos) |
🔴 关键 |
| 过滤内容空列表意外行为 | Optional.filter + fallback 到空 FilterContent | 🟡 中等 |
| FilterContent 缺少 equals/hashCode | 实现完整比较方法 | 🟡 中等 |
| 搜索文本关闭后丢失 | StorageSetting 增加 searchContent 字段持久化 | 🟢 改善 |
| 服务端无法使用配方书分类 | RecipeBookCategoryCategory 移至主包、使用 server RecipeManager | 🟢 改善 |
建议:考虑在合适的 lifecycle hook 中清除 StorageServerStub.STUBS 以防止长期运行时缓存泄漏。
总评: 这是一个重大的架构重构(从 Container-based → Screen + RPC-based),一次性解决了存储系统的多个已知 bug。代码质量高,RPC 校验器安全,序列化兼容性被谨慎处理。建议批准合并。
|
现在我已充分分析,可以进行全面审查了。 代码审查摘要 — PR #4190操作: edited 🔴 关键
|
| 声称 | 状态 | 对应文件 |
|---|---|---|
| 主界面拆分(GUI 拆分) | ✅ | StorageScreen(重写为 Screen 子类)、CategorySettingsScreen(新文件) |
| 类别设置拆分 | ✅ | CategorySettingsScreen(新,原 CategorySetting 已删除) |
| 搜索栏 | ✅ | StorageScreen.init 中的 EditBox + SwitchableButton |
| 搜索栏状态按钮 | ✅ | SwitchableButton(SearchMode.CLEAR/RETENTION) |
| 排序方式按钮 | ✅ | SwitchableButton(SortMode.COUNT/MOD/NAME) |
| 排序顺序按钮 | ✅ | SwitchableButton(OrderMode.SEQUENTIAL/REVERSE) |
| NBT 折叠按钮 | ✅ | SwitchableButton(NbtDisplayMode.UNFOLD/FOLD) |
| 类别滚动条 | ✅ | CategoryList 滚动区域从 112 扩展至 160 |
| 添加自定义类别 | ✅ | CategorySettingsScreen + SettingServerStub.addCustom |
| 修复多方块无法打开 UI | ✅ | 4 个 Block 文件的 getMainPartPos 修复 |
| 修复存储方块吞物品 | ✅ | StorageMenu 删除(移除快速移动存根) |
结论: APPROVE — 该 PR 彻底修复了存储系统的架构问题。旧版基于 MenuProvider + AbstractContainerMenu 的方案被干净的 Screen + RPC 架构取代,多个 bug(吞物品、NPE、多方块位置偏移)一次性得到解决。代码质量高,序列化/验证等边缘情况处理得当。
由 Hermes Agent 审查
Uh oh!
There was an error while loading. Please reload this page.