Fix: 增强MAAEND账号切换以支持最多5个账号 - #419
Conversation
下拉框展开后改为从"最近"底部扫描到画面底部,替换固定 ROI, 并将 1920/1080 基准帧尺寸与登录表单 ROI 提取为模块常量。
- 点击账号后等待其从下拉列表消失再提交,避免点击未生效时登入错误账号 - 移除展开态恒真的纵坐标过滤,用 account_list_top 单一状态表达展开与否 - 补充下拉框、登录表单与模板匹配的识别结果日志,便于实机排查 - 后四位识别失败时回退前三位匹配,仅接受唯一命中且不用于折叠表单校验 - 选号轮询预算由 30 秒放宽至 90 秒,适配展开态更大的识别区域
审查者指南增强 MAAEND 多账号登录切换流程:通过扩大 OCR 区域、合并账号行、后四位及前三位组合匹配和明确歧义处理,可靠支持最多五个已保存账号;同时以逐帧状态判断、点击防抖和提交前确认降低误选风险,并补充模板/OCR 诊断日志及版本更新。 稳健的 MAAEND 账号切换时序图sequenceDiagram
participant Login as MAAEND登录表单
participant OCR as OCR识别
participant Selector as 账号切换逻辑
Login->>OCR: _read_text(_LOGIN_SCAN_ROI)
OCR-->>Selector: OCRItem列表
Selector->>Selector: _group_rows(items)
Selector->>Selector: _match_account(rows, account_id)
alt 下拉框已展开
alt 找到目标账号
Selector->>Login: _click_box(target)
Selector->>Selector: 等待_ACCOUNT_CLICK_COOLDOWN
else 连续_ACCOUNT_MISSING_FRAMES帧未找到
Selector-->>Login: RuntimeError
end
else 目标未选中
Selector->>Login: _click_box(recent)
end
alt 目标账号连续_SUBMIT_CONFIRM_FRAMES帧确认
Selector->>Login: _click_box(login_button)
else 尚未确认
Selector->>OCR: 继续读取下一帧
end
掩码账号匹配流程图flowchart TD
A[读取账号列表OCR] --> B[_group_rows 合并同一行文本]
B --> C[_match_account 按后四位匹配]
C -->|无候选| D[继续逐帧识别]
C -->|唯一候选| E[选择目标账号]
C -->|多个候选| F{前三位能否唯一消歧}
F -->|能| E
F -->|不能| G[抛出RuntimeError并停止误选]
文件级变更
可能相关的问题
提示与命令与 Sourcery 交互
自定义使用体验访问你的控制面板以:
获取帮助Original review guide in EnglishReviewer's Guide增强 MAAEND 多账号登录切换流程:通过扩大 OCR 区域、合并账号行、后四位及前三位组合匹配和明确歧义处理,可靠支持最多五个已保存账号;同时以逐帧状态判断、点击防抖和提交前确认降低误选风险,并补充模板/OCR 诊断日志及版本更新。 Sequence diagram for robust MAAEND account switchingsequenceDiagram
participant Login as MAAEND登录表单
participant OCR as OCR识别
participant Selector as 账号切换逻辑
Login->>OCR: _read_text(_LOGIN_SCAN_ROI)
OCR-->>Selector: OCRItem列表
Selector->>Selector: _group_rows(items)
Selector->>Selector: _match_account(rows, account_id)
alt 下拉框已展开
alt 找到目标账号
Selector->>Login: _click_box(target)
Selector->>Selector: 等待_ACCOUNT_CLICK_COOLDOWN
else 连续_ACCOUNT_MISSING_FRAMES帧未找到
Selector-->>Login: RuntimeError
end
else 目标未选中
Selector->>Login: _click_box(recent)
end
alt 目标账号连续_SUBMIT_CONFIRM_FRAMES帧确认
Selector->>Login: _click_box(login_button)
else 尚未确认
Selector->>OCR: 继续读取下一帧
end
Flow diagram for masked account matchingflowchart TD
A[读取账号列表OCR] --> B[_group_rows 合并同一行文本]
B --> C[_match_account 按后四位匹配]
C -->|无候选| D[继续逐帧识别]
C -->|唯一候选| E[选择目标账号]
C -->|多个候选| F{前三位能否唯一消歧}
F -->|能| E
F -->|不能| G[抛出RuntimeError并停止误选]
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
您好——我发现了 1 个问题
面向 AI Agent 的提示
请处理本次代码审查中的评论:
## 单独评论
### 评论 1
<location path="app/task/MaaEnd/tools/login.py" line_range="347-361" />
<code_context>
+ # 已点击目标账号,等待下拉框收起后再提交
+ account_clicked = False
+
+ async for frame in _poll_frames(hwnd, 90, activate=False):
+ if account_list_top is not None:
+ # 展开态从“最近”底部扫描到画面底部,避免固定 ROI 截断靠后的账号
+ ocr_items = await asyncio.to_thread(
+ _read_text,
+ frame,
+ (0, account_list_top, _FRAME_WIDTH, _FRAME_HEIGHT),
+ )
+ logger.debug(f"下拉框识别结果: {_format_ocr_items(ocr_items)}")
+ target = _match_account(ocr_items, account_id, allow_prefix=True)
+ if target is None:
+ # 点击后目标从列表消失即下拉框已收起,回到表单确认选中结果
+ if account_clicked:
+ account_list_top = None
+ continue
- if selector_expanded and target is not None:
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 OCR 在某一帧中暂时未识别到已点击的账号时,`_match_account` 会返回 `None`,代码会立即清除 `account_list_top`,即使下拉框仍处于打开状态。下一次迭代会使用收起后的表单路径,并可能在选择实际生效之前点击登录按钮,从而提交之前选中的账号。
**触发条件:** 点击账号后,OCR 识别结果暂时不完整时。
**建议修复:** 在清除 `account_list_top` 并提交之前,应要求有稳定的证据表明下拉框已经关闭且目标账号已被选中——例如连续一帧或多帧检测到登录表单中的目标。
</issue_to_address>Sourcery 评估
需要人工审查。 当前有 1 个发现需要优先处理;如果 OCR 未能识别目标账号的后四位数字,新的唯一前缀回退逻辑可能会选择另一 个具有相同前缀的已保存账号,并使用该账号提交登录表单。回滚可以防止未来再次选错账号,但无法撤销在错误账号会话中已经发生的操作或数据访问。
阻塞性发现:app/task/MaaEnd/tools/login.py:361
请帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会利用反馈来改进审查结果。
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="app/task/MaaEnd/tools/login.py" line_range="347-361" />
<code_context>
+ # 已点击目标账号,等待下拉框收起后再提交
+ account_clicked = False
+
+ async for frame in _poll_frames(hwnd, 90, activate=False):
+ if account_list_top is not None:
+ # 展开态从“最近”底部扫描到画面底部,避免固定 ROI 截断靠后的账号
+ ocr_items = await asyncio.to_thread(
+ _read_text,
+ frame,
+ (0, account_list_top, _FRAME_WIDTH, _FRAME_HEIGHT),
+ )
+ logger.debug(f"下拉框识别结果: {_format_ocr_items(ocr_items)}")
+ target = _match_account(ocr_items, account_id, allow_prefix=True)
+ if target is None:
+ # 点击后目标从列表消失即下拉框已收起,回到表单确认选中结果
+ if account_clicked:
+ account_list_top = None
+ continue
- if selector_expanded and target is not None:
</code_context>
<issue_to_address>
**issue (bug_risk):** When OCR temporarily misses the clicked account for one frame, `_match_account` returns `None` and the code immediately clears `account_list_top`, even though the dropdown is still open. The next iteration uses the collapsed-form path and can click the login button before the selection has actually taken effect, submitting the previously selected account.
**Triggers:** When OCR recognition is transiently incomplete after clicking an account.
**Suggested fix:** Require stable evidence that the dropdown has closed and the target account is selected—such as detecting the login form target for a consecutive frame or frames—before clearing `account_list_top` and submitting.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and if OCR misses the target account's last four digits, the new unique-prefix fallback can select a different saved account with the same prefix and submit the login form for it. Reverting prevents future mis-selections, but it cannot undo any actions or data access that occurred in the wrong account session.
Blocking findings: app/task/MaaEnd/tools/login.py:361
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
@sourcery-ai review |
There was a problem hiding this comment.
你好——我发现了 2 个问题
面向 AI Agent 的提示
请处理本次代码审查中的评论:
## 具体评论
### 评论 1
<location path="app/task/MaaEnd/tools/login.py" line_range="372-377" />
<code_context>
+ if len(candidates) <= 1:
+ return candidates[0] if candidates else None
+
+ # 前三位仅用于收窄候选,不放宽匹配:后四位未命中时不会走到这里
+ prefix = account_id[:3]
+ narrowed = [
+ box for text, box in rows if suffix in text and prefix in text
+ ]
+ if len(narrowed) == 1:
+ logger.warning(f"后四位 {suffix} 命中多行,已按前三位 {prefix} 收窄")
+ return narrowed[0]
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 OCR 只识别出目标账号前三位、未识别出后四位时,`candidates` 为空,函数直接返回 `None`;前三位收窄逻辑只有在后四位已经命中多行时才执行,因此账号下拉列表会始终匹配失败并最终报错。
**Triggers:** 当账号后四位 OCR 不完整但前三位识别成功时。
**Suggested fix:** 在后四位未命中时单独按前三位筛选,并仅在唯一命中时返回该账号。
</issue_to_address>
### 评论 2
<location path="app/task/MaaEnd/tools/login.py" line_range="409" />
<code_context>
+ # 展开态连续识别到账号行但没有目标的帧数,用于区分漏识别与账号确实没保存
+ missing_frames = 0
+
+ async for frame in _poll_frames(hwnd, 40, activate=False):
+ now = asyncio.get_running_loop().time()
+ items = await asyncio.to_thread(_read_text, frame, _LOGIN_SCAN_ROI)
</code_context>
<issue_to_address>
**issue (bug_risk):** 选号流程仍以 `_poll_frames(hwnd, 40, ...)` 为轮询预算,超过 40 秒就退出并抛出“未找到目标账号”,没有实现提交说明中将选号预算放宽到 90 秒的行为;OCR 较慢或下拉列表展开响应较慢时,靠后账号会在 90 秒预算耗尽前被错误判定为失败。
**Triggers:** 当目标账号识别或界面响应耗时超过 40 秒但未超过预期的 90 秒预算时。
**Suggested fix:** 将该轮询超时调整为 90 秒,或提取独立的选号超时常量并与产品预期保持一致。
```suggestion
async for frame in _poll_frames(hwnd, 90, activate=False):
```
</issue_to_address>Sourcery 评估
需要人工审查。 需要先处理 2 个发现;如果 OCR 或账号匹配出现错误,客户端可能会登录并操作错误的已保存账号,从而可能在该账号下执行操作或造成数据变更。回滚可以防止未来再次选错账号,但无法撤销错误会话期间已经执行的活动。
阻塞性发现:app/task/MaaEnd/tools/login.py:377、app/task/MaaEnd/tools/login.py:409
请帮助我变得更有用!请点击每条评论上的 👍 或 👎,我会利用反馈来改进审查结果。
Original comment in English
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="app/task/MaaEnd/tools/login.py" line_range="372-377" />
<code_context>
+ if len(candidates) <= 1:
+ return candidates[0] if candidates else None
+
+ # 前三位仅用于收窄候选,不放宽匹配:后四位未命中时不会走到这里
+ prefix = account_id[:3]
+ narrowed = [
+ box for text, box in rows if suffix in text and prefix in text
+ ]
+ if len(narrowed) == 1:
+ logger.warning(f"后四位 {suffix} 命中多行,已按前三位 {prefix} 收窄")
+ return narrowed[0]
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 OCR 只识别出目标账号前三位、未识别出后四位时,`candidates` 为空,函数直接返回 `None`;前三位收窄逻辑只有在后四位已经命中多行时才执行,因此账号下拉列表会始终匹配失败并最终报错。
**Triggers:** 当账号后四位 OCR 不完整但前三位识别成功时。
**Suggested fix:** 在后四位未命中时单独按前三位筛选,并仅在唯一命中时返回该账号。
</issue_to_address>
### Comment 2
<location path="app/task/MaaEnd/tools/login.py" line_range="409" />
<code_context>
+ # 展开态连续识别到账号行但没有目标的帧数,用于区分漏识别与账号确实没保存
+ missing_frames = 0
+
+ async for frame in _poll_frames(hwnd, 40, activate=False):
+ now = asyncio.get_running_loop().time()
+ items = await asyncio.to_thread(_read_text, frame, _LOGIN_SCAN_ROI)
</code_context>
<issue_to_address>
**issue (bug_risk):** 选号流程仍以 `_poll_frames(hwnd, 40, ...)` 为轮询预算,超过 40 秒就退出并抛出“未找到目标账号”,没有实现提交说明中将选号预算放宽到 90 秒的行为;OCR 较慢或下拉列表展开响应较慢时,靠后账号会在 90 秒预算耗尽前被错误判定为失败。
**Triggers:** 当目标账号识别或界面响应耗时超过 40 秒但未超过预期的 90 秒预算时。
**Suggested fix:** 将该轮询超时调整为 90 秒,或提取独立的选号超时常量并与产品预期保持一致。
```suggestion
async for frame in _poll_frames(hwnd, 90, activate=False):
```
</issue_to_address>Sourcery assessment
Needs a human reviewer. 2 findings to address first, and if OCR or account matching is wrong, the client could log into and operate the wrong saved account, potentially causing actions or data changes under that account. Reverting prevents future mis-selection but cannot undo activity performed during an incorrect session.
Blocking findings: app/task/MaaEnd/tools/login.py:377, app/task/MaaEnd/tools/login.py:409
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| # 前三位仅用于收窄候选,不放宽匹配:后四位未命中时不会走到这里 | ||
| prefix = account_id[:3] | ||
| narrowed = [ | ||
| box for text, box in rows if suffix in text and prefix in text | ||
| ] | ||
| if len(narrowed) == 1: |
There was a problem hiding this comment.
issue (bug_risk): 当 OCR 只识别出目标账号前三位、未识别出后四位时,candidates 为空,函数直接返回 None;前三位收窄逻辑只有在后四位已经命中多行时才执行,因此账号下拉列表会始终匹配失败并最终报错。
Triggers: 当账号后四位 OCR 不完整但前三位识别成功时。
Suggested fix: 在后四位未命中时单独按前三位筛选,并仅在唯一命中时返回该账号。
Original comment in English
issue (bug_risk): 当 OCR 只识别出目标账号前三位、未识别出后四位时,candidates 为空,函数直接返回 None;前三位收窄逻辑只有在后四位已经命中多行时才执行,因此账号下拉列表会始终匹配失败并最终报错。
Triggers: 当账号后四位 OCR 不完整但前三位识别成功时。
Suggested fix: 在后四位未命中时单独按前三位筛选,并仅在唯一命中时返回该账号。
| # 展开态连续识别到账号行但没有目标的帧数,用于区分漏识别与账号确实没保存 | ||
| missing_frames = 0 | ||
|
|
||
| async for frame in _poll_frames(hwnd, 40, activate=False): |
There was a problem hiding this comment.
issue (bug_risk): 选号流程仍以 _poll_frames(hwnd, 40, ...) 为轮询预算,超过 40 秒就退出并抛出“未找到目标账号”,没有实现提交说明中将选号预算放宽到 90 秒的行为;OCR 较慢或下拉列表展开响应较慢时,靠后账号会在 90 秒预算耗尽前被错误判定为失败。
Triggers: 当目标账号识别或界面响应耗时超过 40 秒但未超过预期的 90 秒预算时。
Suggested fix: 将该轮询超时调整为 90 秒,或提取独立的选号超时常量并与产品预期保持一致。
| async for frame in _poll_frames(hwnd, 40, activate=False): | |
| async for frame in _poll_frames(hwnd, 90, activate=False): |
Original comment in English
issue (bug_risk): 选号流程仍以 _poll_frames(hwnd, 40, ...) 为轮询预算,超过 40 秒就退出并抛出“未找到目标账号”,没有实现提交说明中将选号预算放宽到 90 秒的行为;OCR 较慢或下拉列表展开响应较慢时,靠后账号会在 90 秒预算耗尽前被错误判定为失败。
Triggers: 当目标账号识别或界面响应耗时超过 40 秒但未超过预期的 90 秒预算时。
Suggested fix: 将该轮询超时调整为 90 秒,或提取独立的选号超时常量并与产品预期保持一致。
| async for frame in _poll_frames(hwnd, 40, activate=False): | |
| async for frame in _poll_frames(hwnd, 90, activate=False): |
提升 MAAEND 账号切换的多账号支持和登录稳定性。 新功能: - 增强 MAAEND 登录账号切换流程,支持在最多五个已保存账号中可靠选择目标账号并完成登录。 错误修复: - 修复账号下拉列表较长时无法识别靠后账号,以及 OCR 后四位识别不完整导致账号选择失败的问题。 改进: - 改进登录表单与账号列表的 OCR 识别、模板匹配和调试日志,提升多显示器及不同窗口尺寸下的稳定性。 构建: - 更新版本信息。 <details> <summary>Original summary in English</summary> 增强 MAAEND 多账号登录切换能力,提升目标账号识别和登录流程的稳定性。 新功能: - 增强 MAAEND 登录账号切换,可靠支持从最多五个已保存账号中选择目标账号并完成登录。 错误修复: - 修复长账号下拉列表中靠后账号无法识别,以及账号后四位 OCR 不完整导致选择失败的问题。 改进: - 提升登录表单和账号列表在不同窗口尺寸及多显示器环境下的识别与交互稳定性,并补充模板匹配和 OCR 调试日志。 构建: - 更新应用版本信息。 <details> <summary>Original summary in English</summary> 增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。 新功能: - 增强 MAAEND 登录账号切换,支持从最多五个已保存账号中可靠选择目标账号并完成登录。 错误修复: - 修复长账号列表中靠后账号无法识别,以及账号后四位 OCR 识别不完整导致选择失败的问题。 改进: - 提升登录表单和账号列表在不同窗口尺寸及多显示器环境下的识别与交互稳定性,并增加模板匹配和 OCR 调试日志。 构建: - 更新应用版本信息。 <details> <summary>Original summary in English</summary> 增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。 New Features: - 增强 MAAEND 登录账号切换,支持从最多五个已保存账号中可靠选择目标账号并完成登录。 Bug Fixes: - 修复长账号列表中靠后账号无法识别以及账号后四位 OCR 不完整导致选择失败的问题。 Enhancements: - 提升登录表单和账号列表在不同窗口尺寸及多显示器环境下的识别与交互稳定性,并增加模板匹配和 OCR 调试日志。 Build: - 更新应用版本信息。 </details> <details> <summary>Original summary in English</summary> 增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。 新功能: - 增强 MAAEND 登录账号切换,支持从最多五个已保存账号中可靠选择目标账号并完成登录。 错误修复: - 修复长账号列表中靠后账号无法识别,以及账号后四位 OCR 识别不完整导致选择失败的问题。 改进: - 提升登录表单和账号列表在不同窗口尺寸及多显示器环境下的识别与交互稳定性,并增加模板匹配和 OCR 调试日志。 构建: - 更新应用版本信息。 <details> <summary>Original summary in English</summary> 增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。 New Features: - 增强 MAAEND 登录账号切换,支持从最多五个已保存账号中可靠选择目标账号并完成登录。 Bug Fixes: - 修复长账号列表中靠后账号无法识别以及账号后四位 OCR 不完整导致选择失败的问题。 Enhancements: - 提升登录表单和账号列表在不同窗口尺寸及多显示器环境下的识别与交互稳定性,并增加模板匹配和 OCR 调试日志。 Build: - 更新应用版本信息。 </details> </details> </details> </details>
Sourcery 摘要
提升 MAAEND 账号切换的多账号支持和登录稳定性。
新功能:
错误修复:
改进:
构建:
Original summary in English
Sourcery 摘要
增强 MAAEND 多账号登录切换能力,提升目标账号识别和登录流程的稳定性。
新功能:
错误修复:
改进:
构建:
Original summary in English
Sourcery 摘要
增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。
新功能:
错误修复:
改进:
构建:
Original summary in English
Summary by Sourcery
增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。
New Features:
Bug Fixes:
Enhancements:
Build:
Original summary in English
Sourcery 摘要
增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。
新功能:
错误修复:
改进:
构建:
Original summary in English
Summary by Sourcery
增强 MAAEND 多账号登录切换的可靠性,确保目标账号在登录提交前得到准确识别和确认。
New Features:
Bug Fixes:
Enhancements:
Build: