Added Storage Fluid Port. 添加了仓储流体端口 - #4806
Conversation
- 新增 StorageFluidPort 方块及对应方块实体和渲染器支持 - 仓储端口扫描逻辑扩展,支持仓储流体端口互联共用核心路径 - 客户端存储界面新增流体伪槽位,渲染流体图标和数量 - 增加流体槽位鼠标交互,支持空桶现场取液操作 - JEI 集成增强,支持识别空容器+仓储流体的现场桶装配方输入 - 增加高效流体高度偏置计算,仓储流体端口控制流体水位 - 优化 FluidTank 渲染,支持内缩像素调整避免 Z-fighting - 增加仓储流体端口对应合成配方定义 - 修正物品分拣器默认面朝,潜行时反向摆放逻辑
- 优化FluidNetworkManager调用,避免level为空时的空指针异常 - 调整StorageJeiSupport的hasFluidFor方法逻辑,修正流体检测判定错误 - 修正TerminalJeiTransferSupport中判断空容器需求的条件,从deficit <= 0改为deficit == 0 - 调整导入引用顺序和删除无用导入,整理代码结构 - StorageScreen中修复getStorageSlot方法重复定义的问题 - StorageFluidPortBlockEntity新增获取核心主位置方法getCoreMainPos - 细节错误调整和注释优化,提高代码健壮性和可读性
- 为 ICategory 接口增加 testFluid 默认方法,支持流体判定 - 实现 FluidCategory 流体分类,定义流体分类图标与名称 - 在 OrCategory 和 AndCategory 中覆盖 testFluid 实现复合判定逻辑 - 命名空间分类支持对流体命名空间的判定 - 注册并引导流体分类,添加流体分类语言条目 - PlayerSetting 中添加默认流体分类条目 - StorageScreen 支持流体格的左键倒液体和右键物品行为存入 - StorageClientStub 和 StorageServerStub 支持移动物品时根据鼠标键决定是否倾倒流体 - 优化流体倾倒后空容器的回收逻辑,优先入仓储再回退玩家背包 - 服务端增加流体条目排序与分类过滤,保证流体正确参与存储排序与筛选 - 完善流体相关 RPC 调用参数及处理,兼容左右键操作不同逻辑 - 丰富客户端 TexturedButton,支持右键操作回调功能 - 新增流体分类数据文件定义,确保数据层支持流体分类功能
- 在移动物品之前记录点击的物品,避免首次移走整叠后记录被清空 - 实现 Shift+双击左键批量移入同种物品,与原版保持节奏一致 - 添加 findInventorySlotWith 方法,寻找仍持有目标物品的背包槽位 - 更新 lastQuickMoved 字段,用于跟踪上一次快速移动的物品 - 调整 StorageServerStub 导入顺序,优化代码结构
- 删除无用的minY变量,直接使用inset作为Y轴起始点 - 调整流体渲染盒子的Y轴起始和结束坐标为inset和计算后的maxY - 确保气体类型流体充满整个水箱且透明度正确 refactor(setting): 精简PlayerSetting类,移除废弃方法和不必要导入 - 删除addCustom(ItemStack)方法及相关FilterCategory导入 - 优化导入列表,去除未使用的类 - 保持自定义类别添加功能代码简洁明了
Reason: script execution via -e/-c flag Reply |
代码审查摘要 — PR #4806操作: opened 📋 声称验证表(对照 #4792 的 TODO 逐条核对)
🔴 关键1.
if (core == null || ...) { StorageFluidRegistry.unregister(this.worldPosition); return; }
...
StorageFluidRegistry.register(storage.getId(), serverLevel, this.worldPosition); // 旧 id 未清
顺带两个同源问题:
建议:
|
| 被测目标 | 推荐测试场景 | 优先级 |
|---|---|---|
StorageFluidRegistry.unregister/register |
端口链 A→B 重挂后 collect(A) 不再含该端口;跨维度同坐标端口互不误删 |
🔴 |
StorageServerStub.produceFilledContainer |
空容器数量/取用被并发或能力拒绝导致 removed < count 时,流体与空桶总量不变 |
🔴 |
fillBucketFromStorage |
两次 sync 之间流体列表元素增删后点击,仍取到点击时的那种流体 | 🟡 |
StorageFluidPortBlockEntity.computeNextHeightBias |
fill=0 / 0.5 / 0.62 / 0.75 / 1.0 及 ±20 clamp 边界;区间内保持偏置不再变化 | 🟡 |
FluidAmountUtil.formatAmount / formatExactAmount |
999 mB、1000 mB、1250 mB、≥1000 B 缩写、formatExactAmount(1575) |
🟢 |
StorageFluidPortBlockEntity.loadAdditional |
空/满/带组件的 tank NBT 往返;空端口掉落物与未放置物品可堆叠 | 🟡 |
pourIntoFluidPort |
端口余量不足(部分倒入)、无可用端口(回退存桶物品)、批量倒桶只播一次音效 | 🟡 |
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched SKILL.md in skill 'pr-diff-scope-reconciliation' (1 replacement). |
代码审查摘要 — PR #4806
|
| 声称 | 状态 | 对应实现 |
|---|---|---|
| 与仓储端口类似可互连延伸 | ✅ | StoragePortBlockEntity.findSoleCore / isPort 外提 |
| 128 B 单流体、拆除保留、门格海绵清除 | ✅ | CAPACITY_MB、saveToDrop、clearFluid |
| 50%~75% 水位自动调等效高度(最多 20 米) | ✅ | computeNextHeightBias / heightBiasAt |
| UI 显示流体、不占类别、按数量排序 | 折算 1 B = 1 物品,与原文 1 mB = 1 物品不符(见 5) | |
| 少于 1B 用 mB、达 1B 用 B、3 位有效数字 | ✅ | FluidAmountUtil |
| 点击流体格铁桶取一桶 / 缺桶提示 | ✅ | fillBucketFromStorage + 两条提示文案 |
| 倒桶自动进同流体端口,无端口则存桶物品 | ✅ | pourIntoFluidPort + 左键/右键分流 |
| JEI 识别空桶 + 流体现场合成盛装 | 做齐但部分失败路径吞资源(见 3) |
结论: COMMENT(草稿阶段) — 代码自上一轮起未变,上面 3 项 🔴 未修完前不建议转 ready;48 为建议项。修完 13 后可再触发审查复核。
复核说明:本轮同时把「新增 nullness 注解是否违规」按目标分支
AGENTS.md重新核对——dev/1.21/1.6规定必须用javax.annotation.Nullable(strict non-null by default,全树 439 文件用 javax、0 文件用 JSpecify),故本 PR 新增的 3 处 javax 注解合规,不构成问题;唯一不一致是StorageFluidPortBlock.java用了org.jetbrains.annotations.Nullable(💡 级一致性 nit)。
由 Hermes Agent 审查
- 引入 StorageFluidPortBlockItem,支持流体容量显示及物品内液面渲染 - 实现 StorageFluidPortItemRenderer,渲染物品内流体和模型玻璃窗口 - StorageFluidPortBlockEntity 新增存储流体端口连通性校验及注册机制 - 优化 StorageFluidRegistry,支持跨维度流体端口管理与流体匹配抽取 - StorageServerStub 支持按流体身份交互,增强流体桶操作的原子性与安全性 - StorageScreen 客户端交互改为发送流体身份,避免并发下流体对应错误 - ModelSelection 类使用模式匹配语法优化代码风格 - 添加渲染相关常量暴露,方便物品渲染统一内缩尺寸 - ServerLifecycleEventListener 中清理流体注册表,避免服务端残留数据
Reason: shell execution via heredoc Reply |
代码审查摘要 — PR #4806(
|
| 上轮问题 | 状态 | 复核依据 |
|---|---|---|
StorageFluidRegistry 改挂存储时旧登记不解除 |
✅ 已修 | 表改为 Map<ResourceKey<Level>, Map<UUID, Set<BlockPos>>>(与 StorageBlockRegistry 同形,维度优先);unregister(@Nullable UUID, ResourceKey<Level>, BlockPos);validateLink() 先注销旧 storageId、置 null,再重新 register;setRemoved() 带维度;ServerLifecycleEventListener 新增 clear() |
produceFilledContainer 部分失败吞资源 |
✅ 已修 | 两段 SIMULATE 预检(drain(..., true) + hasEnoughContainers)→ 先扣空容器(失败 giveBackContainers 还回)→ 再真 drain;并发不足时 giveBackContainers + refillFluid 灌回。差额与已耗材料都还清了 |
| 伪槽位用下标当身份 | ✅ 已修 | StorageClientStub.interact(..., FluidStack fluid)(@CallableParam(OPTIONAL_STREAM_CODEC)),服务端统一 StorageFluidRegistry.find(id, fluid) 按 isSameFluidSameComponents 匹配;客户端上报 getFluidSlot(slot).icon()。跨 RPC 身份已是实体而非下标 |
附带确认:上一轮 entry.amount()(mB);死状态 working / coreMainPos / getCoreMainPos() 已删除,findSoleCore + isPort() 提为 StoragePortBlockEntity 静态方法(两端口可互相延伸),StoragePortBlockEntity.validateLink() 仍在开头 working=false; coreMainPos=null,无回归。
⚠️ 建议处理(非阻塞)
StorageJeiSupport#hasFluidFor的 javadoc 与实现相反 — 实现是「仓储没有足量该流体 / 该物品不是流体容器 → 返回 true」,而本轮新增的 javadoc 写的是「仓储中存在足量(至少一桶)的同种流体」。两处调用点(if (hasFluidFor(...)) return false;/continue;)逻辑自洽,但注释与命名双反,后人按注释改动必然反转行为。建议改名(如needsOnTheFlyFilling)并修正注释。- 无关改动仍在 PR 内,用 blob 三点对比确认都来自本 PR 自己的提交(非继承自 dev):
- commit 1:
ItemSplitterBlock默认朝向翻转(getOpposite()去掉)、ModBlocks.ITEM_SPLITTER改.item(ChuteBlockItem::new)、font/small.png(401→958 B,所有仓储 UI 数字用它渲染); - 本轮:
pipe_glass_node.png(306→301 B)、ModelSelectionBakery把instanceof Fixed fixed改为 record 解构instanceof Fixed(SelectionPart part)(已核 AnvilLib 源码record Fixed(SelectionPart part),语义等价、可编译,非编译错误)。
PR 描述目前只有resolved #4792,建议拆分提交或在描述里逐条说明这些改动的理由(字体若有新字形需求请写明)。
- commit 1:
- 倾倒序列的 undo 不对称 —
deposit/moveInventoryStackToStorage的倾倒发生在matchesStorageItem过滤之前,且倒入产物不计入moved,被倒空的容器由giveEmptiedContainerToStorage入库 → Ctrl+Z 无法恢复。注释已声明是有意设计,建议在描述/提示里明示。
💡 提示(细节)
StorageFluidPortBlockEntity的 javadoc 称 FluidTank「锁定首个流体」;实际空罐可被另一种流体占用(findAcceptor也正是靠这个才给空端口首次入液),措辞可收紧。#前缀搜索时流体条目会被服务端全部排除(addFluidEntries只处理@,客户端对#直接放行原序),即流体 tag 搜索缺失;建议对齐物品的matchesTag或注明不支持。findAcceptor在多个空端口间按HashMap迭代序任选(且可能跨维度选择),首次入液会占掉「恰好为空」的端口;建议稳定顺序或注释说明。pourIntoFluidPort返回值是「触及的桶数」:端口接近满时 FluidUtil 只转移部分 mB 也算 1 桶,且返回容器可能不是空桶(注释写作「空容器」)。目前只用于「是否改动」判定,建议注释收紧。heightBias不入 NBT(重载回落 0,若水位已在 5075% 区间则不再主动泵送),且每次偏置变化都5 次);建议节流或持久化。FluidNetworkManager.markDirty触发全网重扫(一次充满约 4FluidAmountUtil.formatAmount(0)→"0 mB"(物品侧 0 直接显示0);≥1000 B 先(long)截断再缩写(1999 B →1K B)。显示细节,酌情统一。- nullness:本轮 3 处新增
javax.annotation.Nullable与目标分支dev/1.21/1.6的AGENTS.md(strict non-null by default,要求用 javax)一致 ✅;唯一 nit 是StorageFluidPortBlock.java用了org.jetbrains.annotations.Nullable,与同分支其它文件不一致,建议统一。
🟢 看起来不错
onContentsChanged覆写已含rememberFluid()+setChanged()+sendBlockUpdated(UPDATE_ALL)+StorageServerStub.onContentsChanged(storageId):流体变化既落盘又驱动仓储 UI 重同步。FluidEntry/SyncResult的StreamCodec.composite参数序与 record 声明逐一对应(VAR_INT数量 +OPTIONAL_STREAM_CODEC图标),无字段序错位;10 个新增/修改 JSON 全部可解析,EOF 换行缺失仅出现在 datagen 产物(既有模式)。- 序列化四路径共用
TAG_TANK,物品渲染器/FluidTankItemTooltip读取的Tank/Fluid键一致,掉落物保留流体且空端口不写 NBT 以保持可堆叠。 - 客户端伪槽位隔离彻底:
applySyncResult与applyPreservedSyncResults都刷新fluids,resetServerSlots/hasContents/getStorageSlot/applySearchFilter/ 渲染 /getFluidSlotAt统一按>= FLUID_SLOT_BASE分流;interact末尾重读containerMenu.getCarried()。 - 注册链完整:
ModBlocks带.item(StorageFluidPortBlockItem::new)、ModBlockEntities带.renderer(...)+.register()、Capabilities.FluidHandler.BLOCK、创造标签、pickaxe tag、recipe/advancement/loot/blockstate/category 全部就位;StorageInput.FLUID_BUCKET追加在枚举末尾,无序号兼容问题;TexturedButton右键门控isValidClickButton与onClick分支一致。
📋 声称验证表(issue #4792「[TODO] 仓储流体端口」)
| 声称 | 状态 | 对应实现 |
|---|---|---|
| 配方:空/潜影壳/空 + 储罐×3 + 空/潜影壳/空 → 1 个 | ✅ | recipe/storage_fluid_port.json(shulker_shell×2 + fluid_tank×3) |
| 128 B 容积、单一流体、拆除保留流体 | ✅ | CAPACITY_MB = 128 * 1000、TAG_TANK 四路径、getDrops/saveToDrop/playerWillDestroy |
| 门格海绵右键清除流体 | ✅ | StorageFluidPortBlock.useItemOn + clearFluid() |
| 可与仓储端口互相延伸连接 | ✅ | StoragePortBlockEntity.findSoleCore + isPort() 双方共认 |
| 等效高度调节维持 50%~75%、最多 20 米 | ✅ | computeNextHeightBias(LOW .5 / HIGH .75 / MID .625 / RATE 8 / MAX 20) |
| 气体行为类似(模拟压力) | ✅ | FluidNetworkScanner.heightBiasAt → effectiveHeight = Y + phi + bias(驱动气压推导) |
| UI 显示流体、不占类别、1 mB = 1 物品排序 | ✅ | addFluidEntries(entry.amount() 参与比较)、ModCategories.FLUID 仅默认列出 |
| 数量格式:<1B 用 mB、≥1B 用 B、小数三位有效数字 | ✅ | FluidAmountUtil.formatAmount / formatExactAmount |
| 点击流体格用铁桶取一桶,缺桶弹提示 | ✅ | takeFluidBucket + fillBucketFromStorage + bucket_missing / not_enough |
| 放入桶装流体时自动倾倒入端口,无端口则存桶物品 | ✅(行为扩展) | pourIntoFluidPort + findAcceptor(空端口也接受,与「无相同流体就存物品」的字面略有出入,属合理扩展,建议注明) |
| JEI 合成识别「空桶 + 流体」并自动盛装 | ✅ | countProducibleContainers + produceFilledContainer + StorageJeiSupport.addProducibleFluidContainers(检查阶段与可用池两端都补齐) |
🧪 测试建议
| 被测目标 | 建议场景 | 优先级 |
|---|---|---|
StorageFluidRegistry.unregister |
A 存储改挂 B 后 collect(A) 不含该端口;两维度同坐标互不影响;clear() 后无残留 |
🔴 |
produceFilledContainer |
SIMULATE 通过但 drain/容器不足时的回滚(容器与流体都归还);流体不足一桶的边界 | 🔴 |
| 流体伪槽位身份匹配 | 点击期间端口被拆 / 新区块卸载 / 接入新流体 → 按身份仍取到正确流体(不串流体、不发空请求) | 🟡 |
FluidAmountUtil |
0 / 999 / 1000 / 1575 / 999999 mB 的显示文本 | 🟡 |
| JEI 空桶+流体 | 流体不足一桶、空桶被多槽位争用时不得重复计数 | 🟡 |
结论: COMMENT(草案阶段) — 上一轮三项 🔴 均已修复且有据可查,本轮未发现新的阻塞问题;剩余为命名/注释、无关改动说明与显示细节类建议。建议在转 ready_for_review 前处理第 1、2 项(尤其 hasFluidFor 的反向注释与夹带改动的描述)。
PR 标题「Added Storage Fluid Port. 添加了仓储流体端口」准确且已中英双语,未修改标题(仅建议去掉句末句点以符合
<英文标题> <中文标题>惯例)。
由 Hermes Agent 审查
|
审查完成。以下是完整审查意见(已核对 PR head 全量源码 + 目标分支 代码审查摘要 — PR #4806操作: ready_for_review 🔴 关键(必须修复后再合并)
而 for (int i = 0; i < order.size(); i++) {
int index = order.getInt(i);
long stackAmount = view.amount(index); // ← index = 16777216 → IndexOutOfBoundsException触发条件(不需要特殊配置): 终端目标存储挂着有液体的流体端口,且排序把流体条目排在首个可取出物品条目之前:
服务端在交互/RPC 里抛出未捕获异常(终端取物失败、日志刷屏,视上层包装还可能断连)。 修复建议: 两处循环加守卫
|
| 需求 | 状态 | 对应实现 |
|---|---|---|
| 空/潜影壳/储罐×3 配方得 1 | ✅ | ShapedRecipeLoader.storageFluidPort ↔ recipe/storage_fluid_port.json 一致 |
| 可连集装箱/存储站,双向延伸连接关系 | ✅ | StoragePortBlockEntity.findSoleCore + isPort(含 StorageFluidPortBlock)共用扫描 |
| 128 B 单流体、拆除保留、海绵清除 | ✅ | CAPACITY_MB = 128 * 1000、saveToDrop/getDrops/playerWillDestroy、clearFluid |
| 50%~75% 等效高度自适应,±20 m,越远越快 | ✅ | computeNextHeightBias + ADJUST_RATE/MAX_HEIGHT_BIAS + FluidNetworkScanner 偏置 |
| 气体同样通过模拟压力维持 | ✅ | 同一偏置驱动 FluidPipeNetwork 的气压项(L559–560、L643) |
| UI 显示流体、不占类别、1 mB = 1 物品排序 | ✅ | StorageFluidRegistry.collect + FluidCategory + addFluidEntries(entry.amount() 直接参与比较) |
| 数量 <1 B 用 mB、≥1 B 用 B、三位有效数字 | ✅ | FluidAmountUtil.formatAmount / formatExactAmount |
| 点击流体格用桶装出,缺桶给提示 | ✅ | takeFluidBucket + bucket_missing/not_enough 提示 |
| 放桶装流体自动倾倒,无对应端口则存桶物品 | ✅ | pourIntoFluidPort + 左/右键区分(左键倒、右键存物品) |
| JEI 填充合成识别 空桶 + 流体 | ✅ | StorageJeiSupport.producibleFromFluid / addProducibleFluidContainers、withdrawNeedsFromStorages 现场盛装 |
另:PR 标题基本准确,仅建议统一为
Add Storage Fluid Port 添加仓储流体端口(现为 "Added Storage Fluid Port. 添加了仓储流体端口")。本次gh auth status显示/opt/data/home/.config/gh/hosts.yml中 token 已失效,故未自动修改标题。
🧪 测试建议
| 被测目标 | 建议场景 | 优先级 |
|---|---|---|
extractFromTerminal / terminalExtractFirst |
目标存储挂有含液体的流体端口 × 各 SortMode × OrderMode(含 REVERSE),确认 order 中的伪槽位被跳过、终端能正常取出物品 |
🔴 |
StorageFluidPortBlockEntity.computeNextHeightBias |
空罐 / 恰好 50% / 75% / 边界值 ±20 clamp / 多次 tick 后是否收敛不震荡 | 🟡 |
StorageFluidRegistry.drain(…, simulate) + produceFilledContainer |
跨端口凑量、模拟通过但 EXECUTE 失败、容器扣取失败的回滚 | 🟡 |
FluidAmountUtil |
999 mB / 1000 mB / 1024 mB / 128000 mB / 1234567 mB 的单位与有效数字 | 🟢 |
结论: REQUEST_CHANGES — 功能实现完整、对 #4792 的需求逐项落实且细节(偏置收敛、失败回滚、序列化/同步)质量较高;但必须修复终端取出路径对流体伪槽位的越界索引(🔴),并建议把 ItemSplitter 朝向/物品类改动、ModelSelectionBakery 重构、合成系统相关修复从本 PR 中拆出,二进制贴图改动请补充说明。
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). |
- 在StorageScreen中新增浮层提示组件,实现点击处提示流体交互失败原因 - 设计浮层显示优先级及位置,避免被界面其他元素遮挡 - 修改StorageServerStub,流体交互函数返回包含失败原因的结果 - 新增FluidNotice枚举,统一管理流体交互失败提示文本 - 细化装桶逻辑,提前判定空桶存在性并反馈具体提示 - 确保交互失败原因可传至客户端,由界面自行渲染提示信息 - 避免仓储界面中动作栏消息被界面覆盖,改用浮层提示机制
Reason: shell execution via heredoc Reply |
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: 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 |
代码审查摘要 — PR #4806(草稿)操作: 🔴 关键(建议合并前修复)1. 普通文本搜索时服务端丢弃流体条目,导致「按名称搜索流体」永远搜不到,客户端对应代码成为死代码
boolean matches = search.isEmpty()
|| search.charAt(0) == '@'
&& id.getNamespace().toLowerCase(Locale.ROOT).contains(search.substring(1));对照物品侧 boolean matchesSearch = search.isEmpty()
|| search.charAt(0) == '@' && id.getNamespace()...contains(...)
|| search.charAt(0) == '#' && item.tags().anyMatch(...)
|| search.charAt(0) != '@' && search.charAt(0) != '#'; // ← 普通文本:服务端放行,交给客户端流体这条少了「普通文本 → 返回 true」与
建议直接把
|
| 夹带改动 | 归属于 | 影响 |
|---|---|---|
ItemSplitterBlock.getStateForPlacement 朝向翻转(getHorizontalDirection().getOpposite() → getHorizontalDirection())+ ModBlocks.ITEM_SPLITTER 的物品类型 .item() → .item(ChuteBlockItem::new) |
878c5f6c |
已有方块行为变更:ChuteBlockItem.onItemUseFirst 会在被点击方块具备 ItemHandler 时改为 useOn(直接放置),与分配器朝向改动叠加,需要单独的测试与说明 |
ModelSelectionBakery 的 instanceof ModelSelection.Fixed(SelectionPart part) record 模式重构 |
d7695724 |
与流体端口无关,纯语言层改写 |
PlayerSetting.addCustom(ItemStack) 删除 + FilterCategory 导入清理 |
377adff3 |
死代码清理,混在 fix(renderer) 提交里 |
craftBudget()(64/perCraft → 按 maxStackSize)+ consumeCraftingInput/refillAndCollectSlots/autoRefillCrafting 剩余物重写 |
878c5f6c |
与「桶在合成里」相关,可留在本 PR,但改动量大,建议在描述里单独说明并给出验证方式(不可堆叠产物现在只合成 1 个,是行为变更) |
4. heightBias / rememberedFluid 都不持久化
rememberedFluid 不写 NBT 已在 javadoc 声明是有意的;heightBias 没有说明——重载/区块重载后偏置归零,管道网络会按真实 Y 重扫,10 tick 内重新收敛。若确认可接受,建议在字段 javadoc 里补一句,免得后续被当 bug 报。
5. StorageFluidRegistry.positions(UUID) 标注「供测试与调试使用」,但本 PR 未附任何测试
PR 覆盖了序列化往返(Tank)、网络 codec、合成剩余物、等效高度闭环调节等易错路径,建议至少补上:register/unregister 对称与跨维度隔离、collect() 同类流体合并与取空占位、computeNextHeightBias 的死区/±20 clamp、FluidAmountUtil 各档位,否则该 helper 属于无消费者的公开 API。
6. 流体伪槽位编号依赖 collect() 的列表顺序
槽位 = FLUID_SLOT_BASE + index,而 index 来自 livePorts() 遍历 HashMap<维度, Map<UUID, Set<BlockPos>>>(HashMap/HashSet 迭代序),且 order(createOrder 时)与 fluids(sync 时)是两次独立 collect()。点击路径已用流体身份 isSameFluidSameComponents 兜住服务端错配,但渲染侧仍可能瞬时把 A 流体的图标画到 B 的槽位。建议给流体槽位一个稳定映射(如按流体 id 排序或取最小坐标端口为代表)。
7. TerminalJeiTransferSupport.producibleFromFluid() 只看空容器、不看流体储量
javadoc 已说明「是否真有流体由服务端决定」,但 JEI 侧因此可能出现「可转移」假阳性、实际转移失败。若非有意保留,建议同时查 screen.getFluids()(StorageJeiSupport.producibleFromFluid 就是这么做的)。
🟢 看起来不错
- 与 [TODO] 仓储流体端口 #4792 要求逐条对应:配方(空/潜影壳/空 + 三储罐)、与仓储端口双向延伸连接、128 B 单流体、拆除保留流体、门格海绵清除、50%~75% 目标区间 + 最远 20 格等效高度调节、1 mB = 1 物品排序、mB / B / 三位有效数字显示、点击装桶 + 缺桶提示、倒桶自动倾入同流体端口(无端口回退存桶)、JEI 空桶+流体现场盛装。
StoragePortBlockEntity.findSoleCore()抽取等价(已与目标分支逐行对账:cores.size() != 1 → null、visitedPorts < CONNECTIVITY_LIMIT、isPort()覆盖两类端口均一致)。- 注册/生命周期对称:
onLoad → FluidNetworkManager.addContainer、setRemoved → removeContainer + StorageFluidRegistry.unregister,ServerStoppedEvent清静态表,与项目内FluidTankBlockEntity等既有模式一致。 StorageFluidPortBlock的getDrops/getCloneItemStack/playerWillDestroy(创造模式非空掉落)完全沿用StoragePortBlock的既有写法;空罐不写 BE 数据以保持可堆叠,考虑周到。- 交互失败提示走界面浮层而非动作栏(仓储界面开着时动作栏被遮挡)——设计正确;
FLYOUT_Z=300的层次与两次flush()的排序理由在注释里交代清楚。 StorageFluidPortBlockItem/ 渲染器 /FluidTankItemTooltip的Tank→Fluid结构一致;小字体small.json已声明0-9 . B m K M,新数量文本可渲染(纹理同步扩容)。- 生成文件「无结尾换行」与目标分支既有 datagen 输出一致(已实测
storage_port.json同样以}结尾),非问题。
📋 声称验证表
| 声称 | 状态 | 对应实现 |
|---|---|---|
| resolved #4792:方块 + 配方 + 连接延伸 | ✅ | StorageFluidPortBlock/BlockEntity、ShapedRecipeLoader.storageFluidPort、findSoleCore/isPort |
| 128 B 单流体、拆除保留、门格海绵清除 | ✅ | CAPACITY_MB、saveToDrop/getDrops、clearFluid |
| 等效高度 50%~75% / 最多 20 格 / 变化率随偏差 | ✅ | computeNextHeightBias(死区保持、Math.clamp(±20)) |
| UI 显示流体、1 mB = 1 物品排序 | ✅ | addFluidEntries(entry.amount() 直接入 OrderEntry) |
| 数量显示 mB/B/三位有效数字 | ✅ | FluidAmountUtil.formatAmount/formatExactAmount |
| 点击装桶 + 缺桶提示 | ✅ | takeFluidBucket/fillBucketFromStorage + FluidNotice.BUCKET_MISSING |
| 倒桶自动倾入 + 无端口回退存桶 | ✅ | pourIntoFluidPort/findAcceptor,失败回退 view.insert |
| JEI 空桶 + 流体识别并填充 | ✅ | StorageJeiSupport/TerminalJeiTransferSupport/produceFilledContainer |
| UI 中按名称搜索流体 | ❌ | 见 🔴 1(服务端普通搜索丢弃流体条目,客户端过滤分支不可达) |
结论: COMMENT(草稿态) — 功能与 #4792 要求基本对齐、生命周期与注册完整,但 🔴 1 使「流体搜索」这条设计好的路径实际失效(客户端已有代码却永远走不到),建议修复后再转 ready;同时建议拆分第 3 条列出的无关改动(尤其是 ItemSplitter 朝向/物品类型的既有方块行为变更)以便分别验证。
建议标题(gh auth status 显示 token 已失效,本次未自动修改):
Add Storage Fluid Port and fluid storage interactions 添加仓储流体端口与仓储流体交互
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
StorageServerStub.addFluidEntries |
普通文本 / @ns / #tag 搜索下流体条目必须保留(回归 🔴 1) |
🔴 |
StorageFluidRegistry |
register↔unregister 对称、跨维度同坐标隔离、clear()、同类流体合并与取空占位 |
🔴 |
StorageFluidPortBlockEntity |
saveAdditional/loadAdditional 往返、getUpdateTag 含 Tank、空罐不写 NBT、setRemoved 后注册表无残留 |
🔴 |
computeNextHeightBias |
0.5/0.75 死区、±20 clamp、空罐归 0、偏差越大步长越大 | 🟡 |
FluidAmountUtil |
999 mB / 1000 mB / 1.25 B / 1 000 000 mB(K 缩写) | 🟡 |
pourIntoFluidPort / fillBucketFromStorage |
无端口→存桶、仅剩 250 mB→提示缺桶优先、指针被占→不消耗空桶 | 🟡 |
StoragePortBlockEntity.findSoleCore |
0 / 1 / 2 个核心、端口链互相延伸、超 CONNECTIVITY_LIMIT |
🟢 |
由 Hermes Agent 审查
Reason: script execution via -e/-c flag Reply |
|
💾 Self-improvement review: Patched references/storage-rpc-gui-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/pr4806-storage-fluid-port-review.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched SKILL.md in skill 'pr-diff-scope-reconciliation' (1 replacement). |
|
审查完成。以下是审查意见(直接输出,未执行任何 gh 评论命令; 代码审查摘要 — PR #4806Operation: 🔴 关键(需修复后合并)1. // 普通文本搜索由客户端按本地化名称过滤;服务端只处理 @ 前缀
boolean matches = search.isEmpty()
|| search.charAt(0) == '@'
&& id.getNamespace().toLowerCase(Locale.ROOT).contains(search.substring(1));
if (!matches) { continue; }物品路径 || search.charAt(0) != '@' && search.charAt(0) != '#'; // 普通文本全部放行,交给客户端二次过滤缺了这一条 → 搜索框里输入 boolean matches = search.isEmpty()
|| search.charAt(0) == '@'
&& id.getNamespace().toLowerCase(Locale.ROOT).contains(search.substring(1))
|| search.charAt(0) != '@' && search.charAt(0) != '#'; // ← 补齐(
|
| issue #4792 要求 | 状态 | 对应实现 |
|---|---|---|
方块 storage_fluid_port + 配方(空/潜影壳/空、储罐×3、空/潜影壳/空 得 1) |
✅ | ModBlocks.STORAGE_FLUID_PORT、ShapedRecipeLoader.storageFluidPort、generated recipe/advancement/loot/pickaxe |
| 可连集装箱/存储站,且与仓储端口互相延伸连接 | ✅ | StoragePortBlockEntity.findSoleCore + isPort 双向识别 |
| 128 B 容积、每端口单一流体、拆除保留流体 | ✅ | CAPACITY_MB = 128*1000、FluidTank(首流体锁定)、saveToDrop + playerWillDestroy(创造) |
| 门格海绵右键清除流体 | ✅ | StorageFluidPortBlock.useItemOn + clearFluid() |
| 非气体/气体均靠等效高度维持在 50%–75%,最多 ±20 | ✅ | ADJUST_FILL_LOW/HIGH=0.5/0.75、MAX_HEIGHT_BIAS=20、FluidNetworkScanner.heightBiasAt(气体走 effectiveHeight - Y 气压) |
| UI 显示流体、不占类别、按数量 1 mB = 1 物品排序 | ✅ | FLUID_SLOT_BASE 伪槽位 + addFluidEntries(entry.amount() 直接参与比较) |
| <1 B 用 mB、≥1 B 用 B、小数保留三位有效数字 | ✅ | FluidAmountUtil.formatAmount/formatExactAmount(≥1000 B 额外并入 K/M 缩写,属扩展) |
| 点击流体格自动用铁桶装一桶,缺桶弹提示 | ✅ | fillBucketFromStorage + FluidNotice.BUCKET_MISSING/NOT_ENOUGH + 界面浮层 |
| 放入桶装流体时自动倾倒入同流体端口,无端口则存桶物品 | ✅(有扩展) | pourIntoFluidPort + findAcceptor(同流体端口优先,其次空端口,再退回普通入库) |
| JEI 填充合成识别「空桶 + 流体」并自动盛装 | ✅ | StorageJeiSupport、TerminalJeiTransferSupport、produceFilledContainer |
| 普通文本搜索下流体仍可用名称过滤 | ❌ | 见 🔴 1 |
🧪 测试建议
| 被测目标 | 推荐测试场景 | 优先级 |
|---|---|---|
StorageServerStub.addFluidEntries |
空/@ns/普通文本/#tag 四种搜索下流体条目是否入 order(回归 🔴 1) |
🔴 |
StorageFluidRegistry.drain(id, fluid, mb, simulate) |
单端口不足需跨端口凑量;SIMULATE 不改状态;EXECUTE 后余额守恒 | 🔴 |
produceFilledContainer |
空容器取自背包/存储/指针三来源;容器不足、流体不足、drain 中途不足三条回滚路径数量守恒 | 🔴 |
StorageFluidRegistry.collect |
多端口同流体合并;取空端口以 0 占位且下标不前移;端口改挂后不残留旧存储 | 🟡 |
StorageFluidPortBlockEntity.computeNextHeightBias |
fill=0/0.49/0.5/0.625/0.75/0.76/1.0 与 ±20 截断;区间内保持不变 | 🟡 |
StorageServerStub.SyncResult / FluidEntry |
StreamCodec 往返(含 amount=0 占位条目不丢流体类型) |
🟡 |
StorageServerStub.interact |
流体格左键/右键/Shift、指针被占用、无端口可倾倒时各分支的 changed 与 notice |
🟡 |
consumeCraftingInput 剩余物 |
2 水桶 + 空桶剩余物、催化剂(净变化 0 返回 false)、单水桶 + 空桶 | 🟢 |
StorageFluidRegistry.register/unregister |
维度隔离(同坐标不同维度互不影响)、clear() 后无残留 |
🟢 |
结论: REQUEST_CHANGES — 功能实现与 issue #4792 的规格高度吻合,生命周期/序列化/回滚/伪槽位隔离都做得扎实,值得肯定。但 🔴 1(普通搜索会隐藏全部流体条目)是用户可直接触发的功能缺陷,建议修复后再合并;ItemSplitterBlock 朝向反转属已有方块的行为变更)。
标题建议(gh 未认证,本次未自动修改):
Add Storage Fluid Port 新增仓储流体端口
若按上条把夹带改动也写进标题,可考虑:Add Storage Fluid Port and Fluid Storage UI 新增仓储流体端口与流体仓储界面
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'texture-asset-pr-review' (1 replacement). · Patched references/pr4806-storage-fluid-port-review.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). |
- 修改合成格清空顺序,先送入存储站,存储站满后回退玩家背包 - 新增returnToStorageOrInventory方法,确保物品优先送入存储站 - 调整合成物品转移相关注释,提高描述准确性 - 细化排序方法,新增createItemOrder用于仅包含真实物品槽位排序 - 细化createOrder方法参数,支持包含或排除流体伪槽位 - 流体伪槽位排序仅用于界面渲染,避免索引越界问题 - 修正部分注释,提升代码可读性和维护性
- 统一物品归还流程,新增 returnItems 方法处理多级归还路径 - 替换旧方法调用,增加玩家参数以便准确处理物品归还 - 优化物品放回存储和背包的顺序与兜底逻辑,避免物品丢失 - 调整容器归还逻辑,新增对玩家实例的支持与统一处理 - 生产桶装流体时改用玩家实例,确保物品正确发放与回收 - 删除冗余旧方法,简化代码结构和调用关系
- 修改遍历循环仅遍历主背包槽位,避免将物品放入盔甲槽或副手槽 - 统一使用 Inventory.INVENTORY_SIZE 替代 getContainerSize() 减少错误 - 确保物品叠加与取用逻辑仅作用于主背包,避免材料统计和扣除不一致 - 保持与原版Inventory#add逻辑一致,防止堆叠与空槽判断异常 - 修复因盔甲槽错误遍历导致的物品放置与材料扣除问题
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement). |
Reason: script execution via -e/-c flag Reply |
代码审查摘要 — PR #4806操作: synchronize | 范围: 48 文件(36 Java、9 生成资源、3 源资源;14 新增)/ +3066 −155 | CI: build ✅ checkstyle ✅ | 关联 #4792 本 PR 实现了 #4792「仓储流体端口」的全部要点。核心实现质量不错:注册表按维度分层、点击按流体身份而非下标匹配、装桶走「模拟→扣容器→执行→失败回滚」、双写序列化齐全、伪槽位在客户端各物品路径都做了跳过。以下是需要修的点与建议。
|
| 要求 | 状态 | 证据 |
|---|---|---|
| storage_fluid_port 方块 + 指定配方 | ✅ | ModBlocks / ShapedRecipeLoader / recipe json |
| 可连集装箱/存储站,且与仓储端口可互相延伸 | ✅ | findSoleCore 静态化 + isPort() |
| 128 B、单一流体、拆除保留、海绵清除 | ✅ | CAPACITY_MB=128000、FluidTank、saveToDrop/getDrops、MENGER_SPONGE 右键 |
| 50~75% 水位调节、最多 20 米、越远越快 | ✅ | ADJUST_FILL_LOW/HIGH、MAX_HEIGHT_BIAS=20、step ∝ |error| |
| 气体同样按模拟压力维持 | ✅ | FluidNetworkScanner 的 effectiveHeight 推导同时作用于气体 |
| UI 显示流体、不占类别、1 mB=1 物品排序、单位规则 | ✅ | StorageFluidRegistry.collect / FLUID_SLOT_BASE、addFluidEntries、FluidAmountUtil |
| 点击流体格用铁桶装一桶、缺桶提示 | ✅ | FLUID_BUCKET / takeFluidBucket / FluidNotice.BUCKET_MISSING |
| 桶装流体自动倾倒,无对应端口则存桶物品 | ✅ | pourIntoFluidPort + 回退 view.insert |
| JEI 填充合成识别空桶+流体 | ✅ | StorageJeiSupport / TerminalJeiTransferSupport + 服务端 produceFilledContainer |
| 「resolved #4792」 | issue #4792 仍为 open;resolved 不是 GitHub 关闭关键字,建议写 Resolves #4792 |
结论:REQUEST_CHANGES
功能与 #4792 完全对齐、CI 通过、实现细节质量高。请先处理 hasFluidFor 名实相反),并把
标题建议:当前标题准确描述主功能但未覆盖随带修正,建议 Add Storage Fluid Port 添加仓储流体端口(或更完整:Add Storage Fluid Port and storage/crafting fixes 添加仓储流体端口及仓储/合成修正)。本次 gh auth status 显示 token 失效(Active account: Gugle2308, invalid token),按流程未执行 gh pr edit,故以文字给出建议。
🧪 测试建议
| 被测目标 | 建议场景 | 优先级 |
|---|---|---|
quickMoveToStorage / undo |
Shift+左键倾倒流体桶 → Shift+Z 撤销(仓储内另有同种桶)应无错位撤销 | 🔴 |
StorageFluidPortBlockEntity 注册表 |
端口区块卸载期间改链路 → 重载后仅在新存储可见;旧存储 UI/drain 不应触及 | 🔴 |
produceFilledContainer |
空桶不足 / 流体不足一桶 / 中途失败:容器与流体都应回到原处,不增不减 | 🔴 |
takeFluidBucket / fillBucketFromStorage |
指针空/持桶/持他物、跨多端口凑满 1 B、并发取空 | 🟡 |
FluidAmountUtil |
0 / 999 / 1000 / 1234 / 1500 / 128000 mB 与 formatExactAmount 的进位与有效数字 |
🟡 |
| 序列化 | 带流体物品的拆放(含创造模式与 Ctrl 中键克隆)、区块重载、Tank 缺失容错 |
🟡 |
heightBias |
液/气两态在含泵与多层容器网络中从空/满收敛到 50–75% 且不振荡 | 🟡 |
StorageScreen 伪槽位 |
折叠/搜索/Shift 取液/流体取空后列表不跳位、不越界、不 NPE | 🟡 |
由 Hermes Agent 审查
代码审查摘要 — PR #4806操作:
|
| 无关改动 | 位置 | 性质 |
|---|---|---|
放置朝向反转 getOpposite() → getHorizontalDirection() |
ItemSplitterBlock.getStateForPlacement |
🔴 现有方块行为变更,且与仓库内 17+ 个方块的主流约定(getHorizontalDirection().getOpposite())相反 |
ITEM_SPLITTER 物品改为 ChuteBlockItem |
ModBlocks |
现有物品行为变更(右键容器可直接放置) |
连合成预算 64 / perCraft → 按产物堆叠上限折算 |
craftBudget(),3 处调用 |
现有手感变更:不可堆叠产物(镐子等)从最多 64 次变为 1 次 |
合成剩余物处理重写 + returnCraftingRemainder |
consumeCraftingInput |
影响桶/碗等剩余物去向 |
clearCrafting 归还顺序:背包优先 → 存储优先 |
clearCrafting |
用户可见变更(JEI 转移后材料改落到仓储) |
| 剩余物占格时先收走再补料 | autoRefillCrafting、refillAndCollectSlots |
连续合成语义变更 |
getContainerSize() → INVENTORY_SIZE 共 5 处 |
多个方法 | 独立 bugfix(物品/材料误入盔甲槽),值得单独 PR |
仓储界面 Shift+双击批量移入(lastQuickMoved/findInventorySlotWith) |
StorageScreen |
新功能 |
| 浮层 flyout 重构 + z 序/flush 处理 | StorageScreen |
渲染重构 |
record 模式重构、addCustom(ItemStack) 删除、<= 0→== 0 |
ModelSelectionBakery、PlayerSetting、TerminalJeiTransferSupport |
纯清理(已验证 addCustom(ItemStack) 在目标分支无调用方,安全) |
| 二进制纹理改动 | textures/block/pipe_glass_node.png、textures/font/small.png |
与流体端口无关:前者是玻璃管道外观,后者 font/small.json 的 chars 未变(. m B K 等字形本已存在)故非新增字形所需。请确认是有意修改 |
2. StorageJeiSupport.hasFluidFor 名字与语义相反(易埋雷)
// 名字读作「有该流体」,实际 return true 表示「仓储里没有可用的该流体」
if (StorageJeiSupport.hasFluidFor(screen.getFluids(), variant)) return false; // producibleFromFluid
if (StorageJeiSupport.hasFluidFor(fluids, variant)) continue; // addProducibleFluidContainerscontent.isEmpty() 分支也返回 true。两处调用都靠「取反使用」才正确,后续任何一次顺手使用都会写反。建议改名(如 lacksFluidFor/needsProducingFromFluid)或反转返回值。
3. findAcceptor 与 #4792 规格不一致
规格:"自动将流体倾倒入有相同流体的仓储流体端口中,没有对应的端口则存入对应的桶物品"。
实现:无同种流体端口时回退到任意空端口(并把该端口永久锁定为该流体),桶不再作为物品入库。请确认这是有意的放宽(空端口可接收任意流体)还是应严格按规格退回物品存储。
4. 等效高度调节缺少「已接入管网」守卫(规格限定 + 性能)
规格限定:"储存了非气体流体且通过管道连接了其他流体储存方块时" 才调节。实现里只要 tank 非空就调节(不看是否接管道、不区分气体)。后果:无管道连接的满水端口在水位偏离 50%~75% 时,每 10 tick 改变一次 heightBias → FluidNetworkManager.markDirty(level) → tickLevel 走该维度全量 rebuild()(逐网络 FluidNetworkScanner.scan + 玻璃管显示迁移)。偏置 clamp 到 ±20 后自终止(约 7 次),但属于白白重扫;建议加「是否已接入管网/其他容器」守卫。
💡 建议(非阻塞)
FluidCategory与「不占类别」:[TODO] 仓储流体端口 #4792 写「在 ui 中显示对应流体,不占类别」,实现新增category.anvilcraft.fluid并加入PlayerSetting默认 listed(默认UNLIMITED不过滤,无副作用)。请确认这是有意的额外过滤能力。heightBias不持久化:重载后从 0 重新调节(10 tick 内到位),期间有一次等效高度跳变。若在意"存档前后一致"可考虑写入 NBT。livePorts每次调用遍历所有维度,而collect()在每次sync、每次find/drain/findAcceptor都会跑一遍;端口数量大时可考虑缓存/按维度直查。- 仓库无
src/test源集,故建议改为手测清单(草稿阶段):①无核心时端口独立被桶/管道读写;②端口从 A 存储改挂 B 存储后 A 界面不再显示、drain(A)不抽到该端口;③取空后条目占位显示 0 且槽位编号不整体前移;④区块卸载/超维存储站跨维度;⑤删掉端口方块后StorageFluidRegistry无残留(positions());⑥装载入后直接取空的占位流体名。
🟢 看起来不错
findSoleCore抽取 +isPort双类型判断,仓储端口 ↔ 流体端口双向延伸完整;StoragePortBlockEntity.validateLink重构后与旧实现等价(cores.size()!=1→ null,不写coreMainPos/working)。- 交互按流体身份匹配(
isSameFluidSameComponents)而非下标,明确规避了「点击与处理之间列表变化导致取到别的流体」。 createItemOrder(排除伪槽位)专供取物路径,从源头避免StorageView越界;FLUID_SLOT_BASE + index在服务端collect/ 客户端fluids/ 折叠路径三处索引基准一致;伪槽位在contents、serverSlots、hasContents、applySearchFilter、applyPreservedSyncResults等所有遍历点都有 skip 守卫。- 装桶失败采用「先模拟再执行 + 失败
giveEmptiedContainer回滚」;produceFilledContainer严格「先扣容器后抽流体」,失败时giveBackContainers+refillFluid双向回滚 —— 不会吞物品/流体;transferMaterial(Exact)把盛装量计入moved后由调用方写入槽位,账目守恒。 - 空端口不写 BlockEntityTag(保证与未放置过物品可堆叠)、创造模式
playerWillDestroy掉落带流体端口(模仿原版潜影盒),与同类StoragePortBlock逐行一致。 - 数据生成完整:blockstate/物品模型/配方/成就/战利品表/
mineable/pickaxe/anvilcraft/category/fluid.json+en_us/en_ud均已同步(FluidNotice的两个 key 也存在)。 - Capabilities 注册(
IFluidHandlerHolder)、BE 渲染器注册、onLoadaddContainer /setRemovedremoveContainer+unregister 生命周期对称 ✅
📋 声称验证表
| 声称 | 状态 | 说明 |
|---|---|---|
| 添加仓储流体端口 | ✅ | StorageFluidPortBlock/BlockEntity/BlockItem、128 B 单流体、拆除保留、门格海绵清除、配方(潜影壳+3 储罐+潜影壳)、UI 流体格(1 mB=1 物品、mB/B/三位有效数字)、JEI 空桶+流体盛装 —— 均与 #4792 相符 |
| resolved #4792 | 主体实现,但有两处与规格不符:findAcceptor 空端口兜底(应按规格退回桶物品)、等效高度调节未限定「已通过管道连接其他流体储存方块」 |
|
| 交互:点击流体格装桶 + 缺桶提示 | ✅ | FLUID_BUCKET/QUICK_MOVE_FROM_STORAGE 分支 + FluidNotice.BUCKET_MISSING/NOT_ENOUGH 浮层提示 |
结论: COMMENT(草稿状态不阻塞)— 功能主体实现质量较高、与 #4792 基本对齐;合并前请先处理「范围外改动/纹理改动」的拆分或说明,以及问题 2–4(命名反向、findAcceptor 规格偏差、高度调节守卫)。
✏️ PR 标题
gh auth status 显示 The token in /opt/data/home/.config/gh/hosts.yml is invalid(未认证),按 webhook 约定未执行 export GITHUB_TOKEN/source .env,故本次未自动修改标题,仅给出建议:
- 若拆分无关改动:
Add Storage Fluid Port 添加仓储流体端口 - 若保持当前范围:
Add Storage Fluid Port and storage fluid handling 添加仓储流体端口与仓储流体处理
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'pr-fix-claim-verification' (1 replacement). · Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). |
代码审查摘要 — PR #4806操作: 已核对 diff(patch-diff)、PR head 🔴 关键
|
| 声称(PR 描述 / issue #4792) | 状态 | 对应实现 |
|---|---|---|
| resolved #4792 | 功能已实现,但 issue 仍 open(PR 未合并,自动关闭属预期);规格逐项见下 | |
| 配方:空/潜影壳/空、储罐×3、空/潜影壳/空 → 1 | ✅ | ShapedRecipeLoader.storageFluidPort + recipe/storage_fluid_port.json |
| 可与集装箱/存储站连接,与仓储端口互相延伸 | ✅ | StoragePortBlockEntity.findSoleCore/isPort 静态化共用 |
| 128 B 容积、单一流体、拆除保留、海绵清除 | CAPACITY_MB/FluidTank/saveToDrop/clearFluid(海绵清除残留 0 条目,见警告) |
|
| 非气体流体:以等效高度把水位维持在 50%~75%,最远越快,最多 20 格 | ✅ | ADJUST_FILL_LOW/HIGH = 0.5/0.75、ADJUST_RATE、MAX_HEIGHT_BIAS = 20、Math.clamp |
| 气体行为类似(模拟压力) | ✅ | 偏置写入 FluidEndpoint 的 effectiveHeight,网络以 effectiveHeight - Y 推气压(FluidNetworkScanner.heightBiasAt) |
| UI 显示流体、不占类别、1 mB = 1 物品排序 | ✅ | addFluidEntries(entry.amount() 直接参与比较)+ 独立伪槽位 |
| 少于 1 B 用 mB、到 1 B 用 B、小数三位有效数字 | ✅ | FluidAmountUtil.formatAmount(MathContext(3))/formatExactAmount |
| 点击流体格自动用铁桶装一桶取出;缺桶弹提示 | ✅ | StorageInput.FLUID_BUCKET + fillBucketFromStorage + FluidNotice.BUCKET_MISSING 浮层 |
| 放入桶装流体时自动倾倒入同流体端口,无端口则存桶物品 | ✅ | pourIntoFluidPort + findAcceptor,左键倒/右键存桶 |
| JEI 识别空桶+流体组合,自动盛装并填充合成表 | ✅ | produceFilledContainer + StorageJeiSupport.producibleFromFluid / addProducibleFluidContainers / TerminalJeiTransferSupport.producibleFromFluid |
| 描述:增加了之前缺失的部分快捷键(Shift+双击批量) | ✅ | lastQuickMoved + findInventorySlotWith + isDoubleClick 分支 |
| 描述:修改了 JEI 转移前的清空物品去向 | ✅ | clearCrafting 改为存储优先(returnItems(..., true)) |
| 描述:修复物品被放入盔甲栏 | ✅ | 6 处 getContainerSize() → Inventory.INVENTORY_SIZE |
| 描述未提及:分拣器朝向翻转 / ChuteBlockItem | 见警告(属未声明的夹带变更) |
🧪 测试建议
| 被测目标 | 推荐测试场景 | 优先级 |
|---|---|---|
StorageServerStub.terminalReorder + TerminalRemoteOverlay |
接入流体端口后打开远程终端,确认页尾无空白格、翻页/光标不被伪槽位影响 | 🔴 |
StorageFluidPortBlockEntity.clearFluid |
海绵清空后确认 StorageFluidRegistry.collect 不再返回 0 条目 |
🟡 |
StoragePortBlockEntity.findSoleCore |
端口链跨未加载区块时不得触发同步加载(isLoaded 守卫回归) |
🟡 |
StorageFluidRegistry.collect/drain/findAcceptor |
多端口同流体合并、跨维度同坐标、端口拆/挂迁移后 drain(旧存储) 不得抽到新存储的流体 |
🔴 |
produceFilledContainer 回滚路径 |
空容器不足 / 流体不足 / 模拟通过但实际抽取失败 → 物品与流体总量守恒(不增不减) | 🔴 |
StorageFluidPortBlockEntity.saveToDrop / getUpdateTag |
满/半/空端口掉落物 NBT、空端口物品可堆叠、重载后流体与水位一致 | 🟡 |
FluidAmountUtil.formatAmount |
0 / 999 / 1000 / 1.25 B / 1000 B(→1K B) / 128000 mB 边界 | 🟢 |
分类过滤 matchesFluidCategoryFilters |
流体分类黑名单(折叠/非折叠两种显示路径)、@namespace 与 #tag 搜索 |
🟡 |
结论: REQUEST_CHANGES — 功能主体质量高、与 issue #4792 规格高度吻合,越界/并发/序列化等硬风险都处理到位;但 terminalReorder 把流体伪槽位发给不支持的终端界面 是本 PR 引入的可见 UI 缺陷,需先修(改用 createItemOrder 即可);另请确认/拆分分拣器朝向与 pipe_glass_node.png 两项夹带变更,并处理海绵清除残留下 rememberedFluid 的问题。
建议 PR 标题(gh 未认证,未自动修改):
Add Storage Fluid Port for storage networks 新增仓储流体端口
由 Hermes Agent 审查
- 添加 hasAdjacentPipe 方法判断端口是否有相邻管道连接 - 在 adjustHeightBias 方法前置条件判断无相邻管道时跳过调整 - 减少无管网连接时的重复 markDirty 调用,防止全局管网重建 - 引入 Level 和 Direction 检查相邻方块是否为管道部件 - 保持管网高度偏置调整仅在有效连接时执行,提高性能与稳定性
|
我已完成对 PR #4806 的完整审查(diff 48 文件 / +3071 −155,PR 处于 draft、mergeable=clean)。以下是审查意见: 代码审查摘要 — PR #4806操作: edited(draft;github 报告 📋 声称验证表
🔴 关键(需修复后合并)
|
|
💾 Self-improvement review: Patched references/hardcoded-block-list-coverage.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). |
- findAcceptor 方法改为只返回已存放同种流体的端口,避免空端口误吞桶装流体 - 新增 findRefillTarget 方法,优先同种流体端口,无合适时选空端口,防止回滚流体丢失 - refillFluid 方法改为使用 findRefillTarget,保证灌回流体时端口匹配更准确 - 增加相关方法的详细注释说明使用场景和设计考量
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: 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 |
|
|
|
我已完成审查(diff 已下载并交叉引用了目标分支与 PR head 源码)。以下是审查意见: 代码审查摘要 — PR #4806操作: synchronize(PR 当前为 draft) ✅ 与 #4792 规格的逐项核对
|
| 声称 | 状态 | 对应文件 |
|---|---|---|
| Added Storage Fluid Port | ✅ | StorageFluidPortBlock/BlockEntity/BlockItem、StorageFluidRegistry、渲染器、注册、配方/掉落/标签/语言 |
| resolved #4792 | — | |
| 增加了之前缺失的部分快捷键 | ✅ | Shift+双击左键批量移入(lastQuickMoved/findInventorySlotWith)、Alt+左键倾倒 / Alt+右键存桶(moveSameToStorage(slot, pour))、存入按钮右键存入(TexturedButton 右键支持 + deposit(..., pour=false)) |
| 修改了 JEI 转移前的清空物品去向 | ✅ | clearCrafting → returnItems(..., storageFirst=true);returnToInventoryOrStorage 删除、替换为三级归还 |
| 修复了会把物品放入盔甲栏的问题 | ✅ | 6 处 getContainerSize() → Inventory.INVENTORY_SIZE(并保留 restockHand 所需的上界) |
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
StorageFluidPortBlockEntity#computeNextHeightBias |
49.9%/50%/75%/75.1% 边界、空罐归零、±20 clamp、无相邻管道不调整 | 🔴 |
StorageFluidRegistry |
同种流体跨端口合并;取空后 0 占位与顺序稳定;drain simulate/execute 一致;跨维度同坐标隔离;register/unregister 对称 |
🔴 |
produceFilledContainer / fillBucketFromStorage |
模拟通过但执行失败的回滚(不吞桶、不凭空增流体);空桶来自指针/背包/存储三条路径;指针被占用时不消耗桶 | 🔴 |
| 掉落 NBT 往返 | 满/空端口拆下→重放的 Tank/Fluid 一致性;空端口不加 BE data(保证与原物品堆叠) |
🟡 |
FluidAmountUtil |
999/1000/1250/1_000_000 mB 与 3 位有效数字、K/M 缩写阈值 | 🟡 |
| RPC 契约 | interact 新增 FluidStack(空栈编解码)、SyncResult/InteractionResult 新增字段的编解码与越界槽位容错 |
🟡 |
| 背包遍历回归 | 背包满/副手槽(40) 物品均衡补货、JEI 取料不得动盔甲槽 | 🟡 |
StorageScreen 流体格交互 |
左键(空指针装桶 / 拿桶倾倒)、右键(存桶物品)、Shift+左键(直接入背包)与缺桶提示浮层 | 🟡 |
说明:本次为纯 diff + 上游源码交叉引用审查,未运行 Gradle 编译/
runData(无 dev 构建环境),也未核对两张二进制贴图的实际像素变化;建议合并前由 CI 或作者补一次compileJava+ 游戏内验证。
结论
COMMENT — 未发现崩溃、吞物品或存档不兼容类阻塞缺陷,实现与 #4792 规格逐条吻合、失败回滚与越界防护做得比一般 PR 细。建议优先处理 hasFluidFor 反向命名),并说明 ItemSplitterBlock 朝向反转等夹带变更)是否有意,之后即可从 draft 转 ready for review。
关于标题:gh auth status 显示 token 已失效(The token in .../hosts.yml is invalid),本次未自动修改标题。建议标题(已体现本 PR 实际范围): Add Storage Fluid Port with storage UI & JEI fluid support 添加仓储流体端口(含仓储界面与 JEI 流体支持)
由 Hermes Agent 审查
代码审查摘要 — PR #4806操作: synchronize(PR 当前为 draft) 📋 声称验证表
✅ 与 TODO #4792 规格逐条对照(issue 正文即为验收标准)
|
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
validateLink / 存储归属 |
端口从 A 存储改挂 B、拆掉核心、区块卸载后重载:UI 归属与 drain 目标不串台 |
🔴 |
produceFilledContainer 回滚 |
模拟通过但实际抽取不足、空容器扣取失败:桶与流体都不增减 | 🔴 |
takeFluidBucket / fillBucketFromStorage |
储量 <1000 mB 无桶(提示「需要空桶」优先)、有桶不足量、指针被占用 | 🔴 |
pourIntoFluidPort |
多桶整批倾倒、端口容量不足中途 break、空容器去向(入库优先→背包→掉落) | 🟡 |
| 伪槽位编号稳定性 | 某流体被取空后槽位编号不前移;新增/移除端口后条目正确增删(对应警告 1) | 🟡 |
clearCrafting 去向 |
存储放得下/放不下、toStorage=false 时背包优先 |
🟡 |
Inventory.INVENTORY_SIZE 边界 |
背包仅剩盔甲槽空位时产物不得写入盔甲/副手 | 🟡 |
| 高度偏置 | 50%~75% 收敛、边界不来回横跳、±20 截断、气体同样生效 | 🟢 |
结论: COMMENT(暂无阻塞性问题,但建议先解决警告 1、3 并把无关变更拆分/写明) —— 主体实现与 TODO #4792 高度吻合,注册/序列化/RPC/渲染/数据生成齐全,伪槽位与生命周期处理细致;主要问题集中在「界面刷新时机」「反向命名的可维护性」与「混入的无关行为变更」。PR 仍为 draft,转入 ready-for-review 时我可以再过一遍。
建议标题(gh 的 token 已失效,本次未自动修改,请手动或修复 gh 认证后执行):
gh pr edit 4806 --title "Add Storage Fluid Port with fluid slots and bucket pour/fill interactions 添加仓储流体端口并支持流体存取交互"
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). · Patched SKILL.md in skill 'pr-fix-claim-verification' (1 replacement). |
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched SKILL.md in skill 'github-webhook-pr-review' (1 replacement). |
- 移除端口时通知 StorageServerStub 清理相关归属缓存,避免伪槽位遗留空格子 - 更新注册逻辑,切换存储归属时注销旧归属并注册新归属,修正UI显示异常问题 - 增加归属变更时对旧归属和新归属均调用内容变化通知,确保界面正确刷新 - 修正 JEI 集成中流体容器判断逻辑,改为判断仓储中是否缺少足量流体以决定是否需要现场盛装 - 优化缺少流体判定函数注释,明确三种返回 true 的情况及 false 的语义
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: 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 |
代码审查摘要 — PR #4806操作: 🔴 关键1. 「只遍历主背包」的修复只做了服务端一半 —— 客户端 JEI 判定范围仍是含盔甲/副手的 0..40,会出现「JEI 认为可转移、服务端静默不转移」 本 PR 把服务端所有背包遍历由
但 客户端 JEI 的可用量统计没有同步收窄,仍包含盔甲槽 36–39 与副手槽 40:
改动前两端都用 建议: 把
|
| 声称 | 状态 | 对应证据 |
|---|---|---|
| resolved #4792 | ✅ | #4792[TODO] 仓储流体端口 的 10 条要求逐条实现(见上);issue 当前仍 open,但 base = dev/1.21/1.6 即仓库默认分支,resolved #4792 是合法关闭关键字 → 合并后自动关闭 |
| 增加了之前缺失的部分快捷键 | ✅ | Shift+双击批量移入(lastQuickMoved + findInventorySlotWith)、Alt+左/右键区分倾倒与入库、流体格左/右键与 Shift 分支、TexturedButton 右键回调 |
| 修改了 jei 转移前的清空物品去向 | ✅ | clearCrafting → returnItems(..., storageFirst=true),先入存储再回退背包,兜底掉落 |
| 修复了会把物品放入盔甲栏的问题 | 服务端取用/放置路径已收窄到 INVENTORY_SIZE ✅;客户端 JEI 判定范围未同步 → 见 🔴1 |
标题建议(未自动修改:gh auth status 显示 /opt/data/home/.config/gh/hosts.yml token 失效,按流程跳过 gh pr edit)
当前标题 Added Storage Fluid Port. 添加了仓储流体端口 只覆盖了新增方块,未体现本 PR 的仓储界面流体槽位、桶交互快捷键、JEI 现场盛装与几处修复。建议:
Add Storage Fluid Port with storage UI fluid slots and bucket shortcuts 添加仓储流体端口、仓储界面流体槽位与桶交互
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
StorageJeiSupport.availableCount / StorageServerStub.hasEnoughMaterial |
材料仅在副手/盔甲槽时,JEI 检查与服务端取用范围必须一致(当前会静默失败) | 🔴 |
StorageFluidRegistry.collect |
多端口多流体 + 反复 register/unregister 后,下标与流体映射保持稳定 | 🟡 |
StorageServerStub.produceFilledContainer |
模拟阶段通过、实际抽取不足(并发)时容器与流体双向回滚,总量守恒 | 🟡 |
StorageServerStub.consumeCraftingInput |
催化剂类配方(剩余物 == 原料)净变化为 0 → 终止循环不漏产出 | 🟡 |
StorageFluidPortBlockEntity.computeNextHeightBias |
fill 0 / 0.49 / 0.5 / 0.75 / 1.0 边界与 ±20 钳制;空罐 → 0 | 🟡 |
StorageFluidPortBlockEntity.saveToDrop / loadAdditional |
空端口拆下不与未放置物品堆叠;带流体放置后恢复数量 | 🟡 |
StorageScreen.getFluidSlotAt / getFluidSlot |
伪槽位命中区域与渲染坐标一致;越界返回 null | 🟢 |
结论: REQUEST_CHANGES(偏轻) — 功能实现完整且覆盖 #4792 全规格,回滚与并发设计扎实;但 🔴1 的「一端改一端未改」会让 JEI 转移在副手/盔甲场景静默失败,建议修掉后再合并;
由 Hermes Agent 审查
代码审查摘要 — PR #4806(Added Storage Fluid Port 添加了仓储流体端口)操作:
✅ 交叉核对通过的关键 API(对目标分支源码验证)
🔴 关键(建议合并前处理)
|
| PR 声称 | 状态 | 对应实现 |
|---|---|---|
| 新增仓储流体端口 | ✅ | StorageFluidPortBlock(+BlockItem/BlockEntity/Renderer/ItemRenderer)、ModBlocks、ModBlockEntities、ShapedRecipeLoader、blockstate/model/loot/recipe/advancement/tag/创造栏/分类数据 全套生成资源 |
| resolved #4792 | ✅ | findAcceptor 只认同种流体端口 + pourIntoFluidPort; |
| 增加了之前缺失的部分快捷键 | ✅ | TexturedButton 右键回调(存入按钮左/右键区分倾倒)、Shift+双击批量移入(lastQuickMoved + findInventorySlotWith)、craftBudget 预算折算;已确认新增的 isDoubleClick 调用与既有调用不冲突(Shift 分支总会 return,不会二次消费双击状态) |
| 修改了 JEI 转移前的清空物品去向 | ✅ | clearCrafting → returnItems(..., storageFirst = true):存储优先 → 背包 → 掉落 |
| 修复会把物品放入盔甲栏的问题 | ✅ | 5 处 getContainerSize() → Inventory.INVENTORY_SIZE(placeCraftingResult*、transferMaterialExact、hasEnoughMaterial、transferFromInventory、countInInventory、giveBackToInventory、consumeOne) |
(描述未提)物品分拣器朝向翻转 + 改用 ChuteBlockItem |
ItemSplitterBlock.getStateForPlacement / ModBlocks.ITEM_SPLITTER — 功能性行为变更,需说明 |
|
(描述未提)ModelSelection 风格重构 / PlayerSetting.addCustom(ItemStack) 删除 / small.png·pipe_glass_node.png 贴图 |
与流体端口无关,建议拆分或说明;small.png 是共享字体图集,需确认 |
🧪 测试建议(未编译,纯静态分析;建议作者按此自查)
| 被测目标 | 建议场景 | 优先级 |
|---|---|---|
StorageFluidPortBlockEntity.adjustHeightBias() |
空罐 → 灌满 → 反复取放,确认最终稳定在 50%~75% 且不反复横跳;断管网(无相邻管道)时偏置是否冻结、重接后 10 tick 内收敛 | 🔴 |
StorageFluidRegistry.collect()/livePorts() |
3 个以上端口 + 2 种流体,反复拆装/改挂存储,校验 BASE+index 与流体身份是否始终一致(对应 🔴2) |
🔴 |
StorageServerStub.withdrawNeedsFromStorages |
存储同时存在"成品水桶 + 空桶 + 端口流体",验证是否优先用现成桶(对应 🔴1) | 🔴 |
interact(FLUID_BUCKET / QUICK_MOVE_FROM_STORAGE) |
指针空/拿空桶/拿满桶/拿石头 4 种情况 × 左/右键 × Shift;存量 999 mB 边界(提示"不足一桶" ) | 🟡 |
produceFilledContainer() |
流体/空桶各差 1 时回滚,确认物品与流体总量守恒(含跨维度端口与区块卸载端口) | 🟡 |
consumeCraftingInput + autoRefillCrafting |
桶返回类配方(水桶→空桶)、催化剂配方连续合成,确认不吞原料、不无限产出 | 🟡 |
StorageFluidPortBlockEntity 序列化 |
拆除带流体端口 → 重放 → 液面/tooltip 一致;空端口拆除后与新建物品可堆叠 | 🟢 |
结论:REQUEST_CHANGES(但整体质量高,仅需处理 🔴 四项) — 新方块/UI/JEI 三条主线的结构、生命周期对称性和序列化完整性都很扎实,注释质量明显高于平均水准。需要处理的是:withdrawNeedsFromStorages 现场盛装顺序(行为不一致)、流体伪槽位下标不稳定的稳健性问题、物品分拣器默认朝向翻转的说明/确认、JEI 单槽多桶的可用池数量;其余为文档与一致性建议。
关于 PR 标题: 当前标题格式合规(英文 + 中文),但它只体现了主要功能,未涵盖本 PR 同时包含的合成/JEI/背包修复与分拣器朝向变更。因本环境 gh 未认证(The token in …/hosts.yml is invalid),按约定未自动修改,建议改为:
Add Storage Fluid Port and storage UI fluid slots 添加仓储流体端口与界面流体槽位
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched SKILL.md in skill 'pr-diff-scope-reconciliation' (1 replacement). |
|
💾 Self-improvement review: Patched SKILL.md in skill 'pr-diff-scope-reconciliation' (1 replacement). · Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). |
- 在英文和逆转文本中新增储液端口及其按住Shift的详细显示内容 - ItemTooltipManager中新增StorageFluidPort的普通与Shift提示文本 - 介绍储液端口的容量、连接规则、交互操作及破坏后保留流体机制
Reason: shell execution via heredoc Reply |
|
审查完成。以下是审查意见(已按要求不做任何 代码审查摘要 — PR #4806操作: ✅ 本轮新增提交(tooltip)逐条核对
|
| 声称 | 状态 | 依据 |
|---|---|---|
| resolved #4792(仓储流体端口) | ✅ | StorageFluidPortBlock/BlockEntity/Registry、注册链、生成资源、tooltip 全部到位 |
| 增加了之前缺失的部分快捷键 | diff 中未见键盘绑定(KeyMapping/GLFW)新增,可见的是修饰键交互:Shift+点流体格取桶入背包、Shift+双击/Alt 批量移入、左键倾倒 / 右键存桶、deposit 按钮右键。若指键盘热键请写明具体键位 |
|
| 修改了 jei 转移前的清空物品去向 | ✅ | clearCrafting → returnItems(..., storageFirst = true)(存储优先,放不下退背包),并有 Block.popResource 三级兜底 |
| 修复了会把物品放入盔甲栏的问题 | 137234d85a 把 6 处遍历改为 Inventory.INVENTORY_SIZE ✅;但客户端 JEI 判定侧未同步(见 |
|
| (本轮新增)储液端口提示信息 | ✅ | NORMAL/SHIFT 文案与实现逐条一致;en_us/en_ud 已 datagen 同步 |
⚠️ 变更归属(与流体端口无关的改动 — 已跑 blob 三点对比)
本 PR 首个提交 878c5f6c23 同时改动了流体端口之外的三个文件(git show --stat 878c5f6c23 明确列出):
| 改动 | PR base 32da04af17 / 目标分支 tip |
PR head 41cf46ab9b |
判定 |
|---|---|---|---|
ItemSplitterBlock 默认朝向 getHorizontalDirection().getOpposite() → getHorizontalDirection()(注释同步改写) |
1a34af345d |
29f80c97d5 |
本 PR 自身改动 |
ModBlocks.ITEM_SPLITTER:.item() → .item(ChuteBlockItem::new) |
同上文件组 | 同上 | 本 PR 自身改动 |
textures/font/small.png(401 → 958 B,共享位图字体,所有仓储 UI 数字都走它) |
4f3f027dfc |
e590690d6a |
本 PR 自身改动 |
- 朝向一行在当前目标分支上由
add asset of spoofy redstone component (#4803)引入,本 PR 改回了相反语义 → 这是对已合并行为的翻转,建议说明是否有意、或拆成独立 PR;font/small.png影响全模组数字渲染,也请确认是否本 PR 有意改动。
🧪 测试建议
| 被测目标 | 推荐场景 | 优先级 |
|---|---|---|
StorageFluidRegistry.validateLink() |
A 存储 → 拆链 → 20 tick 内接 B:collect(A) 不含该端口、drain(A) 抽不到 B 的流体、两端 orders 缓存均失效 |
🔴 |
moveInventoryStackToStorage(pour=true) 调用点 |
倾倒 64 个水桶后 Ctrl+Z:undo 不应还原不存在的成品桶 | 🔴 |
withdrawNeedsFromStorages |
背包只剩 0 格 + 仓储有流体+空桶:不得静默丢失成品桶(应掉落/退回) | 🔴 |
addFluidEntries + StorageScreen.applySearchFilter |
普通文本 / @ns / #tag / 空搜索下流体条目与服务端 order 的一致性 |
🟡 |
| tooltip | en_us / en_ud 行序与反转逐行一致、storage_fluid_port 两条键存在 |
🟢 |
验证方式说明:本轮为 webhook 无人值守会话,未运行 gradle 构建;tooltip 文案通过「生成 lang 文件 ↔
ItemTooltipManager文本块 ↔ 实现源码」三方交叉核对完成,en_ud逐行人工比对。
结论: REQUEST_CHANGES — 主功能(仓储流体端口)实现完整、与 #4792 规格逐条对齐,新增 tooltip 提交本身没有问题;但
建议标题(gh auth status 显示 token 无效,未自动执行 gh pr edit):Add Storage Fluid Port and fluid storage interactions 添加仓储流体端口与仓储流体交互
由 Hermes Agent 审查
|
💾 Self-improvement review: Patched references/shell-only-diff-navigation.md in skill 'github-webhook-pr-review' (1 replacement). · Patched SKILL.md in skill 'anvilcraft-storage-system-review' (1 replacement). · Patched references/pr4806-storage-fluid-port-review.md in skill 'anvilcraft-storage-system-review' (1 replacement). |
Uh oh!
There was an error while loading. Please reload this page.