Skip draft vision when Dota 2 is not the foreground window.

Prevents Alt-Tab desktop frames from advancing confirm streaks or burning strategy_tail polls.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
voson
2026-07-26 12:20:54 +08:00
co-authored by Cursor
parent 7dc3e515e9
commit e567a5cdfc
6 changed files with 101 additions and 11 deletions
+47
View File
@@ -21,6 +21,53 @@ import numpy as np
RAW_DIR = Path(__file__).parent / "samples" / "raw"
GSI_JSONL = "gsi.jsonl"
DOTA_EXE = "dota2.exe"
def is_dota_foreground() -> bool:
"""True when the foreground process is dota2.exe.
Uses Win32 GetForegroundWindow + QueryFullProcessImageNameW. On non-Windows
or if the probe fails, returns True so recognition is not blocked.
"""
if sys.platform != "win32":
return True
try:
import ctypes
from ctypes import wintypes
user32 = ctypes.WinDLL("user32", use_last_error=True)
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
hwnd = user32.GetForegroundWindow()
if not hwnd:
return False
pid = wintypes.DWORD()
user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
if not pid.value:
return False
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
handle = kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pid.value)
if not handle:
return False
try:
buf = ctypes.create_unicode_buffer(32768)
size = wintypes.DWORD(len(buf))
# QueryFullProcessImageNameW(hProcess, dwFlags, lpExeName, lpdwSize)
QueryFullProcessImageNameW = kernel32.QueryFullProcessImageNameW
QueryFullProcessImageNameW.argtypes = [
wintypes.HANDLE, wintypes.DWORD, wintypes.LPWSTR, ctypes.POINTER(wintypes.DWORD)
]
QueryFullProcessImageNameW.restype = wintypes.BOOL
if not QueryFullProcessImageNameW(handle, 0, buf, ctypes.byref(size)):
return False
return Path(buf.value).name.lower() == DOTA_EXE
finally:
kernel32.CloseHandle(handle)
except Exception:
return True
def raw_dir_for_match(match_id: str | None = None) -> Path: