200 lines
7.8 KiB
Python
200 lines
7.8 KiB
Python
import os.path
|
|
import platform as pf
|
|
from logging import getLogger
|
|
from typing import Tuple
|
|
|
|
from PyQt5.QtCore import Qt, pyqtSlot
|
|
from PyQt5.QtGui import QShowEvent
|
|
from PyQt5.QtWidgets import QFileDialog, QComboBox, QLineEdit
|
|
from legendary.models.game import Game, InstalledGame
|
|
|
|
from rare.components.tabs.settings.widgets.env_vars import EnvVars
|
|
from rare.components.tabs.settings.widgets.game import GameSettingsBase
|
|
from rare.components.tabs.settings.widgets.launch import LaunchSettingsBase
|
|
from rare.components.tabs.settings.widgets.overlay import DxvkSettings
|
|
from rare.components.tabs.settings.widgets.wrappers import WrapperSettings
|
|
from rare.models.game import RareGame
|
|
from rare.utils import config_helper as config
|
|
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
|
|
|
if pf.system() != "Windows":
|
|
from rare.components.tabs.settings.widgets.wine import WineSettings
|
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
from rare.components.tabs.settings.widgets.proton import ProtonSettings
|
|
from rare.components.tabs.settings.widgets.overlay import MangoHudSettings
|
|
|
|
logger = getLogger("GameSettings")
|
|
|
|
|
|
class GameWrapperSettings(WrapperSettings):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent=parent)
|
|
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameLaunchSettings(LaunchSettingsBase):
|
|
|
|
def __init__(self, parent=None):
|
|
super(GameLaunchSettings, self).__init__(GameWrapperSettings, parent=parent)
|
|
|
|
self.game: Game = None
|
|
self.igame: InstalledGame = None
|
|
|
|
self.skip_update_combo = QComboBox(self)
|
|
self.skip_update_combo.addItem(self.tr("Default"), None)
|
|
self.skip_update_combo.addItem(self.tr("No"), "false")
|
|
self.skip_update_combo.addItem(self.tr("Yes"), "true")
|
|
self.skip_update_combo.currentIndexChanged.connect(self.__skip_update_changed)
|
|
|
|
self.offline_combo = QComboBox(self)
|
|
self.offline_combo.addItem(self.tr("Default"), None)
|
|
self.offline_combo.addItem(self.tr("No"), "false")
|
|
self.offline_combo.addItem(self.tr("Yes"), "true")
|
|
self.offline_combo.currentIndexChanged.connect(self.__offline_changed)
|
|
|
|
self.override_exe_edit = PathEdit(
|
|
file_mode=QFileDialog.ExistingFile,
|
|
name_filters=["*.exe", "*.app"],
|
|
placeholder=self.tr("Relative path to the replacement executable"),
|
|
edit_func=self.__override_exe_edit_callback,
|
|
save_func=self.__override_exe_save_callback,
|
|
parent=self
|
|
)
|
|
|
|
self.launch_params_edit = QLineEdit(self)
|
|
self.launch_params_edit.setPlaceholderText(self.tr("Game specific command line arguments"))
|
|
self.launch_params_edit.textChanged.connect(self.__launch_params_changed)
|
|
|
|
self.main_layout.insertRow(0, self.tr("Skip update check"), self.skip_update_combo)
|
|
self.main_layout.insertRow(1, self.tr("Offline mode"), self.offline_combo)
|
|
self.main_layout.insertRow(2, self.tr("Launch parameters"), self.launch_params_edit)
|
|
self.main_layout.insertRow(3, self.tr("Override executable"), self.override_exe_edit)
|
|
|
|
def showEvent(self, a0: QShowEvent):
|
|
if a0.spontaneous():
|
|
return super().showEvent(a0)
|
|
|
|
skip_update = config.get_option(self.app_name, "skip_update_check", fallback=None)
|
|
self.skip_update_combo.setCurrentIndex(self.offline_combo.findData(skip_update, Qt.UserRole))
|
|
|
|
offline = config.get_option(self.app_name, "offline", fallback=None)
|
|
self.offline_combo.setCurrentIndex(self.offline_combo.findData(offline, Qt.UserRole))
|
|
|
|
if self.igame:
|
|
self.offline_combo.setEnabled(self.igame.can_run_offline)
|
|
self.override_exe_edit.set_root(self.igame.install_path)
|
|
else:
|
|
self.offline_combo.setEnabled(False)
|
|
self.override_exe_edit.set_root("")
|
|
|
|
launch_params = config.get_option(self.app_name, "start_params", "")
|
|
self.launch_params_edit.setText(launch_params)
|
|
|
|
override_exe = config.get_option(self.app_name, "override_exe", fallback="")
|
|
self.override_exe_edit.setText(override_exe)
|
|
|
|
return super().showEvent(a0)
|
|
|
|
@pyqtSlot(int)
|
|
def __skip_update_changed(self, index):
|
|
data = self.skip_update_combo.itemData(index, Qt.UserRole)
|
|
config.save_option(self.app_name, "skip_update_check", data)
|
|
|
|
def __override_exe_edit_callback(self, path: str) -> Tuple[bool, str, int]:
|
|
if not path or self.igame is None:
|
|
return True, path, IndicatorReasonsCommon.VALID
|
|
if not os.path.isabs(path):
|
|
path = os.path.join(self.igame.install_path, path)
|
|
# lk: Compare paths through python's commonpath because in windows we
|
|
# cannot compare as strings
|
|
# antonia disapproves of this
|
|
if os.path.commonpath([self.igame.install_path, path]) != self.igame.install_path:
|
|
return False, self.igame.install_path, IndicatorReasonsCommon.WRONG_PATH
|
|
if not os.path.exists(path):
|
|
return False, path, IndicatorReasonsCommon.WRONG_PATH
|
|
|
|
if not path.endswith(".exe") and not path.endswith(".app"):
|
|
return False, path, IndicatorReasonsCommon.WRONG_PATH
|
|
path = os.path.relpath(path, self.igame.install_path)
|
|
return True, path, IndicatorReasonsCommon.VALID
|
|
|
|
def __override_exe_save_callback(self, path: str):
|
|
config.save_option(self.app_name, "override_exe", path)
|
|
|
|
@pyqtSlot(int)
|
|
def __offline_changed(self, index):
|
|
data = self.skip_update_combo.itemData(index, Qt.UserRole)
|
|
config.save_option(self.app_name, "offline", data)
|
|
|
|
def __launch_params_changed(self, value) -> None:
|
|
config.save_option(self.app_name, "start_params", value)
|
|
|
|
def load_settings(self, rgame: RareGame):
|
|
self.game = rgame.game
|
|
self.igame = rgame.igame
|
|
self.app_name = rgame.app_name
|
|
self.wrappers_widget.load_settings(rgame.app_name)
|
|
|
|
|
|
if pf.system() != "Windows":
|
|
|
|
class GameWineSettings(WineSettings):
|
|
def load_settings(self, app_name):
|
|
self.app_name = app_name
|
|
|
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
|
|
class GameProtonSettings(ProtonSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
class GameMangoHudSettings(MangoHudSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameDxvkSettings(DxvkSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameEnvVars(EnvVars):
|
|
def load_settings(self, app_name):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameSettings(GameSettingsBase):
|
|
def __init__(self, parent=None):
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
GameWineSettings, GameProtonSettings, GameMangoHudSettings,
|
|
parent=parent
|
|
)
|
|
elif pf.system() != "Windows":
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
GameWineSettings,
|
|
parent=parent
|
|
)
|
|
else:
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
parent=parent
|
|
)
|
|
|
|
def load_settings(self, rgame: RareGame):
|
|
self.set_title.emit(rgame.app_title)
|
|
self.app_name = rgame.app_name
|
|
self.launch.load_settings(rgame)
|
|
if pf.system() != "Windows":
|
|
self.wine.load_settings(rgame.app_name)
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
self.proton_tool.load_settings(rgame.app_name)
|
|
self.mangohud.load_settings(rgame.app_name)
|
|
self.dxvk.load_settings(rgame.app_name)
|
|
self.env_vars.load_settings(rgame.app_name)
|