Added server status and server selection dropdown.
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user