Skip to content

AI Coding的一些准备#2015

Open
DoctorReid wants to merge 60 commits into
mainfrom
ai_coding_prep
Open

AI Coding的一些准备#2015
DoctorReid wants to merge 60 commits into
mainfrom
ai_coding_prep

Conversation

@DoctorReid
Copy link
Copy Markdown
Collaborator

@DoctorReid DoctorReid commented Feb 14, 2026

1. PR说明

游戏更新后,对新玩法的适配,我们的做法是:

  1. 人工了解玩法流程
  2. 截图,做画面配置
  3. 写代码,做流程编排

结合AI,我设想的做法是:

  1. 假设我们有维护了绝区零的已有玩法介绍,以及游戏操作流程(现在的界面路由能力)
  2. 新玩法出现、或者旧玩法更新时,我们通过操作人工记录(需要一个新的操作记录工具)、或者结合1来引导AI去适应新流程
  3. 在了解玩法过程中,配合AI更新文档、配置、代码

要达到上述目标,我们需要:

  1. 维护足够的文档
  2. 提供能力让AI可以了解当前游戏画面、代码、配置等信息

本次PR就是为了更好的AI Coding做的一些准备。

1.1. 文档

初步整理了文档结构,方便在编程工具引入为规范。

后续开发过程中再把游戏玩法说明、功能设计之类的补上,目标是让AI能真的懂我们的项目在做什么、绝区零是个什么游戏、玩法是怎样的。

1.2. MCP Server

为了编程工具更好地辅助开发,引入了 zzz_od 的 mcp server,为编程工具提供了解游戏的能力。

当前只有几个基础工具,算是完成一个小实验,能让我自己从公司ssh到家里,然后只用终端进行AI Coding。

后续其他工具以及相关的框架调整计划,在假期闲余时间再补充。

未来希望拓展实现:

  1. 可以为用户提供自检能力,参考 OpenClaw,它就内置了自己的所有使用说明。
  2. Agent自动化一些限时活动,就是我们不想做的只能用一个小版本的功能。

我想再过1年,模型能力再度提升,算力价格再度下降,免费的模型也能支撑实现上述目标。(现在其实可以用QWEN CODE CLI的OAUTH认证,是可以随便接入的,每天2000次对话)

1.3. 编程工具规范

当前个人使用的是Claude Code,所以我将这部分的项目级配置提交了。其他编程工具大家可以自行补充,注意统一维护好即可。

1.4. 子模块

本次将 zzz-od-test 正式转成了子模块,理论上不影响普通用户使用。转化的主要原因是,大部分编程工具都会默认忽略 .gitignore 里的文件,导致没法很好地@这些测试文件。

2. 其他

2.1. Coding Plan

最近国内厂商都逐渐开始提供了,而且基本都有vision模型的支持,价格上也算实惠。我是比较早就入了智谱的max包年,使用下来感觉是挺不错的。我现在在公司里,已经差不多80%代码和文档是AI写的了。

我建议是大家可以用经费统一采购共用,平时也可以少些折腾。

2.2. SDD开发

这是我公司内部在尝试的开发模式,感觉流程还是略重一些,个人也还没熟练,暂时就不引入。

2.3. 文档&测试

目前觉得,AI Coding的关键,是维护好文档和测试。文档里决定了架构、设计、规范,测试保证了实现质量,至于具体的实现代码,在前两项约束下,不会差到哪里去。

所以怎么维护好这个项目里文档和测试,是后续要好好想的内容。

2.4. 变

说实话过去一年,大模型和相关工具发展都太快了,个人了解信息也有限,有些甚至不如大家了解的多,所以还得靠大家的集思广益,完善上述提案,甚至是推翻之后提出更好的。

3. 结语

最后衷心感谢大家一直以来为项目的付出

Summary by CodeRabbit

发布说明

  • New Features

    • 新增MCP服务器支持Claude Code集成,提供游戏自动化工具(截图、OCR、游戏操作)
    • 新增Battle Assistant战斗辅助功能
    • 添加Claude Code的Pyright LSP语言服务器插件支持
  • Documentation

    • 新增完整开发文档体系(项目概览、编码规范、测试标准、工作流指南)
    • 新增MCP服务器架构与安装指南
    • 新增游戏内容更新和大地图录制流程文档
  • Tests

    • 新增MCP游戏操作功能测试
  • Chores

    • 更新依赖配置(mcp、psutil、pyright)
    • 更新.gitignore规则
    • 添加git子模块

DoctorReid and others added 3 commits February 12, 2026 23:29
集成 MCP (Model Context Protocol) 服务器,为游戏操作提供标准化的接口。
- 实现 ZZZ OD MCP 服务器,支持游戏窗口检测、截图、屏幕分析等操作
- 添加守护进程工具,支持自动启动和管理
- 完善文档和安装脚本

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 新增项目概述、开发流程规范
- 新增编码规范、测试规范、文档规范
- 新增 CLAUDE.md 作为 AI 辅助开发的指导文档
- 添加 zzz-od-test 子模块

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 新增 one_dragon 框架架构文档
- 新增应用插件系统、CV 流水线、目标状态模块开发指南
- 新增开发环境配置文档
- 新增 ops 和 user 文档目录
- 添加 pyright 到开发依赖
- 添加 .claude-plugin 配置

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 14, 2026

Important

Review skipped

Too many files!

This PR contains 210 files, which is 60 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 22996388-8aa6-43ea-8eac-ccf6a498d0ac

📥 Commits

Reviewing files that changed from the base of the PR and between 91baf99 and 8217550.

⛔ Files ignored due to path filters (56)
  • assets/template/agent_state/aria_cheer_energy_3_1/mask.png is excluded by !**/*.png
  • assets/template/agent_state/aria_cheer_energy_3_1/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_aria/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_aria/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_1_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_aria/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_aria/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_2_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_aria/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_aria/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_chain_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_aria/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_aria/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/battle/avatar_quick_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
  • assets/template/compendium/completed/mask.png is excluded by !**/*.png
  • assets/template/compendium/completed/raw.png is excluded by !**/*.png
  • assets/template/hollow/avatar_aria/mask.png is excluded by !**/*.png
  • assets/template/hollow/avatar_aria/raw.png is excluded by !**/*.png
  • assets/template/hollow/avatar_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/hollow/avatar_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/hollow/avatar_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/hollow/avatar_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/hollow/avatar_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/hollow/avatar_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
  • assets/template/intel_board/refresh/mask.png is excluded by !**/*.png
  • assets/template/intel_board/refresh/raw.png is excluded by !**/*.png
  • assets/template/normal_world_investigation/btn_area_info_close/mask.png is excluded by !**/*.png
  • assets/template/normal_world_investigation/btn_area_info_close/raw.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_aria/mask.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_aria/raw.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_aria_discordant_note/mask.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_aria_discordant_note/raw.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_panyinhu_culinary_jewel/mask.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_panyinhu_culinary_jewel/raw.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_sunna_afternoon_tea_break/mask.png is excluded by !**/*.png
  • assets/template/predefined_team/avatar_sunna_afternoon_tea_break/raw.png is excluded by !**/*.png
📒 Files selected for processing (210)
  • .github/workflows/build-release.yml
  • .github/workflows/build-running-resources.yml
  • .github/workflows/mirrorchyan_release_note.yml
  • .github/workflows/mirrorchyan_uploading.yml
  • .github/开发文档/开发指南.md
  • .gitignore
  • assets/game_data/compendium_data.yml
  • assets/game_data/screen_info/3d_map.yml
  • assets/game_data/screen_info/_od_merged.yml
  • assets/game_data/screen_info/battle.yml
  • assets/game_data/screen_info/coffee_shop.yml
  • assets/game_data/screen_info/compendium.yml
  • assets/game_data/screen_info/compendium_combat.yml
  • assets/game_data/screen_info/compendium_errands.yml
  • assets/game_data/screen_info/compendium_primer.yml
  • assets/game_data/screen_info/compendium_tactics.yml
  • assets/game_data/screen_info/compendium_training.yml
  • assets/game_data/screen_info/intel_board.yml
  • assets/game_data/screen_info/inter_knot.yml
  • assets/game_data/screen_info/lost_void_bangboo_store.yml
  • assets/game_data/screen_info/lost_void_choose_common.yml
  • assets/game_data/screen_info/lost_void_entry.yml
  • assets/game_data/screen_info/lost_void_gear.yml
  • assets/game_data/screen_info/lost_void_normal_world.yml
  • assets/game_data/screen_info/matrix_action.yml
  • assets/game_data/screen_info/normal_world.yml
  • assets/game_data/screen_info/normal_world_basic.yml
  • assets/game_data/screen_info/normal_world_investigation.yml
  • assets/game_data/screen_info/random_play.yml
  • assets/template/agent_state/aria_cheer_energy_3_1/config.yml
  • assets/template/compendium/completed/config.yml
  • assets/template/intel_board/refresh/config.yml
  • assets/template/normal_world_investigation/btn_area_info_close/config.yml
  • config/auto_battle/全配队通用.merged.yml
  • config/auto_battle/击破站场-强攻速切.merged.yml
  • config/auto_battle/异常站场-强攻速切.merged.yml
  • config/auto_battle/强攻站场-击破支援速切.merged.yml
  • config/auto_battle/自动守护.merged.yml
  • config/auto_battle_operation/仪玄-凸.sample.yml
  • config/auto_battle_operation/伊德海莉-终结技.sample.yml
  • config/auto_battle_operation/伊芙琳-终结技.sample.yml
  • config/auto_battle_operation/凯撒-终结技.sample.yml
  • config/auto_battle_operation/卢西娅-终结技.sample.yml
  • config/auto_battle_operation/叶瞬光-终结技-收.sample.yml
  • config/auto_battle_operation/叶瞬光-终结技-起.sample.yml
  • config/auto_battle_operation/奥菲丝-终结技.sample.yml
  • config/auto_battle_operation/妮可-终结技.sample.yml
  • config/auto_battle_operation/席德-终结技.sample.yml
  • config/auto_battle_operation/悠真-终结技.sample.yml
  • config/auto_battle_operation/悠真-自动EA.sample.yml
  • config/auto_battle_operation/扳机-终结技.sample.yml
  • config/auto_battle_operation/朱鸢-终结技.sample.yml
  • config/auto_battle_operation/柏妮思-终结技.sample.yml
  • config/auto_battle_operation/柳-终结技.sample.yml
  • config/auto_battle_operation/格莉丝-终结技.sample.yml
  • config/auto_battle_operation/橘福福-终结技.sample.yml
  • config/auto_battle_operation/派派-终结技.sample.yml
  • config/auto_battle_operation/浮波柚叶-终结技.sample.yml
  • config/auto_battle_operation/潘引壶-终结技.sample.yml
  • config/auto_battle_operation/照-终结技.sample.yml
  • config/auto_battle_operation/爱丽丝-终结技.sample.yml
  • config/auto_battle_operation/爱芮-强化特殊技.sample.yml
  • config/auto_battle_operation/爱芮-支援攻击.sample.yml
  • config/auto_battle_operation/爱芮-普通攻击.sample.yml
  • config/auto_battle_operation/爱芮-终结技.sample.yml
  • config/auto_battle_operation/爱芮-连携攻击.sample.yml
  • config/auto_battle_operation/爱芮-长按攻击.sample.yml
  • config/auto_battle_operation/爱芮-闪A.sample.yml
  • config/auto_battle_operation/猫又-终结技.sample.yml
  • config/auto_battle_operation/琉音-终结技.sample.yml
  • config/auto_battle_operation/真斗-终结技.sample.yml
  • config/auto_battle_operation/简-终结技.sample.yml
  • config/auto_battle_operation/耀嘉音-终结技.sample.yml
  • config/auto_battle_operation/般岳-终结技-撼天动地.sample.yml
  • config/auto_battle_operation/艾莲-终结技.sample.yml
  • config/auto_battle_operation/苍角-终结技.sample.yml
  • config/auto_battle_operation/莱卡恩-终结技.sample.yml
  • config/auto_battle_operation/薇薇安-终结技.sample.yml
  • config/auto_battle_operation/连携-取消.sample.yml
  • config/auto_battle_operation/通用-终结技.sample.yml
  • config/auto_battle_operation/雅-终结技.sample.yml
  • config/auto_battle_operation/雨果-终结技.sample.yml
  • config/auto_battle_operation/零号安比-终结技.sample.yml
  • config/auto_battle_operation/青衣-终结技.sample.yml
  • config/auto_battle_state_handler/叶瞬光-失衡决策.sample.yml
  • config/auto_battle_state_handler/轮换-紧急-全角色.sample.yml
  • config/auto_battle_state_handler/速切模板-全角色.sample.yml
  • config/auto_battle_state_handler/速切模板-叶瞬光.sample.yml
  • config/auto_battle_state_handler/速切模板-悠真.sample.yml
  • config/auto_battle_state_handler/速切模板-柏妮思.sample.yml
  • config/auto_battle_state_handler/速切模板-爱芮.sample.yml
  • config/project.yml
  • config/redemption_codes.sample.yml
  • deploy/OneDragon-RuntimeLauncher.spec
  • deploy/build_full.bat
  • deploy/generate_module_manifest.py
  • deploy/hook_path_inject.py
  • deploy/module_manifest.py
  • docs/develop/README.md
  • docs/develop/background_mode_design.md
  • docs/develop/runtime-launcher.md
  • docs/develop/zzz/application/intel_board.md
  • src/one_dragon/base/conditional_operation/loader.py
  • src/one_dragon/base/config/custom_config.py
  • src/one_dragon/base/config/one_dragon_config.py
  • src/one_dragon/base/config/yaml_config.py
  • src/one_dragon/base/config/yaml_operator.py
  • src/one_dragon/base/controller/controller_base.py
  • src/one_dragon/base/controller/pc_button/ds4_button_controller.py
  • src/one_dragon/base/controller/pc_button/keyboard_mouse_controller.py
  • src/one_dragon/base/controller/pc_button/pc_button_controller.py
  • src/one_dragon/base/controller/pc_button/pc_button_listener.py
  • src/one_dragon/base/controller/pc_button/virtual_gamepad_controller.py
  • src/one_dragon/base/controller/pc_button/xbox_button_controller.py
  • src/one_dragon/base/controller/pc_controller_base.py
  • src/one_dragon/base/cv_process/cv_service.py
  • src/one_dragon/base/operation/application/application_run_context.py
  • src/one_dragon/base/operation/application_base.py
  • src/one_dragon/base/operation/one_dragon_context.py
  • src/one_dragon/base/operation/operation.py
  • src/one_dragon/base/push/channel/server_chan.py
  • src/one_dragon/base/push/push_config.py
  • src/one_dragon/base/push/push_service.py
  • src/one_dragon/base/screen/screen_area.py
  • src/one_dragon/base/screen/screen_info.py
  • src/one_dragon/base/screen/screen_loader.py
  • src/one_dragon/base/screen/screen_utils.py
  • src/one_dragon/envs/ghproxy_service.py
  • src/one_dragon/envs/git_service.py
  • src/one_dragon/launcher/exe_launcher.py
  • src/one_dragon/launcher/runtime_launcher.py
  • src/one_dragon/utils/app_utils.py
  • src/one_dragon/utils/cv2_utils.py
  • src/one_dragon/utils/str_utils.py
  • src/one_dragon/utils/yaml_utils.py
  • src/one_dragon_qt/app/directory_picker.py
  • src/one_dragon_qt/services/unpack_runner.py
  • src/one_dragon_qt/utils/layout_utils.py
  • src/one_dragon_qt/view/code_interface.py
  • src/one_dragon_qt/view/devtools/devtools_image_analysis_interface.py
  • src/one_dragon_qt/view/devtools/devtools_screen_manage_interface.py
  • src/one_dragon_qt/view/devtools/devtools_template_helper_interface.py
  • src/one_dragon_qt/view/installer_interface.py
  • src/one_dragon_qt/view/one_dragon/one_dragon_run_interface.py
  • src/one_dragon_qt/view/setting/setting_custom_interface.py
  • src/one_dragon_qt/view/setting/setting_push_interface.py
  • src/one_dragon_qt/widgets/app_run_list.py
  • src/one_dragon_qt/widgets/base_interface.py
  • src/one_dragon_qt/widgets/column.py
  • src/one_dragon_qt/widgets/download_card/launcher_download_card.py
  • src/one_dragon_qt/widgets/draggable_list.py
  • src/one_dragon_qt/widgets/row.py
  • src/one_dragon_qt/widgets/scroll_credits.py
  • src/one_dragon_qt/widgets/setting_card/expand_setting_card_group.py
  • src/one_dragon_qt/widgets/setting_card/gamepad_action_key_card.py
  • src/one_dragon_qt/widgets/setting_card/setting_card_base.py
  • src/one_dragon_qt/windows/window.py
  • src/zzz_od/application/battle_assistant/auto_battle/auto_battle_app.py
  • src/zzz_od/application/battle_assistant/battle_assistant_config.py
  • src/zzz_od/application/battle_assistant/dodge_assitant/dodge_assistant_app.py
  • src/zzz_od/application/battle_assistant/operation_debug/operation_debug_app.py
  • src/zzz_od/application/charge_plan/charge_plan_app.py
  • src/zzz_od/application/charge_plan/charge_plan_config.py
  • src/zzz_od/application/charge_plan/charge_plan_run_record.py
  • src/zzz_od/application/city_fund/city_fund_app.py
  • src/zzz_od/application/engagement_reward/engagement_reward_app.py
  • src/zzz_od/application/game_config_checker/mouse_sensitivity_checker/mouse_sensitivity_checker.py
  • src/zzz_od/application/hollow_zero/lost_void/context/lost_void_context.py
  • src/zzz_od/application/hollow_zero/lost_void/lost_void_app.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/interact/lost_void_artifact_pos.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/interact/lost_void_bangboo_store.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/interact/lost_void_choose_common.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/interact/lost_void_choose_gear.py
  • src/zzz_od/application/hollow_zero/lost_void/operation/lost_void_run_level.py
  • src/zzz_od/application/intel_board/__init__.py
  • src/zzz_od/application/intel_board/intel_board_app.py
  • src/zzz_od/application/intel_board/intel_board_app_factory.py
  • src/zzz_od/application/intel_board/intel_board_config.py
  • src/zzz_od/application/intel_board/intel_board_const.py
  • src/zzz_od/application/intel_board/intel_board_run_record.py
  • src/zzz_od/application/notify/notify_app.py
  • src/zzz_od/application/notorious_hunt/notorious_hunt_config.py
  • src/zzz_od/application/random_play/random_play_app.py
  • src/zzz_od/application/world_patrol/operation/transport_by_3d_map.py
  • src/zzz_od/application/world_patrol/operation/world_patrol_run_route.py
  • src/zzz_od/application/world_patrol/world_patrol_app.py
  • src/zzz_od/application/world_patrol/world_patrol_service.py
  • src/zzz_od/application/zzz_application_launcher.py
  • src/zzz_od/auto_battle/auto_battle_operator.py
  • src/zzz_od/config/game_config.py
  • src/zzz_od/context/zzz_context.py
  • src/zzz_od/controller/zzz_pc_controller.py
  • src/zzz_od/game_data/agent.py
  • src/zzz_od/game_data/compendium.py
  • src/zzz_od/game_data/map_area.py
  • src/zzz_od/gui/app.py
  • src/zzz_od/gui/dialog/charge_plan_setting_dialog.py
  • src/zzz_od/gui/dialog/intel_board_setting_dialog.py
  • src/zzz_od/gui/dialog/notorious_hunt_setting_dialog.py
  • src/zzz_od/gui/dialog/shared_dialog_manager.py
  • src/zzz_od/gui/view/battle_assistant/auto_battle_interface.py
  • src/zzz_od/gui/view/battle_assistant/dodge_assistant_interface.py
  • src/zzz_od/gui/view/battle_assistant/operation_debug_interface.py
  • src/zzz_od/gui/view/devtools/agent_template_generator_interface.py
  • src/zzz_od/gui/view/devtools/app_devtools_interface.py
  • src/zzz_od/gui/view/devtools/template_card_widget.py
  • src/zzz_od/gui/view/home/home_interface.py
  • src/zzz_od/gui/view/one_dragon/charge_plan_interface.py
  • src/zzz_od/gui/view/one_dragon/notorious_hunt_interface.py
  • src/zzz_od/gui/view/one_dragon/zzz_one_dragon_run_interface.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

概述

本变更为 ZZZ OD 项目添加了 MCP(模型上下文协议)服务器实现、完整的开发者文档体系、Claude 插件配置,以及针对游戏集成的工具组件。包括项目级文档、开发指南、MCP 服务器核心模块、游戏操作工具和守护进程管理脚本。

变更

集群 / 文件 摘要
Claude 插件配置
.claude-plugin/...
新增 uv-pyright-lsp 插件配置,包含插件元数据和 LSP 服务器定义,通过 uv 运行 pyright-langserver;新增完整的插件 README 文档。
项目根级配置
.gitignore, .gitmodules, pyproject.toml, CLAUDE.md
修改 .gitignore 移除 CLAUDE.md 忽略规则并添加 .claude/settings.json 追踪;新增 zzz-od-test 子模块;pyproject.toml 添加 mcp、psutil、pyright 开发依赖;新增 CLAUDE.md 文档规范。
开发者文档
docs/develop/*
新增项目概览、开发指南、编码/测试/文档/工作流标准、开发环境配置;新增应用插件系统、CV 管道架构、目标状态模块开发者指南等架构文档。
运维及用户文档
docs/ops/*, docs/user/*
新增版本更新记录、大地图录制流程文档;新增战斗助手使用指南。
MCP 服务器核心实现
src/zzz_mcp/*
新增 MCP 包初始化、上下文生命周期管理、工具注册框架及四类工具(基础检查、截图、游戏操作、屏幕分析);新增 MCP 服务器主程序和管理接口。
MCP 工具实现
src/zzz_mcp/tools/*
实现 check_game_window、capture_game_screen、open_and_enter_game、analyze_screen 等工具,包含错误处理和上下文验证逻辑。
MCP 守护进程及安装脚本
tools/mcp/*
新增服务器和守护进程安装、启动、管理 PowerShell 脚本;新增 zzz_od_daemon.py 实现远程管理接口;新增 README 和快速开始文档。
MCP 测试
tests/zzz_mcp/*
新增游戏操作工具的单元测试,覆盖上下文初始化、工具注册、错误处理场景。

流程图

sequenceDiagram
    participant Claude Code
    participant MCP Server
    participant ZContext
    participant Game Controller
    participant Game Window

    Claude Code->>MCP Server: capture_game_screen()
    MCP Server->>ZContext: get_zzz_context()
    ZContext-->>MCP Server: ZContext instance
    MCP Server->>Game Controller: get_screenshot(independent=false)
    Game Controller->>Game Window: 获取游戏窗口截图
    Game Window-->>Game Controller: RGB image
    Game Controller-->>MCP Server: image data
    MCP Server->>MCP Server: 转换 RGB→BGR
    MCP Server->>MCP Server: 保存为 PNG
    MCP Server-->>Claude Code: 截图文件路径

    Claude Code->>MCP Server: open_and_enter_game()
    MCP Server->>ZContext: get_zzz_context()
    MCP Server->>MCP Server: 启动运行上下文
    MCP Server->>Game Controller: 执行 OpenAndEnterGame 操作
    Game Controller->>Game Window: 启动游戏流程
    Game Window-->>Game Controller: 操作完成
    Game Controller-->>MCP Server: 成功/失败状态
    MCP Server->>MCP Server: 停止运行上下文
    MCP Server-->>Claude Code: 操作结果消息
Loading

预估代码审查工作量

🎯 3 (中等复杂) | ⏱️ ~35 分钟

可能相关的 PR

  • ZenlessZoneZero-OneDragon#1487:本 PR 中新增的 zzz_lifespan 调用 ZContext.init(),与该 PR 对 ZContext 生命周期方法的重构(init/init_async/init_controller)直接相关。

建议审查者

  • Usagi-wusaqi

🐰 兔子翻山又越岭,
MCP 工具齐登场,
截图操作样样全,
文档指南路明亮,
游戏集成不再难!

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ai_coding_prep
📝 Coding Plan
  • Generate coding plan for human review comments

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🤖 Fix all issues with AI agents
In `@src/zzz_mcp/zzz_mcp_server.py`:
- Line 37: 运行时代码使用了 mcp.streamable_http_app(),但 mcp 当前只在开发依赖中;将 mcp 从 dev
依赖移到主依赖中以确保在运行时可用。修改 pyproject.toml 的 [tool.poetry.dependencies](或相应依赖节)添加/移动
"mcp" 并设置合适的版本约束(例如 ">=1.0.0"),然后更新锁文件并重新安装依赖(poetry lock && poetry install 或
pip/poetry 等项目使用的流程);确保 mcp 在运行环境中可导入以支持 mcp.streamable_http_app() 的调用。

In `@src/zzz_mcp/zzz_od_server_manage.py`:
- Around line 21-38: The code duplicates utility functions across modules;
extract the shared logic (find_main_server_process, is_port_in_use,
start_zzz_od_server, stop_zzz_od_server, restart_zzz_od_server,
get_zzz_od_server_status) into a new common helper module (e.g.,
zzz_od_server_utils) and have both src/zzz_mcp/zzz_od_server_manage.py and
src/tools/mcp/daemon/zzz_od_daemon.py import and call those helpers; move all
psutil-based iteration and port-checking logic (the bodies of
find_main_server_process and is_port_in_use) and the process
start/stop/restart/status implementations into that module, keep only thin
wrappers or direct imports in the two entry modules, and update any references
to these function names to use the shared implementations.
- Around line 16-18: Replace the hardcoded PROJECT_ROOT with a dynamic Path
computed from the current file location: use pathlib.Path(__file__).resolve()
and walk up to the repository root (e.g., .parents[n] or search for a marker) to
set PROJECT_ROOT; then construct MAIN_SERVER_SCRIPT as a Path(PROJECT_ROOT) /
"src/zzz_mcp/zzz_mcp_server.py" (or keep MAIN_SERVER_SCRIPT as a relative string
but join it with PROJECT_ROOT when used). Update any uses of os.path to pathlib
APIs and keep MAIN_SERVER_PORT unchanged; modify references to PROJECT_ROOT and
MAIN_SERVER_SCRIPT in zzz_od_server_manage.py to use the new Path objects.
- Around line 60-71: The current subprocess invocation builds cmd via f-string
and uses subprocess.Popen with shell=True (cmd variable) which risks command
injection; change subprocess.Popen to pass args as a list (e.g., ["uv", "run",
"--env-file", ".env", "python", MAIN_SERVER_SCRIPT] after chdir or use
cwd=PROJECT_ROOT) and remove shell=True, and when calling process.communicate()
capture the unused stdout as _ and only use stderr (e.g., `_, stderr =
process.communicate()`), updating references to subprocess.Popen, cmd,
PROJECT_ROOT, MAIN_SERVER_SCRIPT, and process accordingly.

In `@tools/mcp/daemon/zzz_od_daemon.py`:
- Line 11: Replace the use of typing.Optional with the modern union operator by
changing the return type annotation at the noted function (the function that
currently returns Optional[psutil.Process]) to psutil.Process | None; also
remove the now-unused "Optional" import from the top of the file (the from
typing import Optional line). Ensure any other Optional[...] in this module is
updated to the X | None form to follow the Python 3.11+ guideline.
- Around line 17-19: PROJECT_ROOT is hardcoded to a Windows developer path;
replace it with a dynamic Path computed via pathlib (e.g., derive from
Path(__file__).resolve().parents or by walking up until a repo marker like
".git" or "pyproject.toml") and build MAIN_SERVER_SCRIPT using Path operations
(Path(...) / MAIN_SERVER_SCRIPT) instead of string concatenation; update any
uses of PROJECT_ROOT to expect a pathlib.Path object and remove the raw r"..."
literal so the module works cross-platform.
🟡 Minor comments (15)
docs/ops/锄大地.md-10-12 (1)

10-12: ⚠️ Potential issue | 🟡 Minor

地图来源部分待完善。

此部分标记为"待暗檬补充",建议在合并前补充完整,以便用户了解地图的获取来源。

需要我帮助起草此部分的内容结构吗?

docs/ops/锄大地.md-16-16 (1)

16-16: ⚠️ Potential issue | 🟡 Minor

移除或正确标记调试函数的用户文档引用

large_map_recorder_utils.__debug_read_extract 是一个私有调试函数(双下划线前缀),仅在 if __name__ == '__main__' 块中执行,用于开发调试。不应在用户文档中直接引用此内部实现细节。

建议:要么从文档中移除该函数的引用,要么清晰标注这是一个调试工具,不属于公开API。如需为用户提供图像转化的标准方式,应提供相应的公开接口。

docs/README.md-36-38 (1)

36-38: ⚠️ Potential issue | 🟡 Minor

文档链接路径需要与实际文件路径保持一致。

这些链接缺少 standards/ 子目录前缀,会导致 404。

🔧 修正链接路径
-- **[开发规范](develop/coding-standards.md)** - Python 代码规范和编码约定
-- **[测试规范](develop/testing-standards.md)** - 测试编写和执行规范
-- **[文档规范](develop/documentation-standards.md)** - 文档编写规范
+- **[开发规范](develop/standards/coding-standards.md)** - Python 代码规范和编码约定
+- **[测试规范](develop/standards/testing-standards.md)** - 测试编写和执行规范
+- **[文档规范](develop/standards/documentation-standards.md)** - 文档编写规范
.claude-plugin/uv-pyright-lsp/README.md-40-46 (1)

40-46: ⚠️ Potential issue | 🟡 Minor

uv add pyright 会将 pyright 加入生产依赖而非开发依赖。

根据 pyproject.tomlpyright 已被放在 [dependency-groups] dev 中。文档应建议使用 --group dev 以保持一致。

🔧 建议修正安装命令
-uv add pyright
+uv add --group dev pyright
 # or
-uv pip install pyright
+uv sync --group dev
docs/README.md-7-26 (1)

7-26: ⚠️ Potential issue | 🟡 Minor

目录结构树中的文件路径与实际路径不一致。

根据 PR 中的其他文件(如 docs/develop/standards/workflow-standard.md),规范文档实际位于 develop/standards/ 子目录下,但此处目录树将它们列在 develop/ 根目录下。此外,代码块缺少语言标识(静态分析提示 MD040)。

🔧 建议修正目录树
-```
+```text
 docs/
 ├── README.md              # 本文件
 ├── develop/              # 开发文档
 │   ├── project-overview.md              # 项目概述和快速开始
 │   ├── development-guide.md             # 开发指引总览
-│   ├── coding-standards.md            # 开发规范
 │   ├── development-environments.md      # 开发环境配置
-│   ├── testing-standards.md           # 测试规范
-│   ├── documentation-standards.md     # 文档编写规范
+│   ├── standards/                     # 开发规范
+│   │   ├── coding-standards.md        # 开发规范
+│   │   ├── testing-standards.md       # 测试规范
+│   │   ├── documentation-standards.md # 文档编写规范
+│   │   └── workflow-standard.md       # 开发流程规范
 │   ├── one_dragon/                  # one_dragon 框架文档
 │   └── zzz/                         # zzz 游戏开发文档
docs/develop/development-environments.md-13-15 (1)

13-15: ⚠️ Potential issue | 🟡 Minor

修正命令语法:使用斜杠命令而非 claude 前缀。

claude plugin marketplace add 不是有效的命令格式。Claude Code CLI 中的正确语法是斜杠命令:/plugin marketplace add OneDragon-Anything/OneDragon-CC-Plugins

请将文档中的命令更新为正确的斜杠命令格式。

tools/mcp/daemon/start_daemon.ps1-1-10 (1)

1-10: ⚠️ Potential issue | 🟡 Minor

注释中的默认端口与实际默认值不一致。

第 4 行注释说明默认端口为 8001,但第 9 行参数实际默认值为 23002。请修正注释以避免误导。

🔧 建议修复
 # 使用方式:
-#   .\start_daemon.ps1              # 使用默认端口(8001)
+#   .\start_daemon.ps1              # 使用默认端口(23002)
 #   .\start_daemon.ps1 -Port 9001   # 指定端口
docs/develop/standards/testing-standards.md-63-68 (1)

63-68: ⚠️ Potential issue | 🟡 Minor

conftest.py 路径应与目录结构约定统一使用 tests(复数)。

第 30 行的目录结构示例使用 zzz-od-test/tests/,但第 65 行和第 108 行的 conftest.py 路径错误地使用了 zzz-od-test/test/(单数)。应统一改为 zzz-od-test/tests/conftest.py

docs/ops/版本更新.md-18-30 (1)

18-30: ⚠️ Potential issue | 🟡 Minor

章节编号重复:两个 1.1.1. 小节。

Line 18 #### 1.1.1.原理 和 Line 30 #### 1.1.1.长条类-1 使用了相同的编号,第二个应为 1.1.2.长条类-1

docs/develop/zzz/mcp/README.md-115-122 (1)

115-122: ⚠️ Potential issue | 🟡 Minor

可用工具表缺少 analyze_screen

根据 src/zzz_mcp/tools/screen_analysis.py 中注册的 analyze_screen 工具,该表未列出画面分析工具。建议补充以保持文档与实现一致。

建议修改
 | `check_game_window` | 检查游戏窗口状态 | ✅ |
 | `capture_game_screen` | 捕获游戏画面 | ✅ |
 | `open_and_enter_game` | 打开并进入游戏 | ✅ |
+| `analyze_screen` | 分析游戏当前画面(OCR) | ✅ |
docs/develop/zzz/mcp/installation.md-102-109 (1)

102-109: ⚠️ Potential issue | 🟡 Minor

卸载 Daemon 的端口查找命令缺少错误处理提示。

第 104 行的 PowerShell 命令在没有匹配进程时会抛出异常(Select-String 返回 $null,调用 .ToString() 失败)。建议在文档中提示用户先确认进程存在,或使用更健壮的写法。

建议修改
 # 停止 Daemon
+# 先检查端口是否在监听
+netstat -ano | findstr :23002
+# 如果有输出,使用最后一列的 PID 停止进程
 $pid = (netstat -ano | Select-String ":23002.*LISTENING").ToString().Split()[-1]
 Stop-Process -Id $pid -Force
docs/develop/zzz/mcp/remote-ssh.md-23-25 (1)

23-25: ⚠️ Potential issue | 🟡 Minor

Session 编号描述不够准确。

SSH shell 进程不一定运行在 Session 0。Windows OpenSSH 的 sshd 服务运行在 Session 0,但 SSH 登录后的 shell 通常在一个独立的非交互式 session 中(不一定是 Session 0)。关键点是它与交互式桌面 session 隔离,建议措辞调整为更通用的描述,避免固定 Session 编号。

src/zzz_mcp/tools/base.py-41-43 (1)

41-43: ⚠️ Potential issue | 🟡 Minor

win_rect 存在 TOCTOU 竞态:两次属性访问之间窗口状态可能变化。

win_rect 是一个每次调用都重新计算的 property。Line 41 检查非 None 后,Line 42 再次访问时窗口可能已关闭,返回 None,导致 Line 43 抛出 AttributeError

🔧 建议只访问一次
-        if game_win.win_rect is not None:
-            rect = game_win.win_rect
+        rect = game_win.win_rect
+        if rect is not None:
             status_lines.append(f"  窗口位置: x={rect.x1}, y={rect.y1}, 宽={rect.width}, 高={rect.height}")
tests/zzz_mcp/test_game_operation.py-151-168 (1)

151-168: ⚠️ Potential issue | 🟡 Minor

未使用变量 context(Line 154)以及重复的工具查找模式。

静态分析正确标记了 context 被赋值但从未使用。如果不需要引用它,直接使用匿名上下文管理器即可。另外,test_mcp._tool_manager._tools 这种访问私有属性的方式在多个测试方法中重复出现,较为脆弱。

🔧 修复未使用变量
-            async with zzz_lifespan(mock_mcp) as context:
+            async with zzz_lifespan(mock_mcp):
tests/zzz_mcp/test_game_operation.py-178-201 (1)

178-201: ⚠️ Potential issue | 🟡 Minor

集成测试中同样存在未使用的 context 变量(Line 181)。

与上面相同的问题。

🔧 修复
-            async with zzz_lifespan(mock_mcp) as context:
+            async with zzz_lifespan(mock_mcp):
🧹 Nitpick comments (24)
docs/ops/锄大地.md (1)

28-30: 路线录制部分内容较简略。

相比大地图录制的详细步骤,路线录制部分仅包含一句说明。如果这是有意为之(例如功能还在开发中),建议明确说明;否则可以考虑补充更详细的录制步骤。

.gitmodules (1)

1-3: 子模块使用 SSH URL,可能导致部分贡献者和 CI 环境克隆失败。

git@github.com: 需要配置 SSH key。对于未配置 SSH 的贡献者或使用 HTTPS token 认证的 CI 环境,克隆会失败。建议改用 HTTPS URL:

♻️ 建议改为 HTTPS URL
 [submodule "zzz-od-test"]
 	path = zzz-od-test
-	url = git@github.com:OneDragon-Anything/zzz-od-test.git
+	url = https://github.com/OneDragon-Anything/zzz-od-test.git
CLAUDE.md (1)

24-26: context7 工具引用缺少说明或安装指引。

如果 context7 是一个 MCP 工具/插件,建议补充简要说明或链接到安装文档,避免使用者不清楚如何获取该工具。

tools/mcp/README.md (1)

27-30: 代码块缺少语言标识。

第 27 行的代码块没有指定语言,建议添加语言标识(如 text),以符合 markdownlint 规范并改善渲染效果。

🔧 建议修复
-```
+```text
 请检查游戏窗口状态
 请捕获游戏画面
-```
+```
docs/develop/one_dragon/cv_pipeline_architecture.md (1)

137-143: 文档中的示例代码应与编码规范保持一致。

此处示例使用了 Dict[str, Type[CvStep]],但 coding-standards.md 中明确要求使用内置泛型类型 dict/type,而非从 typing 导入。建议修正为:

self.available_steps: dict[str, type[CvStep]] = { ... }
docs/develop/one_dragon/application_plugin_system.md (1)

161-175: 内置插件示例与第三方插件示例的父类调用风格不一致。

Line 164 使用 ApplicationFactory.__init__(self, ...),而 Line 224 使用 super().__init__(...)coding-standards.md 推荐使用 super().__init__(...),建议统一写法以保持文档示例一致性。

docs/develop/one_dragon/target_state_module_developer_guide.md (1)

49-51: Mermaid 图中的类型标注应与编码规范一致。

List[DetectionTask]List[TargetStateDef] 应改为 list[DetectionTask]list[TargetStateDef],与 coding-standards.md 中使用内置泛型类型的规范保持一致。

tools/mcp/install.ps1 (2)

23-23: $ConfigPath 已赋值但从未使用。

静态分析工具也标记了此问题。如果不再需要,建议移除以避免混淆。


50-54: 避免使用 Invoke-Expression 执行外部命令。

Invoke-Expression 存在代码注入风险(PSScriptAnalyzer: PSAvoidUsingInvokeExpression)。虽然当前输入受控,但建议改用 & 调用操作符,直接执行命令更安全且更符合 PowerShell 最佳实践。此问题同样存在于 Line 87 和 Line 135。

♻️ 建议修改
-    $Cmd = "claude mcp add --transport http $ServerKey $McpUrl"
-    Write-Host "[CMD] $Cmd" -ForegroundColor Yellow
-
-    try {
-        $Output = Invoke-Expression $Cmd 2>&1
+    Write-Host "[CMD] claude mcp add --transport http $ServerKey $McpUrl" -ForegroundColor Yellow
+
+    try {
+        $Output = & claude mcp add --transport http $ServerKey $McpUrl 2>&1
tools/mcp/daemon/install_daemon.ps1 (1)

1-164: install.ps1 存在大量重复代码。

install_daemon.ps1install.ps1 的结构和逻辑几乎完全相同(Install/Uninstall/Check 三个函数、主入口逻辑),仅配置值不同(脚本路径、Key、端口)。可以考虑抽取一个共享的辅助脚本或函数模块来减少维护成本。

此外,Invoke-Expression 的安全问题同样适用于此文件(Lines 51, 84, 131),建议参照 install.ps1 的审查意见统一修改。

tools/mcp/daemon/zzz_od_daemon.py (2)

22-39: src/zzz_mcp/zzz_od_server_manage.py 存在大量重复代码。

find_main_server_processis_port_in_use,以及 start/stop/restart/get_status 四个工具函数与 zzz_od_server_manage.py 中的实现完全相同(参见 relevant code snippets)。建议 daemon 直接导入复用 zzz_od_server_manage 中的函数,避免维护两份相同逻辑。


62-72: subprocess.Popen 使用 shell=True 拼接字符串命令存在安全风险。

Ruff S602 也标记了此问题。虽然当前 PROJECT_ROOTMAIN_SERVER_SCRIPT 是内部常量,但如果后续可配置化则会产生命令注入风险。建议使用列表形式传参并设置 cwd

🛡️ 建议修改
-        cmd = f'cd /d "{PROJECT_ROOT}" && uv run --env-file .env python {MAIN_SERVER_SCRIPT} --port {MAIN_SERVER_PORT}'
-
-        process = subprocess.Popen(
-            cmd,
-            shell=True,
+        process = subprocess.Popen(
+            ["uv", "run", "--env-file", ".env", "python", MAIN_SERVER_SCRIPT, "--port", str(MAIN_SERVER_PORT)],
+            cwd=PROJECT_ROOT,
docs/develop/zzz/mcp/dev-tools-design.md (1)

7-11: 为无语言标识的代码块添加语言标记。

markdownlint 提示未指定代码块语言。对于纯文本流程图和对话示例,可使用 text 标识。同样适用于第 46 行的代码块。

建议修改
-```
+```text
 人工玩游戏 → 截图记录 → 创建配置 → 编写代码 → 测试调试 → 优化完善

第 46 行同理:

-```
+```text
 用户: 帮我开发一个"随便观制造"的自动流程
docs/develop/zzz/mcp/architecture.md (1)

7-67: 为 ASCII 架构图代码块添加语言标记。

与第 143 行的 PsExec 示例代码块相同,建议添加 text 或对应语言标识以满足 markdownlint 规范。

建议修改

第 7 行:

-```
+```text
 ┌─────────────────────────────────────────────────────────────────┐

第 143 行:

-```
+```powershell
 PsExec -i 1 cmd /c "start_mcp_server.ps1"
docs/develop/zzz/mcp/README.md (1)

23-26: 为纯文本代码块添加语言标记。

第 23、70、88 行的代码块缺少语言标识。对于用户输入提示和服务器输出,可使用 text 标记。

docs/develop/zzz/mcp/installation.md (1)

111-164: 安装指南中的常见问题与 troubleshooting.md 高度重复。

"常见问题"部分(问题 1-4)与 troubleshooting.md 中的内容几乎完全一致。可考虑在此处精简为简要说明并链接到 troubleshooting.md,避免维护两份相同内容时产生不一致。

src/zzz_mcp/zzz_mcp_server.py (1)

15-18: 模块级别的副作用:导入即触发 MCP 实例创建和工具注册。

mcp 实例和 register_all_tools 在模块导入时即执行。如果其他模块(如测试)导入此文件,会产生意外副作用。考虑将这些移入 main() 或使用惰性初始化。

src/zzz_mcp/context.py (1)

46-61: 全局引用应在 after_app_shutdown() 之后再清除。

Line 59 在调用 ctx.after_app_shutdown() 之前就将 _zzz_context 设为 None。虽然 after_app_shutdown 使用的是本地 ctx 引用,但如果关闭过程中有其他组件(如正在执行的 tool)通过 get_zzz_context() 访问全局上下文,会过早得到 None。建议调换顺序:

♻️ 建议调换清理顺序
     finally:
         # 清理资源
         log.info("ZZZ MCP Server: Shutting down ZContext...")
-        _zzz_context = None
         ctx.after_app_shutdown()
+        _zzz_context = None
         log.info("ZZZ MCP Server: ZContext shutdown complete")
src/zzz_mcp/tools/screenshot.py (1)

57-59: 时间戳精度仅到秒级,同一秒内多次截图会覆盖。

time.strftime 精度到秒。如果短时间内连续截图,文件会被覆盖。可考虑加入毫秒或序号。

♻️ 使用更高精度的时间戳
-            timestamp = time.strftime("%Y%m%d_%H%M%S")
-            filename = f"screenshot_{timestamp}.png"
+            timestamp = time.strftime("%Y%m%d_%H%M%S")
+            ms = int(time.time() * 1000) % 1000
+            filename = f"screenshot_{timestamp}_{ms:03d}.png"
tests/zzz_mcp/test_game_operation.py (3)

36-44: 两个测试类中 setUp/tearDown 完全重复。

TestGameOperationContextTestGameOperationToolsetUp/tearDown 逻辑完全一致,可以提取到一个公共基类中。

♻️ 建议提取公共基类
class _McpTestBase(unittest.TestCase):
    def setUp(self):
        import zzz_mcp.context as ctx_module
        ctx_module._zzz_context = None

    def tearDown(self):
        import zzz_mcp.context as ctx_module
        ctx_module._zzz_context = None

class TestGameOperationContext(_McpTestBase):
    ...

class TestGameOperationTool(_McpTestBase):
    ...

Also applies to: 105-113


46-61: asyncio.run() 在 unittest 方法中嵌套调用。

目前每个异步测试都通过在同步方法内调用 asyncio.run(test()) 来驱动——这可以工作,但如果将来需要共享事件循环或使用 pytest-asyncio,迁移成本较高。当前阶段可接受,仅作为提示。

Also applies to: 63-80, 82-99


123-124: 改用 FastMCP 的公开 API 获取工具列表,而非直接访问私有 _tool_manager._tools

代码在多处(第 123-124、134-137 行及其他位置)通过 mcp._tool_manager._tools 访问工具,这依赖于 FastMCP 的私有实现。FastMCP 提供了公开方法 has_tool()get_tools() 来查询工具,建议将这些私有访问替换为公开 API,或至少将此访问封装为一个辅助函数,以降低维护成本和未来升级风险。

src/zzz_mcp/zzz_od_server_manage.py (2)

10-10: 使用 Optional 而非 | None

根据编码规范,目标 Python 3.11+,应使用 X | None 替代 Optional[X]

♻️ 修复
-from typing import Optional
-
-def find_main_server_process() -> Optional[psutil.Process]:
+def find_main_server_process() -> psutil.Process | None:

As per coding guidelines, **/*.py: Target Python 3.11+ and use modern syntax features such as | instead of Union.

Also applies to: 21-21


114-114: 未使用变量 gone 及可简化的列表拼接。

静态分析建议:gone 未使用可用 _ 替代;[proc] + children 可改为 [proc, *children]

♻️ 修复
-        gone, alive = psutil.wait_procs([proc] + children, timeout=5)
+        _, alive = psutil.wait_procs([proc, *children], timeout=5)

print("-" * 60)

# 获取Starlette应用并使用uvicorn运行
app = mcp.streamable_http_app()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

FastMCP streamable_http_app API documentation

💡 Result:

streamable_http_app is a FastMCP server helper that builds a Starlette ASGI app configured for the Streamable HTTP transport.

API (method on FastMCP server)

streamable_http_app(
  self,
  path: str | None = None,
  middleware: list[ASGIMiddleware] | None = None
) -> StarletteWithLifespan
  • path: URL path for the StreamableHTTP endpoint
  • middleware: Starlette/ASGI middleware to apply
    Returns: a StarletteWithLifespan app you can mount/run with an ASGI server. [1]

Related lower-level factory (same transport)

FastMCP also documents a factory function (useful if you’re wiring things manually):

create_streamable_http_app(
  server: FastMCP,
  streamable_http_path: str,
  event_store: EventStore | None = None,
  auth: AuthProvider | None = None,
  json_response: bool = False,
  stateless_http: bool = False,
  debug: bool = False,
  routes: list[BaseRoute] | None = None,
  middleware: list[Middleware] | None = None
) -> StarletteWithLifespan

[2]

Where to read it

  • FastMCP server docs page that defines streamable_http_app: [1]
  • FastMCP HTTP transport docs page that defines create_streamable_http_app and related classes: [2]

Sources: [1] FastMCP server docs (streamable_http_app) (fastmcp.wiki), [2] FastMCP HTTP docs (create_streamable_http_app) (fastmcp.wiki)

Citations:


🏁 Script executed:

# Check for version constraints in the repository
fd -e "requirements.txt" -e "pyproject.toml" -e "setup.py" -e "setup.cfg" -e "poetry.lock" -e "Pipfile"

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 70


🏁 Script executed:

# Look at the specific file to understand context and imports
head -50 src/zzz_mcp/zzz_mcp_server.py

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 1108


🏁 Script executed:

# Search more thoroughly for dependency/version files
find . -type f -name "pyproject.toml" -o -name "requirements*.txt" -o -name "poetry.lock" -o -name "Pipfile" 2>/dev/null | head -20

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 104


🏁 Script executed:

# Check git files for any dependency information
git ls-files | grep -E "(requirements|setup|pyproject|poetry|Pipfile)" | head -20

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 102


🏁 Script executed:

# Look for any comments or documentation about mcp library version
rg "fastmcp|mcp\." -A 2 -B 2 --max-count=10 pyproject.toml setup.py requirements.txt 2>/dev/null || echo "No dependency files found via rg"

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 120


🏁 Script executed:

# Read the pyproject.toml to check dependencies
cat pyproject.toml

Repository: OneDragon-Anything/ZenlessZoneZero-OneDragon

Length of output: 2128


mcp 库添加到主依赖项。

streamable_http_app() 方法在 FastMCP 官方文档中有明确定义,当前版本约束 mcp>=1.0.0(dev 依赖)已支持此 API。然而,此文件是运行时代码,需要访问 mcp 库,因此应将 mcp 从 dev 依赖移至 pyproject.toml 的主依赖项中。

🤖 Prompt for AI Agents
In `@src/zzz_mcp/zzz_mcp_server.py` at line 37, 运行时代码使用了
mcp.streamable_http_app(),但 mcp 当前只在开发依赖中;将 mcp 从 dev 依赖移到主依赖中以确保在运行时可用。修改
pyproject.toml 的 [tool.poetry.dependencies](或相应依赖节)添加/移动 "mcp" 并设置合适的版本约束(例如
">=1.0.0"),然后更新锁文件并重新安装依赖(poetry lock && poetry install 或 pip/poetry
等项目使用的流程);确保 mcp 在运行环境中可导入以支持 mcp.streamable_http_app() 的调用。

Comment on lines +16 to +18
PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon"
MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
MAIN_SERVER_PORT = 8000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

硬编码的本地开发路径,其他开发者/环境无法使用。

PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon" 是某位开发者的本地绝对路径。这会导致:

  1. 其他开发者或 CI 环境直接启动失败
  2. 路径在非 Windows 系统上无效

应基于当前文件位置动态计算项目根目录。

🐛 建议使用动态路径
+from pathlib import Path
+
 # 配置
-PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon"
+PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent  # src/zzz_mcp -> src -> project root
 MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
 MAIN_SERVER_PORT = 8000

As per coding guidelines, **/*.py: Use pathlib library for path handling instead of os.path.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon"
MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
MAIN_SERVER_PORT = 8000
from pathlib import Path
# 配置
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent # src/zzz_mcp -> src -> project root
MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
MAIN_SERVER_PORT = 8000
🤖 Prompt for AI Agents
In `@src/zzz_mcp/zzz_od_server_manage.py` around lines 16 - 18, Replace the
hardcoded PROJECT_ROOT with a dynamic Path computed from the current file
location: use pathlib.Path(__file__).resolve() and walk up to the repository
root (e.g., .parents[n] or search for a marker) to set PROJECT_ROOT; then
construct MAIN_SERVER_SCRIPT as a Path(PROJECT_ROOT) /
"src/zzz_mcp/zzz_mcp_server.py" (or keep MAIN_SERVER_SCRIPT as a relative string
but join it with PROJECT_ROOT when used). Update any uses of os.path to pathlib
APIs and keep MAIN_SERVER_PORT unchanged; modify references to PROJECT_ROOT and
MAIN_SERVER_SCRIPT in zzz_od_server_manage.py to use the new Path objects.

Comment on lines +21 to +38
def find_main_server_process() -> Optional[psutil.Process]:
"""查找 zzz_od MCP 主服务器进程"""
for proc in psutil.process_iter(['pid', 'name', 'cmdline', 'create_time']):
try:
cmdline = proc.info['cmdline']
if cmdline and any('zzz_mcp_server.py' in arg for arg in cmdline):
return proc
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
return None


def is_port_in_use(port: int) -> bool:
"""检查端口是否被占用"""
for conn in psutil.net_connections():
if conn.laddr.port == port and conn.status == 'LISTEN':
return True
return False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

src/tools/mcp/daemon/zzz_od_daemon.py 存在大量重复代码。

find_main_server_processis_port_in_usestart_zzz_od_serverstop_zzz_od_serverrestart_zzz_od_serverget_zzz_od_server_status 等函数与 daemon 模块中的实现几乎完全相同(对比 relevant code snippets 可确认)。这违反了 DRY 原则,后续维护时容易导致两处逻辑不一致。

建议将公共逻辑提取到一个共享模块中,两个入口分别导入使用。

Also applies to: 42-85, 88-126, 129-149, 152-188

🤖 Prompt for AI Agents
In `@src/zzz_mcp/zzz_od_server_manage.py` around lines 21 - 38, The code
duplicates utility functions across modules; extract the shared logic
(find_main_server_process, is_port_in_use, start_zzz_od_server,
stop_zzz_od_server, restart_zzz_od_server, get_zzz_od_server_status) into a new
common helper module (e.g., zzz_od_server_utils) and have both
src/zzz_mcp/zzz_od_server_manage.py and src/tools/mcp/daemon/zzz_od_daemon.py
import and call those helpers; move all psutil-based iteration and port-checking
logic (the bodies of find_main_server_process and is_port_in_use) and the
process start/stop/restart/status implementations into that module, keep only
thin wrappers or direct imports in the two entry modules, and update any
references to these function names to use the shared implementations.

Comment on lines +60 to +71
try:
cmd = f'cd /d "{PROJECT_ROOT}" && uv run --env-file .env python {MAIN_SERVER_SCRIPT}'

# 使用 POPEN 启动,不阻塞
process = subprocess.Popen(
cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
encoding='utf-8'
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

shell=True 的安全风险及 stdout 未使用。

  1. shell=True 配合 f-string 拼接的命令存在命令注入风险(虽然当前 PROJECT_ROOT 是常量,但如果后续从配置或环境变量读取则可能被利用)。建议改用列表形式传参。
  2. Line 80: stdout 解包后未使用,可用 _ 替代。
🔧 建议改用列表形式,避免 shell=True
-        cmd = f'cd /d "{PROJECT_ROOT}" && uv run --env-file .env python {MAIN_SERVER_SCRIPT}'
-
-        # 使用 POPEN 启动,不阻塞
-        process = subprocess.Popen(
-            cmd,
-            shell=True,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            text=True,
-            encoding='utf-8'
-        )
+        process = subprocess.Popen(
+            ["uv", "run", "--env-file", ".env", "python", str(MAIN_SERVER_SCRIPT)],
+            cwd=str(PROJECT_ROOT),
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            text=True,
+            encoding='utf-8',
+        )

同时修复 Line 80 的未使用变量:

-            stdout, stderr = process.communicate()
+            _stdout, stderr = process.communicate()
🧰 Tools
🪛 Ruff (0.15.0)

[warning] 63-63: Comment contains ambiguous (FULLWIDTH COMMA). Did you mean , (COMMA)?

(RUF003)


[error] 64-64: subprocess call with shell=True identified, security issue

(S602)

🤖 Prompt for AI Agents
In `@src/zzz_mcp/zzz_od_server_manage.py` around lines 60 - 71, The current
subprocess invocation builds cmd via f-string and uses subprocess.Popen with
shell=True (cmd variable) which risks command injection; change subprocess.Popen
to pass args as a list (e.g., ["uv", "run", "--env-file", ".env", "python",
MAIN_SERVER_SCRIPT] after chdir or use cwd=PROJECT_ROOT) and remove shell=True,
and when calling process.communicate() capture the unused stdout as _ and only
use stderr (e.g., `_, stderr = process.communicate()`), updating references to
subprocess.Popen, cmd, PROJECT_ROOT, MAIN_SERVER_SCRIPT, and process
accordingly.

import time
import psutil
import uvicorn
from typing import Optional
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

应使用 X | None 替代 Optional[X]

编码规范要求 Python 3.11+ 使用 | 语法。Line 22 的返回类型注解应改为 psutil.Process | None

♻️ 建议修改
-from typing import Optional
-
-...
-
-def find_main_server_process() -> Optional[psutil.Process]:
+def find_main_server_process() -> psutil.Process | None:

As per coding guidelines, **/*.py: Use | instead of Union.

🤖 Prompt for AI Agents
In `@tools/mcp/daemon/zzz_od_daemon.py` at line 11, Replace the use of
typing.Optional with the modern union operator by changing the return type
annotation at the noted function (the function that currently returns
Optional[psutil.Process]) to psutil.Process | None; also remove the now-unused
"Optional" import from the top of the file (the from typing import Optional
line). Ensure any other Optional[...] in this module is updated to the X | None
form to follow the Python 3.11+ guideline.

Comment on lines +17 to +19
PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon"
MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
MAIN_SERVER_PORT = 23001
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

硬编码的开发者本地路径,其他环境无法运行。

PROJECT_ROOT 被硬编码为 D:\code\workspace\ZenlessZoneZero-OneDragon,这会导致在任何其他机器上运行时直接失败。应动态计算项目根目录。

🐛 建议修改
+from pathlib import Path
+
 # 配置
-PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon"
+PROJECT_ROOT = str(Path(__file__).resolve().parent.parent.parent)
 MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py"
 MAIN_SERVER_PORT = 23001

As per coding guidelines, **/*.py: Use pathlib library for path handling instead of os.path.

🤖 Prompt for AI Agents
In `@tools/mcp/daemon/zzz_od_daemon.py` around lines 17 - 19, PROJECT_ROOT is
hardcoded to a Windows developer path; replace it with a dynamic Path computed
via pathlib (e.g., derive from Path(__file__).resolve().parents or by walking up
until a repo marker like ".git" or "pyproject.toml") and build
MAIN_SERVER_SCRIPT using Path operations (Path(...) / MAIN_SERVER_SCRIPT)
instead of string concatenation; update any uses of PROJECT_ROOT to expect a
pathlib.Path object and remove the raw r"..." literal so the module works
cross-platform.

@kawayiYokami
Copy link
Copy Markdown
Contributor

以现有的框架,在我看来可以实现LLM控制自动战斗以外的所有流程,可以让LLM自己生成skill。

ShadowLemoon and others added 24 commits March 15, 2026 16:17
* feat: 返回大世界要灵活一点

* feat: 矩阵行动战前准备

* feat: 矩阵行动战斗

* fix: 修复逆天的战斗结束需要OCR到10次才停止的BUG

* perf :提高OCR频率减少战斗无法结束的可能

* feat: 藏品无脑选择同流派

* fix: 更新悬赏进度

* feat: UI集成

* feat: 纯ocr判断武备,不再需要人手添加

* perf:扩大藏品选择区域

* perf: 悬赏节点和进出口的BUG

* perf: 提高藏品/武备选择鲁棒性

* fix: 重写迷失之地三大副本导航

* feat: ocr选择武备,不再使用模板匹配,降低人力成本

* fix: 修复选择数量判断错误

* perf:优化代码质量

* 合并文档

* perf: 提取方法,减少代码长度

* perf: 使用round_wait

* chore: 更新常量

* 删除矩阵行动弹窗

* 新模板

* 合并代码到迷失之地

* 等待时间独立到各自状态里

* perf: 优化代码

---------

Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
* 适配千夏皮肤-午后茶歇(sunna_afternoon_tea_break)

* 专业挑战室适配: 牲鬼·卫律使者
* fix: 丽都城募优化等级领取逻辑

* feat: 调整通知时机,使得始终返回节点通知

* refactor: 循环节点

* fix: 修复购买大月卡后无法返回大世界

* chore: 重新调整通知时机和部分逻辑

* chore: 移除冗余
* feat: 回到大世界操作添加确保回到街区的可选参数

* perf: 使用上一个节点名称判断

* fix: 添加retry_wait

* fix: 修复通过跳转列表前往
* feat: 恶名狩猎计划支持拖动来调整刷取顺序

* fix: 修复恶名狩猎拖动排序数据同步问题

* chore: 删除没必要的向后兼容保留别名

* perf: 提取基类update_item方法

---------

Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
* perf: 优化锄大地停止追踪绳网检测以减少等待

* perf: 添加错误选择区域时的节点处理和等待动画稳定

* perf: 检测到无任务追踪立即执行路线

* chore: 移除多余的调用

* fix:(搜索传送点循环): 消除失败后的屏幕脏,减少过多的尝试次数

* refactor: 合并两个节点

* chore: 更新按钮-区域信息关闭名称
* feat: 添加安装清单生成和文件复制校验功能

* perf: 优化清单枚举

* perf: 使用流式复制+校验的方式复制文件

* ci: 使用python脚本替代工作流中的pwsh脚本

* perf: 更改命令执行方式

* fix: 修复 CI 脚本的细节问题

- get_version.py: git push/tag 加 check=True,修复风格(返回类型注解 + raise SystemExit)
- prepare_release_assets.py: 删除死代码 last_err,修正步骤注释序号
- installer_interface.py: 路径安全检查改用 is_relative_to(),语义更清晰

* feat: 无清单时跳过解包;补充下载重试日志;修复 _is_same_dir 方法缺失;预计算磁盘空间

* feat: 路径确认后立即迁移文件,在选路界面展示搬运进度

- 将 UnpackResourceRunner 抽离为独立模块 services/unpack_runner.py
  · 新增 log_message 信号实时推送单行状态文案
  · 新增 is_done / is_success 属性供结束后查询
- DirectoryPickerWindow 确认路径后立即启动文件迁移
  · 用 QStackedWidget 区分选路页和进度页,消除布局抖动
  · "preparing" 文案纳入 DirectoryPickerTranslator(中英互切)
- InstallerInterface 移除全部解包相关代码,清理无用依赖

* fix: 文件校验失败的时候跳过而不是中断

* perf: 优化进度条和日志

* perf: 整理ci脚本命令行参数

* perf: 优化日志显示
 - 引入节流机制,避免日志更新过于频繁导致界面闪烁
 - 避免过长日志撑宽界面

* perf: installer_dir规定为str;json获取添加重试
* ci: PR 自动构建预览

* ci: 优化版本号逻辑
- 自动打开情报板、筛选恶名狩猎/专业挑战室、接取并完成委托
- 支持经验刷满模式(恶名狩猎500/专业挑战室250,上限5000)
- 添加框架方法round_by_ocr_and_click_by_priority
- 重构恶名狩猎移动流程并复用
- 支持预备编队选择和自动战斗指令配置
- 新增基于TeachTip的设置框

---------

Co-authored-by: A-nony-mous <33509289+A-nony-mous@users.noreply.github.com>
Co-authored-by: DoctorReid <doctorreid2024@outlook.com>
Co-authored-by: Usagi-wusaqi <2181802336@qq.com>
* fix: 修复开局武备选择

* fix: 简化通用选择

* fix:修复同流派标志的武备可选的BUG
* feat: 优化矩阵行动配队选择流程

- 添加区域滚动功能 scroll_area,支持上下滚动查找配队
- round_by_find_and_click_area 新增 pre_delay 参数,支持识别后延迟点击(默认0.3秒)
- 新增 cv2_utils.is_colorful 方法,判断按钮是否加载完成(彩色)
- 矩阵行动选择配队支持滚动查找目标编队,最多向下5次+向上5次
- 添加主战编队槽和协战编队槽区域,用于准确检测主战/协战文字
- 修复滚动坐标计算逻辑,统一按距顶部比例计算位置

* fix: 挑战完成后清空房间类型缓存

---------

Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
ShadowLemoon and others added 30 commits March 15, 2026 16:18
* feat(notify): include current charge power in one-dragon completion push

* chore: address PR review suggestions

* chore: fix review and lint issues

* feat(notify): estimate natural charge recovery before push

* refactor: simplify charge power record flow

* refactor: use tuple snapshot for charge power record

* perf: 简化代码

* perf: 移除cast调用;内联恢复体力时间常量

---------

Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
* refactor: 重构画面管理,增加弹出表格功能

* refactor: 优化 ScreenArea 属性初始化,简化文本和模板字段处理

* refactor: 重构表格列元数据存储方式

* fix: 修复id_mark位置

* refactor: screen区域添加formatter字段并移除_text属性

* feat: 添加颜色范围、坐标校验

* perf: 统一记录状态和应用新值
* feat: 角色模板生成工具

* fix: 修正代理人ID正则表达式,支持下划线和数字

原有正则 ^[a-z]+$ 过于严格,无法匹配项目中实际存在的代理人ID,
如 soldier_11, jane_doe, zhu_yuan 等。

修改为 ^[a-z][a-z0-9_]*$ 以支持:
- 以小写字母开头
- 包含小写字母、数字、下划线

* refactor: 使用 pathlib 替代 os.path 进行路径处理

符合项目编码规范要求使用 pathlib 库处理路径。

变更:
- 移除 import os
- 添加 from pathlib import Path
- os.path.normpath -> Path.resolve()
- os.path.dirname -> Path.parent

* 移除未使用方法
- 新增 ExpandSettingCardGroup,继承 ExpandSettingCard,提供手风琴式折叠卡片组
- 分隔线随卡片可见性自动同步,通过 eventFilter 监听 Show/Hide 事件
* fix: 修复隐藏卡片后组件大小出错

* refactor: 使用枚举+装饰器消除按键配置样板代码

- 新增 GameKeyAction 枚举(15 个按键动作)和 _KEY_DEFAULTS 字典
- 使用 @_with_key_properties 装饰器在类定义时动态生成 45 个按键 property,
  替代原先 270+ 行手写 property/setter(~500 行 → 164 行)

* refactor: 将Margins改为不可变类

* refactor: 重构自定义主题色

* fix: 代理人模板生成使用Margins
* feat: 适配Server酱v3

* refactor: 使用手风琴式设置卡组重构通知设置
* perf: 简化一条龙运行界面布局层级

移除多余的中间容器,减少布局嵌套:
- 移除 scroll_content (QWidget) 和 scroll_layout (QVBoxLayout)
- AppRunList 直接作为 ScrollArea 的内容
- 将边距设置移到 DraggableList 中

优化前层级:
ScrollArea -> QWidget -> QVBoxLayout -> AppRunList -> DraggableList -> 卡片

优化后层级:
ScrollArea -> AppRunList -> DraggableList -> 卡片

* feat: 为开发工具添加截图按钮

在图像分析、画面管理、模板管理三个界面的选择图片按钮旁添加截图按钮,
可直接对游戏进行截图。

* feat: 截图按钮无需选中画面/模板即可使用

- 移除截图按钮的禁用限制,使其始终可用
- 截图时如果没有选中画面/模板,自动创建新的
- 保持截图功能独立,不受选择状态限制

* refactor: 将 screenshot_btn 信号连接移到 _init_signal_connections 方法中

* style: 为 _on_screenshot_clicked 方法添加返回类型注解

* fix: 截图自动创建画面时清除历史记录
* feat: 新增爱芮角色及优化终结技模板

* feat: 调整柏妮思速切决策
* fix: 处理二次运行时,进入咨询分支的情况

* refactor: 节点上time.sleep转化成节点内pre_delay,节点内success_wait转化成节点下click的pre_delay(严格等价替换)

* perf: 发挥 pre_delay 全局默认值的优势,尝试减少不必要的等待

* chore: 按钮-关闭和返回区域改成模板匹配

* perf: 二次确认应迅速自处理,而不是交给缓慢的返回大世界

* fix: 二次确认电脑慢的情况?

* perf: 识别到正在营业迅速自返回,而不是 OCR 53次触发返回大世界的兜底
实现完整的后台游戏控制架构,支持在游戏窗口不在前台时进行所有操作。

核心架构:
- VirtualGamepadController: 基于 vgamepad 的虚拟手柄控制器
- pc_controller_base 双模式分发: click()/drag_to() 根据后台/前台模式自动分发
  - 后台: PostMessage 点击 + Xbox 手柄按键替代
  - 前台: pyautogui 点击 + 键盘操作
- action_keys 字典替代原有 15 个独立 key_* 属性
- _action_btn 辅助方法消除重复模板

手柄操作:
- gamepad_key 参数替代 pc_alt 的点击分发 (screen_info YAML 配置驱动)
- 手柄转向 _gamepad_turn: 自包含模式切换 + 速度下限保护
- DS4/Xbox 按键控制器提取公共基类
- 按键连击 tap_combo 使用列表存储,动态生成手柄动作键

鼠标闪切:
- _ensure_mouse_mode: 后台模式下短暂切前台触发 Raw Input 键鼠切换
- mouse_flash_duration 可配置 (默认 0.05s)
- SetForegroundWindow 失败时使用 ALT 键技巧重试
* fix: 修复锄大地传送后立即遇敌导致返回大世界触发脱离卡死并使路线在错误位置执行

* chore: 清除一些完全浪费时间的大世界判断条件

* refactor: 移除没必要的wait

* refactor: 修改参数名称,提升代码可读性
* refactor(charge_plan): 优化特训目标跳过处理

* fix(charge_plan): 始终标记跳过
* ci(running_resource): 添加PR检查,优化提交流程

* fix: checkout仓库错误
---------

Co-authored-by: Usagi-wusaqi <2181802336@qq.com>
Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
* Fix issue of not finding team_name in matrix by removing whitespace

* fix bug

* refactor matrix team selection node
* fix: 修复后台驻留线程

* refactor: 删除多余的处理并统一名称

* perf(auto_battle): 使用代际计数器简化周期性线程处理

* fix: 应用退出的时候只松开按下的按键

* perf: 移除多余的try

* fix: 修复清理顺序问题

* fix: 退出的时候确保所有排队的通知都发送完成

* perf: 优化顺序问题

---------

Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
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.

8 participants