From 7609553b12091d9a40ec880d6e0b8cfa747288ef Mon Sep 17 00:00:00 2001 From: derrod Date: Wed, 16 Dec 2020 12:35:31 +0100 Subject: [PATCH] [core/utils] More generic/robust selective dl, add support for Fortnite Existing installations should ask for the install tags that should be used on first update. It will now be easier to add more games as well. --- legendary/cli.py | 13 ++++++----- legendary/utils/cli.py | 31 +++++++++++++++++++++++++ legendary/utils/game_workarounds.py | 36 ----------------------------- legendary/utils/selective_dl.py | 35 ++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 42 deletions(-) create mode 100644 legendary/utils/selective_dl.py diff --git a/legendary/cli.py b/legendary/cli.py index 0fb68f5..de8e434 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -21,10 +21,10 @@ from legendary import __version__, __codename__ from legendary.core import LegendaryCore from legendary.models.exceptions import InvalidCredentialsError from legendary.models.game import SaveGameStatus, VerifyResult -from legendary.utils.cli import get_boolean_choice +from legendary.utils.cli import get_boolean_choice, sdl_prompt from legendary.utils.custom_parser import AliasedSubParsersAction from legendary.utils.lfs import validate_files -from legendary.utils.game_workarounds import cyber_prompt_2077 +from legendary.utils.selective_dl import get_sdl_appname # todo custom formatter for cli logger (clean info, highlighted error/warning) logging.basicConfig( @@ -579,14 +579,15 @@ class LegendaryCLI: logger.info(f'Using existing repair file: {repair_file}') # Workaround for Cyberpunk 2077 preload - if game.app_name.startswith('Ginger'): - if not self.core.is_installed(game.app_name): - args.install_tag = cyber_prompt_2077() + if not args.install_tag and ((sdl_name := get_sdl_appname(game.app_name)) is not None): + config_tags = self.core.lgd.config.get(game.app_name, 'install_tags', fallback=None) + if not self.core.is_installed(game.app_name) or config_tags is None: + args.install_tag = sdl_prompt(sdl_name, game.app_title) if game.app_name not in self.core.lgd.config: self.core.lgd.config[game.app_name] = dict() self.core.lgd.config.set(game.app_name, 'install_tags', ','.join(args.install_tag)) else: - args.install_tag = self.core.lgd.config.get(game.app_name, 'install_tags', fallback='').split(',') + args.install_tag = config_tags.split(',') logger.info('Preparing download...') # todo use status queue to print progress from CLI diff --git a/legendary/utils/cli.py b/legendary/utils/cli.py index c044144..2ee7fcd 100644 --- a/legendary/utils/cli.py +++ b/legendary/utils/cli.py @@ -1,3 +1,6 @@ +from legendary.utils.selective_dl import games + + def get_boolean_choice(prompt, default=True): if default: yn = 'Y/n' @@ -11,3 +14,31 @@ def get_boolean_choice(prompt, default=True): return True else: return False + + +def sdl_prompt(app_name, title): + tags = [''] + if '__required' in games[app_name]: + tags.extend(games[app_name]['__required']['tags']) + + print(f'You are about to install {title}, this game supports selective downloads.') + print('The following optional packs are available:') + for tag, info in games[app_name].items(): + if tag == '__required': + continue + print(' *', tag, '-', info['name']) + + print('Please enter a comma-separated list of optional packs to install (leave blank for defaults)') + examples = ','.join([g for g in games[app_name].keys() if g != '__required'][:2]) + choices = input(f'Additional packs [e.g. {examples}]: ') + if not choices: + return tags + + for c in choices.split(','): + c = c.strip() + if c in games[app_name]: + tags.extend(games[app_name][c]['tags']) + else: + print('Invalid tag:', c) + + return tags diff --git a/legendary/utils/game_workarounds.py b/legendary/utils/game_workarounds.py index ee16ec4..ecc8d60 100644 --- a/legendary/utils/game_workarounds.py +++ b/legendary/utils/game_workarounds.py @@ -17,39 +17,3 @@ def is_opt_enabled(app_name, version): if version in versions or not versions: return True return False - - -_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': 'русский'}, - 'zh': {'tags': ['voice_zh_cn'], 'name': '中文(中国)'} -} - - -def cyber_prompt_2077(): - print('You are about to install Cyberpunk 2077, this game supports selective downloads for langauge packs.') - print('The following language packs are available:') - for tag, info in _cyberpunk_sdl.items(): - print(' *', tag, '-', info['name']) - - print('Please enter a comma-separated list of language packs to install (leave blank for english only)') - choices = input('Additional languages [e.g. de,fr]: ') - if not choices: - return [''] - - tags = [''] - for c in choices.split(','): - c = c.strip() - if c in _cyberpunk_sdl: - tags.extend(_cyberpunk_sdl[c]['tags']) - else: - print('Invalid tag:', c) - - return tags diff --git a/legendary/utils/selective_dl.py b/legendary/utils/selective_dl.py new file mode 100644 index 0000000..2a0b405 --- /dev/null +++ b/legendary/utils/selective_dl.py @@ -0,0 +1,35 @@ +_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': '中文(中国)'} +} + +_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) 中文(中国)'} +} + +games = { + 'Fortnite': _fortnite_sdl, + 'Ginger': _cyberpunk_sdl +} + + +def get_sdl_appname(app_name): + for k in games.keys(): + if app_name.startswith(k): + return k + return None