summaryrefslogtreecommitdiff
path: root/raveos-center/raveos_center/gaming.py
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-center/raveos_center/gaming.py')
-rw-r--r--raveos-center/raveos_center/gaming.py272
1 files changed, 272 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/gaming.py b/raveos-center/raveos_center/gaming.py
new file mode 100644
index 0000000..9652958
--- /dev/null
+++ b/raveos-center/raveos_center/gaming.py
@@ -0,0 +1,272 @@
+import os
+import re
+import subprocess
+from pathlib import Path
+
+from raveos_center.muveletek import Lepes, root
+
+KONFIG = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config"))
+KORNYEZET = KONFIG / "environment.d" / "raveos-gaming.conf"
+GAMEMODE_INI = KONFIG / "gamemode.ini"
+GAMESCOPE = ["gamescope", "gamescope-session-git", "gamescope-session-steam-git"]
+MANGOHUD_CONF = KONFIG / "MangoHud" / "MangoHud.conf"
+MANGOHUD_MODOK = [
+ ("", "Alapértelmezett"),
+ ("1", "Csak FPS"),
+ ("2", "Vízszintes sáv"),
+ ("3", "Bővített"),
+ ("4", "Részletes"),
+]
+SCHED_EXT = Path("/sys/kernel/sched_ext")
+PROTON_CACHYOS = "proton-cachyos-slr"
+GAMING_MOD = ["gamemode", "governor", "ntsync", "utemezo"]
+GOV_ALAPBOL = "A rendszer alapból is performance módban fut."
+
+
+def _telepitett():
+ try:
+ kimenet = subprocess.run(["pacman", "-Qq"], capture_output=True, text=True, timeout=30).stdout
+ except (OSError, subprocess.TimeoutExpired):
+ return set()
+ return set(kimenet.split())
+
+
+def _cpufreq():
+ return Path("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor").exists()
+
+
+def _ntsync_beepitett():
+ try:
+ kimenet = subprocess.run(["modinfo", "-F", "filename", "ntsync"], capture_output=True, text=True, timeout=10)
+ except (OSError, subprocess.TimeoutExpired):
+ return False
+ return kimenet.stdout.strip() == "(builtin)"
+
+
+def _rendszer_gov():
+ try:
+ return Path("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor").read_text().strip()
+ except OSError:
+ return ""
+
+
+def _desiredgov():
+ try:
+ sorok = GAMEMODE_INI.read_text(encoding="utf-8").splitlines()
+ except OSError:
+ return None
+ szakasz = ""
+ for sor in sorok:
+ t = sor.strip()
+ if t.startswith("[") and t.endswith("]"):
+ szakasz = t[1:-1].strip()
+ elif szakasz == "general":
+ talalat = re.match(r"desiredgov\s*=\s*(\S+)", t)
+ if talalat:
+ return talalat.group(1)
+ return None
+
+
+def _desiredgov_ir(ertek):
+ try:
+ sorok = GAMEMODE_INI.read_text(encoding="utf-8").splitlines()
+ except FileNotFoundError:
+ sorok = []
+ uj = []
+ szakasz = ""
+ general_volt = False
+ beirva = False
+ for sor in sorok:
+ t = sor.strip()
+ if t.startswith("[") and t.endswith("]"):
+ if szakasz == "general" and not beirva:
+ uj.append(f"desiredgov={ertek}")
+ beirva = True
+ szakasz = t[1:-1].strip()
+ general_volt = general_volt or szakasz == "general"
+ elif szakasz == "general" and re.match(r"desiredgov\s*=", t):
+ if not beirva:
+ uj.append(f"desiredgov={ertek}")
+ beirva = True
+ continue
+ uj.append(sor)
+ if not beirva:
+ if not general_volt:
+ uj.append("[general]")
+ uj.append(f"desiredgov={ertek}")
+ GAMEMODE_INI.parent.mkdir(parents=True, exist_ok=True)
+ ideiglenes = GAMEMODE_INI.with_suffix(".ini.uj")
+ ideiglenes.write_text("\n".join(uj) + "\n", encoding="utf-8")
+ os.replace(ideiglenes, GAMEMODE_INI)
+
+
+def _mangohud_sor():
+ try:
+ return any(s.strip() == "MANGOHUD=1" for s in KORNYEZET.read_text().splitlines())
+ except OSError:
+ return False
+
+
+def _utemezo_allapot():
+ if not SCHED_EXT.is_dir():
+ return {
+ "aktiv": False,
+ "elerheto": False,
+ "megjegyzes": "A futó kernel nem támogatja (sched_ext nélkül fordították).",
+ }
+ try:
+ fut = (SCHED_EXT / "state").read_text().strip() == "enabled"
+ nev = (SCHED_EXT / "root" / "ops").read_text().strip() if fut else ""
+ except OSError:
+ fut, nev = False, ""
+ return {"aktiv": fut, "elerheto": True, "megjegyzes": f"Most fut: {nev}" if nev else ""}
+
+
+def mangohud_mod():
+ try:
+ sorok = MANGOHUD_CONF.read_text(encoding="utf-8").splitlines()
+ except OSError:
+ return ""
+ for sor in sorok:
+ talalat = re.match(r"\s*preset\s*=\s*(-?\d)", sor)
+ if talalat:
+ return talalat.group(1)
+ return ""
+
+
+def mangohud_mod_beallit(mod):
+ try:
+ sorok = MANGOHUD_CONF.read_text(encoding="utf-8").splitlines()
+ except FileNotFoundError:
+ sorok = []
+ sorok = [s for s in sorok if not re.match(r"\s*preset\s*=", s)]
+ if mod:
+ tobbi = [m for m, _ in MANGOHUD_MODOK if m and m != mod]
+ sorok.insert(0, "preset=" + ",".join([mod] + tobbi + ["0"]))
+ if not sorok:
+ MANGOHUD_CONF.unlink(missing_ok=True)
+ return
+ MANGOHUD_CONF.parent.mkdir(parents=True, exist_ok=True)
+ ideiglenes = MANGOHUD_CONF.with_suffix(".conf.uj")
+ ideiglenes.write_text("\n".join(sorok) + "\n", encoding="utf-8")
+ os.replace(ideiglenes, MANGOHUD_CONF)
+
+
+def _proton_cachyos_elerheto():
+ try:
+ return subprocess.run(["pacman", "-Si", PROTON_CACHYOS], capture_output=True, timeout=30).returncode == 0
+ except (OSError, subprocess.TimeoutExpired):
+ return False
+
+
+def _governor_allapot(gamemode):
+ rendszer = _rendszer_gov()
+ kivant = _desiredgov() or "performance"
+ if not gamemode:
+ return {"aktiv": False, "elerheto": False, "megjegyzes": "Ehhez előbb a GameMode-ot kapcsold be."}
+ if not rendszer:
+ return {"aktiv": False, "elerheto": False, "megjegyzes": "Ezen a gépen nincs órajel-szabályozás (pl. virtuális gép)."}
+ if rendszer == "performance":
+ return {"aktiv": True, "elerheto": False, "megjegyzes": GOV_ALAPBOL}
+ return {"aktiv": kivant == "performance", "elerheto": True, "megjegyzes": ""}
+
+
+def allapot():
+ telepitett = _telepitett()
+ gamemode = {"gamemode", "lib32-gamemode"} <= telepitett
+ mangohud = "mangohud" in telepitett
+ ntsync_beepitett = _ntsync_beepitett()
+ return {
+ "gamemode": {"aktiv": gamemode, "elerheto": True, "megjegyzes": "", "root": True},
+ "mangohud": {
+ "aktiv": _mangohud_sor() and mangohud,
+ "elerheto": True,
+ "megjegyzes": "Kijelentkezés és újra bejelentkezés után lép életbe.",
+ "root": not mangohud,
+ },
+ "gamescope": {
+ "aktiv": set(GAMESCOPE) <= telepitett,
+ "elerheto": True,
+ "megjegyzes": "" if "steam" in telepitett else "A Steam munkamenethez a Steam is szükséges.",
+ "root": True,
+ },
+ "governor": dict(_governor_allapot(gamemode), root=False, cpufreq=bool(_rendszer_gov())),
+ "ntsync": {
+ "aktiv": ntsync_beepitett
+ or (Path("/etc/modules-load.d/ntsync.conf").exists() and Path("/dev/ntsync").exists()),
+ "elerheto": not ntsync_beepitett,
+ "megjegyzes": "A RaveOS kernelébe be van építve, mindig aktív." if ntsync_beepitett else "",
+ "root": True,
+ },
+ "utemezo": dict(_utemezo_allapot(), root=True),
+ "proton_cachyos": {
+ "aktiv": PROTON_CACHYOS in telepitett,
+ "elerheto": PROTON_CACHYOS in telepitett or _proton_cachyos_elerheto(),
+ "megjegyzes": "",
+ "root": True,
+ },
+ }
+
+
+def lepesek(azon, be):
+ if azon == "gamemode":
+ csomagok = ["gamemode", "lib32-gamemode"]
+ return [Lepes("GameMode", root("telepit" if be else "eltavolit", *csomagok))], None
+ if azon == "mangohud":
+ lista = []
+ if be and "mangohud" not in _telepitett():
+ lista.append(Lepes("MangoHud telepítése", root("telepit", "mangohud", "lib32-mangohud")))
+ return lista, lambda: _mangohud(be)
+ if azon == "gamescope":
+ return [Lepes("Gamescope session", root("telepit" if be else "eltavolit", *(GAMESCOPE if be else GAMESCOPE[1:])))], None
+ if azon == "governor":
+ return [], lambda: _governor(be)
+ if azon == "ntsync":
+ return [Lepes("NTSync", root("ntsync", "be" if be else "ki"))], None
+ if azon == "utemezo":
+ return [Lepes("Játékra hangolt ütemező", root("utemezo", "be" if be else "ki"))], None
+ if azon == "proton_cachyos":
+ return [Lepes("Proton-CachyOS", root("telepit" if be else "eltavolit", PROTON_CACHYOS))], None
+ return [], None
+
+
+def _mangohud(be):
+ sorok = []
+ try:
+ sorok = [s for s in KORNYEZET.read_text().splitlines() if s.strip() != "MANGOHUD=1"]
+ except OSError:
+ pass
+ if be:
+ sorok.append("MANGOHUD=1")
+ if sorok:
+ KORNYEZET.parent.mkdir(parents=True, exist_ok=True)
+ KORNYEZET.write_text("\n".join(sorok) + "\n")
+ else:
+ KORNYEZET.unlink(missing_ok=True)
+
+
+def _governor(be):
+ rendszer = _rendszer_gov()
+ if be:
+ _desiredgov_ir("performance")
+ elif rendszer and rendszer != "performance":
+ _desiredgov_ir(rendszer)
+
+
+def gaming_mod_valtozasok(adat, be):
+ valtozasok = []
+ gamemode_lesz = adat["gamemode"]["aktiv"] or be
+ for a in GAMING_MOD:
+ if a == "gamemode" and not be:
+ continue
+ if a == "governor":
+ elerheto = gamemode_lesz and adat[a]["cpufreq"] and adat[a]["megjegyzes"] != GOV_ALAPBOL
+ else:
+ elerheto = adat[a]["elerheto"]
+ if elerheto and adat[a]["aktiv"] != be:
+ valtozasok.append((a, be))
+ return valtozasok
+
+
+def gaming_mod_aktiv(adat):
+ return all(adat[a]["aktiv"] for a in GAMING_MOD if adat[a]["elerheto"] or adat[a]["aktiv"])