AI Coding的一些准备#2015
Conversation
集成 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>
|
Important Review skippedToo many files! This PR contains 210 files, which is 60 over the limit of 150. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (56)
📒 Files selected for processing (210)
You can disable this status message by setting the Use the checkbox below for a quick retry:
概述本变更为 ZZZ OD 项目添加了 MCP(模型上下文协议)服务器实现、完整的开发者文档体系、Claude 插件配置,以及针对游戏集成的工具组件。包括项目级文档、开发指南、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: 操作结果消息
预估代码审查工作量🎯 3 (中等复杂) | ⏱️ ~35 分钟 可能相关的 PR
建议审查者
诗
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
|
There was a problem hiding this comment.
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.toml,pyright已被放在[dependency-groups] dev中。文档应建议使用--group dev以保持一致。🔧 建议修正安装命令
-uv add pyright +uv add --group dev pyright # or -uv pip install pyright +uv sync --group devdocs/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 -Forcedocs/develop/zzz/mcp/remote-ssh.md-23-25 (1)
23-25:⚠️ Potential issue | 🟡 MinorSession 编号描述不够准确。
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.gitCLAUDE.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>&1tools/mcp/daemon/install_daemon.ps1 (1)
1-164: 与install.ps1存在大量重复代码。
install_daemon.ps1与install.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_process、is_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_ROOT和MAIN_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完全重复。
TestGameOperationContext和TestGameOperationTool的setUp/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 ofUnion.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() |
There was a problem hiding this comment.
🧩 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: aStarletteWithLifespanapp 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_appand related classes: [2]
Sources: [1] FastMCP server docs (streamable_http_app) (fastmcp.wiki), [2] FastMCP HTTP docs (create_streamable_http_app) (fastmcp.wiki)
Citations:
- 1: https://fastmcp.wiki/en/python-sdk/fastmcp-server-server?utm_source=openai
- 2: https://fastmcp.wiki/en/python-sdk/fastmcp-server-http?utm_source=openai
🏁 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.pyRepository: 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 -20Repository: 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 -20Repository: 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.tomlRepository: 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() 的调用。
| PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon" | ||
| MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py" | ||
| MAIN_SERVER_PORT = 8000 |
There was a problem hiding this comment.
硬编码的本地开发路径,其他开发者/环境无法使用。
PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon" 是某位开发者的本地绝对路径。这会导致:
- 其他开发者或 CI 环境直接启动失败
- 路径在非 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 = 8000As 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.
| 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.
| 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 |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
与 src/tools/mcp/daemon/zzz_od_daemon.py 存在大量重复代码。
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 等函数与 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.
| 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' | ||
| ) |
There was a problem hiding this comment.
shell=True 的安全风险及 stdout 未使用。
shell=True配合 f-string 拼接的命令存在命令注入风险(虽然当前PROJECT_ROOT是常量,但如果后续从配置或环境变量读取则可能被利用)。建议改用列表形式传参。- 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 |
There was a problem hiding this comment.
🛠️ 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.
| PROJECT_ROOT = r"D:\code\workspace\ZenlessZoneZero-OneDragon" | ||
| MAIN_SERVER_SCRIPT = "src/zzz_mcp/zzz_mcp_server.py" | ||
| MAIN_SERVER_PORT = 23001 |
There was a problem hiding this comment.
硬编码的开发者本地路径,其他环境无法运行。
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 = 23001As 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.
|
以现有的框架,在我看来可以实现LLM控制自动战斗以外的所有流程,可以让LLM自己生成skill。 |
* 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>
* 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仓库错误
[skip ci]
--------- 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>
1. PR说明
游戏更新后,对新玩法的适配,我们的做法是:
结合AI,我设想的做法是:
要达到上述目标,我们需要:
本次PR就是为了更好的AI Coding做的一些准备。
1.1. 文档
初步整理了文档结构,方便在编程工具引入为规范。
后续开发过程中再把游戏玩法说明、功能设计之类的补上,目标是让AI能真的懂我们的项目在做什么、绝区零是个什么游戏、玩法是怎样的。
1.2. MCP Server
为了编程工具更好地辅助开发,引入了 zzz_od 的 mcp server,为编程工具提供了解游戏的能力。
当前只有几个基础工具,算是完成一个小实验,能让我自己从公司ssh到家里,然后只用终端进行AI Coding。
后续其他工具以及相关的框架调整计划,在假期闲余时间再补充。
未来希望拓展实现:
我想再过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
Documentation
Tests
Chores