feat(os): 大世界购买行动力双模式及紧急调度增强 - #777
Conversation
合并以下 16 个提交为单个 PR 提交: [feat] 大世界智能调度新增购买行动力双模式功能 - 新增 BuyActionPointMode 配置(off / hazard1_leveling / meowfficer_farming) - 新增 BuyActionPointUpperThreshold / BuyActionPointLowerThreshold 双阈值控制 - 新增月末行动力清理功能(MonthEndActionPointCleanupEnable) - 新增行动力阈值推送通知(30 分钟最小间隔) - 新增 CoinTaskMixin(黄币补充任务通用 Mixin) - 配置/i18n 同步更新(5 种语言) [fix] 购买行动力逻辑修复 - 添加购买行动力 OCR 有效性校验,防止错误覆盖计数器 - 修复 _is_buy_action_point_ocr_valid 缺少 server 导入 - 同步购买计数前先选中石油按钮,防止 OCR 读到药箱数量 - 修复 BuyActionPointLimit 临时覆盖残留导致错误延迟 - 修复 action_point_buy 与 BuyActionPointLimit 冲突 - 买行动力模式改用下限阈值决定购买时机 - 减少买行动力模式下行动力弹窗频率,防止 TooManyClickError - 消除智能调度下冗余行动力弹窗(os/map.py + meowfficer_farming.py) - 购买后使用缓存 AP 而非过期本地变量 - 修复 BuyActionPointUpperThreshold 未生效 - 功能2购买逻辑改为仅使用 UpperThreshold [fix] 其他 - fix(daily): 为 daily_checked 添加 list[int] 类型注解 - fix(webui): 修复翻译文件 key 缺失导致 GUI 启动 KeyError 崩溃
CI 检查报告
检查结果
导入冒烟测试
|
审阅者指南实现了一个与智能调度深度集成的双模式 OS 行动力购买系统,增加了具备每周购买追踪和改进 OCR 校验的 AP 感知调度循环,引入月末 AP 购买阻断、行动力缓存和弹窗抑制以避免 TooManyClickError,并更新配置、OCR 选项以及类型安全/GUI 回退逻辑。 OS 智能调度双模式行动力购买的时序图sequenceDiagram
participant OpsiScheduling
participant Config
participant ActionPointUI
participant HazardLeveling
participant MeowfficerFarming
OpsiScheduling->>OpsiScheduling: run_smart_scheduling_once()
OpsiScheduling->>OpsiScheduling: _is_buy_action_point_mode_active()
alt BuyActionPointMode enabled and not is_running_prevent_action_point_overflow_task()
OpsiScheduling->>OpsiScheduling: _run_buy_action_point_mode()
OpsiScheduling->>OpsiScheduling: _sync_buy_action_point_count_with_game()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_set_button(0)
OpsiScheduling->>ActionPointUI: action_point_get_buy_remain()
OpsiScheduling->>OpsiScheduling: _is_buy_action_point_ocr_valid()
ActionPointUI-->>OpsiScheduling: remain
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>Config: OpsiGeneral_BuyActionPointLimit
alt buy_limit <= 0 and sync_result == 0
OpsiScheduling->>OpsiScheduling: notify_push()
OpsiScheduling->>OpsiScheduling: _delay_smart_scheduling_to_server_update()
OpsiScheduling-->>OpsiScheduling: return True
else buy_limit > 0 or restored to 5
OpsiScheduling->>OpsiScheduling: _get_buy_action_point_count()
alt hazard1_leveling mode
OpsiScheduling->>OpsiScheduling: _run_buy_ap_hazard1_loop(buy_limit)
loop while current_count < buy_limit
OpsiScheduling->>OpsiScheduling: _buy_one_action_point()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_buy()
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>OpsiScheduling: _set_buy_action_point_count()
OpsiScheduling->>OpsiScheduling: _run_scheduled_hazard1_leveling()
OpsiScheduling->>HazardLeveling: run_hazard1_leveling_once(ap_preserve, ap_checked=True)
HazardLeveling-->>OpsiScheduling: ActionPointLimit (when AP exhausted)
end
else meowfficer_farming mode
OpsiScheduling->>OpsiScheduling: _run_buy_ap_meowfficer_loop(buy_limit)
loop while current_count < buy_limit
OpsiScheduling->>OpsiScheduling: _get_scheduling_action_point()
alt current_ap < upper_threshold
OpsiScheduling->>OpsiScheduling: _buy_one_action_point()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_buy()
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>OpsiScheduling: _set_buy_action_point_count()
end
OpsiScheduling->>OpsiScheduling: _get_priority_table_for_buy_count()
OpsiScheduling->>OpsiScheduling: _get_filtered_priority_table()
OpsiScheduling->>OpsiScheduling: notify_push()
OpsiScheduling->>Config: temporary(OpsiGeneral_BuyActionPointLimit=0)
loop for each task_name in filtered_table
OpsiScheduling->>OpsiScheduling: _run_scheduled_coin_task_once(task_name, 0)
alt success
OpsiScheduling->>OpsiScheduling: _get_scheduling_action_point(force_refresh=True)
else ActionPointLimit or AP < lower_threshold
OpsiScheduling-->>OpsiScheduling: break to next purchase
end
end
end
end
end
else BuyActionPointMode disabled or prevent_overflow task running
OpsiScheduling->>OpsiScheduling: normal yellow_coins/AP scheduling
end
文件级改动
可能关联的 Issue
提示与命令与 Sourcery 交互
自定义你的体验访问你的 控制面板 以:
获取帮助Original review guide in EnglishReviewer's GuideImplements a dual-mode OS action point buying system tightly integrated with smart scheduling, adds AP-aware scheduling loops with weekly purchase tracking and improved OCR validation, introduces month-end AP purchase blocking, action point caching and popup suppression to avoid TooManyClickError, and updates configuration, OCR options, and type safety/GUI fallbacks. Sequence diagram for OS smart scheduling dual-mode action point buyingsequenceDiagram
participant OpsiScheduling
participant Config
participant ActionPointUI
participant HazardLeveling
participant MeowfficerFarming
OpsiScheduling->>OpsiScheduling: run_smart_scheduling_once()
OpsiScheduling->>OpsiScheduling: _is_buy_action_point_mode_active()
alt BuyActionPointMode enabled and not is_running_prevent_action_point_overflow_task()
OpsiScheduling->>OpsiScheduling: _run_buy_action_point_mode()
OpsiScheduling->>OpsiScheduling: _sync_buy_action_point_count_with_game()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_set_button(0)
OpsiScheduling->>ActionPointUI: action_point_get_buy_remain()
OpsiScheduling->>OpsiScheduling: _is_buy_action_point_ocr_valid()
ActionPointUI-->>OpsiScheduling: remain
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>Config: OpsiGeneral_BuyActionPointLimit
alt buy_limit <= 0 and sync_result == 0
OpsiScheduling->>OpsiScheduling: notify_push()
OpsiScheduling->>OpsiScheduling: _delay_smart_scheduling_to_server_update()
OpsiScheduling-->>OpsiScheduling: return True
else buy_limit > 0 or restored to 5
OpsiScheduling->>OpsiScheduling: _get_buy_action_point_count()
alt hazard1_leveling mode
OpsiScheduling->>OpsiScheduling: _run_buy_ap_hazard1_loop(buy_limit)
loop while current_count < buy_limit
OpsiScheduling->>OpsiScheduling: _buy_one_action_point()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_buy()
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>OpsiScheduling: _set_buy_action_point_count()
OpsiScheduling->>OpsiScheduling: _run_scheduled_hazard1_leveling()
OpsiScheduling->>HazardLeveling: run_hazard1_leveling_once(ap_preserve, ap_checked=True)
HazardLeveling-->>OpsiScheduling: ActionPointLimit (when AP exhausted)
end
else meowfficer_farming mode
OpsiScheduling->>OpsiScheduling: _run_buy_ap_meowfficer_loop(buy_limit)
loop while current_count < buy_limit
OpsiScheduling->>OpsiScheduling: _get_scheduling_action_point()
alt current_ap < upper_threshold
OpsiScheduling->>OpsiScheduling: _buy_one_action_point()
OpsiScheduling->>ActionPointUI: action_point_enter()
OpsiScheduling->>ActionPointUI: action_point_safe_get()
OpsiScheduling->>ActionPointUI: action_point_buy()
OpsiScheduling->>ActionPointUI: action_point_quit()
OpsiScheduling->>OpsiScheduling: _set_buy_action_point_count()
end
OpsiScheduling->>OpsiScheduling: _get_priority_table_for_buy_count()
OpsiScheduling->>OpsiScheduling: _get_filtered_priority_table()
OpsiScheduling->>OpsiScheduling: notify_push()
OpsiScheduling->>Config: temporary(OpsiGeneral_BuyActionPointLimit=0)
loop for each task_name in filtered_table
OpsiScheduling->>OpsiScheduling: _run_scheduled_coin_task_once(task_name, 0)
alt success
OpsiScheduling->>OpsiScheduling: _get_scheduling_action_point(force_refresh=True)
else ActionPointLimit or AP < lower_threshold
OpsiScheduling-->>OpsiScheduling: break to next purchase
end
end
end
end
end
else BuyActionPointMode disabled or prevent_overflow task running
OpsiScheduling->>OpsiScheduling: normal yellow_coins/AP scheduling
end
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我发现了 1 个问题,并给出了一些整体反馈:
- 在
_run_buy_ap_meowfficer_loop中,push_content代码块引用了bought_this_round和buy_round,但bought_this_round从未被定义,而buy_round只在购买分支中被赋值;当当前 AP ≥ 上限阈值时,这会导致NameError和/或UnboundLocalError。建议显式维护一个表示“本轮是否有购买”的布尔变量,并在两条执行路径中都安全地初始化buy_round。 - 60 秒的 AP 缓存 TTL 逻辑在
_get_scheduling_action_point和_run_scheduled_hazard1_leveling中重复出现;可以考虑把 TTL 和缓存检查提取到一个小的辅助函数或共享常量中,以降低这两个调用点未来出现差异的风险。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `_run_buy_ap_meowfficer_loop`, the `push_content` block references `bought_this_round` and `buy_round`, but `bought_this_round` is never defined and `buy_round` is only set in the purchase branch, which will cause a `NameError` and/or `UnboundLocalError` when current AP ≥ upper threshold; consider explicitly tracking a boolean for "bought this round" and initializing `buy_round` safely for both paths.
- The 60-second AP cache TTL logic is duplicated between `_get_scheduling_action_point` and `_run_scheduled_hazard1_leveling`; factoring the TTL and cache-check into a small helper or shared constant would reduce the risk of the two callsites diverging over time.
## Individual Comments
### Comment 1
<location path="module/os/tasks/scheduling.py" line_range="1300-1301" />
<code_context>
+ f'[大世界-买行动力] 第 {buy_count} 次购买后优先级表: {task_names}'
+ )
+
+ # 推送本轮购买状态和下一步任务
+ if bought_this_round:
+ push_content = (
+ f'第 {buy_round}/{buy_limit} 次购买行动力完成\n'
</code_context>
<issue_to_address>
**issue (bug_risk):** Variable `bought_this_round` is used but never defined in `_run_buy_ap_meowfficer_loop`, which will raise at runtime.
In this function, `bought_this_round` is only read when composing the push content and is never set in any branch, so this path will immediately raise a `NameError`. You likely want a flag indicating whether a purchase occurred in the current loop iteration, e.g. compute it (such as `bought_this_round = current_ap < upper_threshold and self._buy_one_action_point()`) before this block and use that value here.
</issue_to_address>帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据这些反馈改进后续的代码评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In
_run_buy_ap_meowfficer_loop, thepush_contentblock referencesbought_this_roundandbuy_round, butbought_this_roundis never defined andbuy_roundis only set in the purchase branch, which will cause aNameErrorand/orUnboundLocalErrorwhen current AP ≥ upper threshold; consider explicitly tracking a boolean for "bought this round" and initializingbuy_roundsafely for both paths. - The 60-second AP cache TTL logic is duplicated between
_get_scheduling_action_pointand_run_scheduled_hazard1_leveling; factoring the TTL and cache-check into a small helper or shared constant would reduce the risk of the two callsites diverging over time.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `_run_buy_ap_meowfficer_loop`, the `push_content` block references `bought_this_round` and `buy_round`, but `bought_this_round` is never defined and `buy_round` is only set in the purchase branch, which will cause a `NameError` and/or `UnboundLocalError` when current AP ≥ upper threshold; consider explicitly tracking a boolean for "bought this round" and initializing `buy_round` safely for both paths.
- The 60-second AP cache TTL logic is duplicated between `_get_scheduling_action_point` and `_run_scheduled_hazard1_leveling`; factoring the TTL and cache-check into a small helper or shared constant would reduce the risk of the two callsites diverging over time.
## Individual Comments
### Comment 1
<location path="module/os/tasks/scheduling.py" line_range="1300-1301" />
<code_context>
+ f'[大世界-买行动力] 第 {buy_count} 次购买后优先级表: {task_names}'
+ )
+
+ # 推送本轮购买状态和下一步任务
+ if bought_this_round:
+ push_content = (
+ f'第 {buy_round}/{buy_limit} 次购买行动力完成\n'
</code_context>
<issue_to_address>
**issue (bug_risk):** Variable `bought_this_round` is used but never defined in `_run_buy_ap_meowfficer_loop`, which will raise at runtime.
In this function, `bought_this_round` is only read when composing the push content and is never set in any branch, so this path will immediately raise a `NameError`. You likely want a flag indicating whether a purchase occurred in the current loop iteration, e.g. compute it (such as `bought_this_round = current_ap < upper_threshold and self._buy_one_action_point()`) before this block and use that value here.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| # 推送本轮购买状态和下一步任务 | ||
| if bought_this_round: |
There was a problem hiding this comment.
issue (bug_risk): 变量 bought_this_round 在 _run_buy_ap_meowfficer_loop 中被使用但从未定义,运行时会抛出异常。
在这个函数中,bought_this_round 只在构造推送内容时被读取,但在任何分支中都没有被赋值,因此这条执行路径会立即触发 NameError。你可能需要一个标志位来表示当前循环迭代中是否发生了购买,例如在该代码块之前计算它(比如 bought_this_round = current_ap < upper_threshold and self._buy_one_action_point()),然后在这里使用这个值。
Original comment in English
issue (bug_risk): Variable bought_this_round is used but never defined in _run_buy_ap_meowfficer_loop, which will raise at runtime.
In this function, bought_this_round is only read when composing the push content and is never set in any branch, so this path will immediately raise a NameError. You likely want a flag indicating whether a purchase occurred in the current loop iteration, e.g. compute it (such as bought_this_round = current_ap < upper_threshold and self._buy_one_action_point()) before this block and use that value here.
|
不是哥们,你AI改的代码能看一下吗?你自己看看改的什么东西,自己重新改,还有大世界智能调度麻烦用有点脑子的AI改,这坨屎山太容易出问题了 |
📋 PR 概览
本 PR 将 16 个提交合并为单个提交,专注于 大世界(OS)智能调度+购买行动力双模式 及关联修复。
一、版本对比
BuyActionPointLimit,按购买次数上限控制BuyActionPointLimit(次数限制)+BuyActionPointUpperThreshold(上限阈值),通过BuyActionPointMode切换action_point_set_button(0));新增 OCR 有效性校验TooManyClickErroraction_point_setdaily_checked类型list无注解,append(n)类型不安全list[int]注解 +append(int(n))dic_lang["ja-JP"][key] = dic_lang["en-US"][key]直接取值,key 缺失时 KeyError 崩溃en-US.get(key)安全回退二、功能新增
2.1 购买行动力双模式(
BuyActionPointMode)OpsiScheduling中新增购买行动力模式配置,用户可选择off(关闭)、hazard1_leveling(侵蚀1练级模式)、meowfficer_farming(耄耋相接模式)。CoinTaskMixin中新增状态管理:STATE_KEY_BUY_AP_COUNT(本周已购次数)、STATE_KEY_BUY_AP_WEEK_ID(ISO 周标识),通过BuyActionPointUpperThreshold/BuyActionPointLowerThreshold控制阈值。2.2 月末行动力清理(
MonthEndActionPointCleanupEnable)action_point.py中_is_in_month_end_purchase_block_week():基于服务器时间计算当前自然周与下月首周的重合关系。2.3 推送通知增强
CoinTaskMixin.notify_push():校验推送配置有效性(_is_push_config_valid),格式化启动器通知文案(_format_launcher_notification,喵~风格),发送成功后记录时间戳。三、问题修复
scheduling.pyaction_point_set_button(0)选中石油/误识别为1)scheduling.py_is_buy_action_point_ocr_valid校验逻辑server未导入导致ModuleNotFoundErrorimport module.config.serverscheduling.pyBuyActionPointLimit临时覆盖残留导致错误延迟action_point.pybuy_limit <= 0时按游戏上限 5 次恢复action_point_buy与BuyActionPointLimit冲突action_point.pyscheduling.pyBuyActionPointLowerThresholdTooManyClickErrorscheduling.pymap.py+meowfficer_farming.pymap.py:检测到_smart_scheduling_context时跳过;meowfficer_farming.py:仅在非智能调度上下文时调用action_point_setscheduling.pyBuyActionPointUpperThreshold未生效scheduling.pydaily_checked类型不一致append(n)可能存非 intdaily.pydaily_checked: list[int]+append(int(n))en-US直接[]取值,key 缺失抛出异常lang.pyen-US.get(key)安全回退四、实现说明
4.1 变更文件一览
module/os/tasks/scheduling.pymodule/os_handler/action_point.pyBuyActionPointLimit残留恢复逻辑module/os/map.pymodule/os/tasks/meowfficer_farming.pyaction_point_setmodule/daily/daily.pydaily_checked类型注解module/webui/lang.pyen-US.get(key)安全回退config/template.jsonmodule/config/argument/argument.yamlmodule/config/argument/args.jsonmodule/config/config_generated.pymodule/config/i18n/*.json(×5)4.2 双模式决策逻辑
配置常量(
CoinTaskMixin):模式读取(
OpsiScheduling):阈值读取(含容错,避免非法配置值):
计数器跨周自动重置(基于服务器时间 ISO 周标识):
双模式决策表:
4.3 智能调度弹窗抑制(双文件联动)
问题:智能调度+代跑子任务时,
OpsiScheduling外层已查询过行动力,子任务内部的搜敌和进入海域逻辑又会重复触发行动力弹窗,导致高频弹窗,可能触发TooManyClickError。抑制点 1 —
module/os/map.py(搜敌前跳过冗余弹窗刷新):抑制点 2 —
module/os/tasks/meowfficer_farming.py(跳过重复的action_point_set):完整调用链路:
五、测试情况
off/hazard1_leveling/meowfficer_farming三模式_is_buy_action_point_ocr_valid检测斜杠误识别BuyActionPointLimit <= 0时自动按游戏上限 5 恢复_is_in_month_end_purchase_block_week()服务器时间偏移server_time_offset()计算AP_NOTIFY_MIN_INTERVAL_MINUTES = 30map.py+meowfficer_farming.py双点处理en-US.get(key)替代en-US[key]daily_checked: list[int]+append(int(n))六、注意事项
BuyActionPointMode后需等待 ISO 周重置(周一凌晨),BuyActionPointWeekId才能正确更新OpsiGeneral_OpsiOnePushConfig或Error_OnePushConfig),provider 不能为nullcnocr模型(日服白色字符),极端模糊截图下可能误识别,系统已自动重试Summary by Sourcery
为 OS 智能调度引入可配置的双模式行动点购买机制,包含每周计数和动态任务优先级,以及相关的调度、OCR 和配置增强。
新功能:
BuyActionPointMode,支持 hazard1 练级和喵菲瑟(meowfficer)刷取两种模式,在 OS 智能调度中驱动不同的行动点购买与执行循环。错误修复:
BuyActionPointLimit覆写导致购买上限被强制为 0,在需要时恢复为游戏内的最大值。TooManyClickError和不必要的提示。ja-JP键时抛出KeyError。daily_checked始终存储整数,并具有正确的类型注解,避免类型不一致。改进优化:
Original summary in English
Summary by Sourcery
Introduce configurable dual-mode action point purchasing for OS smart scheduling, with weekly counters and dynamic task prioritization, plus related scheduling, OCR, and config enhancements.
New Features:
Bug Fixes:
Enhancements: