fear: PC 端支持 完成后退出明日方舟 (#16351)

* fix: 修复pc端任务完成后勾选自动关闭游戏但无法关闭的问题

* fix: IsWindow检查与WM_CLOSE关闭

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Jin Zhaonian
2026-04-27 01:36:19 +08:00
committed by GitHub
parent b65b37fba8
commit 60cbc68e59

View File

@@ -135,8 +135,72 @@ bool Win32Controller::start_game(const std::string& client_type [[maybe_unused]]
bool Win32Controller::stop_game(const std::string& client_type [[maybe_unused]])
{
Log.warn("stop_game is not supported on Win32Controller");
return false;
LogTraceFunction;
if (!m_hwnd) {
Log.info("No window handle available, game may already be closed");
return true;
}
HWND hwnd = static_cast<HWND>(m_hwnd);
if (!IsWindow(hwnd)) {
Log.info("Invalid or stale window handle, game may already be closed, hwnd:", m_hwnd);
return true;
}
DWORD pid = 0;
DWORD tid = GetWindowThreadProcessId(hwnd, &pid);
if (tid == 0) {
DWORD error = GetLastError();
Log.error("Failed to get thread/process id from hwnd, hwnd:", m_hwnd, "last_error:", error);
return false;
}
if (pid == 0) {
Log.error("Failed to get process id from hwnd, hwnd:", m_hwnd);
return false;
}
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid);
if (!hProcess) {
DWORD error = GetLastError();
Log.error("Failed to open process, pid:", pid, "last_error:", error);
return false;
}
if (PostMessage(hwnd, WM_CLOSE, 0, 0)) {
DWORD wait_result = WaitForSingleObject(hProcess, 5000);
if (wait_result == WAIT_OBJECT_0) {
CloseHandle(hProcess);
Log.info("Game process closed gracefully, pid:", pid);
return true;
}
}
BOOL ok = TerminateProcess(hProcess, 0);
if (!ok) {
DWORD error = GetLastError();
CloseHandle(hProcess);
Log.error("Failed to terminate process, pid:", pid, "last_error:", error);
return false;
}
DWORD wait_result = WaitForSingleObject(hProcess, 5000);
CloseHandle(hProcess);
if (wait_result == WAIT_TIMEOUT) {
Log.error("Terminate process timed out, pid:", pid);
return false;
}
if (wait_result == WAIT_FAILED) {
DWORD error = GetLastError();
Log.error("Wait for process termination failed, pid:", pid, "last_error:", error);
return false;
}
Log.info("Game process terminated, pid:", pid);
return true;
}
bool Win32Controller::click(const Point& p)