-
Notifications
You must be signed in to change notification settings - Fork 24
feat: 添加游戏意外退出尝试重启逻辑 #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: 添加游戏意外退出尝试重启逻辑 #77
Conversation
## **Summary**
This Pull Request introduces a new feature to detect **`Arknights`** game crashes on macOS using Optical Character Recognition (OCR) against the system's Problem Reporter window.
The core addition is the **`ProblemReporterScanner`**, which periodically checks the screen for the crash report window and uses OCR to confirm if the reported process is related to the game.
Alongside the detection logic, a new user preference is implemented: **`autoRestartGameOnCrash`**. When this setting is enabled and a crash is detected, the `MaaToolClient` logic is triggered to automatically restart the game, significantly improving the user experience during unattended operation.
This change provides a robust, platform-specific solution for high-fidelity crash detection, allowing the application to autonomously recover and continue operation, thus enhancing the overall stability and reliability of the automation tool.
### **Key Changes**
1. **New Feature:** Introduced **`ProblemReporterScanner`** for macOS-specific crash detection using OCR on the Problem Reporter window.
2. **User Preference:** Added new setting `autoRestartGameOnCrash` to store the user's preference for automatic game restart upon crash detection.
3. **UI Integration:** Added a corresponding option to the user settings interface.
4. **Logic Integration:**
* Updated **`MaaToolClient`** to incorporate the new crash detection logic and initiate the game restart process when the setting is enabled.
* Updated **`MAAViewModel`** to handle the new setting storage, retrieval, and UI state synchronization.
-----
-----
## **摘要**
本次拉取请求(PR)引入了一项新功能,通过对系统**“问题报告”**窗口执行光学字符识别(OCR),来检测 macOS 上的 **《明日方舟》** 游戏崩溃。
核心新增部分是 **`ProblemReporterScanner`**,它会周期性地检查屏幕上的崩溃报告窗口,并利用 OCR 确认报告的进程是否与游戏相关。
与检测逻辑同时,我们实现了一个新的用户偏好设置:**`autoRestartGameOnCrash`**。当此设置启用且检测到崩溃时,将触发 `MaaToolClient` 逻辑来自动重启游戏,从而显著改善无人值守操作期间的用户体验。
本次更改提供了一个健壮的、针对特定平台的解决方案,用于高精度的崩溃检测。它允许应用程序在检测到崩溃后自动恢复并继续运行,从而增强了自动化工具的整体稳定性和可靠性。
### **主要更改**
1. **新功能:** 引入 **`ProblemReporterScanner`**,使用 OCR 技术对“问题报告”窗口进行扫描,实现 macOS 特有的崩溃检测。
2. **用户偏好设置:** 新增 `autoRestartGameOnCrash` 设置项,用于存储用户关于检测到崩溃时是否自动重启游戏的偏好。
3. **界面集成:** 在用户设置界面中添加了相应选项。
4. **逻辑集成:**
* 更新 **`MaaToolClient`**,纳入新的崩溃检测逻辑,并在设置启用时启动游戏重启流程。
* 更新 **`MAAViewModel`**,处理新设置的存储、检索和 UI 状态同步。
Reviewer's Guide通过扫描系统“问题报告程序”窗口并进行 OCR,实现了 Arknights 在 macOS 上的崩溃检测与自动重启路径,将其接入 MaaToolClient 的连接处理流程,并在 MAAViewModel 中持久化为可由用户切换的设置,同时在连接设置 UI 中展示该选项。 File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAdds a macOS-specific crash detection and auto-restart path for Arknights by scanning the system Problem Reporter window via OCR, wiring it into MaaToolClient connection handling and exposing a user-toggleable setting persisted in MAAViewModel and surfaced in the connection settings UI. 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你好,我已经审阅了你的改动,这里是一些反馈:
- 在
MaaToolClient.stateUpdateHandler中,当allowscanreporter为 true 且ProblemReporterScanner.checkArknights()返回 false 时,不会调用connection.restart(),因此客户端可能一直卡在.waiting状态;建议在未检测到崩溃窗口时,确保会重启连接。 .waiting分支里的Task { ... }打破了现有的结构化流程,并将 actor 隔离与MainActor.run混合使用;你很可能可以把这段逻辑保留在 actor 上下文内(不再创建非结构化任务),直接await扫描器,然后按条件选择重启或重新拉起。- 在
stopGame()中,MaaToolClient使用allowscanreporter: allowscanreporter和一个任意的appBundleURL 进行初始化;如果这里只是为了终止游戏,建议传递allowscanreporter: false,或者将终止逻辑与“崩溃后重启”的路径解耦,以避免误用无效的 bundle URL。
面向 AI Agent 的提示词
Please address the comments from this code review:
## Overall Comments
- 在 `MaaToolClient.stateUpdateHandler` 中,当 `allowscanreporter` 为 true 且 `ProblemReporterScanner.checkArknights()` 返回 false 时,不会调用 `connection.restart()`,因此客户端可能一直卡在 `.waiting` 状态;建议在未检测到崩溃窗口时,确保会重启连接。
- `.waiting` 分支里的 `Task { ... }` 打破了现有的结构化流程,并将 actor 隔离与 `MainActor.run` 混合使用;你很可能可以把这段逻辑保留在 actor 上下文内(不再创建非结构化任务),直接 `await` 扫描器,然后按条件选择重启或重新拉起。
- 在 `stopGame()` 中,`MaaToolClient` 使用 `allowscanreporter: allowscanreporter` 和一个任意的 `appBundle` URL 进行初始化;如果这里只是为了终止游戏,建议传递 `allowscanreporter: false`,或者将终止逻辑与“崩溃后重启”的路径解耦,以避免误用无效的 bundle URL。
## Individual Comments
### Comment 1
<location> `MeoAsstMac/Core/MaaToolClient.swift:54-63` </location>
<code_context>
try? await Task.sleep(for: .seconds(0.5))
- connection.restart()
+ // 开启一个新的异步任务
+ Task {
+ if allowscanreporter {
+ let isFound = await ProblemReporterScanner.checkArknights()
+
+ if isFound {
+ print("成功!在【问题报告程序】中发现了 'Arknights'")
+ try await NSWorkspace.shared.openApplication(at: appBundle, configuration: .init())
+ }
+ } else {
+ await MainActor.run {
+ self.connection.restart()
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** 当 `allowscanreporter` 为 true 且未检测到 `Arknights` 时,连接不会被重启。
在之前的逻辑中,`.waiting` 始终会导致调用 `connection.restart()`。现在,当 `allowscanreporter` 为 `true` 且 `checkArknights()` 返回 `false` 时,不会调用 `connection.restart()`,因此连接可能会无限期地停留在 `.waiting` 状态。请确保在 `allowscanreporter == true` 的路径中,当未找到 reporter 窗口或 OCR 不匹配时也会重启连接(例如,在 `!isFound` 分支中调用 `connection.restart()`)。
</issue_to_address>
### Comment 2
<location> `MeoAsstMac/Core/MaaToolClient.swift:63-64` </location>
<code_context>
+ try await NSWorkspace.shared.openApplication(at: appBundle, configuration: .init())
+ }
+ } else {
+ await MainActor.run {
+ self.connection.restart()
+ }
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** 在 `MainActor` 中重启 `NWConnection` 与 `MaaToolClient` 的 actor 隔离状态相冲突。
在 `Task {}` 内,你切换到 `MainActor` 去调用 `self.connection.restart()`,但 `connection` 是隔离在 `MaaToolClient` actor 内的。这样会破坏 actor 隔离,并带来并发问题风险。相反,应当直接在 actor 中调用 `await self.connection.restart()`,只在需要与 `restart()` 分离的 UI/主线程工作时才使用 `MainActor`。
</issue_to_address>
### Comment 3
<location> `MeoAsstMac/Model/MAAViewModel.swift:699` </location>
<code_context>
func stopGame() async throws {
- guard let client = await MaaToolClient(address: connectionAddress) else { return }
+ guard let client = await MaaToolClient(address: connectionAddress, allowscanreporter: allowscanreporter, appBundle: URL(fileURLWithPath: "/Users")) else { return }
try await client.terminate()
}
</code_context>
<issue_to_address>
**issue (bug_risk):** 在停止游戏时传入 `/Users` 作为 `appBundle` 不一致且可能导致意外的启动行为。
`startGame()` 会将真实的 `appBundle` 传给 `MaaToolClient`,但 `stopGame()` 现在使用的是 `URL(fileURLWithPath: "/Users")`。如果 `allowscanreporter` 为 true 且连接进入 `.waiting` 状态,客户端可能会使用这个无效的 bundle 调用 `openApplication(at: appBundle)`,从而引发错误或异常行为。对于停止逻辑,要么在两个路径中一致地传递正确的 bundle,要么在此路径中禁用 reporter 行为(例如使用 `allowscanreporter: false`)。
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈持续改进审查质量。
Original comment in English
Hey there - I've reviewed your changes - here's some feedback:
- In
MaaToolClient.stateUpdateHandler, whenallowscanreporteris true andProblemReporterScanner.checkArknights()returns false,connection.restart()is never called, so the client can remain stuck in the.waitingstate; consider ensuring the connection is restarted when no crash window is detected. - The
Task { ... }inside the.waitingcase breaks the existing structured flow and mixes actor isolation withMainActor.run; you can likely keep this logic within the actor context (without spawning an unstructured task) by directlyawait-ing the scanner and then conditionally restarting or relaunching. - In
stopGame(),MaaToolClientis initialized withallowscanreporter: allowscanreporterand an arbitraryappBundleURL; if the intent is only to terminate the game, consider passingallowscanreporter: falseor otherwise decoupling termination logic from the restart-on-crash path to avoid accidentally using a bogus bundle URL.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `MaaToolClient.stateUpdateHandler`, when `allowscanreporter` is true and `ProblemReporterScanner.checkArknights()` returns false, `connection.restart()` is never called, so the client can remain stuck in the `.waiting` state; consider ensuring the connection is restarted when no crash window is detected.
- The `Task { ... }` inside the `.waiting` case breaks the existing structured flow and mixes actor isolation with `MainActor.run`; you can likely keep this logic within the actor context (without spawning an unstructured task) by directly `await`-ing the scanner and then conditionally restarting or relaunching.
- In `stopGame()`, `MaaToolClient` is initialized with `allowscanreporter: allowscanreporter` and an arbitrary `appBundle` URL; if the intent is only to terminate the game, consider passing `allowscanreporter: false` or otherwise decoupling termination logic from the restart-on-crash path to avoid accidentally using a bogus bundle URL.
## Individual Comments
### Comment 1
<location> `MeoAsstMac/Core/MaaToolClient.swift:54-63` </location>
<code_context>
try? await Task.sleep(for: .seconds(0.5))
- connection.restart()
+ // 开启一个新的异步任务
+ Task {
+ if allowscanreporter {
+ let isFound = await ProblemReporterScanner.checkArknights()
+
+ if isFound {
+ print("成功!在【问题报告程序】中发现了 'Arknights'")
+ try await NSWorkspace.shared.openApplication(at: appBundle, configuration: .init())
+ }
+ } else {
+ await MainActor.run {
+ self.connection.restart()
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** When `allowscanreporter` is true and `Arknights` is not detected, the connection is never restarted.
In the previous logic, `.waiting` always led to `connection.restart()`. Now, when `allowscanreporter` is `true` and `checkArknights()` returns `false`, `connection.restart()` is never called, so the connection can remain in `.waiting` indefinitely. Please ensure the `allowscanreporter == true` path also restarts the connection when the reporter window is not found or OCR does not match (e.g., call `connection.restart()` in the `!isFound` case).
</issue_to_address>
### Comment 2
<location> `MeoAsstMac/Core/MaaToolClient.swift:63-64` </location>
<code_context>
+ try await NSWorkspace.shared.openApplication(at: appBundle, configuration: .init())
+ }
+ } else {
+ await MainActor.run {
+ self.connection.restart()
+ }
+ }
</code_context>
<issue_to_address>
**issue (bug_risk):** Restarting the `NWConnection` from `MainActor` conflicts with the actor-isolated `MaaToolClient` state.
Inside `Task {}` you switch to `MainActor` to call `self.connection.restart()`, but `connection` is isolated to the `MaaToolClient` actor. This violates actor isolation and risks concurrency issues. Instead, call `await self.connection.restart()` directly from the actor, and only use `MainActor` for UI/main-thread work that must be separate from `restart()`.
</issue_to_address>
### Comment 3
<location> `MeoAsstMac/Model/MAAViewModel.swift:699` </location>
<code_context>
func stopGame() async throws {
- guard let client = await MaaToolClient(address: connectionAddress) else { return }
+ guard let client = await MaaToolClient(address: connectionAddress, allowscanreporter: allowscanreporter, appBundle: URL(fileURLWithPath: "/Users")) else { return }
try await client.terminate()
}
</code_context>
<issue_to_address>
**issue (bug_risk):** Passing `/Users` as the `appBundle` when stopping the game is inconsistent and may cause unintended launches.
`startGame()` passes the real `appBundle` to `MaaToolClient`, but `stopGame()` now uses `URL(fileURLWithPath: "/Users")`. If `allowscanreporter` is true and the connection enters `.waiting`, the client may call `openApplication(at: appBundle)` with this invalid bundle, causing an error or unintended behavior. For stopping, either pass the correct bundle consistently or disable the reporter behavior in this path (e.g. `allowscanreporter: false`).
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Summary
This Pull Request introduces a new feature to detect
Arknightsgame crashes on macOS using Optical Character Recognition (OCR) against the system's Problem Reporter window.The core addition is the
ProblemReporterScanner, which periodically checks the screen for the crash report window and uses OCR to confirm if the reported process is related to the game.Alongside the detection logic, a new user preference is implemented:
autoRestartGameOnCrash. When this setting is enabled and a crash is detected, theMaaToolClientlogic is triggered to automatically restart the game, significantly improving the user experience during unattended operation.This change provides a robust, platform-specific solution for high-fidelity crash detection, allowing the application to autonomously recover and continue operation, thus enhancing the overall stability and reliability of the automation tool.
Key Changes
ProblemReporterScannerfor macOS-specific crash detection using OCR on the Problem Reporter window.autoRestartGameOnCrashto store the user's preference for automatic game restart upon crash detection.MaaToolClientto incorporate the new crash detection logic and initiate the game restart process when the setting is enabled.MAAViewModelto handle the new setting storage, retrieval, and UI state synchronization. -----摘要
本次拉取请求(PR)引入了一项新功能,通过对系统**“问题报告”**窗口执行光学字符识别(OCR),来检测 macOS 上的 《明日方舟》 游戏崩溃。
核心新增部分是
ProblemReporterScanner,它会周期性地检查屏幕上的崩溃报告窗口,并利用 OCR 确认报告的进程是否与游戏相关。与检测逻辑同时,我们实现了一个新的用户偏好设置:
autoRestartGameOnCrash。当此设置启用且检测到崩溃时,将触发MaaToolClient逻辑来自动重启游戏,从而显著改善无人值守操作期间的用户体验。本次更改提供了一个健壮的、针对特定平台的解决方案,用于高精度的崩溃检测。它允许应用程序在检测到崩溃后自动恢复并继续运行,从而增强了自动化工具的整体稳定性和可靠性。
主要更改
ProblemReporterScanner,使用 OCR 技术对“问题报告”窗口进行扫描,实现 macOS 特有的崩溃检测。autoRestartGameOnCrash设置项,用于存储用户关于检测到崩溃时是否自动重启游戏的偏好。MaaToolClient,纳入新的崩溃检测逻辑,并在设置启用时启动游戏重启流程。MAAViewModel,处理新设置的存储、检索和 UI 状态同步。Summary by Sourcery
为 Arknights 添加 macOS 特定的崩溃检测功能,并在设置中启用时自动重启游戏。
新功能:
ProblemReporterScanner工具,通过对 macOS “问题报告”窗口进行 OCR 来检测 Arknights 的崩溃。增强内容:
MaaToolClient的连接处理以及游戏启动/停止流程中。AppStorage在MAAViewModel中持久化新的“崩溃自动重启”偏好设置,并通过连接设置界面对其进行暴露;在启用时请求屏幕录制权限。Original summary in English
Summary by Sourcery
Add macOS-specific crash detection for Arknights and automatically restart the game when enabled in settings.
New Features:
Enhancements: