Skip to content

[codex] add Windows PC attach-window support to maa-cli#543

Open
Alphayellowcat wants to merge 8 commits into
MaaAssistantArknights:mainfrom
Alphayellowcat:codex/pc-attachwindow-support
Open

[codex] add Windows PC attach-window support to maa-cli#543
Alphayellowcat wants to merge 8 commits into
MaaAssistantArknights:mainfrom
Alphayellowcat:codex/pc-attachwindow-support

Conversation

@Alphayellowcat
Copy link
Copy Markdown

@Alphayellowcat Alphayellowcat commented May 6, 2026

Summary

This PR adds Windows PC-client support to maa-cli by exposing MaaCore's AttachWindow path through the CLI runtime and profile configuration.

It also updates maa init so users can generate a PC-oriented connection profile without hand-editing the config.

What changed

  • add a PC connection preset for Windows AttachWindow mode
  • add connection.window_title, screencap_method, mouse_method, and keyboard_method
  • route connection.type = "PC" through AsstAsyncAttachWindow instead of ADB connect
  • auto-load the PC platform-diff resource for this preset
  • add Win32 exact-title window discovery for the running game window
  • add --window-title override on the CLI
  • update the config schema and example profile
  • extend maa init so it can generate a PC preset with sensible defaults

Why

MaaCore already exposes AsstAsyncAttachWindow on Windows, but maa-cli only exposed ADB-style connection flows. That meant the GUI could drive the native Windows Arknights client while the CLI could not, even though the core capability already existed.

This closes that feature gap and makes the PC client a first-class connection mode in maa-cli.

User impact

Users on Windows can now configure:

[connection]
type = "PC"
window_title = "明日方舟"

and run maa-cli against the native PC client without going through emulator or ADB flows.

Validation

  • cargo +1.88.0 test -p maa-cli --quiet
    • 302 passed, 0 failed, 26 ignored
  • local runtime validation with a patched maa.exe
    • matched the running 明日方舟 window by title
    • entered the AttachWindow connection path successfully
    • previously verified real in-game screencap through MaaCore AttachWindow on the same setup

Notes

  • this PR is Windows-only for the PC preset
  • the PR is opened as draft because the core connection path is validated, but not every task flow has been exercised end-to-end on the PC client yet

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.

新功能:

  • 引入新的 PC 连接预设,通过 Win32 AttachWindow 附加到原生 Windows 明日方舟客户端,而不是使用 ADB。
  • 支持在连接配置中设置 window_titlescreencap_methodmouse_methodkeyboard_method,并可通过 --window-title CLI 参数覆盖窗口标题。
  • 新增仅适用于 Windows 的实现,通过精确匹配窗口标题定位游戏窗口,并使用从 MaaCore 暴露出的新的 async_attach_window API 进行连接。

增强:

  • 扩展 maa init 和 asst 配置的 schema/示例配置,自动生成并文档化面向 PC 的连接配置以及 platform-diff 资源。
  • 改进安装器测试和 fixtures 路径,并调整错误消息,使其更笼统一致地指代“游戏客户端”,而不是特指 Android 设备。
  • 优化下载中的 ETag 处理,通过集中构造 .etag 辅助文件路径,并现代化 MaaCore 用户目录初始化流程。

测试:

  • 扩展配置和连接相关测试,覆盖新的 PC 预设、PC 默认方法、AttachWindow 参数构造,以及 PC 平台差异资源的自动加载。
  • 调整现有连接、资源、行为配置和密钥相关测试,以适配新增字段和跨平台命令差异。
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.
Original summary in English

Summary by Sourcery

通过在配置、运行时以及示例中贯通 MaaCore 的 Win32 AttachWindow 路径,为 maa-cli 新增 Windows 专用的 PC 连接支持。

新功能:

  • 引入 Windows 专用的 PC 连接预设,通过 Win32 AttachWindow 附着到原生游戏客户端,而不是使用 ADB。
  • 允许为 PC 连接配置 window_titlescreencap_methodmouse_methodkeyboard_method,并更新对应的 schema 和示例配置。
  • maa-types 中暴露新的 Win32 截图与输入方法枚举,并在 maa-cli 中使用它们对 AttachWindow 调用进行参数化。

增强:

  • 扩展 maa init 以生成面向 PC 的连接配置文件,省略具有默认值的 PC 字段,并为 PC 的 platform-diff 资源提供说明文档。
  • 当使用 PC 预设时自动选择 PC 的 platform-diff 资源,并改进连接失败时的提示信息,使其泛指游戏客户端。
  • 新增通过精确标题发现正在运行的游戏窗口的 Win32 窗口查找逻辑,在没有精确匹配时提供相似标题提示。

测试:

  • 扩展配置、预设和连接测试,覆盖 PC 预设、AttachWindow 参数构造以及 PC platform-diff 资源的自动加载。
  • 为新的 Win32 输入和截图方法枚举添加测试,包括解析、序列化以及数值转换。
Original summary in English

Summary by Sourcery

Add Windows-specific PC connection support to maa-cli by wiring MaaCore's Win32 AttachWindow path through configuration, runtime, and examples.

New Features:

  • Introduce a Windows-only PC connection preset that attaches to the native game client via Win32 AttachWindow instead of ADB.
  • Allow configuring window_title, screencap_method, mouse_method, and keyboard_method for PC connections, with schema and example profile updates.
  • Expose new Win32 screencap and input method enums in maa-types and use them to parameterize AttachWindow calls from maa-cli.

Enhancements:

  • Extend maa init to generate PC-oriented connection profiles, omitting defaulted PC fields and documenting PC platform-diff resources.
  • Automatically select the PC platform-diff resource when using the PC preset and improve connection failure messaging to refer generically to the game client.
  • Add Win32 window discovery by exact title for the running game window, with related-title hints when no exact match is found.

Tests:

  • Expand configuration, preset, and connection tests to cover the PC preset, AttachWindow argument construction, and PC platform-diff resource auto-loading.
  • Add tests for the new Win32 input and screencap method enums, including parsing, serialization, and numeric conversions.

@Alphayellowcat Alphayellowcat marked this pull request as ready for review May 6, 2026 08:45
@Alphayellowcat Alphayellowcat marked this pull request as draft May 6, 2026 08:46
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了两个问题,并给出了一些整体层面的反馈:

  • ConnectionConfig/AttachWindowArgs 里的 screencap_methodmouse_methodkeyboard_method 字段是 u64,但在 maa init 的交互提示中使用的是 i32;为了安全性和可读性,建议在配置、模板和 MaaCore 调用之间统一这些字段的整数位宽和有符号性。
  • 在 Windows 的 AttachWindow 路径中,你通过 API 直接传递了原始的 u64 方法 ID;建议为这些方法选择器引入轻量的 newtype 或枚举,使调用点具备自描述性,并降低交换或误用这些数值常量的风险。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- The `screencap_method`, `mouse_method`, and `keyboard_method` fields are `u64` in `ConnectionConfig`/`AttachWindowArgs` but are prompted as `i32` in `maa init`; it would be safer and clearer to align these types to a single integer width/signedness across config, template, and MaaCore calls.
- In the Windows AttachWindow path you pass raw `u64` method IDs through the API; consider introducing small newtypes or enums for these method selectors to make call sites self-documenting and reduce the risk of swapping or misusing these numeric constants.

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/run/windows.rs" line_range="7" />
<code_context>
+    Foundation::{HWND, LPARAM},
+    UI::WindowsAndMessaging::{EnumWindows, GetWindowTextLengthW, GetWindowTextW, IsWindowVisible},
+};
+use windows_sys::core::BOOL;
+
+pub(super) struct WindowMatch {
</code_context>
<issue_to_address>
**issue (bug_risk):** Importing `BOOL` from `windows_sys::core` is likely incorrect and will not compile.

In `windows-sys`, `BOOL` is defined under `windows_sys::Win32::Foundation`, not `windows_sys::core`. Since you already import `HWND` and `LPARAM` from `Foundation`, import `BOOL` there as well:

```rust
use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM};
```

Then remove the `windows_sys::core::BOOL` import, which does not exist and will cause a compile error.
</issue_to_address>

### Comment 2
<location path="crates/maa-cli/src/config/init.rs" line_range="215-224" />
<code_context>
+                x => insert!(config, "window_title" => x),
+            };
+        }
+        if let Some(screencap_method) = obj.get("screencap_method") {
+            match screencap_method.as_int().unwrap() {
+                2 => {}
+                x => insert!(config, "screencap_method" => x),
+            };
+        }
+        if let Some(mouse_method) = obj.get("mouse_method") {
+            match mouse_method.as_int().unwrap() {
+                32 => {}
+                x => insert!(config, "mouse_method" => x),
+            };
+        }
+        if let Some(keyboard_method) = obj.get("keyboard_method") {
+            match keyboard_method.as_int().unwrap() {
+                2 => {}
+                x => insert!(config, "keyboard_method" => x),
+            };
+        }
</code_context>
<issue_to_address>
**issue (bug_risk):** PC input methods are typed as `u64` in config but initialized here via signed integers, which can produce invalid configs.

These fields are `Option<u64>` in `ConnectionConfig`, but the template uses `Input::<i32>` and writes `as_int()` results directly into TOML. If a user enters a negative value, the generated config will contain a negative integer and deserialization into `u64` will fail. Please either reject/guard against negative values here (e.g., bail or clamp on `x < 0`) or update the template to use an unsigned type consistent with the struct definition.
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这些评审有帮助,请考虑分享给他人 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进今后的评审。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • The screencap_method, mouse_method, and keyboard_method fields are u64 in ConnectionConfig/AttachWindowArgs but are prompted as i32 in maa init; it would be safer and clearer to align these types to a single integer width/signedness across config, template, and MaaCore calls.
  • In the Windows AttachWindow path you pass raw u64 method IDs through the API; consider introducing small newtypes or enums for these method selectors to make call sites self-documenting and reduce the risk of swapping or misusing these numeric constants.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `screencap_method`, `mouse_method`, and `keyboard_method` fields are `u64` in `ConnectionConfig`/`AttachWindowArgs` but are prompted as `i32` in `maa init`; it would be safer and clearer to align these types to a single integer width/signedness across config, template, and MaaCore calls.
- In the Windows AttachWindow path you pass raw `u64` method IDs through the API; consider introducing small newtypes or enums for these method selectors to make call sites self-documenting and reduce the risk of swapping or misusing these numeric constants.

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/run/windows.rs" line_range="7" />
<code_context>
+    Foundation::{HWND, LPARAM},
+    UI::WindowsAndMessaging::{EnumWindows, GetWindowTextLengthW, GetWindowTextW, IsWindowVisible},
+};
+use windows_sys::core::BOOL;
+
+pub(super) struct WindowMatch {
</code_context>
<issue_to_address>
**issue (bug_risk):** Importing `BOOL` from `windows_sys::core` is likely incorrect and will not compile.

In `windows-sys`, `BOOL` is defined under `windows_sys::Win32::Foundation`, not `windows_sys::core`. Since you already import `HWND` and `LPARAM` from `Foundation`, import `BOOL` there as well:

```rust
use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM};
```

Then remove the `windows_sys::core::BOOL` import, which does not exist and will cause a compile error.
</issue_to_address>

### Comment 2
<location path="crates/maa-cli/src/config/init.rs" line_range="215-224" />
<code_context>
+                x => insert!(config, "window_title" => x),
+            };
+        }
+        if let Some(screencap_method) = obj.get("screencap_method") {
+            match screencap_method.as_int().unwrap() {
+                2 => {}
+                x => insert!(config, "screencap_method" => x),
+            };
+        }
+        if let Some(mouse_method) = obj.get("mouse_method") {
+            match mouse_method.as_int().unwrap() {
+                32 => {}
+                x => insert!(config, "mouse_method" => x),
+            };
+        }
+        if let Some(keyboard_method) = obj.get("keyboard_method") {
+            match keyboard_method.as_int().unwrap() {
+                2 => {}
+                x => insert!(config, "keyboard_method" => x),
+            };
+        }
</code_context>
<issue_to_address>
**issue (bug_risk):** PC input methods are typed as `u64` in config but initialized here via signed integers, which can produce invalid configs.

These fields are `Option<u64>` in `ConnectionConfig`, but the template uses `Input::<i32>` and writes `as_int()` results directly into TOML. If a user enters a negative value, the generated config will contain a negative integer and deserialization into `u64` will fail. Please either reject/guard against negative values here (e.g., bail or clamp on `x < 0`) or update the template to use an unsigned type consistent with the struct definition.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread crates/maa-cli/src/run/windows.rs Outdated
Foundation::{HWND, LPARAM},
UI::WindowsAndMessaging::{EnumWindows, GetWindowTextLengthW, GetWindowTextW, IsWindowVisible},
};
use windows_sys::core::BOOL;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk):windows_sys::core 导入 BOOL 很可能是不正确的,并且会导致无法编译。

windows-sys 中,BOOL 定义在 windows_sys::Win32::Foundation 下,而不是 windows_sys::core。既然你已经从 Foundation 导入了 HWNDLPARAM,也请从这里一并导入 BOOL

use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM};

然后删除 windows_sys::core::BOOL 的导入;该符号并不存在,会导致编译错误。

Original comment in English

issue (bug_risk): Importing BOOL from windows_sys::core is likely incorrect and will not compile.

In windows-sys, BOOL is defined under windows_sys::Win32::Foundation, not windows_sys::core. Since you already import HWND and LPARAM from Foundation, import BOOL there as well:

use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM};

Then remove the windows_sys::core::BOOL import, which does not exist and will cause a compile error.

Comment thread crates/maa-cli/src/config/init.rs
@Alphayellowcat
Copy link
Copy Markdown
Author

Thanks for the review.

  • I addressed the signedness mismatch in f728873 (fix: validate PC attach-window method ids).
    • the config-side PC method fields are now consistently i32
    • negative values are rejected when generating profiles in maa init
    • the AttachWindow runtime path also validates these values before converting them to the u64 MaaCore API parameters
  • I also investigated the BOOL import suggestion. With the current windows-sys version used in this repository, moving BOOL to windows_sys::Win32::Foundation does not compile (no BOOL in Win32::Foundation). I verified this locally and kept windows_sys::core::BOOL unchanged for compatibility with the dependency version in this PR.

I did not introduce dedicated enums/newtypes for the method IDs in this patch so I could keep the PR focused on landing PC AttachWindow support and the validation fix. Happy to follow up on that refactor separately if maintainers would prefer it.

@Alphayellowcat Alphayellowcat marked this pull request as ready for review May 6, 2026 09:02
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • PC 预设的默认值(窗口标题、截屏/鼠标/键盘方法)以及对非负方法的校验在 ConnectionConfig::attach_window_argsinit.rs 中都有重复;建议将这些常量和校验逻辑集中到一个单独的辅助函数中,以避免后续出现偏差。
  • run/windows.rs 中,EnumWindows 即使在找到完全匹配的标题后仍会继续枚举;如果实际只会使用第一个匹配项,可以在回调中在第一次精确匹配后提前返回,避免不必要的枚举开销。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- PC 预设的默认值(窗口标题、截屏/鼠标/键盘方法)以及对非负方法的校验在 `ConnectionConfig::attach_window_args``init.rs` 中都有重复;建议将这些常量和校验逻辑集中到一个单独的辅助函数中,以避免后续出现偏差。
-`run/windows.rs` 中,`EnumWindows` 即使在找到完全匹配的标题后仍会继续枚举;如果实际只会使用第一个匹配项,可以在回调中在第一次精确匹配后提前返回,避免不必要的枚举开销。

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/config/init.rs" line_range="215-224" />
<code_context>
+        if let Some(screencap_method) = obj.get("screencap_method") {
</code_context>
<issue_to_address>
**suggestion:** 避免为非负的 attach-window 方法重复编写校验逻辑。

对 `screencap_method``mouse_method``keyboard_method` 的非负检查与 `asst.rs` 中的 `validate_attach_window_method` 重复,这在规则变更时有产生不一致的风险。建议将这部分逻辑集中(例如放在 config 模块中的一个共享辅助函数里),这样交互式初始化和运行时解析就能始终使用同一套校验规则。

建议的实现方式:

```rust
        if let Some(screencap_method) = obj.get("screencap_method") {
            let x = screencap_method.as_int().unwrap();
            crate::config::validate_attach_window_method("connection.screencap_method", x)?;
            if x != 2 {
                insert!(config, "screencap_method" => x);
            }
        }

```

为了完整应用上述建议,并避免在代码库中重复校验逻辑,还需要:

1. 引入一个共享的辅助函数,例如放在 `crates/maa-cli/src/config/mod.rs`(或其他中心化的 config 模块)中,类似:
   ```rust
   pub fn validate_attach_window_method(key: &str, value: i64) -> anyhow::Result<()> {
       if value < 0 {
           bail!("{key} must be a non-negative integer, got {value}");
       }
       Ok(())
   }
   ```
2.`asst.rs` 中现有的运行时校验更新为调用新的 `validate_attach_window_method`,而不是在内部重新实现非负检查,这样交互式初始化和运行时解析就能共享同一套规则。
3. 在这个 `init.rs` 文件中,同样将 `mouse_method``keyboard_method` 的非负检查替换为调用 `crate::config::validate_attach_window_method("connection.mouse_method", x)?``crate::config::validate_attach_window_method("connection.keyboard_method", x)?`,同时保留现有的默认值处理逻辑(例如这里的 `2` 的情况)。
4. 确保添加/调整必要的 `use` 语句或使用全限定路径,使所有调用点都能顺利通过编译。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据这些反馈改进后续的代码审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The PC preset defaults (window title, screencap/mouse/keyboard methods) and validation for non-negative methods are duplicated between ConnectionConfig::attach_window_args and init.rs; consider centralizing these constants and the validation in a single helper to avoid drift.
  • In run/windows.rs, EnumWindows continues enumerating even after finding an exact title match; if only the first match is used, you could early-return from the callback after the first exact match to avoid unnecessary enumeration work.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The PC preset defaults (window title, screencap/mouse/keyboard methods) and validation for non-negative methods are duplicated between `ConnectionConfig::attach_window_args` and `init.rs`; consider centralizing these constants and the validation in a single helper to avoid drift.
- In `run/windows.rs`, `EnumWindows` continues enumerating even after finding an exact title match; if only the first match is used, you could early-return from the callback after the first exact match to avoid unnecessary enumeration work.

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/config/init.rs" line_range="215-224" />
<code_context>
+        if let Some(screencap_method) = obj.get("screencap_method") {
</code_context>
<issue_to_address>
**suggestion:** Avoid duplicating validation logic for non-negative attach-window methods.

The non-negative checks for `screencap_method`, `mouse_method`, and `keyboard_method` duplicate `validate_attach_window_method` in `asst.rs`, which risks them diverging if the rules change. Consider centralizing this (e.g., a shared helper in the config module) so interactive init and runtime parsing always use the same validation logic.

Suggested implementation:

```rust
        if let Some(screencap_method) = obj.get("screencap_method") {
            let x = screencap_method.as_int().unwrap();
            crate::config::validate_attach_window_method("connection.screencap_method", x)?;
            if x != 2 {
                insert!(config, "screencap_method" => x);
            }
        }

```

To fully apply your suggestion and avoid duplicated validation logic across the codebase, also:

1. Introduce a shared helper function, e.g. in `crates/maa-cli/src/config/mod.rs` (or another central config module), something like:
   ```rust
   pub fn validate_attach_window_method(key: &str, value: i64) -> anyhow::Result<()> {
       if value < 0 {
           bail!("{key} must be a non-negative integer, got {value}");
       }
       Ok(())
   }
   ```
2. Update the existing runtime validation in `asst.rs` to call this new `validate_attach_window_method` instead of inlining its own non-negative checks, so interactive init and runtime parsing share the same rules.
3. In this `init.rs` file, similarly replace the non-negative checks for `mouse_method` and `keyboard_method` with calls to `crate::config::validate_attach_window_method("connection.mouse_method", x)?` and `crate::config::validate_attach_window_method("connection.keyboard_method", x)?` respectively, preserving any existing default-value handling (like the `2` case here).
4. Ensure any necessary `use` statements or fully-qualified paths are added/adjusted so all call sites compile cleanly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread crates/maa-cli/src/config/init.rs
@Alphayellowcat
Copy link
Copy Markdown
Author

Follow-up in 62dbec6 (refactor: share PC attach-window config defaults):

  • centralized the PC AttachWindow defaults in the shared config module
  • moved non-negative AttachWindow method validation to the shared config helper and reused it from both init.rs and the runtime path in asst.rs

I did not change the EnumWindows traversal to early-return on the first exact match. The current behavior is intentional so the CLI can still detect duplicate visible windows with the same title and emit a warning before selecting the first one.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 22.18%. Comparing base (5d0638c) to head (d17b7be).

❗ There is a different number of reports uploaded between BASE (5d0638c) and HEAD (d17b7be). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (5d0638c) HEAD (d17b7be)
4 1
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #543       +/-   ##
===========================================
- Coverage   71.86%   22.18%   -49.69%     
===========================================
  Files          69        6       -63     
  Lines        6412      284     -6128     
  Branches     6412      284     -6128     
===========================================
- Hits         4608       63     -4545     
+ Misses       1477      220     -1257     
+ Partials      327        1      -326     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

check_interval: Option<time::Duration>,
) -> Result<()> {
let etag_file = dest.with_added_extension("etag");
let etag_file = etag_file_path(dest);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These changes should be unrelated, and I think dest.with_added_extension should work well. Can you discard them?

Comment thread crates/maa-cli/src/config/mod.rs Outdated
Comment on lines +10 to +12
pub(crate) const PC_SCREENCAP_METHOD_DEFAULT: i32 = 2;
pub(crate) const PC_MOUSE_METHOD_DEFAULT: i32 = 32;
pub(crate) const PC_KEYBOARD_METHOD_DEFAULT: i32 = 2;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you please add references for those numbers? If possible, make them enums, similar to what we do for other types in the maa-type crate.

Comment thread crates/maa-cli/src/installer/maa_cli.rs Outdated
use super::*;

const FIXTURE_JSON: &str = include_str!("../../fixtures/version/cli_version.json");
const FIXTURE_JSON: &str = include_str!("../../../maa-version/fixtures/cli_version.json");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is unrelated. Does the symlink not work on Windows?

Comment thread crates/maa-cli/src/run/mod.rs Outdated
/// The match is exact and case-sensitive, following MAA GUI behavior.
/// If omitted, `明日方舟` is used by default.
#[arg(long, verbatim_doc_comment)]
pub window_title: Option<String>,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this value change often? If not, consider setting it only in the configuration; there is no need to add a new CLI argument.

Comment thread crates/maa-cli/src/run/mod.rs Outdated
@Alphayellowcat
Copy link
Copy Markdown
Author

Addressed the latest maintainer feedback in 25c10fb:

  • removed unrelated changes from the PR and kept the diff focused on PC AttachWindow support
  • removed the --window-title CLI flag; window_title remains config/profile-only
  • promoted the PC AttachWindow method values into maa-types enums (Win32ScreencapMethod, Win32InputMethod), and updated maa init, the schema, and the example profile to use enum names instead of numeric values
  • made Preset::Pc Windows-only; on non-Windows, parsing connection.type = "PC" now returns an explicit error

The enum values and defaults follow the current MaaCore / MAA GUI Win32 AttachWindow definitions and defaults.

@Alphayellowcat
Copy link
Copy Markdown
Author

Pushed a follow-up CI cleanup in d17b7be:

  • gated the AttachWindow runtime argument helper and struct behind cfg(target_os = windows)
  • kept the shared PC config/schema fields available cross-platform, with narrowly scoped non-Windows dead_code allowances for serde/schema-only fields
  • changed attach_window_args to return the argument struct directly since enum-to-u64 conversion cannot fail
  • ran cargo +nightly fmt --all to satisfy the format job

Local checks run:

  • cargo +nightly fmt --all -- --check
  • cargo +nightly test -p maa-types --quiet
  • cargo +nightly check -p maa-cli --bin maa --all-features
  • cargo +nightly test -p maa-cli config::asst --bin maa --no-default-features --features git2

The new CI run is currently action_required, so it needs workflow approval before the full matrix can execute.

@wangl-cc
Copy link
Copy Markdown
Member

@sourcery-ai review

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/run/windows.rs" line_range="20-21" />
<code_context>
+pub(super) fn find_window_by_title(expected_title: &str) -> Result<WindowMatch> {
+    let mut state = EnumState::new(expected_title);
+
+    unsafe {
+        EnumWindows(
+            Some(enum_windows_proc),
+            &mut state as *mut EnumState<'_> as LPARAM,
</code_context>
<issue_to_address>
**issue (bug_risk):** 请考虑检查 `EnumWindows` 的返回值,以区分真正的「没有匹配结果」和枚举失败。

如果 `EnumWindows` 调用失败并返回 0,我们目前仍然会报告「No visible window found」,这会掩盖真实的环境/权限错误。请检查其返回值,并在失败时返回一个不同的错误(例如包含 `GetLastError` 的信息),而不是将其视为结果集为空。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,请考虑分享 ✨
帮我变得更有用!请在每条评论上点选 👍 或 👎,我会根据你的反馈改进之后的代码审查。
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/maa-cli/src/run/windows.rs" line_range="20-21" />
<code_context>
+pub(super) fn find_window_by_title(expected_title: &str) -> Result<WindowMatch> {
+    let mut state = EnumState::new(expected_title);
+
+    unsafe {
+        EnumWindows(
+            Some(enum_windows_proc),
+            &mut state as *mut EnumState<'_> as LPARAM,
</code_context>
<issue_to_address>
**issue (bug_risk):** Consider checking the return value of `EnumWindows` to distinguish true "no matches" from an enumeration failure.

If `EnumWindows` fails and returns 0, we currently still report "No visible window found", which hides real environment/permission errors. Please check the return value and, on failure, return a distinct error (e.g., including `GetLastError`) instead of treating it as an empty result set.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +20 to +21
unsafe {
EnumWindows(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): 请考虑检查 EnumWindows 的返回值,以区分真正的「没有匹配结果」和枚举失败。

如果 EnumWindows 调用失败并返回 0,我们目前仍然会报告「No visible window found」,这会掩盖真实的环境/权限错误。请检查其返回值,并在失败时返回一个不同的错误(例如包含 GetLastError 的信息),而不是将其视为结果集为空。

Original comment in English

issue (bug_risk): Consider checking the return value of EnumWindows to distinguish true "no matches" from an enumeration failure.

If EnumWindows fails and returns 0, we currently still report "No visible window found", which hides real environment/permission errors. Please check the return value and, on failure, return a distinct error (e.g., including GetLastError) instead of treating it as an empty result set.

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.

2 participants