1
0
Fork 0
mirror of synced 2024-06-02 02:34:40 +12:00

RareCore: Move entitlements request into an independent worker

Yes, we are back at this. Entitlements are important to have early
as Ubisoft redemption requires them, and they don't depend on anything
else.

* Move config helper initialization into RareCore to make it available
earlier.
This commit is contained in:
loathingKernel 2023-09-15 00:40:28 +03:00
parent 801c07932d
commit 713573b762
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
4 changed files with 77 additions and 65 deletions

View file

@ -1,6 +1,5 @@
import os
import shutil
import sys
from argparse import Namespace
from datetime import datetime, timezone
from typing import Optional
@ -13,7 +12,7 @@ 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 import paths
from rare.widgets.rare_app import RareApp, RareAppException
@ -45,8 +44,6 @@ class Rare(RareApp):
self.signals = RareCore.instance().signals()
self.core = RareCore.instance().core()
config_helper.init_config_handler(self.core)
lang = self.settings.value("language", self.core.language_code, type=str)
self.load_translator(lang)

View file

@ -16,12 +16,15 @@ from rare.models.base_game import RareSaveGame
from rare.models.game import RareGame, RareEosOverlay
from rare.models.signals import GlobalSignals
from rare.utils.metrics import timelogger
from rare.utils import config_helper
from .image_manager import ImageManager
from .workers import (
QueueWorker,
VerifyWorker,
MoveWorker,
FetchWorker,
GamesDlcsWorker,
EntitlementsWorker,
OriginWineWorker,
)
from .workers.uninstall import uninstall_game
@ -55,6 +58,7 @@ class RareCore(QObject):
self.args(args)
self.signals(init=True)
self.core(init=True)
config_helper.init_config_handler(self.__core)
self.image_manager(init=True)
self.settings = QSettings()
@ -68,6 +72,10 @@ class RareCore(QObject):
self.__eos_overlay.signals.game.install.connect(self.__signals.game.install)
self.__eos_overlay.signals.game.uninstall.connect(self.__signals.game.uninstall)
self.__fetch_progress: int = 0
self.__fetched_games_dlcs: bool = False
self.__fetched_entitlements: bool = False
RareCore.__instance = self
def enqueue_worker(self, rgame: RareGame, worker: QueueWorker):
@ -266,24 +274,45 @@ class RareCore(QObject):
logger.info(f'Marking "{rgame.app_title}" as not installed because an exception has occurred...')
logger.error(e)
rgame.set_installed(False)
self.progress.emit(int(idx/length * 80) + 20, self.tr("Loaded <b>{}</b>").format(rgame.app_title))
progress = int(idx/length * self.__fetch_progress) + (100 - self.__fetch_progress)
self.progress.emit(progress, self.tr("Loaded <b>{}</b>").format(rgame.app_title))
@pyqtSlot(int, str)
def __on_fetch_progress(self, increment: int, message: str):
self.__fetch_progress += increment
self.progress.emit(self.__fetch_progress, message)
@pyqtSlot(object, int)
def __on_fetch_result(self, result: Tuple[List, Dict], res_type: int):
logger.info(f"Got API results for {FetchWorker.Result(res_type).name}")
self.progress.emit(15, self.tr("Preparing library"))
self.__add_games_and_dlcs(*result)
self.progress.emit(100, self.tr("Launching Rare"))
logger.debug(f"Fetch time {time.perf_counter() - self.__start_time} seconds")
QTimer.singleShot(100, self.__post_init)
self.completed.emit()
def __on_fetch_result(self, result: Tuple, result_type: int):
if result_type == FetchWorker.Result.GAMESDLCS:
self.__add_games_and_dlcs(*result)
self.__fetched_games_dlcs = True
if result_type == FetchWorker.Result.ENTITLEMENTS:
self.__core.lgd.entitlements = result
self.__fetched_entitlements = True
logger.info(f"Acquired data for {FetchWorker.Result(result_type).name}")
if all([self.__fetched_games_dlcs, self.__fetched_entitlements]):
logger.debug(f"Fetch time {time.perf_counter() - self.__start_time} seconds")
self.progress.emit(100, self.tr("Launching Rare"))
self.completed.emit()
QTimer.singleShot(100, self.__post_init)
def fetch(self):
self.__start_time = time.perf_counter()
fetch_worker = FetchWorker(self.__core, self.__args)
fetch_worker.signals.progress.connect(self.progress)
fetch_worker.signals.result.connect(self.__on_fetch_result)
QThreadPool.globalInstance().start(fetch_worker)
games_dlcs_worker = GamesDlcsWorker(self.__core, self.__args)
games_dlcs_worker.signals.progress.connect(self.__on_fetch_progress)
games_dlcs_worker.signals.result.connect(self.__on_fetch_result)
entitlements_worker = EntitlementsWorker(self.__core, self.__args)
entitlements_worker.signals.progress.connect(self.__on_fetch_progress)
entitlements_worker.signals.result.connect(self.__on_fetch_result)
QThreadPool.globalInstance().start(games_dlcs_worker)
QThreadPool.globalInstance().start(entitlements_worker)
def fetch_saves(self):
def __fetch() -> None:
@ -309,24 +338,6 @@ class RareCore(QObject):
saves_worker = QRunnable.create(__fetch)
QThreadPool.globalInstance().start(saves_worker)
def fetch_entitlements(self) -> None:
def __fetch() -> None:
try:
if (entitlements := self.__core.lgd.entitlements) is None:
with timelogger(logger, "Request entitlements"):
entitlements = self.__core.egs.get_user_entitlements()
self.__core.lgd.entitlements = entitlements
for game in self.__library.values():
game.grant_date()
except (HTTPError, ConnectionError) as e:
logger.error(f"Exception while fetching entitlements from EGS.")
logger.error(e)
return
logger.info(f"Entitlements: {len(list(entitlements))}")
entitlements_worker = QRunnable.create(__fetch)
QThreadPool.globalInstance().start(entitlements_worker)
def resolve_origin(self) -> None:
origin_worker = OriginWineWorker(self.__core, list(self.origin_games))
QThreadPool.globalInstance().start(origin_worker)
@ -334,7 +345,6 @@ class RareCore(QObject):
def __post_init(self) -> None:
if not self.__args.offline:
self.fetch_saves()
# self.fetch_entitlements()
self.resolve_origin()
@property

View file

@ -1,4 +1,4 @@
from .fetch import FetchWorker
from .fetch import FetchWorker, GamesDlcsWorker, EntitlementsWorker
from .install_info import InstallInfoWorker
from .move import MoveWorker
from .uninstall import UninstallWorker

View file

@ -14,9 +14,9 @@ logger = getLogger("FetchWorker")
class FetchWorker(Worker):
class Result(IntEnum):
GAMES = 1
NON_ASSET = 2
COMBINED = 3
ERROR = 0
GAMESDLCS = 1
ENTITLEMENTS = 2
class Signals(QObject):
progress = pyqtSignal(int, str)
@ -27,42 +27,56 @@ class FetchWorker(Worker):
self.signals = FetchWorker.Signals()
self.core = core
self.args = args
self.exclude_non_asset = QSettings().value("exclude_non_asset", False, bool)
class EntitlementsWorker(FetchWorker):
def __init__(self, core: LegendaryCore, args: Namespace):
super(EntitlementsWorker, self).__init__(core, args)
self.exclude_entitlements = QSettings().value("exclude_entitlements", False, bool)
def run_real(self):
progress = 0
entitlements = ()
self.signals.progress.emit(0, self.signals.tr("Updating entitlements"))
if not self.exclude_entitlements:
with timelogger(logger, "Request entitlements"):
entitlements = self.core.egs.get_user_entitlements()
logger.info(f"Entitlements: {len(list(entitlements))}")
self.signals.result.emit(entitlements, FetchWorker.Result.ENTITLEMENTS)
return
class GamesDlcsWorker(FetchWorker):
def __init__(self, core: LegendaryCore, args: Namespace):
super(GamesDlcsWorker, self).__init__(core, args)
self.exclude_non_asset = QSettings().value("exclude_non_asset", False, bool)
def run_real(self):
# Fetch regular EGL games with assets
self.signals.progress.emit(progress, self.signals.tr("Updating game metadata"))
self.signals.progress.emit(0, self.signals.tr("Updating game metadata"))
with timelogger(logger, "Request games"):
games, dlc_dict = self.core.get_game_and_dlc_list(
update_assets=not self.args.offline, platform="Windows", skip_ue=False
)
progress += 10
logger.info(f"Games: {len(games)}. Games with DLCs {len(dlc_dict)}")
# Fetch non-asset games
if not self.exclude_non_asset:
self.signals.progress.emit(progress, self.signals.tr("Updating non-asset metadata"))
self.signals.progress.emit(10, self.signals.tr("Updating non-asset metadata"))
try:
with timelogger(logger, "Request non-asset"):
na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)
except (HTTPError, ConnectionError) as e:
logger.error(f"Exception while fetching non asset games from EGS.")
logger.error(f"Connection error while fetching non asset games")
logger.error(e)
na_games, na_dlc_dict = ([], {})
# FIXME:
# This is here because of broken appIds from Epic:
# https://discord.com/channels/826881530310819914/884510635642216499/1111321692703305729
# There is a tab character in the appId of Fallout New Vegas: Honest Hearts DLC, this breaks metadata storage
# on Windows as they can't handle tabs at the end of the filename (?)
# Legendary and Heroic are also affected, but it completely breaks Rare, so dodge it for now pending a fix.
# NOTE: This is here because of broken appIds from Epic
# https://discord.com/channels/826881530310819914/884510635642216499/1111321692703305729
except Exception as e:
logger.error(f"Exception while fetching non asset games from EGS.")
logger.error(f"General exception while fetching non asset games")
logger.error(e)
na_games, na_dlc_dict = ([], {})
progress += 10
logger.info(f"Non-asset: {len(na_games)}. Non-asset with DLCs: {len(na_dlc_dict)}")
# Combine the two games lists and the two dlc dictionaries between regular and non-asset results
@ -74,14 +88,5 @@ class FetchWorker(Worker):
dlc_dict[catalog_id] = dlcs
logger.info(f"Games: {len(games)}. Games with DLCs: {len(dlc_dict)}")
if not self.exclude_entitlements:
# Get entitlements, Ubisoft integration also uses them
self.signals.progress.emit(progress, self.signals.tr("Updating entitlements"))
with timelogger(logger, "Request entitlements"):
entitlements = self.core.egs.get_user_entitlements()
self.core.lgd.entitlements = entitlements
progress += 10
logger.info(f"Entitlements: {len(list(entitlements))}")
self.signals.progress.emit(progress, self.signals.tr("Preparing games"))
self.signals.result.emit((games, dlc_dict), FetchWorker.Result.COMBINED)
self.signals.progress.emit(10, self.signals.tr("Preparing library"))
self.signals.result.emit((games, dlc_dict), FetchWorker.Result.GAMESDLCS)