1
0
Fork 0
mirror of synced 2024-06-29 19:51:02 +12:00
Rare/rare/components/__init__.py
loathingKernel 1677ea762c
FetchWorker: Fix issue with missing MacOS assets on MacOS
Using `LegendaryCore.get_game_and_dlc_list` with platform `Windows`
updated the assets only for the `Windows` builds of the games missing
`Win32` and `MacOS` assets on clean installs. This caused Rare to not
include MacOS install options on MacOS (duh!). This might also have been
the cause that users were unable to launch games, since they where only
offered the `Windows` build of the games (big duh!).

To fix this, fetch the assets for `Win32` and `MacOS` games before getting
the final list of games and dlcs based on the `Windows` platform.

In this regard, also re-use the existing options for getting metadata to
give the option to the user to include them when updating assets. Also add
an option to include Unreal engine assets which until now were fetched
unconditionally.

* Include Unreal: When the user option is `true` or debugging.
  Defaults to `false`
* Update Win32: When the user option is `true` or debugging.
  Defaults to `false`
* Update MacOS: Force on MacOS, when the option is `true` or debugging on
  other platforms. Defaults to `true` on MacOS and is disabled,
  `false` on others

Furthermore, respect legendary's `default_platform` config option and
set it in the config on new configurations. The new method in our
LegendaryCore monkey allows us to use that option in RareGame when doing
version checks on not installed games, and not defaulting to `Windows`.

Finally, set `install_platform_fallback` to false in a new config to
avoid unwanted side-effects.
2023-12-15 16:57:32 +02:00

130 lines
4.4 KiB
Python

import os
import shutil
from argparse import Namespace
from datetime import datetime, timezone
from typing import Optional
import requests.exceptions
from PyQt5.QtCore import QThreadPool, QTimer, pyqtSlot, Qt
from PyQt5.QtWidgets import QApplication, QMessageBox
from requests import HTTPError
from rare.components.dialogs.launch_dialog import LaunchDialog
from rare.components.main_window import MainWindow
from rare.shared import RareCore
from rare.utils import config_helper, paths
from rare.utils.misc import ExitCodes
from rare.widgets.rare_app import RareApp, RareAppException
class RareException(RareAppException):
def __init__(self, parent=None):
super(RareException, self).__init__(parent=parent)
def _handler(self, exc_type, exc_value, exc_tb) -> bool:
if exc_type == HTTPError:
try:
if RareCore.instance() is not None:
if RareCore.instance().core().login():
return True
raise ValueError
except Exception as e:
self.logger.fatal(str(e))
QMessageBox.warning(None, "Error", self.tr("Failed to login"))
QApplication.exit(1)
return False
class Rare(RareApp):
def __init__(self, args: Namespace):
super(Rare, self).__init__(args, f"{type(self).__name__}_{{0}}.log")
self._hook.deleteLater()
self._hook = RareException(self)
self.rcore = RareCore(args=args)
self.args = RareCore.instance().args()
self.signals = RareCore.instance().signals()
self.core = RareCore.instance().core()
lang = self.settings.value("language", self.core.language_code, type=str)
self.load_translator(lang)
# set Application name for settings
self.main_window: Optional[MainWindow] = None
self.launch_dialog: Optional[LaunchDialog] = None
self.timer: Optional[QTimer] = None
# This launches the application after it has been instantiated.
# The timer's signal will be serviced once we call `exec()` on the application
QTimer.singleShot(0, self.launch_app)
def poke_timer(self):
dt_exp = datetime.fromisoformat(self.core.lgd.userdata['expires_at'][:-1]).replace(tzinfo=timezone.utc)
dt_now = datetime.utcnow().replace(tzinfo=timezone.utc)
td = abs(dt_exp - dt_now)
self.timer.start(int(td.total_seconds() - 60) * 1000)
self.logger.info(f"Renewed session expires at {self.core.lgd.userdata['expires_at']}")
def re_login(self):
self.logger.info("Session expires shortly. Renew session")
try:
self.core.login()
except requests.exceptions.ConnectionError:
self.timer.start(3000) # try again if no connection
return
self.poke_timer()
@pyqtSlot()
def launch_app(self):
self.launch_dialog = LaunchDialog(parent=None)
self.launch_dialog.exit_app.connect(self.launch_dialog.close)
self.launch_dialog.exit_app.connect(self.__on_exit_app)
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.start_app.connect(self.launch_dialog.close)
self.launch_dialog.login()
@pyqtSlot()
def start_app(self):
self.timer = QTimer()
self.timer.timeout.connect(self.re_login)
self.poke_timer()
self.main_window = MainWindow()
self.main_window.exit_app.connect(self.__on_exit_app)
if not self.args.silent:
self.main_window.show()
if self.args.test_start:
self.main_window.close()
self.main_window = None
self.__on_exit_app(0)
@pyqtSlot()
@pyqtSlot(int)
def __on_exit_app(self, exit_code=0):
threadpool = QThreadPool.globalInstance()
threadpool.waitForDone()
if self.timer is not None:
self.timer.stop()
self.timer.deleteLater()
self.timer = None
self.rcore.deleteLater()
del self.rcore
self.processEvents()
shutil.rmtree(paths.tmp_dir())
os.makedirs(paths.tmp_dir())
self.exit(exit_code)
def start(args) -> int:
while True:
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
app = Rare(args)
exit_code = app.exec()
del app
if exit_code != ExitCodes.LOGOUT:
break
return exit_code