Skip to content

Fixed some problems#4198

Merged
PigeonNian merged 3 commits into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix13
Jul 20, 2026
Merged

Fixed some problems#4198
PigeonNian merged 3 commits into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix13

Conversation

@WhereisFff

@WhereisFff WhereisFff commented Jul 19, 2026

Copy link
Copy Markdown
Contributor
  • 流体系统基层扩展并开放部分接口
  • 修复管道放置基准面bug
  • 修复鱼缸输出槽不能再次加工bug
  • 大储罐容量修改512B,tooltip和手册也改了

Copilot AI review requested due to automatic review settings July 19, 2026 20:40

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 reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

现在我已经有了全面的分析,下面给出审查意见。


代码审查摘要 — PR #4198

操作: opened
范围: 10 个文件 (全部 Java) / 1 新增, 0 删除, 9 修改 / 530 行 diff (+250, -39)

文件 +/- 主题
FluidContainerLookup.java +90/-0 🆕 实体+方块统一流体容器查找
FluidPipeNetwork.java +41/-4 实体端点跟踪、连接有效性验证
FishTankBlockEntity.java +45/-0 输出槽再加工机制
FluidEndpoint.java +15/-1 新增 entity 字段
FluidNetworkScanner.java +14/-10 改用 FluidContainerLookup
AnvilEventListener.java +14/-6 铁砧配方触发前后处理鱼缸状态
IEntityCauldron.java +8/-0 新增 usesWholeCauldronFluidTransfers
InWorldRecipeEventListener.java +8/-1 修复物品实体吸入逻辑
PipeBlock.java +3/-6 改用 FluidContainerLookup,自动检测实体处理器
PipeBlockItem.java +2/-1 修复实体流体处理器上的潜行放置基准面

✅ 声称验证表

声称 状态 对应文件
流体系统基层扩展并开放部分接口 FluidContainerLookup (新), FluidEndpoint, FluidNetworkScanner, FluidPipeNetwork, IEntityCauldron, PipeBlock
修复管道放置基准面 bug PipeBlockItem, PipeBlock
修复鱼缸输出槽不能再次加工 bug FishTankBlockEntity, AnvilEventListener, InWorldRecipeEventListener

🔴 关键

  • — 未发现会导致崩溃或数据丢失的逻辑错误。

⚠️ 警告

  1. FishTankBlockEntity: lastRecipeProcessingGameTime 未持久化
    lastRecipeProcessingGameTime(long)是防止同 tick 重复输出处理的关键守卫,但未加入 saveAdditional/loadAdditional。世界重载后该值重置为 Long.MIN_VALUE,导致输出物品可在重载后被铁砧重复处理一次。虽然 processingOutput 本身是瞬态状态不应持久化,但 lastRecipeProcessingGameTime 的持久化能防止重载后的意外重复处理。

    建议修复:saveAdditional 中写入 tag.putLong("LastRecipeGameTime", this.lastRecipeProcessingGameTime),在 loadAdditional 中读取 this.lastRecipeProcessingGameTime = tag.getLong("LastRecipeGameTime")

  2. FishTankBlockEntity: beginRecipeProcessing 在同 tick 多铁砧落下的竞争处理
    当同一 tick 内有多个铁砧同时落在鱼缸上方时(如 TNT 大炮发射的多个铁砧),第二个 beginRecipeProcessing 调用会因为 gameTime == lastRecipeProcessingGameTime 而跳过输出处理。第二个铁砧的处理变为无操作。在常规游戏中此场景罕见,但值得注意。

💡 建议

  1. FluidContainerLookup.find() 实体选择策略(行 80-82)

    if (handler == null || selected != null && selected.getId() <= entity.getId()) {
        continue;
    }

    选择最高 ID(最新生成)的实体。当多个流体处理实体(如炼药锅船 + 流体储罐船)占据同一方块位置时,可能导致非预期的实体被选中。建议添加注释说明选择策略,或考虑更明确的选择逻辑(如优先选择特定类型的实体)。

  2. PipeBlockItem: 实体流体处理器判定的隐式假设
    clickedOnEntityFluidHandler = targetState.canBeReplaced() && clickedOnFluidHandler 假设「可替换方块 = 实体处理器」。如果某方块既是可替换的又注册了 BLOCK 级别的流体能力(理论上可能的边界情况),会被误判为实体处理器。虽然在实际 Mod 环境中几乎不存在这种情况,但建议添加注释说明该假设条件。

  3. FluidEndpoint 6-arg 构造器的潜在隐式实体遗漏
    6-arg 构造器(第 146-155 行)将 entity 默认为 null,用于旧调用方(如 pushFromExternalSource 行 271)。验证 pushFromExternalSourcenull 实体参数在所有下游路径中不会导致 NPE。目前 isEndpointConnected() 仅检查 disconnectedEntityEndpoints(只包含实体端点),所以 null 实体的端点不会被错误断开 ✅。

🟢 看起来不错

  1. FluidContainerLookup 设计清晰 — 抽象了方块+实体流体容器的统一查找逻辑,方块能力优先于实体能力,避免实体在移动时同时从多个位置暴露能力。Result record 结构简洁。

  2. isEntityConnectedToPipe() 碰撞箱检测严谨 — 考虑了实体偏移容忍度(1.1E-3D),扩展 AABB 后与管道碰撞箱相交检测,防止移动实体断连时的幽灵连接。

  3. FishTankBlockEntity 输出再处理机制优雅processingOutput 标志切换 getInput()/getOutput() 的返回,使配方系统将输出视为输入,无需修改配方系统本身。EMPTY_RECIPE_OUTPUT(0 槽位)防止再加工时产生新输出。

  4. AnvilEventListener 双层 try/finally — 确保 finishRecipeProcessing() 在异常时也能被调用,同时 SUPPRESS_DROPS 的嵌套 try/finally 保持了原有资源释放模式。

  5. InWorldRecipeEventListener.spawnItemEntity 修复 — 旧代码 setStackInSlot(0, getStackInSlot(0)) 是无操作的 bug;新代码正确地将掉落物实体中的物品插入输出槽,并消去/更新实体。

  6. PipeBlockItem 放置基准面修复 — 潜行时点击可替换方块上的实体流体处理器不再进入视线模式,而是正确连接到处理器。条件表达式的设计(targetState.canBeReplaced() && clickedOnFluidHandler)准确地识别了实体处理器的场景。


结论: COMMENT — 代码逻辑正确,三个修复均验证有效。仅建议考虑持久化 lastRecipeProcessingGameTime 以防止重载后的潜在重复处理(⚠️ 警告 1),其余为建议性改进。无阻塞性问题。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #4198

操作: review_requested
分支: dev/1.21/fix13dev/1.21/1.6
范围: 10 个文件 (10 Java, 1 新增, 0 删除) / 530 行 diff (240+ 新增, 29- 删除, 29 hunk)
审查者: WhereisFff


审查结果

声称 状态 对应文件
流体系统基层扩展并开放部分接口 FluidContainerLookup (新), FluidEndpoint, FluidNetworkScanner, FluidPipeNetwork, IEntityCauldron, PipeBlock
修复管道放置基准面 bug PipeBlockItem
修复鱼缸输出槽不能再次加工 bug FishTankBlockEntity, AnvilEventListener, InWorldRecipeEventListener

🔴 关键问题

无。 三个声称均已完整实现且逻辑自洽。


⚠️ 警告

1. PipeBlock.isFluidHandlerOrConnectablePump — side 参数语义变化

旧代码:

return level.getCapability(Capabilities.FluidHandler.BLOCK, pos, state, be, null) != null;

新代码:

return FluidContainerLookup.find(level, pos, towardNeighbor) != null;

旧版传入 null(不限面),新版传入 towardNeighbor(管道朝向容器的面)。对于非定向的容器(如大部分 BE),结果相同。但对于定向容器(如某些模组机器只在特定面暴露 handler),此变更可能使 isFluidHandlerOrConnectablePump 在相邻面不是 handler 暴露面时返回 false,导致管道认为该位置无法连接。

这大概率是预期行为(管道本应只连接容器朝向它的面),但如果是旧逻辑的本意是无面限制检测,则需确认。

2. FishTankBlockEntity.processingOutput / lastRecipeProcessingGameTime — 非持久化运行时状态

两个字段均标记为 transient(未序列化到 NBT)。lastRecipeProcessingGameTime 使用 Long.MIN_VALUE 作为初始值,用于同一 gt 内防重复处理。若区块卸载重加载(或服务器重启),该值重置为 MIN_VALUE,在下一次铁砧落地事件中可能重新触发输出加工——但这是可接受的,因为重载后不可能存在"同一 gt 第二次触发"的场景。当前行为正确,但建议添加注释说明此字段不需持久化的原因。

3. getInput()/getOutput() 依赖外部 anvillib 库协作

FishTankBlockEntity.getInput()getOutput() 是新的 public 方法,它们只在 processingOutputtrue 时切换 handler 路由。这些方法需要在配方处理流程(anvillib 的 InWorldRecipeContext)中被调用才能生效。本项目依赖 anvillib 2.0.0+snapshot.473推测 anvillib 的相应接口已经(或将会)更新以调用这些方法。 合并前请确认 anvillib 版本已同步更新,否则 processingOutput 切换逻辑不会实际生效。


💡 建议

4. FluidEndpoint 兼容构造函数可考虑 @Contract(pure=true)(非阻塞)

新增的 6 参数兼容构造函数委托到 7 参数规范构造函数时默认 entity=null,用法正确。pushFromExternalSource 中的调用已适配此模式。无可操作的改进点。

5. FluidContainerLookup.find() 在 entity 选择中有潜在竞争条件

if (handler == null || selected != null && selected.getId() <= entity.getId()) {
    continue;
}

当第一个实体提供 handler 后,第二个实体必须 entity.getId() > selected.getId() 才能替换。这是稳定的优先级选择逻辑(较高 ID = 后生成的实体),但若两个实体的中心点在同一方块单元内时,行为是确定性的。建议明确一下这是按 ID 升序(最早生成的优先)还是降序(最新生成的优先)。当前实现是按 ID 降序 → 最新生成的实体优先selected.getId() <= entity.getId() 时替换)。

6. FishTankBlockEntity.getInput() 返回 IItemHandler 而非 PollableItemHandler

getInput() 的类型签名是 IItemHandler,但字段 this.inputPollableItemHandler。方法 getInputHandler() 虽然暴露了 PollableItemHandler 但未在此 PR 中被配方系统使用。若下游代码需要 poll() 能力,应使用 getInputHandler()。当前无 bug,但类型宽度可以进一步收窄。


🟢 看起来不错

  • IEntityCauldron.usesWholeCauldronFluidTransfers() — 优雅的默认方法设计,实体炼药锅可覆写以选择完整容器转移语义
  • FluidContainerLookup — 统一了方块级和实体级 handler 查找逻辑,消除了重复的能力查询代码
  • FluidPipeNetwork.canTickEndpoints() + 实体断连检测isEntityConnectedToPipe() 的碰撞箱接触判定 (+1.1E-3 容差) 稳健合理,防止已移动实体在断开后继续参与网络 tick
  • FishTank 输出加工生命周期beginRecipeProcessing()/finishRecipeProcessing()AnvilEventListener 中正确包裹 try/finally,确保 processingOutput 在异常时也能恢复
  • InWorldRecipeEventListener 修复 — 旧代码 setStackInSlot(0, ...) 是读写自身(无实际效果),新代码 insertRecipeOutput() 正确将实体物品插入 handler,是本次修复的核心
  • PipeBlockItem 放置修复targetState.canBeReplaced() && clickedOnFluidHandler 精准识别实体流体容器,shift 抑制逻辑干净无副作用
  • 无 TODO/FIXME/调试输出/合并冲突残留

结论:APPROVE ✅

三个修复点均正确实现,代码质量高,模式干净。上述警告均为非阻塞性的观察,建议在合并前确认 anvillib 版本已同步支持 getInput()/getOutput() 调用。


由 Hermes Agent 审查

Copilot AI review requested due to automatic review settings July 20, 2026 07:02
@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

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 reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

Copilot AI review requested due to automatic review settings July 20, 2026 08:41
@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

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 reached their quota limit.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

@PigeonNian
PigeonNian merged commit 6b0a63c into Anvil-Dev:dev/1.21/1.6 Jul 20, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

❌ Non-retryable error (HTTP 402): HTTP 402: Insufficient Balance

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Error code: 402 - {'error': {'message': 'Insufficient Balance', 'type': 'unknown_error', 'param': None, 'code': 'invalid_request_error'}}

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.

4 participants