Initial SyncGames tree: agent, Android, deploy, docs.
Session-gated MinIO save sync with AppImage GUI, CLI edit/session flow, and Gitea release helper. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from typing import Callable
|
||||
|
||||
from syncgames.config import GameConfig
|
||||
|
||||
try:
|
||||
import psutil
|
||||
except ImportError: # pragma: no cover
|
||||
psutil = None # type: ignore
|
||||
|
||||
|
||||
def _norm(name: str) -> str:
|
||||
return name.lower().removesuffix(".exe")
|
||||
|
||||
|
||||
def is_game_running(game: GameConfig) -> bool:
|
||||
if psutil is None:
|
||||
return False
|
||||
names = {_norm(n) for n in game.process_names}
|
||||
# Steam AppID heuristic: look for steam apps running with appid in cmdline
|
||||
appid = game.steam_appid
|
||||
for proc in psutil.process_iter(["name", "cmdline"]):
|
||||
try:
|
||||
pname = _norm(proc.info["name"] or "")
|
||||
if names and pname in names:
|
||||
return True
|
||||
if names and any(pname == _norm(n) for n in names):
|
||||
return True
|
||||
cmd = proc.info.get("cmdline") or []
|
||||
joined = " ".join(cmd).lower()
|
||||
if appid and (
|
||||
f"appid={appid}" in joined
|
||||
or f"steam_appid={appid}" in joined
|
||||
or f"AppId={appid}" in joined
|
||||
):
|
||||
return True
|
||||
for n in game.process_names:
|
||||
if n.lower() in joined:
|
||||
return True
|
||||
except (psutil.Error, TypeError):
|
||||
continue
|
||||
return False
|
||||
|
||||
|
||||
def watch_loop(
|
||||
game: GameConfig,
|
||||
on_start: Callable[[], None],
|
||||
on_end: Callable[[], None],
|
||||
*,
|
||||
poll_s: float = 3.0,
|
||||
) -> None:
|
||||
"""Block forever: fire on_start when process appears, on_end when it exits."""
|
||||
was_running = False
|
||||
while True:
|
||||
running = is_game_running(game)
|
||||
if running and not was_running:
|
||||
on_start()
|
||||
elif not running and was_running:
|
||||
# brief settle for flush
|
||||
time.sleep(2.0)
|
||||
on_end()
|
||||
was_running = running
|
||||
time.sleep(poll_s)
|
||||
Reference in New Issue
Block a user