More fixes to support arch distros.

This commit is contained in:
2026-08-28 20:15:32 +02:00
parent d2c66b6316
commit b37b5291ae
5 changed files with 309 additions and 219 deletions

View File

@@ -10,9 +10,9 @@ from pathlib import Path
import platform
import shutil
import sys
from typing import Mapping
from typing import Mapping, Sequence
from .command import CommandOutcome, CommandRunner
from .command import CommandOutcome, CommandRunner, OutputLineFilter
from .gamebox import build_gamebox_command
from .paths import AppPaths
from .settings import Settings
@@ -47,21 +47,52 @@ def select_runtime(
environment: Mapping[str, str] | None = None,
) -> RuntimeSelection:
env = os.environ if environment is None else environment
umu = shutil.which("umu-run", path=env.get("PATH"))
if settings.proton_path:
proton = Path(settings.proton_path).expanduser().resolve()
if not proton.is_file():
raise RuntimeErrorPT(f"configured Proton script does not exist: {proton}")
steam_root = _steam_root_for_proton(proton)
if settings.runtime == "proton7-container":
if not umu:
raise RuntimeErrorPT(
"containerized Proton 7 was requested but umu-run was not found"
)
return RuntimeSelection(
"proton7-container",
umu,
str(proton),
str(steam_root),
)
if settings.runtime == "auto" and umu:
return RuntimeSelection(
"proton7-container",
umu,
str(proton),
str(steam_root),
)
return RuntimeSelection("proton7", sys.executable, str(proton), str(steam_root))
if settings.runtime in {"auto", "proton7"}:
if settings.runtime in {"auto", "proton7", "proton7-container"}:
proton_result = find_steam_proton7(env)
if proton_result is not None:
proton, steam_root = proton_result
if settings.runtime == "proton7-container" or (
settings.runtime == "auto" and umu
):
if not umu:
raise RuntimeErrorPT(
"containerized Proton 7 was requested but umu-run was not found"
)
return RuntimeSelection(
"proton7-container",
umu,
str(proton),
str(steam_root),
)
return RuntimeSelection("proton7", sys.executable, str(proton), str(steam_root))
if settings.runtime == "proton7":
if settings.runtime in {"proton7", "proton7-container"}:
raise RuntimeErrorPT("Steam Proton 7.0 was requested but not found")
if settings.runtime in {"auto", "umu"}:
umu = shutil.which("umu-run")
if umu:
return RuntimeSelection("umu", umu, None, None)
raise RuntimeErrorPT(
@@ -120,7 +151,7 @@ def prepare_game_runtime(
timeout_seconds=1800.0,
)
)
elif selection.kind == "proton7":
elif selection.kind in {"proton7", "proton7-container"}:
if not selection.proton_path or not selection.steam_root:
raise RuntimeErrorPT("incomplete Proton 7 runtime selection")
if not runner.dry_run:
@@ -219,6 +250,10 @@ def run_game(
runner: CommandRunner,
*,
use_gamebox: bool = True,
timeout_seconds: float = 12 * 60 * 60,
check: bool = True,
extra_environment: Mapping[str, str] | None = None,
output_line_filter: OutputLineFilter | None = None,
) -> CommandOutcome:
if not paths.runtime_view.is_dir() and not runner.dry_run:
raise RuntimeErrorPT("runtime view is missing; prepare the game first")
@@ -229,6 +264,19 @@ def run_game(
"PTEU_REBORN",
]
environment = _umu_environment(paths)
elif selection.kind == "proton7-container":
if not selection.proton_path:
raise RuntimeErrorPT("Proton script path is missing")
game_command = [
selection.executable,
str(paths.runtime_view / "Game.exe"),
"PTEU_REBORN",
]
environment = _umu_proton7_environment(
paths,
selection,
synchronization=resolve_proton_sync_mode(settings.proton_sync),
)
else:
if not selection.proton_path:
raise RuntimeErrorPT("Proton script path is missing")
@@ -248,6 +296,8 @@ def run_game(
)
if use_gamebox:
game_command = build_gamebox_command(game_command, settings)
if extra_environment:
environment.update(extra_environment)
environment["PYTHONPATH"] = _runtime_python_path(
os.environ.get("PYTHONPATH"),
)
@@ -255,8 +305,40 @@ def run_game(
game_command,
cwd=paths.runtime_view,
env_overrides=environment,
timeout_seconds=12 * 60 * 60,
timeout_seconds=timeout_seconds,
check=check,
stream_output=True,
output_line_filter=output_line_filter,
)
def run_proton_prefix_command(
paths: AppPaths,
selection: RuntimeSelection,
runner: CommandRunner,
arguments: Sequence[str],
*,
check: bool = True,
timeout_seconds: float = 60.0,
) -> CommandOutcome:
"""Run a maintenance command in the pinned Proton 7 prefix."""
if selection.kind not in {"proton7", "proton7-container"}:
raise RuntimeErrorPT("the login trace requires the pinned Proton 7 runtime")
if not selection.proton_path or not selection.steam_root:
raise RuntimeErrorPT("incomplete Proton 7 runtime selection")
return runner.run(
[
sys.executable,
"-m",
"ptlinux.proton_compat",
selection.proton_path,
"runinprefix",
*arguments,
],
env_overrides=_proton_environment(paths, selection),
timeout_seconds=timeout_seconds,
check=check,
)
@@ -278,6 +360,33 @@ def _umu_environment(paths: AppPaths) -> dict[str, str]:
}
def _umu_proton7_environment(
paths: AppPaths,
selection: RuntimeSelection,
*,
synchronization: str = RUNTIME_DEFAULT_SYNC,
) -> dict[str, str]:
"""Run the retained Proton 7 build inside its Steam Runtime container."""
if not selection.proton_path:
raise RuntimeErrorPT("Proton script path is missing")
environment = {
# UMU expects the Proton compatibility-data root and manages its pfx child.
# Pointing it at proton_prefix would create a nested pfx -> . compatibility
# symlink; compat_data preserves the exact prefix prepared by Proton 7.
"WINEPREFIX": str(paths.compat_data),
"GAMEID": "umu-pristontale-eu",
"STORE": "none",
"PROTONPATH": str(Path(selection.proton_path).parent),
"PROTON_VERB": "waitforexitandrun",
"PROTONFIXES_DISABLE": "1",
"DXVK_STATE_CACHE_PATH": str(paths.dxvk_cache),
"WINEDEBUG": "-all",
}
environment.update(_proton_sync_environment(synchronization))
return environment
def _proton_environment(
paths: AppPaths,
selection: RuntimeSelection,