1
0
Fork 0
mirror of synced 2024-06-17 01:54:46 +12:00

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.
This commit is contained in:
loathingKernel 2023-12-15 16:57:32 +02:00
parent 687218d29b
commit 1677ea762c
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
10 changed files with 162 additions and 61 deletions

View file

@ -45,8 +45,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

@ -284,7 +284,9 @@ class GameInfo(QWidget, SideTabContents):
)
self.ui.platform.setText(
self.rgame.igame.platform if self.rgame.is_installed and not self.rgame.is_non_asset else "Windows"
self.rgame.igame.platform
if self.rgame.is_installed and not self.rgame.is_non_asset
else self.core.default_platform
)
self.ui.lbl_grade.setDisabled(

View file

@ -74,7 +74,6 @@ class UbiConnectWorker(Worker):
def __init__(self, core: LegendaryCore, ubi_account_id, partner_link_id):
super(UbiConnectWorker, self).__init__()
self.signals = UbiConnectWorker.Signals()
self.setAutoDelete(True)
self.core = core
self.ubi_account_id = ubi_account_id
self.partner_link_id = partner_link_id

View file

@ -1,7 +1,7 @@
import platform
import platform as pf
import re
from logging import getLogger
from typing import Tuple
from typing import Tuple, List
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSettings
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
@ -19,14 +19,21 @@ class RefreshGameMetaWorker(Worker):
class Signals(QObject):
finished = pyqtSignal()
def __init__(self):
def __init__(self, platforms: List[str], include_unreal: bool):
super(RefreshGameMetaWorker, self).__init__()
self.signals = RefreshGameMetaWorker.Signals()
self.setAutoDelete(True)
self.core = LegendaryCoreSingleton()
if platforms:
self.platforms = platforms
else:
self.platforms = ["Windows"]
self.skip_ue = not include_unreal
def run_real(self) -> None:
self.core.get_game_and_dlc_list(True, force_refresh=True)
for platform in self.platforms:
self.core.get_game_and_dlc_list(
True, platform=platform, force_refresh=True, skip_ue=self.skip_ue
)
self.signals.finished.emit()
@ -34,7 +41,7 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
def __init__(self, parent=None):
super(LegendarySettings, self).__init__(parent=parent)
self.setupUi(self)
self.settings = QSettings()
self.settings = QSettings(self)
self.core = LegendaryCoreSingleton()
@ -82,20 +89,36 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
)
self.locale_layout.addWidget(self.locale_edit)
self.win32_cb.setChecked(self.settings.value("win32_meta", False, bool))
self.win32_cb.stateChanged.connect(lambda: self.settings.setValue("win32_meta", self.win32_cb.isChecked()))
self.fetch_win32_check.setChecked(self.settings.value("win32_meta", False, bool))
self.fetch_win32_check.stateChanged.connect(
lambda: self.settings.setValue("win32_meta", self.fetch_win32_check.isChecked())
)
self.mac_cb.setChecked(self.settings.value("mac_meta", platform.system() == "Darwin", bool))
self.mac_cb.stateChanged.connect(lambda: self.settings.setValue("mac_meta", self.mac_cb.isChecked()))
self.fetch_macos_check.setChecked(self.settings.value("macos_meta", pf.system() == "Darwin", bool))
self.fetch_macos_check.stateChanged.connect(
lambda: self.settings.setValue("macos_meta", self.fetch_macos_check.isChecked())
)
self.fetch_macos_check.setDisabled(pf.system() == "Darwin")
self.refresh_game_meta_btn.clicked.connect(self.refresh_game_meta)
self.fetch_unreal_check.setChecked(self.settings.value("unreal_meta", False, bool))
self.fetch_unreal_check.stateChanged.connect(
lambda: self.settings.setValue("unreal_meta", self.fetch_unreal_check.isChecked())
)
def refresh_game_meta(self):
self.refresh_game_meta_btn.setDisabled(True)
self.refresh_game_meta_btn.setText(self.tr("Loading"))
worker = RefreshGameMetaWorker()
worker.signals.finished.connect(lambda: self.refresh_game_meta_btn.setDisabled(False))
worker.signals.finished.connect(lambda: self.refresh_game_meta_btn.setText(self.tr("Refresh game meta")))
self.refresh_metadata_button.clicked.connect(self.refresh_metadata)
# FIXME: Disable the button for now because it interferes with RareCore
self.refresh_metadata_button.setEnabled(False)
self.refresh_metadata_button.setVisible(False)
def refresh_metadata(self):
self.refresh_metadata_button.setDisabled(True)
platforms = []
if self.fetch_win32_check.isChecked():
platforms.append("Win32")
if self.fetch_macos_check.isChecked():
platforms.append("Mac")
worker = RefreshGameMetaWorker(platforms, self.fetch_unreal_check.isChecked())
worker.signals.finished.connect(lambda: self.refresh_metadata_button.setDisabled(False))
QThreadPool.globalInstance().start(worker)
@staticmethod

View file

@ -3,6 +3,7 @@ import json
import logging
import os
from multiprocessing import Queue
from sys import platform as sys_platform
from uuid import uuid4
# On Windows the monkeypatching of `run_real` below doesn't work like on Linux
@ -17,8 +18,8 @@ from legendary.models.game import Game, InstalledGame
from legendary.models.manifest import ManifestMeta
from rare.lgndr.downloader.mp.manager import DLManager
from rare.lgndr.lfs.lgndry import LGDLFS
from rare.lgndr.glue.exception import LgndrException, LgndrLogHandler
from rare.lgndr.lfs.lgndry import LGDLFS
legendary.core.DLManager = DLManager
legendary.core.LGDLFS = LGDLFS
@ -50,6 +51,11 @@ class LegendaryCore(LegendaryCoreReal):
return ret
return unlock
@property
def default_platform(self) -> str:
os_default = "Mac" if sys_platform == "darwin" else "Windows"
return self.lgd.config.get("Legendary", "default_platform", fallback=os_default)
# skip_sync defaults to false but since Rare is persistent, skip by default
# def get_installed_game(self, app_name, skip_sync=True) -> InstalledGame:
# return super(LegendaryCore, self).get_installed_game(app_name, skip_sync)

View file

@ -166,7 +166,8 @@ class RareGame(RareGameSlim):
def update_game(self):
self.game = self.core.get_game(
self.app_name, update_meta=False, platform=self.igame.platform if self.igame else "Windows"
self.app_name, update_meta=False,
platform=self.igame.platform if self.igame else self.core.default_platform
)
def update_igame(self):
@ -228,7 +229,7 @@ class RareGame(RareGameSlim):
if self.igame is not None:
return self.game.app_version(self.igame.platform)
else:
return self.game.app_version()
return self.game.app_version(self.core.default_platform)
@property
def has_update(self) -> bool:

View file

@ -1,5 +1,6 @@
import configparser
import os
import platform
import time
from argparse import Namespace
from itertools import chain
@ -25,6 +26,7 @@ from .workers import (
)
from .workers.uninstall import uninstall_game
from .workers.worker import QueueWorkerInfo, QueueWorkerState
from rare.utils import config_helper
logger = getLogger("RareCore")
@ -54,9 +56,10 @@ 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()
self.settings = QSettings(self)
self.queue_workers: List[QueueWorker] = []
self.queue_threadpool = QThreadPool()
@ -140,6 +143,9 @@ class RareCore(QObject):
for section in ["Legendary", "default", "default.env"]:
if section not in self.__core.lgd.config.sections():
self.__core.lgd.config.add_section(section)
# Set some platform defaults
self.__core.lgd.config.set("Legendary", "default_platform", self.__core.default_platform)
self.__core.lgd.config.set("Legendary", "install_platform_fallback", False)
# workaround if egl sync enabled, but no programdata_path
# programdata_path might be unset if logging in through the browser
if self.__core.egl_sync_enabled:
@ -357,7 +363,7 @@ class RareCore(QObject):
yield game.game
@property
def dlcs(self) -> Dict[str, Game]:
def dlcs(self) -> Dict[str, set[RareGame]]:
"""!
RareGames that ARE DLCs themselves
"""

View file

@ -1,9 +1,10 @@
import platform
import time
from argparse import Namespace
from enum import IntEnum
from logging import getLogger
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtCore import QObject, pyqtSignal, QSettings
from requests.exceptions import ConnectionError, HTTPError
from rare.lgndr.core import LegendaryCore
@ -27,19 +28,54 @@ class FetchWorker(Worker):
self.signals = FetchWorker.Signals()
self.core = core
self.args = args
self.settings = QSettings()
def run_real(self):
# Fetch regular EGL games with assets
self.signals.progress.emit(0, self.signals.tr("Updating game metadata"))
start_time = time.time()
want_unreal = self.settings.value("unreal_meta", False, bool) or self.args.debug
want_win32 = self.settings.value("win32_meta", False, bool)
want_macos = self.settings.value("macos_meta", False, bool)
need_macos = platform.system() == "Darwin"
need_windows = not any([want_win32, want_macos, need_macos, self.args.debug])
if want_win32 or self.args.debug:
logger.info(
"Requesting Win32 metadata due to %s, %s Unreal engine",
"settings" if want_win32 else "debug",
"with" if want_unreal else "without"
)
self.signals.progress.emit(00, self.signals.tr("Updating game metadata for Windows"))
self.core.get_game_and_dlc_list(
update_assets=not self.args.offline, platform="Win32", skip_ue=not want_unreal
)
if need_macos or want_macos or self.args.debug:
logger.info(
"Requesting MacOS metadata due to %s, %s Unreal engine",
platform if need_macos else "settings" if want_macos else "debug",
"with" if want_unreal else "without"
)
self.signals.progress.emit(15, self.signals.tr("Updating game metadata for MacOS"))
self.core.get_game_and_dlc_list(
update_assets=not self.args.offline, platform="Mac", skip_ue=not want_unreal
)
if need_windows:
self.signals.progress.emit(00, self.signals.tr("Updating game metadata for Windows"))
logger.info(
"Requesting Windows metadata, %s Unreal engine",
"with" if want_unreal else "without"
)
games, dlc_dict = self.core.get_game_and_dlc_list(
update_assets=not self.args.offline, platform="Windows", skip_ue=False
update_assets=need_windows, platform="Windows", skip_ue=not want_unreal
)
logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}")
logger.debug(f"Request games: {time.time() - start_time} seconds")
# Fetch non-asset games
self.signals.progress.emit(10, self.signals.tr("Updating non-asset metadata"))
self.signals.progress.emit(30, self.signals.tr("Updating non-asset game metadata"))
start_time = time.time()
try:
na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/legendary.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
# Created by: PyQt5 UI code generator 5.15.10
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_LegendarySettings(object):
def setupUi(self, LegendarySettings):
LegendarySettings.setObjectName("LegendarySettings")
LegendarySettings.resize(595, 334)
LegendarySettings.resize(681, 456)
LegendarySettings.setWindowTitle("LegendarySettings")
self.legendary_layout = QtWidgets.QHBoxLayout(LegendarySettings)
self.legendary_layout.setObjectName("legendary_layout")
@ -125,21 +125,30 @@ class Ui_LegendarySettings(object):
self.clean_button = QtWidgets.QPushButton(self.cleanup_group)
self.clean_button.setObjectName("clean_button")
self.cleanup_layout.addWidget(self.clean_button)
self.right_layout.addWidget(self.cleanup_group, 0, QtCore.Qt.AlignTop)
self.meta_group = QtWidgets.QGroupBox(LegendarySettings)
self.meta_group.setObjectName("meta_group")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.meta_group)
self.right_layout.addWidget(self.cleanup_group)
self.metadata_group = QtWidgets.QGroupBox(LegendarySettings)
self.metadata_group.setObjectName("metadata_group")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.metadata_group)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.win32_cb = QtWidgets.QCheckBox(self.meta_group)
self.win32_cb.setObjectName("win32_cb")
self.verticalLayout_2.addWidget(self.win32_cb)
self.mac_cb = QtWidgets.QCheckBox(self.meta_group)
self.mac_cb.setObjectName("mac_cb")
self.verticalLayout_2.addWidget(self.mac_cb)
self.refresh_game_meta_btn = QtWidgets.QPushButton(self.meta_group)
self.refresh_game_meta_btn.setObjectName("refresh_game_meta_btn")
self.verticalLayout_2.addWidget(self.refresh_game_meta_btn)
self.right_layout.addWidget(self.meta_group)
self.fetch_win32_check = QtWidgets.QCheckBox(self.metadata_group)
self.fetch_win32_check.setObjectName("fetch_win32_check")
self.verticalLayout_2.addWidget(self.fetch_win32_check)
self.fetch_macos_check = QtWidgets.QCheckBox(self.metadata_group)
self.fetch_macos_check.setObjectName("fetch_macos_check")
self.verticalLayout_2.addWidget(self.fetch_macos_check)
self.fetch_unreal_check = QtWidgets.QCheckBox(self.metadata_group)
self.fetch_unreal_check.setObjectName("fetch_unreal_check")
self.verticalLayout_2.addWidget(self.fetch_unreal_check)
self.metadata_info = QtWidgets.QLabel(self.metadata_group)
font = QtGui.QFont()
font.setItalic(True)
self.metadata_info.setFont(font)
self.metadata_info.setObjectName("metadata_info")
self.verticalLayout_2.addWidget(self.metadata_info)
self.refresh_metadata_button = QtWidgets.QPushButton(self.metadata_group)
self.refresh_metadata_button.setObjectName("refresh_metadata_button")
self.verticalLayout_2.addWidget(self.refresh_metadata_button)
self.right_layout.addWidget(self.metadata_group)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.right_layout.addItem(spacerItem1)
self.legendary_layout.addLayout(self.right_layout)
@ -162,10 +171,12 @@ class Ui_LegendarySettings(object):
self.cleanup_group.setTitle(_translate("LegendarySettings", "Cleanup"))
self.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
self.meta_group.setTitle(_translate("LegendarySettings", "Game metadata"))
self.win32_cb.setText(_translate("LegendarySettings", "Load 32bit data"))
self.mac_cb.setText(_translate("LegendarySettings", "Load MacOS data"))
self.refresh_game_meta_btn.setText(_translate("LegendarySettings", "Refresh game meta"))
self.metadata_group.setTitle(_translate("LegendarySettings", "Platforms"))
self.fetch_win32_check.setText(_translate("LegendarySettings", "Include Win32 games"))
self.fetch_macos_check.setText(_translate("LegendarySettings", "Include MacOS games"))
self.fetch_unreal_check.setText(_translate("LegendarySettings", "Include Unreal engine"))
self.metadata_info.setText(_translate("LegendarySettings", "Restart Rare to apply"))
self.refresh_metadata_button.setText(_translate("LegendarySettings", "Refresh metadata"))
if __name__ == "__main__":

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>595</width>
<height>334</height>
<width>681</width>
<height>456</height>
</rect>
</property>
<property name="windowTitle">
@ -200,7 +200,7 @@
<layout class="QVBoxLayout" name="locale_layout"/>
</widget>
</item>
<item alignment="Qt::AlignTop">
<item>
<widget class="QGroupBox" name="cleanup_group">
<property name="title">
<string>Cleanup</string>
@ -227,29 +227,48 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="meta_group">
<widget class="QGroupBox" name="metadata_group">
<property name="title">
<string>Game metadata</string>
<string>Platforms</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="win32_cb">
<widget class="QCheckBox" name="fetch_win32_check">
<property name="text">
<string>Load 32bit data</string>
<string>Include Win32 games</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="mac_cb">
<widget class="QCheckBox" name="fetch_macos_check">
<property name="text">
<string>Load MacOS data</string>
<string>Include MacOS games</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="refresh_game_meta_btn">
<widget class="QCheckBox" name="fetch_unreal_check">
<property name="text">
<string>Refresh game meta</string>
<string>Include Unreal engine</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="metadata_info">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Restart Rare to apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="refresh_metadata_button">
<property name="text">
<string>Refresh metadata</string>
</property>
</widget>
</item>