1
0
Fork 0
mirror of synced 2024-06-02 02:34:40 +12:00
Rare/rare/components/tabs/settings/legendary.py
loathingKernel af6d7c5055 Various WIP
* Use `vars()` instead of directly accessing `__dict__`
* Remove `auto_update` from RareGame's metadata
* Correct check for updating the Steam App ID (We want to keep any changes from the user)
* Collect both Wine and Proton prefixes when removing overlay registry keys.
* Add few convenience functions in config_helper and paths.
2024-02-12 21:52:07 +02:00

244 lines
10 KiB
Python

import platform as pf
import re
from logging import getLogger
from typing import Tuple, List
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSettings
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
from rare.models.options import options
from rare.shared import LegendaryCoreSingleton
from rare.shared.workers.worker import Worker
from rare.ui.components.tabs.settings.legendary import Ui_LegendarySettings
from rare.utils.misc import format_size
from rare.widgets.indicator_edit import PathEdit, IndicatorLineEdit, IndicatorReasonsCommon
logger = getLogger("LegendarySettings")
class RefreshGameMetaWorker(Worker):
class Signals(QObject):
finished = pyqtSignal()
def __init__(self, platforms: List[str], include_unreal: bool):
super(RefreshGameMetaWorker, self).__init__()
self.signals = RefreshGameMetaWorker.Signals()
self.core = LegendaryCoreSingleton()
if platforms:
self.platforms = platforms
else:
self.platforms = ["Windows"]
self.skip_ue = not include_unreal
def run_real(self) -> None:
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()
class LegendarySettings(QWidget, Ui_LegendarySettings):
def __init__(self, parent=None):
super(LegendarySettings, self).__init__(parent=parent)
self.setupUi(self)
self.settings = QSettings(self)
self.core = LegendaryCoreSingleton()
# Platform specific installation directory for macOS games
if pf.system() == "Darwin":
self.mac_install_dir = PathEdit(
self.core.get_default_install_dir("Mac"),
placeholder=self.tr("Default installation folder for macOS games"),
file_mode=QFileDialog.DirectoryOnly,
save_func=self.__mac_path_save,
)
self.install_dir_layout.addWidget(self.mac_install_dir)
# Platform-independent installation directory
self.install_dir = PathEdit(
self.core.get_default_install_dir(),
placeholder=self.tr("Default installation folder for Windows games"),
file_mode=QFileDialog.DirectoryOnly,
save_func=self.__win_path_save,
)
self.install_dir_layout.addWidget(self.install_dir)
# Max Workers
max_workers = self.core.lgd.config["Legendary"].getint(
"max_workers", fallback=0
)
self.max_worker_spin.setValue(max_workers)
self.max_worker_spin.valueChanged.connect(self.max_worker_save)
# Max memory
max_memory = self.core.lgd.config["Legendary"].getint("max_memory", fallback=0)
self.max_memory_spin.setValue(max_memory)
self.max_memory_spin.valueChanged.connect(self.max_memory_save)
# Preferred CDN
preferred_cdn = self.core.lgd.config["Legendary"].get(
"preferred_cdn", fallback=""
)
self.preferred_cdn_line.setText(preferred_cdn)
self.preferred_cdn_line.textChanged.connect(self.preferred_cdn_save)
# Disable HTTPS
disable_https = self.core.lgd.config["Legendary"].getboolean(
"disable_https", fallback=False
)
self.disable_https_check.setChecked(disable_https)
self.disable_https_check.stateChanged.connect(self.disable_https_save)
# Cleanup
self.clean_button.clicked.connect(lambda: self.cleanup(False))
self.clean_keep_manifests_button.clicked.connect(lambda: self.cleanup(True))
self.locale_edit = IndicatorLineEdit(
f"{self.core.language_code}-{self.core.country_code}",
edit_func=self.locale_edit_cb,
save_func=self.locale_save_cb,
horiz_policy=QSizePolicy.Minimum,
parent=self,
)
self.locale_layout.addWidget(self.locale_edit)
self.fetch_win32_check.setChecked(self.settings.value(*options.win32_meta))
self.fetch_win32_check.stateChanged.connect(
lambda: self.settings.setValue(options.win32_meta.key, self.fetch_win32_check.isChecked())
)
self.fetch_macos_check.setChecked(self.settings.value(*options.macos_meta))
self.fetch_macos_check.stateChanged.connect(
lambda: self.settings.setValue(options.macos_meta.key, self.fetch_macos_check.isChecked())
)
self.fetch_macos_check.setDisabled(pf.system() == "Darwin")
self.fetch_unreal_check.setChecked(self.settings.value(*options.unreal_meta))
self.fetch_unreal_check.stateChanged.connect(
lambda: self.settings.setValue(options.unreal_meta.key, self.fetch_unreal_check.isChecked())
)
self.exclude_non_asset_check.setChecked(self.settings.value(*options.exclude_non_asset))
self.exclude_non_asset_check.stateChanged.connect(
lambda: self.settings.setValue(options.exclude_non_asset.key, self.exclude_non_asset_check.isChecked())
)
self.exclude_entitlements_check.setChecked(self.settings.value(*options.exclude_entitlements))
self.exclude_entitlements_check.stateChanged.connect(
lambda: self.settings.setValue(options.exclude_entitlements.key, self.exclude_entitlements_check.isChecked())
)
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
def locale_edit_cb(text: str) -> Tuple[bool, str, int]:
if text:
if re.match("^[a-zA-Z]{2,3}[-_][a-zA-Z]{2,3}$", text):
language, country = text.split("-" if "-" in text else "_")
text = "-".join([language.lower(), country.upper()])
if bool(re.match("^[a-z]{2,3}-[A-Z]{2,3}$", text)):
return True, text, IndicatorReasonsCommon.VALID
else:
return False, text, IndicatorReasonsCommon.WRONG_FORMAT
else:
return True, text, IndicatorReasonsCommon.VALID
def locale_save_cb(self, text: str):
if text:
self.core.egs.language_code, self.core.egs.country_code = text.split("-")
self.core.lgd.config.set("Legendary", "locale", text)
else:
if self.core.lgd.config.has_option("Legendary", "locale"):
self.core.lgd.config.remove_option("Legendary", "locale")
self.core.lgd.save_config()
def __mac_path_save(self, text: str) -> None:
self.__path_save(text, "mac_install_dir")
def __win_path_save(self, text: str) -> None:
self.__path_save(text, "install_dir")
if pf.system() != "Darwin":
self.__mac_path_save(text)
def __path_save(self, text: str, option: str = "Windows"):
self.core.lgd.config["Legendary"][option] = text
if not text and option in self.core.lgd.config["Legendary"].keys():
self.core.lgd.config["Legendary"].pop(option)
else:
logger.debug(f"Set %s option in config to %s", option, text)
self.core.lgd.save_config()
def max_worker_save(self, workers: str):
if workers := int(workers):
self.core.lgd.config.set("Legendary", "max_workers", str(workers))
else:
self.core.lgd.config.remove_option("Legendary", "max_workers")
self.core.lgd.save_config()
def max_memory_save(self, memory: str):
if memory := int(memory):
self.core.lgd.config.set("Legendary", "max_memory", str(memory))
else:
self.core.lgd.config.remove_option("Legendary", "max_memory")
self.core.lgd.save_config()
def preferred_cdn_save(self, cdn: str):
if cdn:
self.core.lgd.config.set("Legendary", "preferred_cdn", cdn.strip())
else:
self.core.lgd.config.remove_option("Legendary", "preferred_cdn")
self.core.lgd.save_config()
def disable_https_save(self, checked: int):
self.core.lgd.config.set(
"Legendary", "disable_https", str(bool(checked)).lower()
)
self.core.lgd.save_config()
def cleanup(self, keep_manifests: bool):
before = self.core.lgd.get_dir_size()
logger.debug("Removing app metadata...")
app_names = set(g.app_name for g in self.core.get_assets(update_assets=False))
self.core.lgd.clean_metadata(app_names)
if not keep_manifests:
logger.debug("Removing manifests...")
installed = [
(ig.app_name, ig.version, ig.platform) for ig in self.core.get_installed_list()
]
installed.extend(
(ig.app_name, ig.version, ig.platform) for ig in self.core.get_installed_dlc_list()
)
self.core.lgd.clean_manifests(installed)
logger.debug("Removing tmp data")
self.core.lgd.clean_tmp_data()
after = self.core.lgd.get_dir_size()
logger.info(
f"Cleanup complete! Removed {(before - after) / 1024 / 1024:.02f} MiB."
)
if (before - after) > 0:
QMessageBox.information(
self,
"Cleanup",
self.tr("Cleanup complete! Successfully removed {}").format(
format_size(before - after)
),
)
else:
QMessageBox.information(self, "Cleanup", "Nothing to clean")