feat: support required tags

This commit is contained in:
Paweł Lidwin 2025-11-04 11:05:00 +01:00
parent e9b9b60874
commit 9ebe1f6e8b
No known key found for this signature in database
GPG key ID: C6EDF064F9FEE1E1
5 changed files with 38 additions and 48 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -1,2 +1,3 @@
requests<3.0
filelock
epic-expreval=0.2

View file

@ -36,6 +36,7 @@ setup(
),
install_requires=[
'requests<3.0',
'epic-expreval==0.2',
'setuptools',
'wheel',
'filelock'