Conversation
Co-authored-by: Copilot <[email protected]>
- Consolidated initialization logic in `actions.go` to improve clarity and reduce redundancy. - Introduced new reporting functions for better error handling and user feedback. - Added a new file `integration.go` to encapsulate common functionalities and improve code organization. - Updated internationalization messages to support new error states and user notifications. - Removed deprecated code and streamlined weapon filtering logic.
There was a problem hiding this comment.
Hey - 我发现了两个问题,并给出了一些整体性的反馈:
- 在
buildInitViewModel中,在执行st == nil判断之前就访问了st.TargetSkillCombinations,如果函数在RunState为 nil 的情况下被调用,就会触发 panic;请把 nil 检查移动到函数最上方,在任何字段访问之前进行。 runUnifiedSkillDecision假定engine一定非 nil,并且无条件调用engine.MatchOCR;建议要么显式声明这个前置条件(例如在不满足时提前返回并上报一个 focus 错误),要么在这里对 nil engine 做保护,以避免未来在新的调用点中以 nil engine 调用该函数时出现潜在的 panic。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `buildInitViewModel`, `st.TargetSkillCombinations` is accessed before the `st == nil` guard, which will panic if the function is called with a nil `RunState`; move the nil check to the very top before any field access.
- `runUnifiedSkillDecision` assumes `engine` is non-nil and calls `engine.MatchOCR` unconditionally; consider either asserting this precondition explicitly (e.g., early return with a focus error) or guarding against a nil engine to avoid potential panics if it is ever invoked with a nil engine in new call sites.
## Individual Comments
### Comment 1
<location path="agent/go-service/essencefilter/integration.go" line_range="104-105" />
<code_context>
+ SlotSkills [3][]string
+}
+
+func buildInitViewModel(st *RunState) InitViewModel {
+ vm := InitViewModel{
+ FilteredWeapons: make([]matchapi.WeaponData, 0, len(st.TargetSkillCombinations)),
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Potential nil pointer dereference when `st` is nil in `buildInitViewModel`
`len(st.TargetSkillCombinations)` is evaluated before checking `st == nil`, so this will panic if `buildInitViewModel` is ever called with a nil `RunState`. Please guard `st == nil` first and only use `st.TargetSkillCombinations` when `st` is confirmed non-nil.
</issue_to_address>
### Comment 2
<location path="agent/go-service/essencefilter/actionsAfterBattle.go" line_range="27" />
<code_context>
}
- skills := []string{ocr.Skills[0], ocr.Skills[1], ocr.Skills[2]}
if st.MatchEngine == nil {
+ reportFocusByKey(ctx, st, "focus.error.no_match_engine")
return false
</code_context>
<issue_to_address>
**question:** After-battle decision now hard-depends on `st.MatchEngine` and no longer falls back to defaults
This now errors when `st.MatchEngine` is nil and assumes `PipelineOpts` was set up earlier, instead of reconstructing options or falling back to `defaultEssenceFilterOptions()`. That tightens the pipeline contract: any flow calling `EssenceFilterAfterBattleSkillDecisionAction` without a prior init that sets `st.MatchEngine` will fail instead of using defaults. If that behavior is desired, please verify all after-battle pipeline JSONs always run the init step first; otherwise consider calling `EnsureMatchEngine` here or restoring a minimal fallback for missing state.
</issue_to_address>帮我变得更有用!请对每条评论点 👍 或 👎,我会根据这些反馈改进后续的评审。
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- In
buildInitViewModel,st.TargetSkillCombinationsis accessed before thest == nilguard, which will panic if the function is called with a nilRunState; move the nil check to the very top before any field access. runUnifiedSkillDecisionassumesengineis non-nil and callsengine.MatchOCRunconditionally; consider either asserting this precondition explicitly (e.g., early return with a focus error) or guarding against a nil engine to avoid potential panics if it is ever invoked with a nil engine in new call sites.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `buildInitViewModel`, `st.TargetSkillCombinations` is accessed before the `st == nil` guard, which will panic if the function is called with a nil `RunState`; move the nil check to the very top before any field access.
- `runUnifiedSkillDecision` assumes `engine` is non-nil and calls `engine.MatchOCR` unconditionally; consider either asserting this precondition explicitly (e.g., early return with a focus error) or guarding against a nil engine to avoid potential panics if it is ever invoked with a nil engine in new call sites.
## Individual Comments
### Comment 1
<location path="agent/go-service/essencefilter/integration.go" line_range="104-105" />
<code_context>
+ SlotSkills [3][]string
+}
+
+func buildInitViewModel(st *RunState) InitViewModel {
+ vm := InitViewModel{
+ FilteredWeapons: make([]matchapi.WeaponData, 0, len(st.TargetSkillCombinations)),
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Potential nil pointer dereference when `st` is nil in `buildInitViewModel`
`len(st.TargetSkillCombinations)` is evaluated before checking `st == nil`, so this will panic if `buildInitViewModel` is ever called with a nil `RunState`. Please guard `st == nil` first and only use `st.TargetSkillCombinations` when `st` is confirmed non-nil.
</issue_to_address>
### Comment 2
<location path="agent/go-service/essencefilter/actionsAfterBattle.go" line_range="27" />
<code_context>
}
- skills := []string{ocr.Skills[0], ocr.Skills[1], ocr.Skills[2]}
if st.MatchEngine == nil {
+ reportFocusByKey(ctx, st, "focus.error.no_match_engine")
return false
</code_context>
<issue_to_address>
**question:** After-battle decision now hard-depends on `st.MatchEngine` and no longer falls back to defaults
This now errors when `st.MatchEngine` is nil and assumes `PipelineOpts` was set up earlier, instead of reconstructing options or falling back to `defaultEssenceFilterOptions()`. That tightens the pipeline contract: any flow calling `EssenceFilterAfterBattleSkillDecisionAction` without a prior init that sets `st.MatchEngine` will fail instead of using defaults. If that behavior is desired, please verify all after-battle pipeline JSONs always run the init step first; otherwise consider calling `EnsureMatchEngine` here or restoring a minimal fallback for missing state.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| func buildInitViewModel(st *RunState) InitViewModel { | ||
| vm := InitViewModel{ |
There was a problem hiding this comment.
issue (bug_risk): 当 buildInitViewModel 中的 st 为 nil 时可能发生空指针解引用
len(st.TargetSkillCombinations) 会在检查 st == nil 之前被求值,因此如果在 RunState 为 nil 的情况下调用 buildInitViewModel,这里会触发 panic。请先对 st == nil 做保护,只在确定 st 非 nil 时再访问 st.TargetSkillCombinations。
Original comment in English
issue (bug_risk): Potential nil pointer dereference when st is nil in buildInitViewModel
len(st.TargetSkillCombinations) is evaluated before checking st == nil, so this will panic if buildInitViewModel is ever called with a nil RunState. Please guard st == nil first and only use st.TargetSkillCombinations when st is confirmed non-nil.
| ctx.OverrideNext(arg.CurrentTaskName, []maa.NextItem{{Name: "EssenceFilterAfterBattleDiscardItemLog"}}) | ||
| } else { | ||
| ctx.OverrideNext(arg.CurrentTaskName, []maa.NextItem{{Name: "EssenceFilterAfterBattleCloseDetail"}}) | ||
| if st.MatchEngine == nil { |
There was a problem hiding this comment.
question: 战后决策现在对 st.MatchEngine 形成硬依赖,不再回退到默认值
当前实现会在 st.MatchEngine 为 nil 时直接报错,并假设 PipelineOpts 之前已经被正确设置,而不是在这里重建选项或回退到 defaultEssenceFilterOptions()。这会收紧整个 pipeline 的约束:任何在未经过设置 st.MatchEngine 的初始化步骤就调用 EssenceFilterAfterBattleSkillDecisionAction 的流程都会失败,而不会使用默认配置。如果这是预期行为,请确认所有战后 pipeline 的 JSON 都会先执行 init 步骤;否则建议在此调用 EnsureMatchEngine,或者为缺失状态恢复一个最小的兜底逻辑。
Original comment in English
question: After-battle decision now hard-depends on st.MatchEngine and no longer falls back to defaults
This now errors when st.MatchEngine is nil and assumes PipelineOpts was set up earlier, instead of reconstructing options or falling back to defaultEssenceFilterOptions(). That tightens the pipeline contract: any flow calling EssenceFilterAfterBattleSkillDecisionAction without a prior init that sets st.MatchEngine will fail instead of using defaults. If that behavior is desired, please verify all after-battle pipeline JSONs always run the init step first; otherwise consider calling EnsureMatchEngine here or restoring a minimal fallback for missing state.
There was a problem hiding this comment.
Pull request overview
该 PR 围绕 Issue #1543 的“战后基质筛选卡住/无法停止任务”问题,对战后基质筛选的 pipeline 与 go-service EssenceFilter 逻辑进行了稳定性改造、i18n 接入与流程重构,以统一战利品/背包两条链路的决策与 UI 汇报方式,并减少噪声日志。
Changes:
- 调整战后筛选 pipeline:新增基于颜色定位黄点的级联 ROI、拆分 CloseDetail 的 Skip/JumBack 路径,并引入 wait_freezes 等待机制。
- go-service EssenceFilter 重构:新增统一集成层(integration.go),复用初始化/决策/汇报逻辑,移除部分统计/技能池日志与状态字段。
- i18n 完善:AutoEssence 焦点文案改为 key,并补齐多语言 locale;matchapi 增补多条聚焦/错误/进度文案与 FormatMessage 辅助。
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| assets/resource/pipeline/EssenceFilter/EssenceFilterAfterBattleLockDiscard.json | 调整战后锁定/弃置/关闭详情分支,并引入 wait_freezes、JumpBack 专用节点 |
| assets/resource/pipeline/EssenceFilter/EssenceFilterAfterBattleCheckItem.json | 新增颜色匹配黄点定位的级联节点,重设 OCR ROI 以提高稳定性 |
| assets/resource/pipeline/AutoEssence/EssenceFilterAfterBattle.json | 焦点文案改为 i18n key,并更新部分等待参数 |
| assets/resource/image/EssenceFilter/EssenceTabChoose.png | 新增/更新图像资源 |
| assets/misc/locales/{zh_cn,zh_tw,en_us,ja_jp,ko_kr}.json | 新增 AutoEssence 战后筛选相关焦点文案翻译 |
| agent/go-service/essencefilter/ui.go | 移除低价值日志输出函数 |
| agent/go-service/essencefilter/state.go | 删除与日志统计相关的 RunState 字段与 Reset 逻辑 |
| agent/go-service/essencefilter/recognitionAfterBattle.go | 调整战后 nth 识别逻辑的日志/注释 |
| agent/go-service/essencefilter/matchapi/loader.go | 修改默认数据目录解析逻辑与错误信息 |
| agent/go-service/essencefilter/matchapi/i18n_messages.json | 大幅补充聚焦/错误/进度类 i18n 文案 |
| agent/go-service/essencefilter/matchapi/i18n.go | 新增 FormatMessage,使用嵌入式 i18n catalog |
| agent/go-service/essencefilter/matchapi/engine.go | 更新 NewDefaultEngine 注释以匹配新的默认数据路径描述 |
| agent/go-service/essencefilter/integration.go | 新增统一集成层:汇报、初始化视图模型、统一技能决策、EnsureMatchEngine |
assets/resource/pipeline/EssenceFilter/EssenceFilterAfterBattleLockDiscard.json
Show resolved
Hide resolved
assets/resource/pipeline/AutoEssence/EssenceFilterAfterBattle.json
Outdated
Show resolved
Hide resolved
| func buildInitViewModel(st *RunState) InitViewModel { | ||
| vm := InitViewModel{ | ||
| FilteredWeapons: make([]matchapi.WeaponData, 0, len(st.TargetSkillCombinations)), | ||
| } | ||
| if st == nil { | ||
| return vm | ||
| } |
There was a problem hiding this comment.
buildInitViewModel 在判断 st == nil 之前就执行了 len(st.TargetSkillCombinations) 来初始化 slice 容量;如果未来有调用方传入 nil(函数签名也允许),这里会直接 panic。建议先做 nil 判断,再决定容量(例如 cap=0 或基于 len 的分支)。
…json Co-authored-by: Copilot <[email protected]>
…eLockDiscard.json Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
#1543
1.更加稳定的roi方式
2.介入全球化
3.重构集成减少代码
4.干掉了不必要的log
5.修复了不选弃置就会自动退出的bug
6.还没想起来反正肯定还有
7.修复了interface相关没写全球化i18的问题
Summary by Sourcery
重构 EssenceFilter 引擎初始化和决策流程,以复用共享逻辑、集中化 UI 报告,并改进本地化和数据目录处理。
New Features:
matchapi.FormatMessage辅助方法和内嵌目录,用于独立于引擎实例的本地化焦点消息。Bug Fixes:
Enhancements:
EnsureMatchEngine辅助方法,以集中化 EssenceFilter 的匹配引擎创建、选项加载和状态接线。data/EssenceFilter,并在无法找到路径时提供更清晰的错误信息。Original summary in English
Summary by Sourcery
Refactor EssenceFilter engine initialization and decision flows to reuse shared logic, centralize UI reporting, and improve localization and data directory handling.
New Features:
Bug Fixes:
Enhancements:
Summary by Sourcery
重构 EssenceFilter 的初始化和决策处理逻辑,在共享背包和战后流程中的引擎设置与 UI 逻辑的同时,改进本地化能力和数据目录解析。
New Features:
Bug Fixes:
Enhancements:
data/EssenceFilter布局,并在解析失败时提供更清晰的错误信息。Original summary in English
Summary by Sourcery
Refactor EssenceFilter initialization and decision handling to share engine setup and UI logic across inventory and after-battle flows while improving localization and data directory resolution.
New Features:
Bug Fixes:
Enhancements: