Skip to content

The rendering of the block work area indicator has been modified. 修改了方块工作范围指示框的渲染 - #4767

Merged
WhereisFff merged 5 commits into
Anvil-Dev:dev/1.21/1.6from
PigeonNian:box/1.21/1.6
Sep 9, 2026
Merged

The rendering of the block work area indicator has been modified. 修改了方块工作范围指示框的渲染#4767
WhereisFff merged 5 commits into
Anvil-Dev:dev/1.21/1.6from
PigeonNian:box/1.21/1.6

Conversation

@PigeonNian

@PigeonNian PigeonNian commented Sep 9, 2026

Copy link
Copy Markdown
Contributor
  • 对于物品收集器等带有工作范围框的方块,鼠标不再指向的时候,线框额外再渲染5秒
  • 修复了预览透明度配置文件的浮点数
  • 修改了奇点晶体tooltip

Pigeon_Nian added 3 commits September 9, 2026 18:12
- 将配置中的多部分预览不透明度类型由float改为double,增强精度
- 在HudTooltipManager中新增解析作用范围方法,提升代码复用性
- 修改多处多部分预览相关代码,确保不透明度转换为float后再使用
- RenderEventListener新增影响范围持久化缓存,避免频繁计算和渲染
- 在渲染事件中根据游戏时间管理作用范围的显示时长,实现边框持续显示效果
- 优化智能放置器和结构扫描器的范围渲染,改用统一的颜色和持久化逻辑
- 精简渲染流程,添加null安全检查,提升稳定性和性能
- 引入 @nullable 注解标记 currentPos 变量
- 在渲染缺失放大器轮廓和玻璃时增加 level 非空检查
- 防止 level 为 null 导致的渲染调用崩溃
- 提升渲染代码的健壮性和稳定性
- 删除了HudTooltipManager中的renderAffectRange方法实现
- 移除了不再使用的renderOutline静态导入
- 简化了代码,减少冗余方法和依赖
- 保持代码清洁,提升可维护性
@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #4767

操作: opened
范围: 4 个文件(全部 Java)/ 269 行 diff,无新增/删除文件
分支: box/1.21/1.6 → dev/1.21/1.6(1.21 项目,跳过 26.1 API 迁移检查集)
标题: 原标题过于笼统("…has been modified"),本想改为 Persist work-range outline for 5s after cursor leaves 鼠标移开后工作范围线框保留 5 秒,但 gh 未认证(token invalid),跳过标题修改。

📋 声称验证表

PR 声称 状态 对应文件
物品收集器等带工作范围框的方块,鼠标不再指向时线框额外渲染 5 秒 RenderEventListener.javaRANGE_OUTLINES 缓存 + RANGE_OUTLINE_PERSIST_TICKS = 100(5s)+ renderPersistedOutlines();三个来源全部接入:renderAffectRange(IHasAffectRange BE)、renderSmartBlockPlacerRangerenderStructureScannerRange
修复预览透明度配置文件的浮点数 AnvilCraftClientConfig.javamultiPartPreviewGhostOpacity/OutlineOpacity float→double)+ LargeBlockPlacePreviewEventListener.java 全部 4 处使用点加 (float) 强转,目标分支上无其他引用遗漏

⚠️ 警告

  • RenderEventListener.java(onRender)— 断开/返回主菜单时静态引用不清理。 level == null 直接 return,既不置空 renderedLevel 也不清 RANGE_OUTLINES → 静态字段钉住上一个 ClientLevel(连同 chunk 缓存数据)直到下次进世界才被替换;停留主菜单期间无法 GC。跨维度/进新世界因 ClientLevel 实例变化会触发清空,功能不受影响,但建议 level == null 分支补 renderedLevel = null; RANGE_OUTLINES.clear();(内存泄漏窗口 = 主菜单停留时长)。
  • RenderEventListener.java(renderAffectRange / renderSmartBlockPlacerRange / renderStructureScannerRange)— 悬停期间线框每帧绘制两遍。 三个方法内部 addRangeOutline() 后立即直接 renderOutline(),帧末 renderPersistedOutlines() 又把刚加入的条目(lastSeenTick == gameTime,未过期)再画一遍。RenderType.lines() 不透明 + LEQUAL 深度下重复像素视觉无差别,但每帧重复提交同一批顶点;若日后换用半透明 RenderType 会出现双重 alpha。建议只保留一条路径:去掉方法内直接 renderOutline 调用,统一由帧末 persisted 渲染(刚 add 的条目当帧即被绘制,行为等价),或让 renderPersistedOutlines 跳过本帧刚刷新的条目。

💡 建议

  • 持久框无目标有效性校验。 方块在 5 秒窗口内被拆除/替换后,过期前仍会在原位渲染幽灵线框。affect range 条目可顺带校验 getBlockEntity(pos) 仍是 IHasAffectRange(placer/scanner 校验方块状态),但"幽灵残留"本身可能就是产品意图,非阻塞。
  • 过期判定基于 level.getGameTime() 多人服时间被拨回(/time set)或 SP 暂停时 lastSeenTick 停止前进 → 线框消失被推迟到时间追回;暂停期间永不消失。如需 5 秒为真实/帧时间,可改用客户端帧计数。低影响,加注释说明即可。
  • 配置 float→double 的根因确认。 所有使用点强转后行为等价(0.3f → (float)0.3 无损)。若原 bug 是配置文件写出 float 精度垃圾(如 0.30000001192092896),同文件中其他 float + @BoundedDiscrete 字段(如 anvilHammerRadialMenuScale)理论上同样受影响——请确认是否只有这两个字段有该问题。

🟢 看起来不错

  • AFFECT_RANGE_COLOR 常量统一了三处重复的 0xFF00FFCC 魔数。
  • HudTooltipManager.renderAffectRangeresolveAffectRange 拆分为纯解析,职责清晰,@Nullable 标注与 null 防护正确(唯一调用方已同步更新)。
  • 换世界/跨维度时通过 renderedLevel 实例对比清空缓存的设计正确;条目按 100 tick 过期,规模有界。
  • renderMissingAmplifierGhostslevel null 防护与 currentPos@Nullable 是合理加固;javax 注解与 1.21 分支惯例一致(216 文件使用,0 jspecify)。
  • 新增记录/字段均无跨线程访问(仅渲染线程),形状均为世界绝对坐标,重放渲染坐标正确。

🧪 测试建议

被测目标 推荐测试场景 优先级
onRender 残留逻辑 悬停物品收集器 → 移开鼠标 → 线框继续显示约 5s(100 tick)后消失 🟡
renderPersistedOutlines 悬停后立即拆掉方块 / 换维度 → 检查幽灵框与旧维度框行为 🟡
shouldRenderEffect 分支 悬停中切换主手物品(goggleMode=HOLDING)→ 线框仍残留至超时;goggle 关闭时无新框 🟡
配置 double 转换 修改 ghost/outline opacity 后实机预览透明度正确(默认 0.3/0.5),旧配置文件可正常加载 🟢
暂停/时间边界 SP 暂停挂机后恢复、/time set 回拨 → 线框最终仍会消失 🟢

结论: COMMENT — 实现与 PR 描述一致,无阻塞性缺陷。建议处理 ⚠️1(静态 Level 泄漏,一行修复)与 ⚠️2(重复绘制)后合入。gh 未认证(token invalid),标题未修改。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'rendering-gpu-pr-review' (1 replacement).

- 修改奇点水晶的普通工具提示为“由微型黑洞和微型白洞形成的水晶”
- 添加奇点水晶的按Shift显示的详细提示,说明其存储天体数据及与超维终端交互方法
- 同步更新en_us和en_ud语言文件中奇点水晶的提示文本内容
@PigeonNian
PigeonNian marked this pull request as draft September 9, 2026 10:57
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -s "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4767" | python3 -c "import json,sys; d=json.load(sys.stdin); print('head:', d['head']['label'], d['head']['sha']); print('base:', d['ba...

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.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4767 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4767 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

交叉验证完成。所有关键点已确认,输出审查意见(converted_to_draft 事件 → 只报实质问题、comment 级别,标题已是规范的中英格式无需修改):


代码审查摘要 — PR #4767

操作: converted_to_draft
范围: 7 个文件(5 Java / 2 lang)/ 323 行 diff
主题: 方块工作范围指示框在鼠标移开后额外保留渲染 5 秒 + 预览透明度配置浮点修复

🔴 关键

无阻断性正确性问题。坐标语义、生命周期、API 迁移均验证正确:

  • renderOutline(..., BlockPos.ZERO, shape) 的 shape 顶点被解释为世界坐标(顶点 = minX - camX),三个来源(affectRange AABB / smartBlockPlacer / structureScanner)都是世界坐标形状,persist 渲染位置与原即时渲染完全一致 ✅
  • renderAffectRangeresolveAffectRange 重构语义等价(provider null / shape null 早退),且 entity==null 防御从调用方下沉到方法内,更安全 ✅
  • RANGE_OUTLINES 清理路径完整:维度切换/重进世界时 renderedLevel 引用变化 → clear;renderPersistedOutlines 在 shouldRenderEffect 真假两条路径末尾均被调用,过期条目不会悬挂 ✅
  • config float→double 后 4 处使用点(全仓库唯一使用文件 LargeBlockPlacePreviewEventListener)全部补齐 (float) 转型,无编译遗漏 ✅
  • 存储的 VoxelShape 均不可变(Shapes.create 即时新实例 / 静态 AABB),跨 5 秒持有安全 ✅

⚠️ 警告

  1. 同帧双重渲染(冗余)RenderEventListener.java 三处调用点(renderAffectRange / renderSmartBlockPlacerRange / renderStructureScannerRange)在 addRangeOutline(...) 后都紧跟一次立即 renderOutline,而帧末 renderPersistedOutlines 会把刚加入的条目再渲染一遍——持续指向中的范围框每帧被画两次。当前 RenderType.lines() + 不透明色(0xFF00FFCC)下视觉无差异,仅是约 2× 顶点浪费;但若未来把颜色改为带透明度的 fill/glass,叠加会增亮。建议:add 后删除立即渲染,统一由帧末 renderPersistedOutlines 绘制(两条路径都会调用它,可保证不丢帧)。

  2. 5 秒尾巴无条件渲染 — 移开鼠标后,即使玩家切换手持物品 / 关闭 hammer 特效开关(shouldRenderEffect 变 false),遗留线框仍会显示满 5 秒。这与描述「鼠标不再指向时额外渲染 5 秒」字面一致,但若设计意图是「仅当特效显示开启时才有尾巴」,需要在 renderPersistedOutlines 前补门控。另外 dragon rod 吞噬范围(DEVOUR_RANGE)同属范围框但未纳入 persist——如需视觉一致可考虑,非必须。

  3. Scope 外变更ItemTooltipManager.java + en_us.json/en_ud.json 的 singularity_crystal tooltip 文本修改(含新增 .shift 键)与「工作范围框渲染」主题无关,疑似混入其他分支工作。draft 阶段建议确认是否拆分。文本本身已验证:en_us 与 Java 侧 NORMAL/SHIFT 内容一致、en_ud 翻转与行序正确(生成器产物,无问题)。

💡 建议

  • config 迁移一致性 — 仓库中 @BoundedDiscrete + float 组合仍有残留:anvilHammerRadialMenuScalehudScale(AnvilCraftClientConfig)。若 float→double 是为规避该组合的浮点/反序列化问题,这两处可能同样受影响,可一并确认;另外已有用户配置文件(anvilcraft-client.toml)中旧 float 值在字段类型变更后会被重置为默认值,用户自定义透明度会丢失(NightConfig 无迁移),可在 PR 描述中注明。
  • 条目上限RANGE_OUTLINES 无显式容量上限,理论上快速扫视大量方块会在 5 秒窗口内积累条目;实际峰值有限(移动窗口自然淘汰),暂可接受,不必处理。

🟢 看起来不错

  • 颜色常量统一抽取 AFFECT_RANGE_COLOR,与旧值 0xFF00FFCC 一致
  • RangeOutline record + lastSeenTick 时间戳设计简洁,迭代器遍历中安全删除
  • 新增 level == null 防御与 level != renderedLevel 清空逻辑完整

🧪 测试建议

被测目标 推荐测试场景 优先级
renderPersistedOutlines 指向收集器→移开:恰 100 ticks 后消失;切维度/重进世界立即清空 🔴
renderAffectRange 等 3 处 持续指向同一方块时帧内仅渲染一次(修复双重渲染后验证) 🟡
config 加载 含旧 float 值的已有 toml 文件加载:字段重置为默认值且无异常 🟡
暂停态 单人暂停时尾巴冻结、恢复后继续计时,不残留 🟢

结论: COMMENT — 逻辑正确、生命周期完整,无阻断问题。建议在 draft 阶段处理双重渲染冗余,并确认 singularity_crystal tooltip 变更是否为意外混入。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'github-webhook-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成,所有关键点已交叉验证。以下是审查意见:


代码审查摘要 — PR #4767

操作: synchronize(PR 当前为 draft 状态)
范围: 7 个文件(5 Java + 2 生成 lang)/ 323 行 diff
分支: PigeonNian:box/1.21/1.6Anvil-Dev:dev/1.21/1.6(1.21.x 项目,非 26.1 迁移,跳过 API 迁移检查)

📋 声称验证表

声称 状态 对应文件
工作范围框在鼠标移开后再渲染 5 秒 RenderEventListener(RANGE_OUTLINES 持久化 + 100 tick 过期)、HudTooltipManager(render→resolve 重构)
修复预览透明度配置的浮点数 AnvilCraftClientConfig float→double,LargeBlockPlacePreviewEventListener 4 处补 (float) 转型

⚠️ 警告

  1. 无关改动混入本 PRsingularity_crystal 工具提示被整体改写:NORMAL 文案从 "Data disk for storing extreme celestial data…" 改为 "A crystal formed of a micro black hole and a micro white hole",并新增 .shift 键(ItemTooltipManager + en_us.json + en_ud.json 三处,与奇点水晶/超维终端上传器功能相关)。这与「工作范围框渲染」和「透明度浮点修复」两个声称毫无关系,建议拆成独立 PR,或至少在描述中说明原因——否则按现状合并会把无关改动带进主干。
  2. float→double 配置迁移兼容性 — 类型变更后需实测一次旧配置文件加载:已生成配置里历史值(如 0.3)以 double 读取应无碍,但请确认配置框架加载后不会触发类型校验/重置(可在现有玩家配置下运行验证)。视觉上 (double)0.3 → (float) 与原来 0.3f 完全一致,这是纯存储/显示精度修复,行为无回归。
  3. renderedLevel 静态强引用残留level == null(断线/回主菜单)时直接 return,RANGE_OUTLINES 不清空、renderedLevel 仍强引用旧 ClientLevel,直到下次进图才被清理。建议:
    Level level = Minecraft.getInstance().level;
    if (level == null) {
        RANGE_OUTLINES.clear();
        renderedLevel = null;
        return;
    }

💡 建议

  • LargeBlockPlacePreviewEventListener 内层 level != null 是死守卫renderMissingAmplifierGhosts 唯一调用者 renderGhost 开头已判 mc.level == null 提前返回,内层两个 guard 实际不可达;若本意是防御某次崩溃,建议移到函数开头统一判断而非包住两个调用。
  • 内层 hammer 检查冗余renderSmartBlockPlacerRange / renderStructureScannerRange 内部仍各自调用 !AnvilHammerItem.shouldRenderEffect(player),外层已统一 gate 后这些分支不可达(player == null 检查仍需要),可选清理。
  • 持久化框的时效性 — 5 秒内方块被破坏/拆除后仍会显示残留线框(形状是快照)。如需精确,可在绘制时校验 keyed BlockPos 的方块是否仍是对应类型,或明确接受此行为。

🟢 看起来不错

  • 坐标语义正确:交叉验证 IHasAffectRange.shape() 返回世界绝对坐标 AABB(如 AABB.ofSize(Vec3.atCenterOf(getBlockPos()), …)),renderOutlineBlockPos.ZERO 偏移 + -cam 平移绘制——因此持久化线框在相机移动后重渲染位置依然正确,无坐标错位 bug。
  • 重构干净:删除旧 HudTooltipManager.renderAffectRange 前已在全树 grep——base 分支仅 RenderEventListener 一处调用,head 无残留调用点;resolveAffectRange 唯一消费方即新 renderAffectRange
  • 类型变更无漏网点:config 字段 double 化后全树 4 处使用点全部显式 (float) 转型(若漏则编译失败,已逐一核对)。
  • 持久化 map 生命周期合理:level 实例变化(维度切换/新进世界)即 clear;过期用 iterator.remove() 安全删除,无并发修改风险,条目数受 5 秒窗口自然约束。
  • 颜色魔数收敛AFFECT_RANGE_COLOR = 0xFF00FFCC,与原三处零散值一致(均 0xff00ffcc),无行为变化。
  • lang 与代码逐字一致:en_us/en_ud .shift 键符合既有 56 个 .shift 键约定,en_ud 全串翻转(含行序反转)与新文本匹配。

结论: COMMENT(无阻断性问题)

持久化实现逻辑正确、改动等价性成立、无编译残留;主要问题是不相关的奇点水晶 tooltip 改动混入本 PR(建议拆分或补充描述),外加 3 个非阻塞清理项。PR 处于 draft 状态,建议拆分/说明后转 ready 再合并。标题「The rendering of the block work area indicator has been modified. 修改了方块工作范围指示框的渲染」基本准确,未修改。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/persisted-outline-cache-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'github-webhook-pr-review' (1 replacement).

- 在 RangeOutline 记录中添加 BlockState,避免加载过时边框
- 处理 Level 为空时清理渲染状态,防止残留边框
- 修改方法由直接渲染改为登记范围,推迟渲染到统一处理
- renderPersistedOutlines 增加对 BlockState 变化检测,及时移除失效边框
- 精简并统一范围边框的添加流程,提升代码可维护性
- 修正并更新部分注释,增强代码可读性
@PigeonNian
PigeonNian marked this pull request as ready for review September 9, 2026 11:12
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4767" -o /tmp/pr4767.json && python3 -c "
import json
d=json.load(open('/tmp/pr4767.json'))
print('state:', d.get('state'))
print('tit...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

gh 认证 token 已失效(401),无法执行 gh pr edit,仅此而已——审查本身走公开 diff 端点,不受影响。分析已完成,输出审查意见。

代码审查摘要 — PR #4767

操作: synchronize
范围: 7 个文件(5 Java + 2 生成 lang)/ 335 行 diff
分支: box/1.21/1.6dev/1.21/1.6(本地克隆已 fetch PR head 与目标分支交叉验证)

📋 声称验证表

声称 状态 对应文件
带工作范围框方块,鼠标移开后线框再渲染 5 秒 RenderEventListener(RANGE_OUTLINES + RANGE_OUTLINE_PERSIST_TICKS=5*20)、HudTooltipManager(renderAffectRangeresolveAffectRange 解耦)、智能放置器/结构扫描仪一并接入
修复预览透明度配置文件浮点数 AnvilCraftClientConfig(2 字段 float→double)、LargeBlockPlacePreviewEventListener(4 处调用点全部补 (float) 强转,git grep 确认无其它使用点遗漏)
(未声称)singularity_crystal tooltip 改写 ⚠️ ItemTooltipManager + en_us.json + en_ud.json

🔴 关键

无编译/逻辑级阻断问题。核心机制验证通过:

  • 过期逻辑正确:注册时 put(pos, new RangeOutline(state, shape, gameTime)) 每帧刷新;渲染时统一 sweep——gameTime > lastSeen + 100 过期、getBlockState(pos) != 存储 state 或换维度(renderedLevel 变化)即清。指向期间每帧 re-put 覆盖,不会闪烁;移开后恰好保留 ~5 秒。✓
  • 渲染位置/姿态不变:三种线框的 shape 均为世界绝对坐标 + BlockPos.ZERO 渲染,与旧代码逐字一致,无回归。✓
  • config 类型迁移安全:base 分支全仓仅 4 处消费这两个字段且全部位于被改文件内,4 处均强转;@BoundedDiscrete + double 与文件中既有 double 字段(groundHeaveParticleChance 等)惯例一致。✓
  • lang 生成物自洽:en_us ↔ en_ud(逐行反转 + 行序反转正确)↔ ItemTooltipManager NORMAL/SHIFT 文案逐字一致,含 \n 换行。✓

⚠️ 警告

  1. 范围外变更未在 PR 描述中声明ItemTooltipManager.java 及生成的 en_us/en_ud.json 中 singularity_crystal 的 tooltip 改写("Data disk"→微黑洞/白洞水晶 + 新增 .shift 上传器说明)与描述的两条改动无关。内容本身自洽、机制上对应 hyperdimension_terminal 配方,无质量问题;若是有意包含请补充 PR 描述,否则建议拆出单独 PR,避免合入记录与真实 diff 不符。

  2. 状态比对会使"5 秒保留"在部分场景缩水renderPersistedOutlineslevel.getBlockState(pos) != outline.blockState(引用比较,MC 状态单例故 == 可行)作为继续绘制条件。若准星离开后的 5 秒内方块状态合法变化(红石切换物品收集器开关、旋转结构扫描仪、方块被破坏),线框会立即消失而非保留满 5 秒。这可能是刻意的保守设计(避免展示过期形状),但需确认是否符合预期——尤其物品收集器这类常被红石切换的方块,用户可能感知到"时有时无"的边框。

  3. 冗余双重闸门onRender 外层已用 !shouldRenderEffect 提前 return,registerSmartBlockPlacerRange / registerStructureScannerRange 内部的 player == null || !shouldRenderEffect 判断已成为死代码(旧代码中它们先于外层闸门执行、内层判断是必需的;重构后语义保留但可清理)。

💡 建议

  • registerAffectRangehitResult.miss 检查 — 另两个 register 均有 if (hitResult.miss) return,此函数没有(沿用旧代码模式)。MISS 时 getBlockPos() 为射线末端空气位、getBlockEntity() 通常为 null 会提前返回,不构成 bug,但补上更一致。
  • LargeBlockPlacePreviewEventListenerlevel != null 守卫是死防御renderGhostmc.level == null 时已 clear() 两列表并 return(第 233-237 行),单线程客户端中到 renderMissingAmplifierGhosts 时 level 不可能为 null。无害,但建议加注释说明或移除,避免读者误以为存在异步置空路径。
  • 残留条目清理时机 — 相机实体非 Player(如 /spectate 生物)时提前 return,RANGE_OUTLINES 要到切回玩家视角或换维度才 sweep;条目量级很小、恢复渲染的首帧即按 gameTime 判过期,影响可忽略,可不处理。
  • PR 标题 — 建议去掉 synchronize: 前缀并体现功能(如 "Persist block work-area outlines for 5s after un-hover; fix preview opacity config")。本会话 gh token 已失效(401),无法代为 gh pr edit,仅作建议。

🟢 看起来不错

  • lastSeenTick + 每帧 put 刷新实现"准星离开后保持",设计简洁正确;三种范围框(收集器类/智能放置器/结构扫描仪)统一走一张持久化表,行为一致。
  • resolveAffectRange 将"解析 shape"与"渲染"解耦,@Nullable 语义完整,调用方判空正确;旧 renderOutline 静态导入清理干净,无残留引用。
  • config float→double 修复点全覆盖;@Nullable 注解与 1.21 分支既有代码(同文件 javax.annotation.Nullable)惯例一致。

结论: COMMENT — 核心功能实现正确、无阻断问题;需作者确认两点:① singularity_crystal tooltip 等范围外变更是否有意包含;② 方块状态变化时提前结束 5 秒保留是否符合预期。

@Gugle2308

Copy link
Copy Markdown
Collaborator

gh 令牌已失效(无法 gh pr edit,且按约束绝不导出 token);标题本身基本达意,不作修改。输出审查意见:

代码审查摘要 — PR #4767

操作: ready_for_review
范围: 7 文件(4 Java, 2 lang 生成, 1 config)/ 335 行 diff — 小 PR,已通读全部 diff

核心逻辑(重构 + 5 秒滞留渲染)

渲染管线从「逐帧直接画」改为「命中时登记 + 统一延迟渲染」:

  • RenderEventListener 新增 Map<BlockPos, RangeOutline>(record 存 blockState/shape/lastSeenTick),renderPersistedOutlines 每帧惰性清理过期条目(gameTime > lastSeen + 100 ticks = 5 秒);shouldRenderEffect 为 false 时也先渲染残留边框再 return,实现"失焦后 5 秒"效果 ✅
  • 失效处理正确:条目按 BlockPos 键存 hit 方块的 BlockState!= 比较在该分支可安全依赖 MC 状态规范化(chunk palette 存 canonical 实例);方块被拆/旋转/换块立即移除 ✅
  • 维度切换/断线(level != renderedLevel / level == null)清空缓存,避免残留 ✅
  • Map 只在渲染线程访问,注册发生在迭代前的同一帧内(put 与 iterator.remove 不重叠),无并发/CME 风险 ✅
  • 形状均为绝对世界坐标 + BlockPos.ZERO 渲染(与旧代码一致,renderOutline 每帧用当前相机平移),相机移动后残留边框位置依然正确 ✅
  • 旧方法(renderAffectRange/renderSmartBlockPlacerRange/renderStructureScannerRange)删除干净,head 分支 grep 确认无残留调用方;HudTooltipManager.resolveAffectRange 拆分合理 ✅
  • LargeBlockPlacePreviewEventListener 的 level 非空防御属冗余(上层已判 mc.level == null 早退),无害

已验证与描述一致

声称 状态 对应实现
工作范围框失焦后额外渲染 5 秒 RANGE_OUTLINE_PERSIST_TICKS = 5*20,覆盖收集器/智能放置器/结构扫描器三类边框
修复预览透明度配置文件浮点数 两字段 floatdouble,4 处调用点(LargeBlockPlacePreviewEventListener)全部补 (float) 强转,grep 确认无遗漏调用点

💡 建议(非阻塞)

  • 范围杂入 — commit 503b623(奇点水晶 tooltip 文本 + en_us/en_ud 同步)与 PR 描述的两个改动无关。lang 与 ItemTooltipManager 内容自洽,但建议从本 PR 拆出或补充说明,避免变更历史语义混乱。
  • 行为细节 — 滞留计时用客户端 level.getGameTime():服务器卡顿/单机暂停时"5 秒"会按游戏刻顺延;另外关闭效果开关(放下锤子/切 goggle)也会触发 5 秒滞留而非立即消失。如非预期可改为渲染帧计时,但按现有语义可接受。
  • registerSmartBlockPlacerRange 等内部重复判 shouldRenderEffect/null level 为旧守卫残留,冗余但无害。

🔴 关键问题

无。逻辑提取与行为等价性、持久化生命周期、坐标空间、类型迁移均验证通过。

结论: COMMENT — ready_for_review 状态,无阻塞性问题;建议仅处理范围杂入的 tooltip 提交。PR 标题基本达意,未修改。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/persisted-outline-cache-review.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'github-webhook-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

gh 未认证(token 失效),标题修改跳过——原标题已含中英文且描述准确,无需改动。审查完成,输出结论:

代码审查摘要 — PR #4767

操作: edited
范围: 7 个文件(5 Java + 2 生成 lang)/ 335 行 diff(0 新增、0 删除)
分支: PigeonNian:box/1.21/1.6 → dev/1.21/1.6(1.21.x 常规功能 PR,非 26.1 迁移,跳过迁移健康度检查)
CI: build ✅ / checkstyle ✅

📋 声称验证表

声称 状态 对应文件
鼠标不再指向时线框额外渲染 5 秒 RenderEventListener.java(RANGE_OUTLINES 静态 Map + 100 ticks 过期)
修复预览透明度配置文件浮点数 AnvilCraftClientConfig.java(float→double)+ LargeBlockPlacePreviewEventListener.java(4 处 (float) 转换)
修改奇点晶体 tooltip ItemTooltipManager.java + en_us.json/en_ud.json(三方文本一致)

🔍 机制验证(与 base 分支旧代码逐一对照)

  • 门控等价性:旧 renderSmartBlockPlacerRange/renderStructureScannerRange/renderAffectRange 与新 register* 系列受同一 shouldRenderEffect 门控(默认 WEARING_OR_HOLDING_HAMMER,内部二次检查一致),无行为回归。
  • 坐标系正确:shape 均为世界坐标 + renderOutline(..., BlockPos.ZERO, ...) → 相机移动后框锚定在世界原位置,5 秒滞留期间不漂移,特性符合预期。
  • 生命周期安全:过期 = gameTime > lastSeenTick + 100(20tick/s → 恰 5 秒);Level 实例切换(切维度/重进世界)即清空;方块状态变化立即移除。BlockState 引用 != 比较可靠(MC BlockState 全局驻留)。
  • null 链完整resolveAffectRange 对 entity null / provider null / shape null 全路径返回 null,register 侧兜底 return。
  • dragon rod(DEVOUR_RANGE)轮廓正确地未纳入持久化——其形状依赖手持物品的动态 range 组件,保持即时渲染是正确取舍。
  • config 类型变更无遗漏:4 处消费点全部加 (float),CI 编译通过证明无其他引用残留。
  • tooltip 数据源一致:ItemTooltipManager map(datagen 源)↔ en_us.json ↔ en_ud.json 翻转镜像完全对应,.shift key 符合既有 tooltip.anvilcraft.item.<id>.shift 约定,含 \n 多行结构一致。

⚠️ 警告

  • LargeBlockPlacePreviewEventListener.javarenderMissingAmplifierGhosts 中新增的两处 if (level != null) 是不可达守卫:renderGhost 调用前已判 mc.level == null → return,同一事件帧内不会再变 null。无害,但建议上提为方法级单一守卫,避免误导调用契约。
  • HudTooltipManager.javarenderAffectRangeresolveAffectRange 是公开方法改名(api.tooltip 包)。若存在第三方 addon 调用该方法会源码/二进制不兼容;若该包属对外 API,建议留 @Deprecated 桥接,否则可忽略。
  • 行为边界确认 — 关闭目镜/放下锤子后,已注册线框仍会滞留至多 5 秒(含 TOGGLE_WITH_KEY 关闭瞬间)。这超出"鼠标不再指向"的描述范围,属于特性的自然延伸,请确认是有意为之。

💡 建议

  • RenderEventListener.renderPersistedOutlines — 每帧对每个条目执行 level.getBlockState(key),建议加 level.isLoaded(key) 短路(传送/死亡后对远处已卸载区块做状态查询,客户端虽不阻塞加载但语义更稳妥)。
  • registerSmartBlockPlacerRange/registerStructureScannerRange 内部保留的 shouldRenderEffect 二次检查现已冗余(调用点在同一 gate 内),可清理。
  • 帧率级 put() 每次新建 RangeOutline record,可在 shape/state 未变时跳过写回(微小优化)。

🟢 看起来不错

  • 过期 + 方块状态双重失效判定设计干净;renderedLevel 实例比较正确覆盖切维度/重连场景。
  • 颜色常量 AFFECT_RANGE_COLOR = 0xFF00FFCC 提取统一,与旧值一致;en_ud 与 en_us 同步更新保持 datagen 一致性。
  • 空手/看空(hitResult 无命中)时不会注册新条目,残留仅按时间自然衰减。

结论: APPROVE — 实现正确,三类改动均与声称一致,无关键问题;仅 3 个非阻塞提示项。

由 Hermes Agent 审查

@WhereisFff
WhereisFff merged commit c9026b2 into Anvil-Dev:dev/1.21/1.6 Sep 9, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

PR #4767 状态为 closed —— 按 webhook 审查规则(closed/labeled → 停止),不获取 diff、不发布审查评论。本次会话到此结束,无需其他操作。

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.

3 participants