Skip to content

Add and fix override action 添加并修复存储容器的覆盖操作 - #4466

Draft
QiuShui1012 wants to merge 2 commits into
Anvil-Dev:dev/1.21/1.6from
QiuShui1012:action/1.21/1.6
Draft

Add and fix override action 添加并修复存储容器的覆盖操作#4466
QiuShui1012 wants to merge 2 commits into
Anvil-Dev:dev/1.21/1.6from
QiuShui1012:action/1.21/1.6

Conversation

@QiuShui1012

Copy link
Copy Markdown
Collaborator
  • 实现了在界面中拿着超维终端右键物品可以把物品收进去
  • 将药盒的左右键操作逻辑与超维终端/护符盒同步
  • 添加一个配置允许反转以上操作,开启后拿着物品左键超维终端/护符盒/药盒或拿着超维终端/护符盒/药盒左键物品才可以把物品收进去

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && python3 -c "
import zipfile
z = zipfile.ZipFile('neoforge-sources.jar')
names = [n for n in z.namelist() if 'AbstractContainerMenu' in n or 'ContainerMenu.java' in n]
print(names[:10])
for ...

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

⚠️ Dangerous command requires approval:

cd /tmp && python3 -c "
import zipfile
z = zipfile.ZipFile('neoforge-sources.jar')
names = [n for n in z.namelist() if 'AbstractContainerMenu' in n]
print('\n'.join(names[:5]))
"

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

分析完成。所有关键交叉验证均已完成(目标分支 API、CI 状态、存储写入链路、lang 翻转)。以下是审查输出:


代码审查摘要 — PR #4466

操作: opened
范围: 9 个文件(+128/−45):7 Java(1 新增)+ 2 生成 lang
分支: action/1.21/1.6dev/1.21/1.6(MC 1.21/1.21.1,NeoForge 21.0.x)
CI: build ✅ / checkstyle ✅(head c501fc99 已通过,含编译)

📋 声称验证表

声称 状态 对应实现
界面中拿着超维终端右键物品收进去 HyperdimensionTerminalItem.overrideStackedOnOther(新增,服务端)+ StorageServerStub.insertIntoStorage(新增)
药盒左右键逻辑与终端/护符盒同步 PillBoxItem 两个 override 改为 isCollectAction 统一判定;AmuletBoxItem 同步切换
配置反转以上操作 AnvilCraftServerConfig.invertContainerCollectClick + ClientEventListener.isCollectMouseButton + ContainerCollectInteraction + en_us/en_ud

🔴 关键问题

无。核心逻辑与既有架构一致,编译通过,未发现数据丢失/安全漏洞。

⚠️ 警告

  1. PillBoxItem.overrideOtherStackedOnMe / AmuletBoxItem — invert 模式下空手左键会命中"取出"分支
    反转后 isCollectAction(PRIMARY) 为真,空手左键点击持有物品的护符盒/药盒会触发 pop 取出,而不是 vanilla 的"拿起盒子"。旧逻辑里 PRIMARY 仅在 other 非空时插入、空手左键永远走 vanilla 拿起;现在空手左键(invert 时)或空手右键(默认时,护符盒本来如此)都会取出。建议确认反转语义是否只想覆盖"拿着物品收进去"(PR 描述正是如此),如果是,pop 分支应限定在默认按键下触发,避免 invert 模式下玩家无法用左键正常拿起盒子。

  2. StorageServerStub.insertIntoStorage 绕过 StorageView 多存储路由
    所有既有存入路径(terminalInsert/deposit/moveSameToStorage)都经 view.insert() 分发(先并入已含同类的存储、再写 primary、最后扩展)。新路径直接 getOrCreate(storageId) 后单点写入绑定存储。当前终端绑定视图是单存储(station,无 crate 链),行为等价;但若未来终端支持 crate 网络/搜索模式合并,此路径会跳过合并逻辑。建议改为复用 view 或至少加注释说明有意为之。

💡 建议

  • 创造模式/纯客户端菜单的预测残留overrideStackedOnOtherplayer instanceof ServerPlayer 门控,客户端预测返回 false → 按 vanilla 交换预测,随后靠服务端广播校正(注释已说明)。但终端拾取器 ItemPickerMenu 是纯客户端菜单(containerId==-1,服务端广播被忽略),RPC 路径为此专门做了 TerminalRemoteOverlay.applyCarriedIfCreative 手动写回;新路径没有对应处理。该场景(终端 GUI 里 cursor 拿着另一个终端点击物品)很边缘,但建议实测确认不会残留错误指针。
  • 服务端配置驱动客户端输入invertContainerCollectClick 是 SERVER 配置,却被纯客户端逻辑读取(ClientEventListener.isCollectMouseButton、预测期的 collectAction())。单人共用配置无问题;专用服务器上客户端读本地副本,服务端与客户端的反转判定可能不一致(表现:终端浮窗拦截按键与服务器实际判定不同)。项目已有先例(AutoEnchantingTableScreenEnergyWeaponUseHUD 均读 AnvilCraft.CONFIG),故不阻塞,若想严谨可考虑挪到 CLIENT 配置。
  • 药盒默认模式行为变更:默认配置下右键持物品点药盒槽位现在是"整组放入"(取代 vanilla 逐格放置)——与护符盒一致,符合 PR 声明的同步目标;仅提醒这是对旧"左键放入"习惯的破坏性变更,文档/更新日志可提一句。

🟢 看起来不错

  • en_ud 翻转校验通过:两条新 lang 键的 upside-down 翻转与 en_us 逐字符一致(独立映射验证),生成无手工错误。
  • 版本刷新链路完整insertIntoStorageInfiniteItemStacksResourceHandler.insertItemonContentsChangedStorageServerStub.onContentsChanged + Storages.setDirty(),与 terminalInsert 同链路,远程终端能感知新写入(代码注释属实)。
  • 无重复插入路径:客户端拦截(hovered 槽位是终端)与新版服务端路径(cursor 持有终端)按构造互斥;StorageScreen 明确排除在拦截外,全部走服务端路径。
  • 防嵌套一致canStore 拒绝潜影盒/超维站/终端本身,两条路径都先校验;getOrCreate 行为与既有 openRemote 一致。
  • insertIntoStorage 返回实际插入数slot.set 处理部分插入与空栈,无计数错误;slot.allowModification 门控位置正确。
  • CI 的 build(编译)与 checkstyle 均通过,代码风格无问题。

结论: COMMENT — 功能实现完整、架构上符合既有模式、无阻断性缺陷。建议作者确认 ⚠️#1 的 invert 空手左键语义是否符合预期,并实测创造模式下新路径的预测残留(建议 #1)。

🧪 测试建议

被测目标 推荐测试场景 优先级
HyperdimensionTerminalItem.overrideStackedOnOther 绑定空/失效 ID、槽位物品被 canStore 拒绝、部分插入、创造模式、Shift 无冲突 🔴
ContainerCollectInteraction + 配置反转 两端配置不一致(专用服务器)时终端浮窗拦截与预测行为 🟡
PillBoxItem 双 override invert=true 时空手左键点盒子(pop vs 拿起)、满盒插入失败回退 vanilla 🟡
StorageServerStub.insertIntoStorage 存储不存在时 getOrCreate 后插入、版本号递增触发远程刷新 🟢

由 Hermes Agent 审查
验证依据:目标分支 dev/1.21/1.6 FETCH_HEAD 源码交叉引用、API 提交状态查询(build/checkstyle 通过)、en_ud 独立翻转校验。

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Skill 'item-override-interaction-pr-review' created.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4466" -o /tmp/pr4466.json 2>/dev/null; python3 -c "
import json
d=json.load(open('/tmp/pr4466.json'))
print('state:', d.get...

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

I have completed my analysis. Let me write the review.

Summary of my verified findings:

  1. Version refresh worksBaseStorage.onContentsChangedStorageServerStub.onContentsChanged(storageId) bumps stub version + clears order cache on every insertItem, so the direct getItems().insertItem used by the new insertIntoStorage correctly refreshes open terminal GUIs. The PR's claim is accurate.
  2. Nesting guard correctcanStore rejects shulker/hyperdimension-station/terminal items for HyperdimensionStorage, preventing nested containers.
  3. Config wiring consistentisCollectMouseButton (client, keyUse/keyAttack) ↔ isCollectAction (server, SECONDARY/PRIMARY) map consistently under the same invertContainerCollectClick config across terminal screen, amulet box, and pill box.
  4. PillBox unification is behavior-preserving — old dual-button (PRIMARY insert / SECONDARY take-out) → single button (insert on item, take-out on empty), matching amulet box. Correct.
  5. Scope creep — unrelated requires_expansion text change.
  6. Asymmetry note — terminal overrideStackedOnOther is server-only vs amulet/pillbox both-sides.

Let me write the review comment.


PR #4466 审查意见

感谢提交。「拿着超维终端右键收纳物品」+ 药盒/护符盒交互统一 + invertContainerCollectClick 配置反转,整体实现思路清晰,我逐项验证如下。

验证通过的部分

  • 版本刷新链路正确insertIntoStorage 直接 storage.getItems().insertItem(...),而 HyperdimensionStorage 的 item handler 每次内容变化都会触发 BaseStorage.onContentsChangedStorageServerStub.onContentsChanged(storageId)(对匹配的 stub version++ 并清空 order 缓存)。所以收纳后已打开的终端 GUI 会自动刷新,与 terminalInsert 远程路径一致,注释中的"触发版本刷新"成立。
  • 嵌套容器防护正确canStoreHYPERDIMENSION 类型拒绝收纳潜影盒/超维存储站/超维终端,与 StorageView.insert 入口一致,防止嵌套死循环。
  • 配置双向一致:客户端 isCollectMouseButtonkeyUse=右 / keyAttack=左)与服务端 isCollectActionSECONDARY / PRIMARY)在同一 invertContainerCollectClick 下映射一致(右键=SECONDARY、左键=PRIMARY),终端屏、护符盒、药盒三方行为统一。
  • 药盒合并为等价重构:旧逻辑是「左=收纳、右=取出」两个键,现统一为单键「点物品收纳 / 点空位取出」,与护符盒一致,两种交互都被保留,无逻辑丢失。
  • 不篡改入参insertItem(stack.copy(), false) 用副本,other.shrink(inserted) + slot.set 处理剩余,局部放入也能正确反映剩余数量。

建议/需关注

  1. 超维终端 overrideStackedOnOther 仅服务端执行,与护符盒/药盒不一致player instanceof ServerPlayer 守卫)。护符盒和药盒两端都运行(客户端预测 + 服务端确认),而终端方法在客户端直接 return false,会落入 vanilla 点击预测。虽靠服务端广播校正(与现有 StorageTerminalClientStub.insert 的异步校正模式一致),但右键点非空槽位时客户端会先做一次 vanilla 预测(可能短暂把槽位物品捏起再被广播回滚),对非创造玩家可能有一帧视觉跳变。建议确认该差异是有意为之(避免重复),并考虑与药盒/护符盒统一或补充客户端同侧处理。

  2. 越界改动(scope creep)gui.anvilcraft.category.container_upgrade.requires_expansion 文案从 "Space Over-compressor Expansions" 改成 "Space Overcompressor Upgrades"(JeiLang.java + en_us + en_ud),与本 PR 的容器覆盖交互无关。若属顺带修正,建议拆到独立 PR 或在描述里说明。

  3. getOrCreate 可能创建幻影存储insertIntoStorageStorages.get().getOrCreate(...),若绑定失效会创建空存储。与既有 openRemote 用法一致,风险低,可不改。

  4. 无行内评论/无测试:本 PR 只改了实现,未见对应测试。核心是容器交互逻辑(收纳、取出、反转配置),建议至少补一条覆盖 overrideStackedOnOther / overrideOtherStackedOnMeinvertContainerCollectClick 两种取值下行为对称的测试。

整体逻辑严谨、与既有存储/RPC 体系契合度高,主要请关注上述第 1、2 点。

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

@PigeonNian
PigeonNian marked this pull request as draft August 18, 2026 10:52
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4466" -o /tmp/pr4466.json; python3 -c "
import json
d = json.load(open('/tmp/pr4466.json'))
print('draft:', d.get('draft'))
print('mer...

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

All checks complete. Writing the review (comment-level, draft PR → serious issues only):


代码审查摘要 — PR #4466

操作: converted_to_draft
范围: 10 个文件 / 368 行 diff(9 处修改 + 1 个新文件 ContainerCollectInteraction.java
分支: action/1.21/1.6 → dev/1.21/1.6(目标分支 MC 版本 [1.21,1.21.1),已用 git fetch + git show FETCH_HEAD 交叉验证)

🔴 关键

  • HyperdimensionTerminalItem.canFitInsideContainerItems(ItemStack) — 签名与目标分支 API 不匹配,编译会失败
    目标分支是 MC 1.21/1.21.1(gradle.properties: minecraft_version_range=[1.21,1.21.1)),该版本 Item.canFitInsideContainerItems()无参签名(带 stack 参数的变体是 1.21.2+ 才引入的)。分支上既有代码可证:ShulkerContainerBlockItemHyperdimensionTerminalItem(FETCH_HEAD 上)均覆写无参版本,且该方法上方保留着 @Override 注解。
    新签名 canFitInsideContainerItems(ItemStack stack) 在 1.21.1 的 Item没有任何可覆写的父方法@Override 直接编译报错;就算去掉注解也会静默变成死重载,终端就丢失了「不能放进容器」的限制(回归)。
    这看起来是从 26.1 分支(该 API 已带参数)移植文件时遗留的——请改回 public boolean canFitInsideContainerItems()

⚠️ 警告

  • AnvilCraftServerConfig 的 SERVER 配置被纯客户端逻辑读取ClientEventListener.isCollectMouseButton() 与客户端菜单预测期的 ContainerCollectInteraction.isCollectAction() 都读 AnvilCraft.CONFIG.invertContainerCollectClick。专用服务器上客户端读本地默认值 → 客户端拦截按键与服务端实际判定不一致(左键点击会先做 vanilla 交换预测再被服务端校正,闪一下)。项目已有先例(AutoEnchantingTableScreenEnergyWeaponUseHUD 均直接读 AnvilCraft.CONFIG),可视为惯例,但建议在配置注释里说明该值在客户端/服务端两处生效。
  • 反转模式下「空手 + 左键」会命中取物分支 — invert=true 时 PRIMARY 也是收纳键,PillBoxItem/AmuletBoxItemother.isEmpty() 分支会把盒子里的物品 pop 出来(对应「拿着盒子左键空槽」也会把物品放出来)。PR 描述只提到反转「收进去」的方向,请确认取物也随反转键生效是有意为之(与护符盒默认行为一致,但配置名/文案只说 collect)。
  • insertIntoStorage 直写绕过 StorageView 多存储路由 — 与既有路径(terminalInsert 等经 StorageView.insert() 先并入同类型存储、再写 primary、再扩展 crate 链)相比,新路径经 Storages.get().getOrCreate(storageId, ...) 单点直写。当前终端绑定即单存储,行为等价;未来支持 crate 网络/搜索合并时此处会分叉。建议补注释说明有意为之,或直接复用 view 路径。

💡 建议

  • StorageServerStub.insertIntoStoragegetOrCreate 在 storageId 类型不匹配时会抛 IllegalArgumentException——目前终端绑定只会指向 HyperdimensionStorage,风险低,知道即可。

🟢 看起来不错

  • 共享判定类抽取干净ContainerCollectInteractioncollectAction() + isCollectAction())被终端/护符盒/药盒三处复用,药盒的 PRIMARY/SECONDARY 双分支也正确合并为「同一按键:有物品收、空槽取」。
  • 版本刷新链路经端到端验证成立storage.getItems().insertItem()UnlimitedItemStacksResourceHandler.onContentsChanged(slot, existing)BaseStorage 回调 → StorageServerStub.onContentsChanged(id)version++ 并清空 order 缓存,远程终端能看到新写入。javadoc 声称属实。
  • 插入语义正确insertItemstack.copy() 保护输入不被 handler 修改;返回值 原数量 - leftover 即实际插入数;部分插入时 other.shrink(inserted) + slot.set 保留余量。
  • 服务端执行 + 客户端预测取舍已文档化player instanceof ServerPlayer 门控 + javadoc 明确「客户端交给 vanilla 预测并在服务端广播后校正」,符合惯例。
  • nesting 防护完整:新路径同样经过 canStore(拒绝潜影盒/终端自身等嵌套)。
  • en_ud 校验通过:两条新键及改动的 requires_expansion 行与 en_us 逐字符翻转一致(含 4→߈、Over-compressor→Overcompressor 的写法同步)。

📋 声称验证表

声称 状态 对应文件
超维终端界面内拿着终端右键物品收进绑定存储 HyperdimensionTerminalItem.overrideStackedOnOther + StorageServerStub.insertIntoStorage
药盒左右键逻辑与终端/护符盒同步 PillBoxItem(合并为单一收集键,默认右键)
反转配置(左键收纳) ContainerCollectInteraction + AnvilCraftServerConfig.invertContainerCollectClick + 客户端 isCollectMouseButton

结论: COMMENT — 交互逻辑本身设计合理、刷新链路经核实成立,但 canFitInsideContainerItems 的签名在 1.21/1.21.1 分支上无法编译(26.1 移植遗留),修复前请勿合并。另外两个语义点(反转模式空手左键会取物、SERVER 配置被客户端读取)建议在描述/注释中明确意图。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'item-override-interaction-pr-review' (1 replacement).

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.

2 participants