1
0
Fork 0
mirror of synced 2024-06-02 10:44:40 +12:00
Rare/rare/commands/launcher/lgd_helper.py

189 lines
6.1 KiB
Python
Raw Normal View History

2022-05-14 08:11:24 +12:00
import os
import platform
import shutil
from argparse import Namespace
2022-05-14 08:11:24 +12:00
from dataclasses import dataclass
from logging import getLogger
2022-07-08 09:56:19 +12:00
from typing import List
2022-05-14 08:11:24 +12:00
from PyQt5.QtCore import QProcess, QProcessEnvironment
from legendary.models.game import LaunchParameters
from rare.models.base_game import RareGameSlim
2022-05-14 08:11:24 +12:00
logger = getLogger("Helper")
class GameArgsError(Exception):
pass
class InitArgs(Namespace):
2022-05-14 08:11:24 +12:00
app_name: str
2023-02-13 05:13:05 +13:00
dry_run: bool = False
debug: bool = False
2022-05-14 08:11:24 +12:00
offline: bool = False
skip_update_check: bool = False
2022-05-14 08:11:24 +12:00
wine_prefix: str = ""
wine_bin: str = ""
@classmethod
def from_argparse(cls, args):
return cls(
app_name=args.app_name,
debug=args.debug,
offline=args.offline,
skip_update_check=args.skip_update_check,
wine_bin=args.wine_bin,
wine_prefix=args.wine_pfx,
2023-02-13 05:13:05 +13:00
dry_run=args.dry_run
)
2022-05-14 08:11:24 +12:00
2022-05-21 22:40:21 +12:00
2022-05-14 08:11:24 +12:00
@dataclass
class LaunchArgs:
2022-05-14 08:11:24 +12:00
executable: str = ""
arguments: List[str] = None
working_directory: str = None
environment: QProcessEnvironment = None
2022-05-14 08:11:24 +12:00
pre_launch_command: str = ""
pre_launch_wait: bool = False
is_origin_game: bool = False # only for windows to launch as url
def __bool__(self):
return bool(self.executable)
def get_origin_params(rgame: RareGameSlim, init_args: InitArgs, launch_args: LaunchArgs) -> LaunchArgs:
core = rgame.core
app_name = rgame.app_name
origin_uri = core.get_origin_uri(app_name, init_args.offline)
2022-05-14 08:11:24 +12:00
if platform.system() == "Windows":
launch_args.executable = origin_uri
launch_args.arguments = []
2022-05-14 08:11:24 +12:00
# only set it here true, because on linux it is a launch command like every other game
launch_args.is_origin_game = True
return launch_args
command = core.get_app_launch_command(app_name)
if not os.path.exists(command[0]) and shutil.which(command[0]) is None:
return launch_args
command.append(origin_uri)
env = core.get_app_environment(app_name)
launch_args.environment = QProcessEnvironment.systemEnvironment()
if os.environ.get("container") == "flatpak":
flatpak_command = ["flatpak-spawn", "--host"]
flatpak_command.extend(f"--env={name}={value}" for name, value in env.items())
command = flatpak_command + command
else:
for name, value in env.items():
launch_args.environment.insert(name, value)
2022-05-14 08:11:24 +12:00
launch_args.executable = command[0]
launch_args.arguments = command[1:]
2022-05-14 08:11:24 +12:00
return launch_args
def get_game_params(rgame: RareGameSlim, args: InitArgs, launch_args: LaunchArgs) -> LaunchArgs:
if not args.offline: # skip for update
if not args.skip_update_check and not rgame.core.is_noupdate_game(rgame.app_name):
2022-05-14 08:11:24 +12:00
try:
latest = rgame.core.get_asset(rgame.app_name, rgame.igame.platform, update=False)
2022-05-14 08:11:24 +12:00
except ValueError:
raise GameArgsError("Metadata doesn't exist")
2022-05-14 08:11:24 +12:00
else:
if latest.build_version != rgame.igame.version:
raise GameArgsError("Game is not up to date. Please update first")
if (not rgame.igame or not rgame.igame.executable) and rgame.game is not None:
# override installed game with base title
if rgame.is_launchable_addon:
app_name = rgame.game.metadata['mainGameItem']['releaseInfo'][0]['appId']
rgame.igame = rgame.core.get_installed_game(app_name)
try:
params: LaunchParameters = rgame.core.get_launch_parameters(
app_name=rgame.game.app_name, offline=args.offline, addon_app_name=rgame.igame.app_name
)
except TypeError:
logger.warning("Using older get_launch_parameters due to legendary version")
params: LaunchParameters = rgame.core.get_launch_parameters(
app_name=rgame.game.app_name, offline=args.offline
)
2022-05-14 08:11:24 +12:00
full_params = []
launch_args.environment = QProcessEnvironment.systemEnvironment()
2022-05-14 08:11:24 +12:00
if os.environ.get("container") == "flatpak":
full_params.extend(["flatpak-spawn", "--host"])
full_params.extend(
f"--env={name}={value}"
for name, value in params.environment.items()
)
else:
for name, value in params.environment.items():
launch_args.environment.insert(name, value)
2022-05-14 08:11:24 +12:00
full_params.extend(params.launch_command)
full_params.append(
os.path.join(params.game_directory, params.game_executable)
)
full_params.extend(params.game_parameters)
full_params.extend(params.egl_parameters)
full_params.extend(params.user_parameters)
launch_args.executable = full_params[0]
launch_args.arguments = full_params[1:]
launch_args.working_directory = params.working_directory
2022-05-14 08:11:24 +12:00
return launch_args
def get_launch_args(rgame: RareGameSlim, init_args: InitArgs = None) -> LaunchArgs:
2022-05-14 08:11:24 +12:00
resp = LaunchArgs()
2022-05-14 08:11:24 +12:00
if not rgame.game:
raise GameArgsError(f"Could not find metadata for {rgame.app_title}")
2022-05-14 08:11:24 +12:00
if rgame.is_origin:
init_args.offline = False
2022-05-14 08:11:24 +12:00
else:
if not rgame.is_installed:
raise GameArgsError("Game is not installed or has unsupported format")
2022-05-14 08:11:24 +12:00
if rgame.is_dlc:
raise GameArgsError("Game is a DLC")
if not os.path.exists(rgame.install_path):
raise GameArgsError("Game path does not exist")
2022-05-14 08:11:24 +12:00
if rgame.is_origin:
resp = get_origin_params(rgame, init_args, resp)
2022-05-14 08:11:24 +12:00
else:
resp = get_game_params(rgame, init_args, resp)
2022-05-14 08:11:24 +12:00
pre_cmd, wait = rgame.core.get_pre_launch_command(init_args.app_name)
2022-05-14 08:11:24 +12:00
resp.pre_launch_command, resp.pre_launch_wait = pre_cmd, wait
return resp
def get_configured_process(env: dict = None):
proc = QProcess()
proc.setProcessChannelMode(QProcess.MergedChannels)
2022-05-14 08:11:24 +12:00
proc.readyReadStandardOutput.connect(
lambda: logger.info(
2022-05-14 08:11:24 +12:00
str(proc.readAllStandardOutput().data(), "utf-8", "ignore")
)
)
2022-05-21 22:40:21 +12:00
environment = QProcessEnvironment.systemEnvironment()
2022-05-14 08:11:24 +12:00
if env:
for e in env:
environment.insert(e, env[e])
2022-05-21 22:40:21 +12:00
proc.setProcessEnvironment(environment)
2022-05-14 08:11:24 +12:00
return proc