Added server status and server selection dropdown.

This commit is contained in:
2026-08-30 22:15:32 +02:00
parent 562c924809
commit bc87f10661
3 changed files with 513 additions and 50 deletions

View File

@@ -7,19 +7,22 @@ from datetime import datetime
import hashlib
import json
import os
from pathlib import Path
from pathlib import Path, PurePosixPath
import platform
import shlex
import shutil
import sys
from typing import Mapping, Sequence
from .command import CommandOutcome, CommandRunner, OutputLineFilter
from .depot import DEFAULT_DEPOT_START_OPTION, DepotStartOption
from .gamebox import build_gamebox_command
from .paths import AppPaths
from .settings import Settings
WINDOWS_GAME_EXE = r"C:\Program Files (x86)\Pristontale EU\Game.exe"
WINDOWS_GAME_DIRECTORY = r"C:\Program Files (x86)\Pristontale EU"
WINDOWS_GAME_EXE = rf"{WINDOWS_GAME_DIRECTORY}\Game.exe"
NATIVE_D3D43_DLLS = ("d3dx9_43", "d3dcompiler_43")
DXVK_D3D9_OVERRIDE = "native,builtin"
DLL_OVERRIDES_KEY = r"HKCU\Software\Wine\DllOverrides"
@@ -293,6 +296,7 @@ def run_game(
selection: RuntimeSelection,
runner: CommandRunner,
*,
start_option: DepotStartOption = DEFAULT_DEPOT_START_OPTION,
use_gamebox: bool = True,
timeout_seconds: float = 12 * 60 * 60,
check: bool = True,
@@ -301,11 +305,15 @@ def run_game(
) -> CommandOutcome:
if not paths.runtime_view.is_dir() and not runner.dry_run:
raise RuntimeErrorPT("runtime view is missing; prepare the game first")
native_executable, windows_executable, game_arguments = _game_start_command(
paths,
start_option,
)
if selection.kind == "umu":
game_command = [
selection.executable,
str(paths.runtime_view / "Game.exe"),
"PTEU_REBORN",
native_executable,
*game_arguments,
]
environment = _umu_environment(paths)
elif selection.kind == "proton7-container":
@@ -313,8 +321,8 @@ def run_game(
raise RuntimeErrorPT("Proton script path is missing")
game_command = [
selection.executable,
str(paths.runtime_view / "Game.exe"),
"PTEU_REBORN",
native_executable,
*game_arguments,
]
environment = _umu_proton7_environment(
paths,
@@ -330,8 +338,8 @@ def run_game(
"ptlinux.proton_compat",
selection.proton_path,
"runinprefix",
WINDOWS_GAME_EXE,
"PTEU_REBORN",
windows_executable,
*game_arguments,
]
environment = _proton_environment(
paths,
@@ -356,6 +364,57 @@ def run_game(
)
def _game_start_command(
paths: AppPaths,
option: DepotStartOption,
) -> tuple[str, str, tuple[str, ...]]:
relative = PurePosixPath(option.path)
if (
relative.is_absolute()
or not relative.parts
or any(part in {"", ".", ".."} for part in relative.parts)
or relative.suffix.casefold() != ".exe"
):
raise RuntimeErrorPT(f"invalid realm executable path: {option.path!r}")
try:
arguments = tuple(shlex.split(option.arguments))
except ValueError as exc:
raise RuntimeErrorPT(
f"invalid launch arguments for realm {option.name}: {exc}"
) from exc
if not arguments:
raise RuntimeErrorPT(f"realm {option.name} has no launch arguments")
native = str(_resolve_runtime_path_case(paths.runtime_view, relative))
windows_relative = "\\".join(relative.parts)
return native, rf"{WINDOWS_GAME_DIRECTORY}\{windows_relative}", arguments
def _resolve_runtime_path_case(root: Path, relative: PurePosixPath) -> Path:
"""Match Windows manifest casing against the case-sensitive runtime view."""
direct = root.joinpath(*relative.parts)
if direct.exists():
return direct
cursor = root
for part in relative.parts:
if not cursor.is_dir():
return direct
try:
matches = tuple(
entry for entry in cursor.iterdir() if entry.name.casefold() == part.casefold()
)
except OSError:
return direct
if not matches:
return direct
if len(matches) > 1:
raise RuntimeErrorPT(
f"realm executable path has ambiguous casing: {relative.as_posix()}"
)
cursor = matches[0]
return cursor
def run_proton_prefix_command(
paths: AppPaths,
selection: RuntimeSelection,