优化: 培养计划每次进入次数+功能: 饰品提取使用预备编队+修复: 饰品提取切换存档陈年bug#581
优化: 培养计划每次进入次数+功能: 饰品提取使用预备编队+修复: 饰品提取切换存档陈年bug#581JoshCai233 wants to merge 9 commits intoOneDragon-Anything:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough新增并调整若干屏幕区域定义;放宽饰品提取存档选择、改为直接点击支援按钮;为饰品提取增加预设编队的点击与 OCR 模糊匹配并分页重试;在拓荒力计划与 UI 中加入 file_num 与 team_name 字段;为“培养目标”引入 OCR 读取体力并据此重算次数;添加按钮位置过滤以避免误点。 Changes
Sequence Diagram(s)sequenceDiagram
participant UI as "UI (PowerPlanCard)"
participant App as "Trailblaze App"
participant OE as "ChallengeOrnamentExtraction"
participant OCR as "OCR 服务"
participant Device as "设备输入"
UI->>App: 提交饰品提取任务 (file_num, team_name)
App->>OE: 初始化并传入 team_name
OE->>Device: 点击“预设编队”按钮 (round_by_find_and_click_area)
Device-->>OE: 点击确认
OE->>OCR: 截图预设编队名称区域并 OCR
OCR-->>OE: 返回候选名称列表
OE->>OE: 与 team_name 模糊匹配
alt 匹配成功
OE->>Device: 点击匹配项
else 未匹配
OE->>Device: 垂直拖动分页
Device-->>OE: 滚动完成
OE->>OCR: 重新 OCR 并重试
end
Estimated code review effort🎯 4 (复杂) | ⏱️ ~60 分钟 Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py (1)
220-236:⚠️ Potential issue | 🟠 Major
update_by_history缺少file_num和team_name的更新该方法从历史记录恢复
team_num、support、plan_times,但遗漏了file_num和team_name。这两个字段都是TrailblazePowerPlanItem的有效属性,并在历史记录中序列化。用户从历史记录恢复设置时,饰品提取的存档编号和编队名称不会被恢复,导致功能不完整。补充应在第 232 行后添加:
self.plan.file_num = history.file_num self.plan.team_name = history.team_name🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py` around lines 220 - 236, The update_by_history method restores team_num, support, plan_times and run_times from the history but omits restoring file_num and team_name, so when recovering a TrailblazePowerPlanItem the saved archive slot and team label are lost; update update_by_history (the method) to also set self.plan.file_num = history.file_num and self.plan.team_name = history.team_name after loading history (use the existing history variable and self.plan object) before calling init_team()/init_character_box()/init_plan_times_input().
🧹 Nitpick comments (4)
src/sr_od/config/team_config.py (1)
19-24:FileNumEnum的成员命名具有误导性。枚举成员使用
TEAM_1、TEAM_2等命名,但该枚举表示的是"存档"(save file),而非"编队"(team)。建议使用FILE_1、FILE_2等命名以保持语义一致,避免后续维护时产生混淆。♻️ 建议修改
class FileNumEnum(Enum): DEFAULT = ConfigItem('默认存档', 0) - TEAM_1 = ConfigItem('存档1', 1) - TEAM_2 = ConfigItem('存档2', 2) - TEAM_3 = ConfigItem('存档3', 3) - TEAM_4 = ConfigItem('存档4', 4) + FILE_1 = ConfigItem('存档1', 1) + FILE_2 = ConfigItem('存档2', 2) + FILE_3 = ConfigItem('存档3', 3) + FILE_4 = ConfigItem('存档4', 4)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/config/team_config.py` around lines 19 - 24, The enum FileNumEnum uses misleading member names (TEAM_1, TEAM_2, etc.) while representing save files; rename the members to FILE_1, FILE_2, FILE_3, FILE_4 (and optionally DEFAULT stays) to match semantics. Update all references/usages of FileNumEnum.TEAM_1, FileNumEnum.TEAM_2, FileNumEnum.TEAM_3, FileNumEnum.TEAM_4 throughout the codebase to the new names (FileNumEnum.FILE_1, etc.) and run tests to ensure no breakage.src/sr_od/app/div_uni/operations/ornamenet_extraction.py (1)
114-123:click_predefined_team中复用支援入队踢4号位角色区域语义不清晰,且缺少防御性检查。
Line 119 点击的是
支援入队踢4号位角色区域(实际坐标为单点[933, 816, 933, 816]),在"点击预设编队按钮"的上下文中语义容易混淆。如果目的是点击空白区域触发界面状态,建议定义一个语义明确的区域名称。Line 117 使用
len(self.team_name) == 0,如果team_name意外为None会抛出TypeError。建议改用not self.team_name更具防御性。♻️ 建议修改 team_name 检查
- if len(self.team_name) == 0: + if not self.team_name: return self.round_success('使用默认编队')🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/app/div_uni/operations/ornamenet_extraction.py` around lines 114 - 123, In click_predefined_team, make two fixes: replace the ambiguous region identifier '支援入队踢4号位角色' used in the call to round_by_click_area with a semantically clear region name (e.g., '空白触发区域' or similar) so the intent of clicking a single-point blank area is explicit, and add a defensive check for an empty team_name by using a truthiness check (not self.team_name) instead of len(self.team_name) == 0; update the call sites inside click_predefined_team (round_by_click_area and subsequent round_by_find_and_click_area usage) to use the new region name.src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py (1)
98-104: 类别可见性切换逻辑重复。
init_category_combo_box(Lines 101-104)和on_category_changed(Lines 167-170)中包含相同的可见性切换逻辑。建议提取为一个私有方法以减少重复。♻️ 建议提取公共方法
def _update_team_visibility(self) -> None: is_ornament = self.plan.mission.cate.cn == '饰品提取' self.team_num_opt.setVisible(not is_ornament) self.file_num_opt.setVisible(is_ornament) self.team_name_input.setVisible(is_ornament)然后在
init_category_combo_box和on_category_changed中调用self._update_team_visibility()。Also applies to: 164-170
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py` around lines 98 - 104, The visibility toggle for team/file/name controls is duplicated in init_category_combo_box and on_category_changed; extract that logic into a private helper (e.g. _update_team_visibility) that reads self.plan.mission.cate.cn and sets self.team_num_opt.setVisible, self.file_num_opt.setVisible and self.team_name_input.setVisible accordingly, then replace the duplicated blocks in both init_category_combo_box and on_category_changed with a call to self._update_team_visibility().src/sr_od/challenge_mission/use_trailblaze_power.py (1)
296-297: 可清理残留的调试注释🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 296 - 297, Remove the leftover debug comments that are no longer needed: delete the two commented lines that call ctx.guide_data.best_match_category_by_name('培养目标', tab) and ctx.guide_data.best_match_mission_by_name('培养目标', category, None) in use_trailblaze_power.py so the file contains no stale debug code; if those calls are actually required, replace the comments with a proper implementation that uses the results instead of leaving them commented out.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sr_od/app/div_uni/operations/choose_oe_file.py`:
- Around line 27-28: The current check only tests self.num > 4 and allows
negative indices to slip through causing Python negative-index behavior; change
the validation in the method that uses self.num (the block invoking round_fail
and later indexing file_areas[self.num-1]) to explicitly validate the allowed
range 0 through 4 (e.g. if not (0 <= self.num <= 4): return
self.round_fail('存档编号只能是0~4')), ensuring negative values are rejected and the
error message matches the actual valid range where 0 means "no selection".
- Around line 94-95: The call to round_by_click_area('菜单', '右上角返回') ignores its
return value so failures (round_fail or round_retry) are unhandled before
returning round_success; update choose_oe_file to capture the result of
round_by_click_area, check for round_fail and round_retry and handle them (e.g.,
return self.round_fail(...) or self.round_retry(...)) or only proceed to return
self.round_success(...) when the click returned success; reference the
round_by_click_area call and use the existing
round_fail/round_retry/round_success helpers to propagate the correct outcome.
In `@src/sr_od/app/div_uni/operations/ornamenet_extraction.py`:
- Line 1: Remove the unused top-level import "time" from the module (it's only
referenced in commented lines around the former uses), so delete the "import
time" statement to avoid unused-import warnings; search for the symbol time in
this file (e.g., references in commented code near lines ~100 and ~104) to
confirm there are no active uses before removing.
In `@src/sr_od/app/trailblaze_power/trailblaze_power_config.py`:
- Around line 12-15: The constructor's parameter default for file_num is the
wrong type: change the signature in __init__ where file_num: int = '' to use an
integer default (file_num: int = 0) and ensure the instance attribute
self.file_num retains an int; update any related type annotations if present so
they match. Locate the __init__ definition in trailblaze_power_config (the
constructor that sets self.mission_id, self.team_num, self.file_num) and make
this default consistent with add_plan() and usages like
ChallengeOrnamentExtraction.
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 115-117: 当前缩放逻辑使用 math.floor 导致 self.plan_times(和
current_challenge_times、self.mission_challenge_times)在实际功率低于配置时可能被缩为 0,从而跳过挑战;在
use_trailblaze_power.py 中修改三处赋值(self.mission_challenge_times, self.plan_times,
current_challenge_times)在取整后至少为 1(例如用 max(1, math.floor(...)) 的思想),确保 plan_times
和 current_challenge_times 最小为 1;保留原有缩放计算但在赋值时套用该下限,相关上下文可在处理战斗次数和
_after_battle_result 的逻辑中验证。
- Around line 108-109: Guard against empty OCR output before indexing by
checking power_unit_str is truthy (and/or len(power_unit_str) > 0) and then test
its first character; replace the current condition with something like: if
power_unit_str and power_unit_str[0] in ['\u00D7', 'x', 'X'] (use the explicit
Unicode multiply sign '\u00D7' instead of a plain '×' to avoid visual ambiguity)
and then strip the leading unit; reference the power_unit_str variable in this
file (use_trailblaze_power.py) when applying the change.
- Around line 110-112: The OCR call assigns self.mission_power_ocr =
str_utils.get_positive_digits(power_unit_str, err=None) which can return None,
breaking the int type and preventing future retries because the check uses if
self.mission_power_ocr == 0; change the assignment logic around
get_positive_digits in the method (the block that logs '识别体力单位失败') to coerce
None to 0 on failure (e.g., set self.mission_power_ocr = 0 when
get_positive_digits returns None) so the attribute remains an int and the retry
condition (self.mission_power_ocr == 0) functions correctly; keep the existing
log.error call but ensure the attribute is reset to 0 after logging.
- Around line 104-105: The code calls screen_loader.get_area('挑战副本',
'预计消耗体力-其他') into variable area1 and then uses area1.rect without a None check,
which can raise AttributeError; update the function (use_trailblaze_power.py) to
check if area1 is None before calling
ctx.ocr_service.get_ocr_result_list(self.last_screenshot, rect=area1.rect) and
handle the missing area gracefully (e.g., log a warning via
self.ctx.logger/process logger, skip OCR and set a sensible default/early
return) so subsequent code does not dereference None.
- Around line 138-144: When the '提示弹框-次数用完' dialog is detected (via
round_by_find_area returning success for the '挑战副本' area), replace the wrong
cancel target '开拓力弹框-取消' with the correct '提示弹框-取消' in the
round_by_find_and_click_area call; keep the existing on_battle_success(0, 200)
call and the same success_wait/retry_wait params, but call
round_by_find_and_click_area(screen, '挑战副本', '提示弹框-取消', success_wait=1,
retry_wait=1) so the "次数用完" dialog is closed reliably (see use pattern in
challenge_ehco_of_war.py).
In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py`:
- Around line 121-131: In init_team, the call
self.team_name_input.setText(self.plan.team_name) currently emits signals and
thus can trigger _on_team_name_changed → _emit_value (causing unwanted writes
during update_by_history); mirror the pattern used in init_run_times_input and
init_plan_times_input by calling self.team_name_input.blockSignals(True) before
setText(...) and self.team_name_input.blockSignals(False) after to suppress
signals during initialization so only intentional user edits fire
_on_team_name_changed/_emit_value.
In `@src/sr_od/interastral_peace_guide/guide_choose_mission.py`:
- Around line 125-131: The matching logic can return None or leave mrl_list
empty causing index errors; update the call to
str_utils.find_best_match_by_difflib(gt('本周可领取奖励次数:0/3','game'), word_list, ...)
to use a looser cutoff (e.g. 0.6) and capture its return in no_times_idx, then
add guards: if no_times_idx is None or not isinstance(no_times_idx, int) skip
the y-coordinate comparison; before doing mrl_list[tp_idx] =
mrl_list[tp_idx][1:] or accessing mrl_list[tp_idx][0].center ensure mrl_list has
sufficient length (check len(mrl_list) > tp_idx and len(mrl_list[tp_idx]) > 0
and >1 before slicing) and provide a clear fallback (e.g. leave tp_point as None
or use mrl_list[tp_idx][0] only when safe) so the code never indexes into None
or an empty list.
---
Outside diff comments:
In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py`:
- Around line 220-236: The update_by_history method restores team_num, support,
plan_times and run_times from the history but omits restoring file_num and
team_name, so when recovering a TrailblazePowerPlanItem the saved archive slot
and team label are lost; update update_by_history (the method) to also set
self.plan.file_num = history.file_num and self.plan.team_name =
history.team_name after loading history (use the existing history variable and
self.plan object) before calling
init_team()/init_character_box()/init_plan_times_input().
---
Nitpick comments:
In `@src/sr_od/app/div_uni/operations/ornamenet_extraction.py`:
- Around line 114-123: In click_predefined_team, make two fixes: replace the
ambiguous region identifier '支援入队踢4号位角色' used in the call to round_by_click_area
with a semantically clear region name (e.g., '空白触发区域' or similar) so the intent
of clicking a single-point blank area is explicit, and add a defensive check for
an empty team_name by using a truthiness check (not self.team_name) instead of
len(self.team_name) == 0; update the call sites inside click_predefined_team
(round_by_click_area and subsequent round_by_find_and_click_area usage) to use
the new region name.
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 296-297: Remove the leftover debug comments that are no longer
needed: delete the two commented lines that call
ctx.guide_data.best_match_category_by_name('培养目标', tab) and
ctx.guide_data.best_match_mission_by_name('培养目标', category, None) in
use_trailblaze_power.py so the file contains no stale debug code; if those calls
are actually required, replace the comments with a proper implementation that
uses the results instead of leaving them commented out.
In `@src/sr_od/config/team_config.py`:
- Around line 19-24: The enum FileNumEnum uses misleading member names (TEAM_1,
TEAM_2, etc.) while representing save files; rename the members to FILE_1,
FILE_2, FILE_3, FILE_4 (and optionally DEFAULT stays) to match semantics. Update
all references/usages of FileNumEnum.TEAM_1, FileNumEnum.TEAM_2,
FileNumEnum.TEAM_3, FileNumEnum.TEAM_4 throughout the codebase to the new names
(FileNumEnum.FILE_1, etc.) and run tests to ensure no breakage.
In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py`:
- Around line 98-104: The visibility toggle for team/file/name controls is
duplicated in init_category_combo_box and on_category_changed; extract that
logic into a private helper (e.g. _update_team_visibility) that reads
self.plan.mission.cate.cn and sets self.team_num_opt.setVisible,
self.file_num_opt.setVisible and self.team_name_input.setVisible accordingly,
then replace the duplicated blocks in both init_category_combo_box and
on_category_changed with a call to self._update_team_visibility().
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
assets/game_data/screen_info/challenge_mission.ymlassets/game_data/screen_info/ornamenet_extraction.ymlsrc/sr_od/app/div_uni/operations/choose_oe_file.pysrc/sr_od/app/div_uni/operations/choose_oe_support.pysrc/sr_od/app/div_uni/operations/ornamenet_extraction.pysrc/sr_od/app/trailblaze_power/trailblaze_power_app.pysrc/sr_od/app/trailblaze_power/trailblaze_power_config.pysrc/sr_od/challenge_mission/use_trailblaze_power.pysrc/sr_od/config/team_config.pysrc/sr_od/gui/interface/one_dragon/sr_echo_of_war_setting_interface.pysrc/sr_od/gui/interface/one_dragon/sr_power_plan_interface.pysrc/sr_od/interastral_peace_guide/guide_choose_mission.py
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py (1)
231-236:⚠️ Potential issue | 🟠 Major
update_by_history未从历史记录中恢复file_num和team_name
update_by_history更新了team_num、support、plan_times、run_times,但遗漏了file_num和team_name。随后调用init_team()会依据self.plan的这两个字段重新初始化 UI,但字段本身未从 history 中更新,导致切换关卡时这两个值不会被恢复。相比之下,
trailblaze_power_config.py的add_plan()在新建计划时已正确从历史记录中读取file_num和team_name(第 66-67 行),两处行为不一致。🐛 建议修复
self.plan.team_num = history.team_num self.plan.support = history.support self.plan.plan_times = history.plan_times self.plan.run_times = 0 + self.plan.file_num = history.file_num + self.plan.team_name = history.team_name self.init_team()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py` around lines 231 - 236, The update_by_history method sets self.plan.team_num, support, plan_times and run_times but fails to restore self.plan.file_num and self.plan.team_name before calling init_team; modify update_by_history to also assign self.plan.file_num = history.file_num and self.plan.team_name = history.team_name (matching the behavior in add_plan in trailblaze_power_config.py) so init_team sees the restored values and the UI is correctly reinitialized.
♻️ Duplicate comments (2)
src/sr_od/challenge_mission/use_trailblaze_power.py (2)
122-124:⚠️ Potential issue | 🟡 Minor
math.floor缩放后三个挑战次数变量均可能变为 0当实际体力消耗(
mission_power_ocr)大于配置值(self.mission.power)时,math.floor(n * power / mission_power_ocr)可能得 0。plan_times = 0会导致_after_battle_result中finish_times >= plan_times(0 >= 0)立即成立,不发起任何挑战即退出。建议至少保证 1。🐛 建议修复
- self.mission_challenge_times = math.floor(self.mission_challenge_times * self.mission.power / self.mission_power_ocr) - self.plan_times = math.floor(self.plan_times * self.mission.power / self.mission_power_ocr) - current_challenge_times = math.floor(current_challenge_times * self.mission.power / self.mission_power_ocr) + self.mission_challenge_times = max(1, math.floor(self.mission_challenge_times * self.mission.power / self.mission_power_ocr)) + self.plan_times = max(1, math.floor(self.plan_times * self.mission.power / self.mission_power_ocr)) + current_challenge_times = max(1, math.floor(current_challenge_times * self.mission.power / self.mission_power_ocr))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 122 - 124, The scaled challenge counts mission_challenge_times, plan_times and current_challenge_times can become 0 due to math.floor when mission_power_ocr > self.mission.power, causing early exit in _after_battle_result (finish_times >= plan_times). Change the scaling to enforce a minimum of 1 for each computed value (e.g., wrap the floor result with max(1, ...)) when updating mission_challenge_times, plan_times and current_challenge_times so they never become zero after scaling; keep using self.mission.power and mission_power_ocr for the computation and ensure _after_battle_result logic remains unchanged.
111-112:⚠️ Potential issue | 🔴 Critical
power_unit_str[0]未做空字符串防护,OCR 结果为空时抛出IndexErrorOCR 的
.data可能返回空字符串,此时power_unit_str[0]直接崩溃。同时 Ruff (RUF001) 警告字符串中含 Unicode 乘号×,建议改用'\u00d7'避免视觉歧义。🐛 建议修复
- if power_unit_str[0] in ['×', 'x']: + if power_unit_str and power_unit_str[0] in ['\u00d7', 'x']: power_unit_str = power_unit_str[1:]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 111 - 112, Guard against empty OCR output and avoid direct indexing: first strip whitespace and check that power_unit_str is non-empty, then remove a leading multiply marker using startswith instead of power_unit_str[0]; for example use power_unit_str = power_unit_str.strip() and then if power_unit_str and power_unit_str.startswith(('\u00d7', 'x', 'X')): remove the first char. Replace any literal '×' in the code with the Unicode escape '\u00d7' to satisfy Ruff RUF001 and include the variable name power_unit_str in your change.
🧹 Nitpick comments (1)
src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py (1)
190-192:on_file_changed的idx参数未使用(Ruff ARG002)Ruff 静态分析报告第 190 行方法参数
idx未使用。当前实现改用self.file_num_opt.currentData()获取值,idx参数仅为满足 Qt 信号槽签名要求。可将参数重命名为_或_idx以明确表达意图,与既有on_team_changed的模式保持一致。♻️ 建议修改
- def on_file_changed(self, idx: int) -> None: + def on_file_changed(self, _idx: int) -> None: self.plan.file_num = self.file_num_opt.currentData() self._emit_value()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py` around lines 190 - 192, The method on_file_changed currently has an unused parameter idx causing Ruff ARG002; rename the parameter to _idx (or _) in the on_file_changed signature to make the unused intent explicit and match the on_team_changed pattern, leaving the body using self.file_num_opt.currentData() and calling self._emit_value() unchanged so Qt signal-slot compatibility is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sr_od/app/div_uni/operations/ornamenet_extraction.py`:
- Around line 127-128: The call to screen_loader.get_area('饰品提取', '区域-预设编队名称')
may return None, so guard accesses to area.rect and area.left_top: after
obtaining area in ornamenet_extraction (where self.last_screenshot and
cv2_utils.crop_image_only are used), check if area is None, log an error via the
same logger pattern used in use_trailblaze_power.py (e.g.
self.ctx.process_logger.error(...)) and return/abort the operation early rather
than proceeding to call cv2_utils.crop_image_only or reference area.left_top;
apply this None-check before any use of area.rect and area.left_top in the
method.
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 116-118: Inside the block guarded by if self.mission_power_ocr ==
0, the code mistakenly compares self.mission.power to the instance attribute
self.mission_power_ocr (still 0) instead of the OCR result local variable
mission_power_ocr, causing the validation to never trigger; change the
comparison to use mission_power_ocr (i.e. elif self.mission.power <
mission_power_ocr) so the "OCR power exceeds configured limit" path can execute
and return 1 as intended, and verify similar places in use_trailblaze_power
where mission_power_ocr vs self.mission_power_ocr may be confused.
---
Outside diff comments:
In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py`:
- Around line 231-236: The update_by_history method sets self.plan.team_num,
support, plan_times and run_times but fails to restore self.plan.file_num and
self.plan.team_name before calling init_team; modify update_by_history to also
assign self.plan.file_num = history.file_num and self.plan.team_name =
history.team_name (matching the behavior in add_plan in
trailblaze_power_config.py) so init_team sees the restored values and the UI is
correctly reinitialized.
---
Duplicate comments:
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 122-124: The scaled challenge counts mission_challenge_times,
plan_times and current_challenge_times can become 0 due to math.floor when
mission_power_ocr > self.mission.power, causing early exit in
_after_battle_result (finish_times >= plan_times). Change the scaling to enforce
a minimum of 1 for each computed value (e.g., wrap the floor result with max(1,
...)) when updating mission_challenge_times, plan_times and
current_challenge_times so they never become zero after scaling; keep using
self.mission.power and mission_power_ocr for the computation and ensure
_after_battle_result logic remains unchanged.
- Around line 111-112: Guard against empty OCR output and avoid direct indexing:
first strip whitespace and check that power_unit_str is non-empty, then remove a
leading multiply marker using startswith instead of power_unit_str[0]; for
example use power_unit_str = power_unit_str.strip() and then if power_unit_str
and power_unit_str.startswith(('\u00d7', 'x', 'X')): remove the first char.
Replace any literal '×' in the code with the Unicode escape '\u00d7' to satisfy
Ruff RUF001 and include the variable name power_unit_str in your change.
---
Nitpick comments:
In `@src/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py`:
- Around line 190-192: The method on_file_changed currently has an unused
parameter idx causing Ruff ARG002; rename the parameter to _idx (or _) in the
on_file_changed signature to make the unused intent explicit and match the
on_team_changed pattern, leaving the body using self.file_num_opt.currentData()
and calling self._emit_value() unchanged so Qt signal-slot compatibility is
preserved.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/sr_od/app/div_uni/operations/choose_oe_file.pysrc/sr_od/app/div_uni/operations/ornamenet_extraction.pysrc/sr_od/app/trailblaze_power/trailblaze_power_config.pysrc/sr_od/challenge_mission/use_trailblaze_power.pysrc/sr_od/gui/interface/one_dragon/sr_power_plan_interface.py
🚧 Files skipped from review as they are similar to previous changes (1)
- src/sr_od/app/div_uni/operations/choose_oe_file.py
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sr_od/app/div_uni/operations/choose_oe_file.py`:
- Line 28: The error message string passed to self.round_fail contains a
fullwidth comma (,) which triggers Ruff RUF001; update the string in
choose_oe_file.py (the self.round_fail call) to use an ASCII comma (,) instead,
or if you intentionally need the fullwidth punctuation, append a noqa RUF001
comment to that line to suppress the lint error; ensure the change only alters
the punctuation or adds the noqa without modifying surrounding logic.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/sr_od/app/div_uni/operations/choose_oe_file.pysrc/sr_od/interastral_peace_guide/guide_choose_mission.py
🚧 Files skipped from review as they are similar to previous changes (1)
- src/sr_od/interastral_peace_guide/guide_choose_mission.py
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/sr_od/challenge_mission/use_trailblaze_power.py (2)
121-124:⚠️ Potential issue | 🟡 Minor缩放后可能得到 0 次,导致直接退出流程。
当实际体力消耗高于配置时,math.floor可能把次数缩为 0,应下限保护。🛡️ 建议修改
- self.mission_challenge_times = math.floor(self.mission_challenge_times * self.mission.power / self.mission_power_ocr) - self.plan_times = math.floor(self.plan_times * self.mission.power / self.mission_power_ocr) - current_challenge_times = math.floor(current_challenge_times * self.mission.power / self.mission_power_ocr) + self.mission_challenge_times = max(1, math.floor(self.mission_challenge_times * self.mission.power / self.mission_power_ocr)) + self.plan_times = max(1, math.floor(self.plan_times * self.mission.power / self.mission_power_ocr)) + current_challenge_times = max(1, math.floor(current_challenge_times * self.mission.power / self.mission_power_ocr))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 121 - 124, The scaling using math.floor on mission_challenge_times, plan_times and current_challenge_times can yield 0 when mission.power > mission_power_ocr, causing an early exit; change the three assignments (the lines updating self.mission_challenge_times, self.plan_times and local current_challenge_times) to enforce a minimum of 1 after scaling (e.g., take max(1, math.floor(...))) so they never become zero while preserving the scaled value.
109-113:⚠️ Potential issue | 🟠 Major避免
power_unit_str[0]越界并显式×字符。
OCR 可能返回空字符串,直接索引会抛IndexError;同时建议用显式 Unicode 字面量避免视觉歧义。🐛 建议修改
- if power_unit_str[0] in ['×', 'x']: - power_unit_str = power_unit_str[1:] + if power_unit_str and power_unit_str[0] in ['\u00d7', 'x']: + power_unit_str = power_unit_str[1:]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 109 - 113, Avoid indexing power_unit_str[0] directly in the block inside use_trailblaze_power.py; instead first check that ocr_result_list[0].data is non-empty before inspecting its first character to prevent IndexError, and compare against the explicit Unicode multiplication sign '×' (U+00D7) as well as ascii 'x' using a safe method like startswith or checking power_unit_str[0] after confirming non-empty; update the variable extraction around power_unit_str and the branch that strips the leading sign so mission_power_ocr = str_utils.get_positive_digits(power_unit_str, err=None) only runs on the validated/normalized string.
🧹 Nitpick comments (1)
src/sr_od/challenge_mission/use_trailblaze_power.py (1)
104-107: 建议移除area1 is None的吞错处理。
这里直接return 1会掩盖配置缺失的问题,按项目习惯更倾向让异常自然暴露以便定位。Based on learnings: 在 StarRailOneDragon 项目中,对于因人为修改配置文件导致的错误(例如 `screen_loader.get_area()` 返回 `None`),倾向于让代码自然抛出异常而不是添加防御性的 `None` 检查,因为直接的错误信息更容易发现和定位配置问题。♻️ 建议修改
- if area1 is None: - log.error('未找到预计消耗体力位置, 请检查配置文件') - return 1🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/sr_od/challenge_mission/use_trailblaze_power.py` around lines 104 - 107, Remove the defensive swallow for a missing area: delete the if-check that tests area1 is None and the subsequent log.error + return 1; instead let self.ctx.screen_loader.get_area('挑战副本', '预计消耗体力-其他') return its value and allow any resulting exception or AttributeError to surface (i.e., don’t catch or return on area1 being None) so configuration errors are exposed; locate this in use_trailblaze_power.py around the area1 = self.ctx.screen_loader.get_area(...) call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/sr_od/app/div_uni/operations/ornamenet_extraction.py`:
- Around line 128-129: The current defensive check uses "if area is None: return
self.round_fail(...)" with a copied, misleading message; instead remove this
defensive check so that a missing area from get_area() will raise an
AttributeError naturally (matching project convention), or if you must keep an
explicit check, replace the message with a correct one like "未找到预设编队配置,请检查配置文件"
and call round_fail only for runtime/logic errors; locate the occurrence around
the get_area usage (refer to get_area and round_fail in ornamenet_extraction.py)
and apply the change.
- Line 27: choose_predefined_team 中在 area 为 None 时返回的错误信息不正确(复制自体力相关方法),请将
choose_predefined_team 里处理 area is None 的 self.round_fail 调用的文本由“未找到预计消耗体力位置,
请检查配置文件”改为更贴切的描述,例如“未找到预设编队名称区域,请检查配置文件”,确保仅修改该返回的错误消息文本(保留 self.round_fail
的调用与控制流不变)。
---
Duplicate comments:
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 121-124: The scaling using math.floor on mission_challenge_times,
plan_times and current_challenge_times can yield 0 when mission.power >
mission_power_ocr, causing an early exit; change the three assignments (the
lines updating self.mission_challenge_times, self.plan_times and local
current_challenge_times) to enforce a minimum of 1 after scaling (e.g., take
max(1, math.floor(...))) so they never become zero while preserving the scaled
value.
- Around line 109-113: Avoid indexing power_unit_str[0] directly in the block
inside use_trailblaze_power.py; instead first check that ocr_result_list[0].data
is non-empty before inspecting its first character to prevent IndexError, and
compare against the explicit Unicode multiplication sign '×' (U+00D7) as well as
ascii 'x' using a safe method like startswith or checking power_unit_str[0]
after confirming non-empty; update the variable extraction around power_unit_str
and the branch that strips the leading sign so mission_power_ocr =
str_utils.get_positive_digits(power_unit_str, err=None) only runs on the
validated/normalized string.
---
Nitpick comments:
In `@src/sr_od/challenge_mission/use_trailblaze_power.py`:
- Around line 104-107: Remove the defensive swallow for a missing area: delete
the if-check that tests area1 is None and the subsequent log.error + return 1;
instead let self.ctx.screen_loader.get_area('挑战副本', '预计消耗体力-其他') return its
value and allow any resulting exception or AttributeError to surface (i.e.,
don’t catch or return on area1 being None) so configuration errors are exposed;
locate this in use_trailblaze_power.py around the area1 =
self.ctx.screen_loader.get_area(...) call.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/sr_od/app/div_uni/operations/ornamenet_extraction.pysrc/sr_od/challenge_mission/use_trailblaze_power.py
3b497df to
26491e1
Compare
Summary by CodeRabbit
新功能
改进