1
0
Fork 0
mirror of synced 2024-06-03 11:14:42 +12:00

Add game_utils.py to launch and uninstall games

-  All game launch and sync save mechanic is now in game_utils.
- some cleanup
This commit is contained in:
Dummerle 2021-11-01 22:53:04 +01:00
parent a97ea45c7a
commit 65f85f9b3d
No known key found for this signature in database
GPG key ID: AB68CC59CA39F2F1
9 changed files with 255 additions and 221 deletions

View file

@ -12,8 +12,10 @@ from rare.ui.components.tabs.games.games_tab import Ui_GamesTab
from rare.utils import legendary_utils
from rare.utils.extra_widgets import FlowLayout
from rare.utils.utils import get_pixmap, download_image
from .cloud_save_utils import CloudSaveUtils
from .game_info import GameInfoTabs
from .game_info.uninstalled_info import UninstalledInfoTabs
from .game_utils import GameUtils
from .game_widgets.base_installed_widget import BaseInstalledWidget
from .game_widgets.base_uninstalled_widget import BaseUninstalledWidget
from .game_widgets.installed_icon_widget import InstalledIconWidget
@ -39,8 +41,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
self.core = shared.core
self.signals = shared.signals
self.settings = QSettings()
self.cloud_save_utils = CloudSaveUtils()
self.cloud_save_utils.sync_finished.connect(self.sync_finished)
self.game_utils = GameUtils(parent=self)
self.before_launch_sync = dict()
self.game_list = shared.api_results.game_list
@ -54,7 +55,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
self.head_bar.egl_sync_clicked.connect(self.show_egl_sync)
self.games.layout().insertWidget(0, self.head_bar)
self.game_info_tabs = GameInfoTabs(self.dlcs, self)
self.game_info_tabs = GameInfoTabs(self.dlcs, self.game_utils, self)
self.game_info_tabs.back_clicked.connect(lambda: self.setCurrentIndex(0))
self.addWidget(self.game_info_tabs)
@ -178,15 +179,6 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
len(self.core.get_installed_list()),
len(self.game_list)))
def sync_finished(self, app_name):
self.widgets[app_name][0].info_text = ""
self.widgets[app_name][0].info_label.setText("")
self.widgets[app_name][1].info_label.setText("")
if app_name in self.before_launch_sync.keys():
self.launch(*self.before_launch_sync[app_name])
self.before_launch_sync.pop(app_name)
def add_installed_widget(self, app_name):
pixmap = get_pixmap(app_name)
if pixmap.isNull():
@ -194,26 +186,15 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
download_image(self.core.get_game(app_name), force=True)
pixmap = get_pixmap(app_name)
icon_widget = InstalledIconWidget(app_name, pixmap)
icon_widget = InstalledIconWidget(app_name, pixmap, self.game_utils)
list_widget = InstalledListWidget(app_name, pixmap)
list_widget = InstalledListWidget(app_name, pixmap, self.game_utils)
self.widgets[app_name] = (icon_widget, list_widget)
icon_widget.show_info.connect(self.show_game_info)
list_widget.show_info.connect(self.show_game_info)
icon_widget.launch_signal.connect(self.prepare_launch)
icon_widget.finish_signal.connect(self.finished)
list_widget.launch_signal.connect(self.prepare_launch)
list_widget.finish_signal.connect(self.finished)
game = self.core.get_game(app_name)
if game.supports_cloud_saves:
icon_widget.sync_game.connect(self.cloud_save_utils.sync_before_launch_game)
list_widget.sync_game.connect(self.cloud_save_utils.sync_before_launch_game)
if icon_widget.update_available:
self.updates.add(app_name)
@ -405,9 +386,6 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
QObjectCleanupHandler().add(self.icon_view.layout())
QObjectCleanupHandler().add(self.list_view.layout())
# QWidget().setLayout(self.icon_view.layout())
# QWidget().setLayout(self.list_view.layout())
self.icon_view.setLayout(icon_layout)
self.list_view.setLayout(list_layout)

View file

@ -99,7 +99,7 @@ class CloudSaveDialog(QDialog, Ui_SyncSaveDialog):
class CloudSaveUtils(QObject):
sync_finished = pyqtSignal(str)
sync_finished = pyqtSignal(str, bool)
def __init__(self):
super(CloudSaveUtils, self).__init__()
@ -119,7 +119,7 @@ class CloudSaveUtils(QObject):
self.thread_pool = QThreadPool.globalInstance()
def sync_before_launch_game(self, app_name):
def sync_before_launch_game(self, app_name) -> bool:
igame = self.core.get_installed_game(app_name)
res, (dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, self.latest_saves.get(app_name))
@ -144,7 +144,6 @@ class CloudSaveUtils(QObject):
result = CloudSaveDialog(igame, dt_local, dt_remote, newer).get_action()
if result == CloudSaveDialog.UPLOAD:
self.upload_saves(igame, dt_local)
return
elif result == CloudSaveDialog.DOWNLOAD:
self.download_saves(igame)
elif result == CloudSaveDialog.CANCEL:
@ -153,20 +152,11 @@ class CloudSaveUtils(QObject):
return False
def game_finished(self, app_name, exit_code):
def game_finished(self, app_name):
igame = self.core.get_installed_game(app_name)
res, (dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, self.latest_saves.get(app_name))
if res == SaveGameStatus.LOCAL_NEWER:
if exit_code != 0:
reply = QMessageBox.question(None, "Cloud Saves", self.tr(
"Game could crashed. Do you want to upload save files? The save files could be corrupt"),
buttons=QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.Yes)
if reply == QMessageBox.No:
self.sync_finished.emit(app_name)
return
self.upload_saves(igame, dt_local)
return
@ -202,7 +192,7 @@ class CloudSaveUtils(QObject):
def worker_finished(self, error_message: str, app_name: str):
if not error_message:
self.sync_finished.emit(app_name)
self.sync_finished.emit(app_name, False)
else:
QMessageBox.warning(None, "Warning", self.tr("Syncing with cloud failed: \n ") + error_message)
self.sync_finished.emit(app_name)
self.sync_finished.emit(app_name, True)

View file

@ -7,10 +7,11 @@ from rare.utils.extra_widgets import SideTabWidget
from .game_dlc import GameDlc
from .game_info import GameInfo
from .game_settings import GameSettings
from ..game_utils import GameUtils
class GameInfoTabs(SideTabWidget):
def __init__(self, dlcs: list, parent=None):
def __init__(self, dlcs: list, game_utils: GameUtils, parent=None):
super(GameInfoTabs, self).__init__(show_back=True, parent=parent)
self.core = shared.core
self.signals = shared.signals
@ -22,7 +23,7 @@ class GameInfoTabs(SideTabWidget):
self.addTab(self.settings, self.tr("Settings"))
self.dlc_list = dlcs
self.dlc = GameDlc(self.dlc_list, self)
self.dlc = GameDlc(self.dlc_list, game_utils, self)
self.addTab(self.dlc, self.tr("Downloadable Content"))
self.tabBar().setCurrentIndex(1)

View file

@ -3,10 +3,9 @@ from PyQt5.QtWidgets import QFrame, QWidget, QMessageBox
from legendary.models.game import Game
from rare import shared
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.tabs.games.game_utils import GameUtils
from rare.ui.components.tabs.games.game_info.game_dlc import Ui_GameDlc
from rare.ui.components.tabs.games.game_info.game_dlc_widget import Ui_GameDlcWidget
from rare.utils import legendary_utils
from rare.utils.models import InstallOptionsModel
from rare.utils.utils import get_pixmap
@ -15,9 +14,10 @@ class GameDlc(QWidget, Ui_GameDlc):
install_dlc = pyqtSignal(str, bool)
game: Game
def __init__(self, dlcs: list, parent=None):
def __init__(self, dlcs: list, game_utils: GameUtils, parent=None):
super(GameDlc, self).__init__(parent=parent)
self.setupUi(self)
self.game_utils = game_utils
self.available_dlc_scroll.setProperty("noBorder", 1)
self.installed_dlc_scroll.setProperty("noBorder", 1)
@ -62,12 +62,9 @@ class GameDlc(QWidget, Ui_GameDlc):
self.available_dlc_label.setVisible(not self.available_dlc_widgets)
self.available_dlc_scroll.setVisible(bool(self.available_dlc_widgets))
def uninstall(self, game):
infos = UninstallDialog(game).get_information()
if infos == 0:
return
legendary_utils.uninstall(game.app_name, self.core, infos)
self.update_dlcs(self.game.app_name)
def uninstall(self, app_name):
if self.game_utils.uninstall_game(app_name):
self.update_dlcs(app_name)
def install(self, app_name):
if not self.core.is_installed(self.game.app_name):
@ -80,7 +77,7 @@ class GameDlc(QWidget, Ui_GameDlc):
class GameDlcWidget(QFrame, Ui_GameDlcWidget):
install = pyqtSignal(str) # Appname
uninstall = pyqtSignal(Game)
uninstall = pyqtSignal(str)
def __init__(self, dlc: Game, installed: bool, parent=None):
super(GameDlcWidget, self).__init__(parent=parent)

View file

@ -0,0 +1,199 @@
import os
import platform
import webbrowser
from dataclasses import dataclass
from logging import getLogger
from PyQt5.QtCore import QObject, QSettings, QProcess, QProcessEnvironment, pyqtSignal
from PyQt5.QtWidgets import QMessageBox, QPushButton
from legendary.models.game import LaunchParameters
from rare import shared
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.extra.console import ConsoleWindow
from rare.components.tabs.games import CloudSaveUtils
from rare.utils import legendary_utils
logger = getLogger("GameUtils")
class GameProcess(QProcess):
game_finished = pyqtSignal(int, str)
def __init__(self, app_name):
super(GameProcess, self).__init__()
self.app_name = app_name
self.finished.connect(lambda x: self.game_finished.emit(x, self.app_name))
@dataclass
class RunningGameModel:
process: GameProcess
app_name: str
class GameUtils(QObject):
running_games = dict()
finished = pyqtSignal(str)
cloud_save_finished = pyqtSignal(str)
launch_queue = dict()
def __init__(self, parent=None):
super(GameUtils, self).__init__(parent=parent)
self.core = shared.core
self.console = ConsoleWindow()
self.cloud_save_utils = CloudSaveUtils()
self.cloud_save_utils.sync_finished.connect(self.sync_finished)
def uninstall_game(self, app_name) -> bool:
game = self.core.get_game(app_name)
infos = UninstallDialog(game).get_information()
if infos == 0:
return False
legendary_utils.uninstall(game.app_name, self.core, infos)
return True
def prepare_launch(self, app_name, offline: bool = False, skip_update_check: bool = False):
game = self.core.get_game(app_name)
if game.supports_cloud_saves and self.cloud_save_utils.sync_before_launch_game(app_name):
self.launch_queue[app_name] = (app_name, skip_update_check, offline)
return
else:
self.launch_game(app_name, offline, skip_update_check)
def launch_game(self, app_name: str, offline: bool = False, skip_update_check: bool = False, wine_bin: str = None,
wine_pfx: str = None):
game = self.core.get_game(app_name)
igame = self.core.get_installed_game(app_name)
if QSettings().value("confirm_start", False, bool):
if not QMessageBox.question(None, "Launch", self.tr("Do you want to launch {}").format(self.game.app_title),
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
logger.info("Cancel Startup")
logger.info("Launching " + game.app_title)
if game.third_party_store == "Origin":
offline = False
else:
if not game:
logger.error("Game not found")
return
if game.is_dlc:
logger.error("Game is dlc")
return
if not os.path.exists(igame.install_path):
logger.error("Game doesn't exist")
return
process = GameProcess(app_name)
process.setProcessChannelMode(GameProcess.MergedChannels)
if game.third_party_store != "Origin":
if not offline:
if not skip_update_check and not self.core.is_noupdate_game(app_name):
# check updates
try:
latest = self.core.get_asset(app_name, update=True)
except ValueError:
print("Metadata doesn't exist")
return None
if latest.build_version != igame.version:
print("Please update game")
return None
params: LaunchParameters = self.core.get_launch_parameters(app_name=app_name, offline=offline,
wine_bin=wine_bin, wine_pfx=wine_pfx)
full_params = list()
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)
process.setWorkingDirectory(params.working_directory)
environment = QProcessEnvironment()
full_env = os.environ.copy()
full_env.update(params.environment)
for env, value in full_env.items():
environment.insert(env, value)
process.setProcessEnvironment(environment)
process.game_finished.connect(self.game_finished)
running_game = RunningGameModel(process=process, app_name=app_name)
process.start(full_params[0], full_params[1:])
self.running_games[game.app_name] = running_game
else:
origin_uri = self.core.get_origin_uri(self.game.app_name, self.offline)
logger.info("Launch Origin Game: ")
if platform.system() == "Windows":
webbrowser.open(origin_uri)
return
wine_pfx = self.core.lgd.config.get(self.game.app_name, 'wine_prefix',
fallback=os.path.expanduser("~/.wine"))
if not wine_bin:
wine_bin = self.core.lgd.config.get(self.game.app_name, 'wine_executable', fallback="/usr/bin/wine")
env = self.core.get_app_environment(self.game.app_name, wine_pfx=wine_pfx)
if not wine_bin or not env.get('WINEPREFIX'):
logger.error(f'In order to launch Origin correctly you must specify the wine binary and prefix '
f'to use in the configuration file or command line. See the README for details.')
return
environment = QProcessEnvironment()
for e in env:
environment.insert(e, env[e])
process.setProcessEnvironment(environment)
process.finished.connect(lambda x: self.game_finished(x, game.app_name))
process.start(wine_bin, origin_uri)
if QSettings().value("show_console", False, bool):
self.console.show()
process.readyReadStandardOutput.connect(lambda: self.console.log(
bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
process.readyReadStandardError.connect(lambda: self.console.error(
bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
else:
process.readyReadStandardOutput.connect(
lambda: print(bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
process.readyReadStandardError.connect(
lambda: print(bytes(process.readAllStandardError()).decode("utf-8", errors="ignore")))
def game_finished(self, exit_code, app_name):
logger.info("Game exited with exit code: " + str(exit_code))
if exit_code == 53 and self.is_origin:
msg_box = QMessageBox()
msg_box.setText(self.tr("Origin is not installed. Do you want to download installer file? "))
msg_box.addButton(QPushButton("Download"), QMessageBox.YesRole)
msg_box.addButton(QPushButton("Cancel"), QMessageBox.RejectRole)
resp = msg_box.exec()
# click install button
if resp == 0:
webbrowser.open("https://www.dm.origin.com/download")
self.running_games.pop(app_name)
self.finished.emit(app_name)
if QSettings().value("show_console", False, bool):
self.console.log(f"Game exited with code: {exit_code}")
if self.core.get_game(app_name).supports_cloud_saves:
if exit_code != 0:
r = QMessageBox.question(None, "Question", self.tr(
"Game exited with code {}, which is not a normal code. It could be caused by a crash. Do you want to sync cloud saves"),
buttons=QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.Yes)
if r != QMessageBox.Yes:
return
self.cloud_save_utils.game_finished(app_name)
def sync_finished(self, app_name):
if app_name in self.launch_queue.keys():
self.cloud_save_finished.emit(app_name)
params = self.launch_queue[app_name]
self.launch_queue.pop(app_name)
self.launch_game(*params)
else:
self.cloud_save_finished.emit(app_name)

View file

@ -1,18 +1,16 @@
import os
import platform
import webbrowser
from logging import getLogger
from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt, QByteArray, QProcessEnvironment
from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt, QByteArray
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel, QPushButton
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel
from legendary.models.game import Game
from rare import shared
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.extra.console import ConsoleWindow
from rare.utils import legendary_utils, utils
from rare.utils import utils
from rare.utils.utils import create_desktop_link
from rare.components.tabs.games.game_utils import GameUtils
logger = getLogger("Game")
@ -21,13 +19,14 @@ class BaseInstalledWidget(QGroupBox):
launch_signal = pyqtSignal(str, QProcess, list)
show_info = pyqtSignal(Game)
finish_signal = pyqtSignal(str, int)
update_list = pyqtSignal()
proc: QProcess()
sync_game = pyqtSignal(str)
def __init__(self, app_name, pixmap: QPixmap):
def __init__(self, app_name, pixmap: QPixmap, game_utils: GameUtils):
super(BaseInstalledWidget, self).__init__()
self.core = shared.core
self.game_utils = game_utils
self.game_utils.cloud_save_finished.connect(self.sync_finished)
self.sync_cloud_saves = False
self.game = self.core.get_game(app_name)
if self.game.third_party_store != "Origin":
@ -55,7 +54,7 @@ class BaseInstalledWidget(QGroupBox):
if self.game.supports_cloud_saves:
sync = QAction(self.tr("Sync with cloud"), self)
sync.triggered.connect(lambda: self.sync_game.emit(self.game.app_name))
sync.triggered.connect(self.sync_game)
self.addAction(sync)
if os.path.exists(os.path.expanduser(f"~/Desktop/{self.game.app_title}.desktop")) \
@ -86,7 +85,9 @@ class BaseInstalledWidget(QGroupBox):
self.addAction(reload_image)
uninstall = QAction(self.tr("Uninstall"), self)
uninstall.triggered.connect(self.uninstall)
uninstall.triggered.connect(
lambda: shared.signals.update_gamelist.emit(self.game.app_name) if self.game_utils.uninstall_game(
self.game.app_name) else None)
self.addAction(uninstall)
def reload_image(self):
@ -128,108 +129,13 @@ class BaseInstalledWidget(QGroupBox):
self.create_start_menu.setText(self.tr("Create Start menu link"))
def launch(self, offline=False, skip_version_check=False):
if QSettings().value("confirm_start", False, bool):
if not QMessageBox.question(self, "Launch", self.tr("Do you want to launch {}").format(self.game.app_title),
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
logger.info("Cancel Startup")
return 1
logger.info("Launching " + self.game.app_title)
if self.is_origin:
self.offline = offline = False
if offline or self.offline:
if not self.igame.can_run_offline:
QMessageBox.warning(self, "Offline",
self.tr("Game cannot run offline. Please start game in Online mode"))
return
if not self.is_origin:
try:
self.proc, params = legendary_utils.launch_game(self.core, self.game.app_name, offline,
skip_version_check=skip_version_check)
if self.game.supports_cloud_saves:
self.sync_cloud_saves = True
self.game_utils.launch_game(self.game.app_name, offline=offline, skip_update_check=skip_version_check)
except Exception as e:
logger.error(e)
QMessageBox.warning(self, "Error",
str(e))
return
else:
origin_uri = self.core.get_origin_uri(self.game.app_name, self.offline)
logger.info("Launch Origin Game: ")
if platform.system() == "Windows":
webbrowser.open(origin_uri)
return
wine_pfx = self.core.lgd.config.get(self.game.app_name, 'wine_prefix', fallback=os.path.expanduser("~/.wine"))
wine_binary = self.core.lgd.config.get(self.game.app_name, 'wine_executable', fallback="/usr/bin/wine")
env = self.core.get_app_environment(self.game.app_name, wine_pfx=wine_pfx)
def sync_finished(self, app_name):
if app_name == self.game.app_name:
self.sync_cloud_saves = False
if not wine_binary or not env.get('WINEPREFIX'):
logger.error(f'In order to launch Origin correctly you must specify the wine binary and prefix '
f'to use in the configuration file or command line. See the README for details.')
return
self.proc = QProcess()
self.proc.setProcessChannelMode(QProcess.MergedChannels)
# process.setWorkingDirectory()
environment = QProcessEnvironment()
for e in env:
environment.insert(e, env[e])
self.proc.setProcessEnvironment(environment)
params = [wine_binary, origin_uri]
if not self.proc:
logger.error("Could not start process")
return 1
self.proc.finished.connect(self.finished)
if self.settings.value("show_console", False, bool):
self.console = ConsoleWindow()
self.console.show()
self.proc.readyReadStandardOutput.connect(lambda: self.console.log(
bytes(self.proc.readAllStandardOutput()).decode("utf-8", errors="ignore")))
self.proc.readyReadStandardError.connect(lambda: self.console.error(
bytes(self.proc.readAllStandardOutput()).decode("utf-8", errors="ignore")))
else:
self.proc.readyReadStandardOutput.connect(self.stdout)
self.proc.readyReadStandardError.connect(self.stderr)
self.launch_signal.emit(self.game.app_name, self.proc, params)
# self.game_running = True
return 0
def stdout(self):
data = self.proc.readAllStandardOutput()
stdout = bytes(data).decode("utf-8", errors="ignore")
print(stdout)
def stderr(self):
stderr = bytes(self.proc.readAllStandardError()).decode("utf-8", errors="ignore")
print(stderr)
logger.error(stderr)
# QMessageBox.warning(self, "Warning", stderr + "\nSee ~/.cache/rare/logs/")
def finished(self, exit_code):
logger.info("Game exited with exit code: " + str(exit_code))
if exit_code == 53 and self.is_origin:
msg_box = QMessageBox()
msg_box.setText(self.tr("Origin is not installed. Do you want to download installer file? "))
msg_box.addButton(QPushButton("Download"), QMessageBox.YesRole)
msg_box.addButton(QPushButton("Cancel"), QMessageBox.RejectRole)
resp = msg_box.exec()
# click install button
if resp == 0:
webbrowser.open("https://www.dm.origin.com/download")
self.finish_signal.emit(self.game.app_name, exit_code)
self.game_running = False
if self.settings.value("show_console", False, bool):
self.console.log(f"Game exited with code: {exit_code}")
def uninstall(self):
infos = UninstallDialog(self.game).get_information()
if infos == 0:
print("Cancel Uninstall")
return
legendary_utils.uninstall(self.game.app_name, self.core, infos)
self.update_list.emit(self.game.app_name)
def sync_game(self):
self.game_utils.cloud_save_utils.sync_before_launch_game(self.game.app_name)

View file

@ -14,8 +14,8 @@ logger = getLogger("GameWidgetInstalled")
class InstalledIconWidget(BaseInstalledWidget):
update_game = pyqtSignal()
def __init__(self, app_name, pixmap):
super(InstalledIconWidget, self).__init__(app_name, pixmap)
def __init__(self, app_name, pixmap, game_utils):
super(InstalledIconWidget, self).__init__(app_name, pixmap, game_utils)
self.setObjectName("game_widget_icon")
self.setContextMenuPolicy(Qt.ActionsContextMenu)
@ -30,6 +30,8 @@ class InstalledIconWidget(BaseInstalledWidget):
self.layout.addWidget(self.image)
self.game_utils.finished.connect(self.game_finished)
self.title_label = QLabel(f"<h4>{self.game.app_title}</h4>")
self.title_label.setAutoFillBackground(False)
self.title_label.setWordWrap(True)
@ -97,3 +99,10 @@ class InstalledIconWidget(BaseInstalledWidget):
# right
elif e.button() == 2:
pass # self.showMenu(e)
def game_finished(self, app_name):
if app_name != self.game.app_name:
return
self.info_text = ""
self.info_label.setText("")

View file

@ -14,8 +14,8 @@ class InstalledListWidget(BaseInstalledWidget):
signal = pyqtSignal(str)
update_game = pyqtSignal()
def __init__(self, app_name, pixmap):
super(InstalledListWidget, self).__init__(app_name, pixmap)
def __init__(self, app_name, pixmap, game_utils):
super(InstalledListWidget, self).__init__(app_name, pixmap, game_utils)
self.dev = self.game.metadata["developer"]
if self.game.third_party_store != "Origin":
self.size = self.igame.install_size

View file

@ -3,62 +3,16 @@ import platform
import shutil
from logging import getLogger
from PyQt5.QtCore import QProcess, QProcessEnvironment, pyqtSignal, QRunnable, QObject, QCoreApplication
from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable
from PyQt5.QtWidgets import QMessageBox
from legendary.core import LegendaryCore
from legendary.models.game import VerifyResult, LaunchParameters
from legendary.models.game import VerifyResult
from legendary.utils.lfs import validate_files
logger = getLogger("Legendary Utils")
def launch_game(core, app_name: str, offline: bool = False, skip_version_check: bool = False):
game = core.get_installed_game(app_name)
if not game:
print("Game not found")
return None
if game.is_dlc:
print("Game is dlc")
return None
if not os.path.exists(game.install_path):
print("Game doesn't exist")
return None
if not offline:
if not skip_version_check and not core.is_noupdate_game(app_name):
# check updates
try:
latest = core.get_asset(app_name, update=True)
except ValueError:
print("Metadata doesn't exist")
return None
if latest.build_version != game.version:
print("Please update game")
return None
params: LaunchParameters = core.get_launch_parameters(app_name=app_name, offline=offline)
full_params = list()
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)
process = QProcess()
process.setProcessChannelMode(QProcess.MergedChannels)
process.setWorkingDirectory(params.working_directory)
environment = QProcessEnvironment()
full_env = os.environ.copy()
full_env.update(params.environment)
for env, value in full_env.items():
environment.insert(env, value)
process.setProcessEnvironment(environment)
return process, full_params
def uninstall(app_name: str, core: LegendaryCore, options=None):
if not options:
options = {"keep_files": False}