diff --git a/legendary/cli.py b/legendary/cli.py index 998005d..06dd7c0 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -27,7 +27,7 @@ from legendary.utils.custom_parser import HiddenAliasSubparsersAction from legendary.utils.env import is_windows_mac_or_pyi from legendary.lfs.eos import add_registry_entries, query_registry_entries, remove_registry_entries from legendary.lfs.utils import validate_files, clean_filename -from legendary.utils.selective_dl import get_sdl_appname +from legendary.utils.selective_dl import get_sdl_data from legendary.lfs.wine_helpers import read_registry, get_shell_folders, case_insensitive_file_search # todo custom formatter for cli logger (clean info, highlighted error/warning) @@ -912,8 +912,8 @@ class LegendaryCLI: logger.info(f'Using existing repair file: {repair_file}') # check if SDL should be disabled - sdl_enabled = not args.install_tag and not game.is_dlc - config_tags = self.core.lgd.config.get(game.app_name, 'install_tags', fallback=None) + sdl_enabled = not args.install_tag + config_tags = self.core.lgd.config.get(game.app_name, 'install_opts', fallback=None) config_disable_sdl = self.core.lgd.config.getboolean(game.app_name, 'disable_sdl', fallback=False) # remove config flag if SDL is reset if config_disable_sdl and args.reset_sdl and not args.disable_sdl: @@ -930,19 +930,20 @@ class LegendaryCLI: elif config_disable_sdl or args.disable_sdl: sdl_enabled = False - if sdl_enabled and ((sdl_name := get_sdl_appname(game.app_name)) is not None): + if sdl_enabled: if not self.core.is_installed(game.app_name) or config_tags is None or args.reset_sdl: - sdl_data = self.core.get_sdl_data(sdl_name, platform=args.platform) + sdl_data = get_sdl_data(self.core.lgd.egl_content_path, game.app_name, game.app_version(args.platform)) if sdl_data: if args.skip_sdl: - args.install_tag = [''] - if '__required' in sdl_data: - args.install_tag.extend(sdl_data['__required']['tags']) + args.install_tag = [] + for entry in sdl_data['Data']: + if entry.get('IsRequired', 'false').lower() == 'true': + args.install_tag.extend(entry.get('Tags', [])) else: args.install_tag = sdl_prompt(sdl_data, game.app_title) - self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag)) + # self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag)) else: - logger.error(f'Unable to get SDL data for {sdl_name}') + logger.error(f'Unable to get SDL data for {game.app_name}') else: args.install_tag = config_tags.split(',') elif args.install_tag and not game.is_dlc and not args.no_install: diff --git a/legendary/core.py b/legendary/core.py index 7b715bb..4b5fa97 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -38,7 +38,6 @@ from legendary.utils.env import is_windows_mac_or_pyi from legendary.lfs.eos import EOSOverlayApp, query_registry_entries from legendary.utils.game_workarounds import is_opt_enabled, update_workarounds, get_exe_override from legendary.utils.savegame_helper import SaveGameHelper -from legendary.utils.selective_dl import games as sdl_games from legendary.lfs.wine_helpers import read_registry, get_shell_folders, case_insensitive_path_search diff --git a/legendary/utils/selective_dl.py b/legendary/utils/selective_dl.py index 6fa37df..21e3d7c 100644 --- a/legendary/utils/selective_dl.py +++ b/legendary/utils/selective_dl.py @@ -1,41 +1,29 @@ -# This file contains definitions for selective downloading for supported games +# This file contains utilities for selective downloads in regards to parsing and evaluating sdlmeta # coding: utf-8 -_cyberpunk_sdl = { - 'de': {'tags': ['voice_de_de'], 'name': 'Deutsch'}, - 'es': {'tags': ['voice_es_es'], 'name': 'español (España)'}, - 'fr': {'tags': ['voice_fr_fr'], 'name': 'français'}, - 'it': {'tags': ['voice_it_it'], 'name': 'italiano'}, - 'ja': {'tags': ['voice_ja_jp'], 'name': '日本語'}, - 'ko': {'tags': ['voice_ko_kr'], 'name': '한국어'}, - 'pl': {'tags': ['voice_pl_pl'], 'name': 'polski'}, - 'pt': {'tags': ['voice_pt_br'], 'name': 'português brasileiro'}, - 'ru': {'tags': ['voice_ru_ru'], 'name': 'русский'}, - 'cn': {'tags': ['voice_zh_cn'], 'name': '中文(中国)'} -} +import os +import json +from epic_expreval import Tokenizer, EvaluationContext -_fortnite_sdl = { - '__required': {'tags': ['chunk0', 'chunk10'], 'name': 'Fortnite Core'}, - 'stw': {'tags': ['chunk11', 'chunk11optional'], 'name': 'Fortnite Save the World'}, - 'hd_textures': {'tags': ['chunk10optional'], 'name': 'High Resolution Textures'}, - 'lang_de': {'tags': ['chunk2'], 'name': '(Language Pack) Deutsch'}, - 'lang_fr': {'tags': ['chunk5'], 'name': '(Language Pack) français'}, - 'lang_pl': {'tags': ['chunk7'], 'name': '(Language Pack) polski'}, - 'lang_ru': {'tags': ['chunk8'], 'name': '(Language Pack) русский'}, - 'lang_cn': {'tags': ['chunk9'], 'name': '(Language Pack) 中文(中国)'} -} +def run_expression(expression, input): + """Runs expression with default EvauluationContext""" + tk = Tokenizer(expression, EvaluationContext()) + tk.compile() + return tk.execute(input) -games = { - 'Fortnite': _fortnite_sdl, - 'Ginger': _cyberpunk_sdl -} - - -def get_sdl_appname(app_name): - for k in games.keys(): - if k.endswith('_Mac'): - continue - - if app_name.startswith(k): - return k - return None +def get_sdl_data(location, app_name, app_version): + applying_meta = [] + for sdmeta_file in location.glob('*sdmeta'): + sdmeta = json.loads(sdmeta_file.read_text('utf-8-sig')) + is_applying_build = any( + build + for build in sdmeta.get('Builds') + if build.get('Asset') == app_name + and run_expression(build['Version'], app_version) + ) + if is_applying_build: + applying_meta.append(sdmeta) + + if applying_meta: + return applying_meta[-1] + return None \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 481d045..5c9dce3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ requests<3.0 filelock +epic-expreval=0.2 \ No newline at end of file diff --git a/setup.py b/setup.py index d4f7e05..c58edd1 100644 --- a/setup.py +++ b/setup.py @@ -36,6 +36,7 @@ setup( ), install_requires=[ 'requests<3.0', + 'epic-expreval==0.2', 'setuptools', 'wheel', 'filelock'