mirror of
https://github.com/derrod/legendary.git
synced 2024-12-22 17:55:27 +00:00
[cli/core/lfs] Add support for mixing platforms
This commit is contained in:
parent
ee3f9a3e07
commit
f280d53496
|
@ -194,7 +194,7 @@ class LegendaryCLI:
|
|||
logger.info('Getting game list... (this may take a while)')
|
||||
|
||||
games, dlc_list = self.core.get_game_and_dlc_list(
|
||||
platform_override=args.platform_override, skip_ue=not args.include_ue,
|
||||
platform=args.platform, skip_ue=not args.include_ue,
|
||||
force_refresh=args.force_refresh
|
||||
)
|
||||
# Get information for games that cannot be installed through legendary (yet), such
|
||||
|
@ -216,24 +216,24 @@ class LegendaryCLI:
|
|||
writer = csv.writer(stdout, dialect='excel-tab' if args.tsv else 'excel', lineterminator='\n')
|
||||
writer.writerow(['App name', 'App title', 'Version', 'Is DLC'])
|
||||
for game in games:
|
||||
writer.writerow((game.app_name, game.app_title, game.app_version, False))
|
||||
for dlc in dlc_list[game.asset_info.catalog_item_id]:
|
||||
writer.writerow((dlc.app_name, dlc.app_title, dlc.app_version, True))
|
||||
writer.writerow((game.app_name, game.app_title, game.app_version(args.platform), False))
|
||||
for dlc in dlc_list[game.asset_infos[args.platform].catalog_item_id]:
|
||||
writer.writerow((dlc.app_name, dlc.app_title, dlc.app_version(args.platform), True))
|
||||
return
|
||||
|
||||
if args.json:
|
||||
_out = []
|
||||
for game in games:
|
||||
_j = vars(game)
|
||||
_j['dlcs'] = [vars(dlc) for dlc in dlc_list[game.asset_info.catalog_item_id]]
|
||||
_j['dlcs'] = [vars(dlc) for dlc in dlc_list[game.asset_infos[args.platform].catalog_item_id]]
|
||||
_out.append(_j)
|
||||
|
||||
return self._print_json(_out, args.pretty_json)
|
||||
|
||||
print('\nAvailable games:')
|
||||
for game in games:
|
||||
print(f' * {game.app_title.strip()} (App name: {game.app_name} | Version: {game.app_version})')
|
||||
if not game.app_version:
|
||||
print(f' * {game.app_title.strip()} (App name: {game.app_name} | Version: {game.app_version(args.platform)})')
|
||||
if not game.app_version(args.platform):
|
||||
_store = game.third_party_store
|
||||
if _store == 'Origin':
|
||||
print(f' - This game has to be activated, installed, and launched via Origin, use '
|
||||
|
@ -242,9 +242,9 @@ class LegendaryCLI:
|
|||
print(f' ! This game has to be installed through third-party store ({_store}, not supported)')
|
||||
else:
|
||||
print(f' ! No version information (unknown cause)')
|
||||
for dlc in dlc_list[game.asset_info.catalog_item_id]:
|
||||
print(f' + {dlc.app_title} (App name: {dlc.app_name} | Version: {dlc.app_version})')
|
||||
if not dlc.app_version:
|
||||
for dlc in dlc_list[game.asset_infos[args.platform].catalog_item_id]:
|
||||
print(f' + {dlc.app_title} (App name: {dlc.app_name} | Version: {dlc.app_version(args.platform)})')
|
||||
if not dlc.app_version(args.platform):
|
||||
print(' ! This DLC is included in the game does not have to be downloaded separately')
|
||||
|
||||
print(f'\nTotal: {len(games)}')
|
||||
|
@ -263,7 +263,8 @@ class LegendaryCLI:
|
|||
versions = dict()
|
||||
for game in games:
|
||||
try:
|
||||
versions[game.app_name] = self.core.get_asset(game.app_name).build_version
|
||||
print(f'{game.title} (App name: {game.app_name}, platform: {game.platform})')
|
||||
versions[game.app_name] = self.core.get_asset(game.app_name, platform=game.platform).build_version
|
||||
except ValueError:
|
||||
logger.warning(f'Metadata for "{game.app_name}" is missing, the game may have been removed from '
|
||||
f'your account or not be in legendary\'s database yet, try rerunning the command '
|
||||
|
@ -315,7 +316,7 @@ class LegendaryCLI:
|
|||
print(f'\nTotal: {len(games)}')
|
||||
|
||||
def list_files(self, args):
|
||||
if args.platform_override:
|
||||
if args.platform:
|
||||
args.force_download = True
|
||||
|
||||
if not args.override_manifest and not args.app_name:
|
||||
|
@ -340,7 +341,7 @@ class LegendaryCLI:
|
|||
if not game:
|
||||
logger.fatal(f'Could not fetch metadata for "{args.app_name}" (check spelling/account ownership)')
|
||||
exit(1)
|
||||
manifest_data, _ = self.core.get_cdn_manifest(game, platform_override=args.platform_override)
|
||||
manifest_data, _ = self.core.get_cdn_manifest(game, platform=args.platform)
|
||||
|
||||
manifest = self.core.load_manifest(manifest_data)
|
||||
files = sorted(manifest.file_manifest_list.elements,
|
||||
|
@ -678,6 +679,7 @@ class LegendaryCLI:
|
|||
args.app_name = self._resolve_aliases(args.app_name)
|
||||
if self.core.is_installed(args.app_name):
|
||||
igame = self.core.get_installed_game(args.app_name)
|
||||
args.platform = igame.platform
|
||||
if igame.needs_verification and not args.repair_mode:
|
||||
logger.info('Game needs to be verified before updating, switching to repair mode...')
|
||||
args.repair_mode = True
|
||||
|
@ -695,6 +697,10 @@ class LegendaryCLI:
|
|||
logger.error('Login failed! Cannot continue with download process.')
|
||||
exit(1)
|
||||
|
||||
# default to windows unless installed game or command line has overriden it
|
||||
if not args.platform:
|
||||
args.platform = 'Windows'
|
||||
|
||||
if args.file_prefix or args.file_exclude_prefix:
|
||||
args.no_install = True
|
||||
|
||||
|
@ -703,9 +709,6 @@ class LegendaryCLI:
|
|||
logger.error(f'Update requested for "{args.app_name}", but app not installed!')
|
||||
exit(1)
|
||||
|
||||
if args.platform_override:
|
||||
args.no_install = True
|
||||
|
||||
game = self.core.get_game(args.app_name, update_meta=True)
|
||||
|
||||
if not game:
|
||||
|
@ -805,7 +808,7 @@ class LegendaryCLI:
|
|||
override_manifest=args.override_manifest,
|
||||
override_old_manifest=args.override_old_manifest,
|
||||
override_base_url=args.override_base_url,
|
||||
platform_override=args.platform_override,
|
||||
platform=args.platform,
|
||||
file_prefix_filter=args.file_prefix,
|
||||
file_exclude_filter=args.file_exclude_prefix,
|
||||
file_install_tag=args.install_tag,
|
||||
|
@ -901,7 +904,8 @@ class LegendaryCLI:
|
|||
if dlcs and not args.skip_dlcs:
|
||||
print('The following DLCs are available for this game:')
|
||||
for dlc in dlcs:
|
||||
print(f' - {dlc.app_title} (App name: {dlc.app_name}, version: {dlc.app_version})')
|
||||
print(f' - {dlc.app_title} (App name: {dlc.app_name}, version: '
|
||||
f'{dlc.app_version(args.platform)})')
|
||||
print('Manually installing DLCs works the same; just use the DLC app name instead.')
|
||||
|
||||
install_dlcs = not args.skip_dlcs
|
||||
|
@ -1344,8 +1348,11 @@ class LegendaryCLI:
|
|||
info_items = dict(game=list(), manifest=list(), install=list())
|
||||
InfoItem = namedtuple('InfoItem', ['name', 'json_name', 'value', 'json_value'])
|
||||
|
||||
game = self.core.get_game(app_name, update_meta=not args.offline)
|
||||
if game and not self.core.asset_available(game):
|
||||
if self.core.is_installed(app_name):
|
||||
args.platform = self.core.get_installed_game(app_name).platform
|
||||
|
||||
game = self.core.get_game(app_name, update_meta=not args.offline, platform=args.platform)
|
||||
if game and not self.core.asset_available(game, platform=args.platform):
|
||||
logger.warning(f'Asset information for "{game.app_name}" is missing, the game may have been removed from '
|
||||
f'your account or you may be logged in with a different account than the one used to build '
|
||||
f'legendary\'s metadata database.')
|
||||
|
@ -1369,11 +1376,11 @@ class LegendaryCLI:
|
|||
elif game:
|
||||
entitlements = self.core.egs.get_user_entitlements()
|
||||
# get latest metadata and manifest
|
||||
if game.asset_info.catalog_item_id:
|
||||
egl_meta = self.core.egs.get_game_info(game.asset_info.namespace,
|
||||
game.asset_info.catalog_item_id)
|
||||
if game.asset_infos[args.platform].catalog_item_id:
|
||||
egl_meta = self.core.egs.get_game_info(game.asset_infos[args.platform].namespace,
|
||||
game.asset_infos[args.platform].catalog_item_id)
|
||||
game.metadata = egl_meta
|
||||
manifest_data, _ = self.core.get_cdn_manifest(game)
|
||||
manifest_data, _ = self.core.get_cdn_manifest(game, args.platform)
|
||||
else:
|
||||
# Origin games do not have asset info, so fall back to info from metadata
|
||||
egl_meta = self.core.egs.get_game_info(game.metadata['namespace'],
|
||||
|
@ -1384,7 +1391,10 @@ class LegendaryCLI:
|
|||
game_infos = info_items['game']
|
||||
game_infos.append(InfoItem('App name', 'app_name', game.app_name, game.app_name))
|
||||
game_infos.append(InfoItem('Title', 'title', game.app_title, game.app_title))
|
||||
game_infos.append(InfoItem('Latest version', 'version', game.app_version, game.app_version))
|
||||
game_infos.append(InfoItem('Latest version', 'version', game.app_version(args.platform),
|
||||
game.app_version(args.platform)))
|
||||
all_versions = {k: v.build_version for k,v in game.asset_infos.items()}
|
||||
game_infos.append(InfoItem('All versions', 'platform_versions', all_versions, all_versions))
|
||||
game_infos.append(InfoItem('Cloud saves supported', 'cloud_saves_supported',
|
||||
game.supports_cloud_saves, game.supports_cloud_saves))
|
||||
if game.supports_cloud_saves:
|
||||
|
@ -1447,6 +1457,7 @@ class LegendaryCLI:
|
|||
igame = self.core.get_installed_game(app_name)
|
||||
if igame:
|
||||
installation_info = info_items['install']
|
||||
installation_info.append(InfoItem('Platform', 'platform', igame.platform, igame.platform))
|
||||
installation_info.append(InfoItem('Version', 'version', igame.version, igame.version))
|
||||
disk_size_human = f'{igame.install_size / 1024 / 1024 / 1024:.02f} GiB'
|
||||
installation_info.append(InfoItem('Install size', 'disk_size', disk_size_human,
|
||||
|
@ -1586,6 +1597,10 @@ class LegendaryCLI:
|
|||
print(f'- {item.name}:')
|
||||
for list_item in item.value:
|
||||
print(' + ', list_item)
|
||||
elif isinstance(item.value, dict):
|
||||
print(f'- {item.name}:')
|
||||
for k, v in item.value.items():
|
||||
print(' + ', k, ':', v)
|
||||
else:
|
||||
print(f'- {item.name}: {item.value}')
|
||||
|
||||
|
@ -1809,8 +1824,8 @@ def main():
|
|||
help='Only update, do not do anything if specified app is not installed')
|
||||
install_parser.add_argument('--dlm-debug', dest='dlm_debug', action='store_true',
|
||||
help='Set download manager and worker processes\' loglevel to debug')
|
||||
install_parser.add_argument('--platform', dest='platform_override', action='store', metavar='<Platform>',
|
||||
type=str, help='Platform override for download (also sets --no-install)')
|
||||
install_parser.add_argument('--platform', dest='platform', action='store', metavar='<Platform>',
|
||||
type=str, help='Platform override for download')
|
||||
install_parser.add_argument('--prefix', dest='file_prefix', action='append', metavar='<prefix>',
|
||||
help='Only fetch files whose path starts with <prefix> (case insensitive)')
|
||||
install_parser.add_argument('--exclude', dest='file_exclude_prefix', action='append', metavar='<prefix>',
|
||||
|
@ -1891,7 +1906,7 @@ def main():
|
|||
launch_parser.add_argument('--no-wine', dest='no_wine', help=argparse.SUPPRESS,
|
||||
action='store_true', default=True)
|
||||
|
||||
list_parser.add_argument('--platform', dest='platform_override', action='store', metavar='<Platform>',
|
||||
list_parser.add_argument('--platform', dest='platform', action='store', metavar='<Platform>', default='Windows',
|
||||
type=str, help='Override platform that games are shown for (e.g. Win32/Mac)')
|
||||
list_parser.add_argument('--include-ue', dest='include_ue', action='store_true',
|
||||
help='Also include Unreal Engine content (Engine/Marketplace) in list')
|
||||
|
@ -1916,8 +1931,8 @@ def main():
|
|||
|
||||
list_files_parser.add_argument('--force-download', dest='force_download', action='store_true',
|
||||
help='Always download instead of using on-disk manifest')
|
||||
list_files_parser.add_argument('--platform', dest='platform_override', action='store', metavar='<Platform>',
|
||||
type=str, help='Platform override for download (disables install)')
|
||||
list_files_parser.add_argument('--platform', dest='platform', action='store', metavar='<Platform>',
|
||||
type=str, help='Platform override for download', default='Windows')
|
||||
list_files_parser.add_argument('--manifest', dest='override_manifest', action='store', metavar='<uri>',
|
||||
help='Manifest URL or path to use instead of the CDN one')
|
||||
list_files_parser.add_argument('--csv', dest='csv', action='store_true', help='Output in CSV format')
|
||||
|
@ -1982,6 +1997,8 @@ def main():
|
|||
help='Only print info available offline')
|
||||
info_parser.add_argument('--json', dest='json', action='store_true',
|
||||
help='Output information in JSON format')
|
||||
info_parser.add_argument('--platform', dest='platform', action='store', metavar='<Platform>',
|
||||
type=str, help='Platform override for download', default='Windows')
|
||||
|
||||
args, extra = parser.parse_known_args()
|
||||
|
||||
|
|
|
@ -312,90 +312,93 @@ class LegendaryCore:
|
|||
if _aliases_enabled and (force or not self.lgd.aliases):
|
||||
self.lgd.generate_aliases()
|
||||
|
||||
def get_assets(self, update_assets=False, platform_override=None) -> List[GameAsset]:
|
||||
def get_assets(self, update_assets=False, platform='Windows') -> List[GameAsset]:
|
||||
# do not save and always fetch list when platform is overridden
|
||||
if platform_override:
|
||||
return [GameAsset.from_egs_json(a) for a in
|
||||
self.egs.get_game_assets(platform=platform_override)]
|
||||
|
||||
if not self.lgd.assets or update_assets:
|
||||
# if not logged in, return empty list
|
||||
if not self.egs.user:
|
||||
return []
|
||||
self.lgd.assets = [GameAsset.from_egs_json(a) for a in self.egs.get_game_assets()]
|
||||
|
||||
return self.lgd.assets
|
||||
if self.lgd.assets:
|
||||
assets = self.lgd.assets.copy()
|
||||
else:
|
||||
assets = dict()
|
||||
|
||||
def get_asset(self, app_name, update=False) -> GameAsset:
|
||||
if update:
|
||||
self.get_assets(update_assets=True)
|
||||
assets.update({
|
||||
platform: [
|
||||
GameAsset.from_egs_json(a) for a in
|
||||
self.egs.get_game_assets(platform=platform)
|
||||
]
|
||||
})
|
||||
|
||||
self.lgd.assets = assets
|
||||
|
||||
return self.lgd.assets[platform]
|
||||
|
||||
def get_asset(self, app_name, platform='Windows', update=False) -> GameAsset:
|
||||
if update or platform not in self.lgd.assets:
|
||||
self.get_assets(update_assets=True, platform=platform)
|
||||
|
||||
try:
|
||||
return next(i for i in self.lgd.assets if i.app_name == app_name)
|
||||
return next(i for i in self.lgd.assets[platform] if i.app_name == app_name)
|
||||
except StopIteration:
|
||||
raise ValueError
|
||||
|
||||
def asset_valid(self, app_name) -> bool:
|
||||
return any(i.app_name == app_name for i in self.lgd.assets)
|
||||
# EGL sync is only supported for Windows titles so this is fine
|
||||
return any(i.app_name == app_name for i in self.lgd.assets['Windows'])
|
||||
|
||||
def asset_available(self, game: Game) -> bool:
|
||||
def asset_available(self, game: Game, platform='Windows') -> bool:
|
||||
# Just say yes for Origin titles
|
||||
if game.third_party_store:
|
||||
return True
|
||||
|
||||
try:
|
||||
asset = self.get_asset(game.app_name)
|
||||
asset = self.get_asset(game.app_name, platform=platform)
|
||||
return asset is not None
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def get_game(self, app_name, update_meta=False) -> Game:
|
||||
def get_game(self, app_name, update_meta=False, platform='Windows') -> Game:
|
||||
if update_meta:
|
||||
self.get_game_list(True)
|
||||
self.get_game_list(True, platform=platform)
|
||||
return self.lgd.get_game_meta(app_name)
|
||||
|
||||
def get_game_list(self, update_assets=True) -> List[Game]:
|
||||
return self.get_game_and_dlc_list(update_assets=update_assets)[0]
|
||||
def get_game_list(self, update_assets=True, platform='Windows') -> List[Game]:
|
||||
return self.get_game_and_dlc_list(update_assets=update_assets, platform=platform)[0]
|
||||
|
||||
def get_game_and_dlc_list(self, update_assets=True, platform_override=None,
|
||||
def get_game_and_dlc_list(self, update_assets=True, platform='Windows',
|
||||
force_refresh=False, skip_ue=True) -> (List[Game], Dict[str, List[Game]]):
|
||||
_ret = []
|
||||
_dlc = defaultdict(list)
|
||||
meta_updated = False
|
||||
|
||||
for ga in self.get_assets(update_assets=update_assets,
|
||||
platform_override=platform_override):
|
||||
for ga in self.get_assets(update_assets=update_assets, platform=platform):
|
||||
if ga.namespace == 'ue' and skip_ue:
|
||||
continue
|
||||
|
||||
game = self.lgd.get_game_meta(ga.app_name)
|
||||
if update_assets and (not game or force_refresh or
|
||||
(game and game.app_version != ga.build_version and not platform_override)):
|
||||
if game and game.app_version != ga.build_version and not platform_override:
|
||||
(game and game.app_version(platform) != ga.build_version)):
|
||||
if game and game.app_version(platform) != ga.build_version:
|
||||
self.log.info(f'Updating meta for {game.app_name} due to build version mismatch')
|
||||
|
||||
eg_meta = self.egs.get_game_info(ga.namespace, ga.catalog_item_id)
|
||||
game = Game(app_name=ga.app_name, app_version=ga.build_version,
|
||||
app_title=eg_meta['title'], asset_info=ga, metadata=eg_meta)
|
||||
game.asset_infos[platform] = ga
|
||||
game = Game(app_name=ga.app_name, app_title=eg_meta['title'], metadata=eg_meta,
|
||||
asset_infos=game.asset_infos)
|
||||
|
||||
if not platform_override:
|
||||
meta_updated = True
|
||||
self.lgd.set_game_meta(game.app_name, game)
|
||||
|
||||
# replace asset info with the platform specific one if override is used
|
||||
if platform_override:
|
||||
game.app_version = ga.build_version
|
||||
game.asset_info = ga
|
||||
meta_updated = True
|
||||
self.lgd.set_game_meta(game.app_name, game)
|
||||
|
||||
if game.is_dlc:
|
||||
_dlc[game.metadata['mainGameItem']['id']].append(game)
|
||||
elif not any(i['path'] == 'mods' for i in game.metadata.get('categories', [])):
|
||||
_ret.append(game)
|
||||
|
||||
if not platform_override:
|
||||
self.update_aliases(force=meta_updated)
|
||||
if meta_updated:
|
||||
self._prune_metadata()
|
||||
self.update_aliases(force=meta_updated)
|
||||
if meta_updated:
|
||||
self._prune_metadata()
|
||||
|
||||
return _ret, _dlc
|
||||
|
||||
|
@ -440,8 +443,7 @@ class LegendaryCore:
|
|||
game = self.lgd.get_game_meta(libitem['appName'])
|
||||
if not game or force_refresh:
|
||||
eg_meta = self.egs.get_game_info(libitem['namespace'], libitem['catalogItemId'])
|
||||
game = Game(app_name=libitem['appName'], app_version=None,
|
||||
app_title=eg_meta['title'], asset_info=None, metadata=eg_meta)
|
||||
game = Game(app_name=libitem['appName'], app_title=eg_meta['title'], metadata=eg_meta)
|
||||
self.lgd.set_game_meta(game.app_name, game)
|
||||
|
||||
if game.is_dlc:
|
||||
|
@ -453,7 +455,7 @@ class LegendaryCore:
|
|||
self.update_aliases(force=True)
|
||||
return _ret, _dlc
|
||||
|
||||
def get_dlc_for_game(self, app_name):
|
||||
def get_dlc_for_game(self, app_name, platform='Windows'):
|
||||
game = self.get_game(app_name)
|
||||
if not game:
|
||||
self.log.warning(f'Metadata for {app_name} is missing!')
|
||||
|
@ -462,8 +464,8 @@ class LegendaryCore:
|
|||
if game.is_dlc: # dlc shouldn't have DLC
|
||||
return []
|
||||
|
||||
_, dlcs = self.get_game_and_dlc_list(update_assets=False)
|
||||
return dlcs[game.asset_info.catalog_item_id]
|
||||
_, dlcs = self.get_game_and_dlc_list(update_assets=False, platform=platform)
|
||||
return dlcs[game.asset_infos['Windows'].catalog_item_id]
|
||||
|
||||
def get_installed_list(self, include_dlc=False) -> List[InstalledGame]:
|
||||
if self.egl_sync_enabled:
|
||||
|
@ -539,6 +541,11 @@ class LegendaryCore:
|
|||
install = self.lgd.get_installed_game(app_name)
|
||||
game = self.lgd.get_game_meta(app_name)
|
||||
|
||||
# Disable wine for non-Windows executables (e.g. native macOS)
|
||||
if not install.platform.startswith('Win'):
|
||||
disable_wine = True
|
||||
wine_pfx = wine_bin = None
|
||||
|
||||
if executable_override or (executable_override := self.lgd.config.get(app_name, 'override_exe', fallback=None)):
|
||||
game_exe = executable_override.replace('\\', '/')
|
||||
exe_path = os.path.join(install.install_path, game_exe)
|
||||
|
@ -584,10 +591,11 @@ class LegendaryCore:
|
|||
|
||||
if install.requires_ot and not offline:
|
||||
self.log.info('Getting ownership token.')
|
||||
ovt = self.egs.get_ownership_token(game.asset_info.namespace,
|
||||
game.asset_info.catalog_item_id)
|
||||
ovt = self.egs.get_ownership_token(game.asset_infos['Windows'].namespace,
|
||||
game.asset_infos['Windows'].catalog_item_id)
|
||||
ovt_path = os.path.join(self.lgd.get_tmp_path(),
|
||||
f'{game.asset_info.namespace}{game.asset_info.catalog_item_id}.ovt')
|
||||
f'{game.asset_infos["Windows"].namespace}'
|
||||
f'{game.asset_infos["Windows"].catalog_item_id}.ovt')
|
||||
with open(ovt_path, 'wb') as f:
|
||||
f.write(ovt)
|
||||
params.egl_parameters.append(f'-epicovt={ovt_path}')
|
||||
|
@ -975,10 +983,9 @@ class LegendaryCore:
|
|||
old_bytes = self.lgd.load_manifest(app_name, igame.version)
|
||||
return old_bytes, igame.base_urls
|
||||
|
||||
def get_cdn_urls(self, game, platform_override=''):
|
||||
platform = 'Windows' if not platform_override else platform_override
|
||||
m_api_r = self.egs.get_game_manifest(game.asset_info.namespace,
|
||||
game.asset_info.catalog_item_id,
|
||||
def get_cdn_urls(self, game, platform='Windows'):
|
||||
m_api_r = self.egs.get_game_manifest(game.asset_infos[platform].namespace,
|
||||
game.asset_infos[platform].catalog_item_id,
|
||||
game.app_name, platform)
|
||||
|
||||
# never seen this outside the launcher itself, but if it happens: PANIC!
|
||||
|
@ -1000,8 +1007,8 @@ class LegendaryCore:
|
|||
|
||||
return manifest_urls, base_urls
|
||||
|
||||
def get_cdn_manifest(self, game, platform_override=''):
|
||||
manifest_urls, base_urls = self.get_cdn_urls(game, platform_override)
|
||||
def get_cdn_manifest(self, game, platform='Windows'):
|
||||
manifest_urls, base_urls = self.get_cdn_urls(game, platform)
|
||||
self.log.debug(f'Downloading manifest from {manifest_urls[0]} ...')
|
||||
r = self.egs.unauth_session.get(manifest_urls[0])
|
||||
r.raise_for_status()
|
||||
|
@ -1036,7 +1043,7 @@ class LegendaryCore:
|
|||
force: bool = False, disable_patching: bool = False,
|
||||
game_folder: str = '', override_manifest: str = '',
|
||||
override_old_manifest: str = '', override_base_url: str = '',
|
||||
platform_override: str = '', file_prefix_filter: list = None,
|
||||
platform: str = '', file_prefix_filter: list = None,
|
||||
file_exclude_filter: list = None, file_install_tag: list = None,
|
||||
dl_optimizations: bool = False, dl_timeout: int = 10,
|
||||
repair: bool = False, repair_use_latest: bool = False,
|
||||
|
@ -1069,7 +1076,7 @@ class LegendaryCore:
|
|||
if _base_urls:
|
||||
base_urls = _base_urls
|
||||
else:
|
||||
new_manifest_data, base_urls = self.get_cdn_manifest(game, platform_override)
|
||||
new_manifest_data, base_urls = self.get_cdn_manifest(game, platform)
|
||||
# overwrite base urls in metadata with current ones to avoid using old/dead CDNs
|
||||
game.base_urls = base_urls
|
||||
# save base urls to game metadata
|
||||
|
@ -1203,6 +1210,8 @@ class LegendaryCore:
|
|||
offline = game.metadata.get('customAttributes', {}).get('CanRunOffline', {}).get('value', 'true')
|
||||
ot = game.metadata.get('customAttributes', {}).get('OwnershipToken', {}).get('value', 'false')
|
||||
|
||||
if file_install_tag is None:
|
||||
file_install_tag = []
|
||||
igame = InstalledGame(app_name=game.app_name, title=game.app_title,
|
||||
version=new_manifest.meta.build_version, prereq_info=prereq,
|
||||
manifest_path=override_manifest, base_urls=base_urls,
|
||||
|
@ -1210,7 +1219,8 @@ class LegendaryCore:
|
|||
launch_parameters=new_manifest.meta.launch_command,
|
||||
can_run_offline=offline == 'true', requires_ot=ot == 'true',
|
||||
is_dlc=base_game is not None, install_size=anlres.install_size,
|
||||
egl_guid=egl_guid, install_tags=file_install_tag)
|
||||
egl_guid=egl_guid, install_tags=file_install_tag,
|
||||
platform=platform)
|
||||
|
||||
return dlm, anlres, igame
|
||||
|
||||
|
@ -1293,7 +1303,7 @@ class LegendaryCore:
|
|||
return os.path.expanduser(self.lgd.config.get('Legendary', 'install_dir', fallback='~/legendary'))
|
||||
|
||||
def install_game(self, installed_game: InstalledGame) -> dict:
|
||||
if self.egl_sync_enabled and not installed_game.is_dlc:
|
||||
if self.egl_sync_enabled and not installed_game.is_dlc and installed_game.platform.startswith('Win'):
|
||||
if not installed_game.egl_guid:
|
||||
installed_game.egl_guid = str(uuid4()).replace('-', '').upper()
|
||||
prereq = self._install_game(installed_game)
|
||||
|
@ -1426,7 +1436,8 @@ class LegendaryCore:
|
|||
def egl_get_exportable(self):
|
||||
if not self.egl.manifests:
|
||||
self.egl.read_manifests()
|
||||
return [g for g in self.get_installed_list() if g.app_name not in self.egl.manifests]
|
||||
return [g for g in self.get_installed_list() if
|
||||
g.app_name not in self.egl.manifests and g.platform.startswith('Win')]
|
||||
|
||||
def egl_import(self, app_name):
|
||||
if not self.asset_valid(app_name):
|
||||
|
@ -1506,8 +1517,8 @@ class LegendaryCore:
|
|||
mf.write(manifest_data)
|
||||
|
||||
mancpn = dict(FormatVersion=0, AppName=app_name,
|
||||
CatalogItemId=lgd_game.asset_info.catalog_item_id,
|
||||
CatalogNamespace=lgd_game.asset_info.namespace)
|
||||
CatalogItemId=lgd_game.asset_infos['Windows'].catalog_item_id,
|
||||
CatalogNamespace=lgd_game.asset_infos['Windows'].namespace)
|
||||
with open(os.path.join(egstore_folder, f'{egl_game.installation_guid}.mancpn', ), 'w') as mcpnf:
|
||||
json.dump(mancpn, mcpnf, indent=4, sort_keys=True)
|
||||
|
||||
|
|
|
@ -177,8 +177,8 @@ class LGDLFS:
|
|||
def assets(self):
|
||||
if self._assets is None:
|
||||
try:
|
||||
self._assets = [GameAsset.from_json(a) for a in
|
||||
json.load(open(os.path.join(self.path, 'assets.json')))]
|
||||
tmp = json.load(open(os.path.join(self.path, 'assets.json')))
|
||||
self._assets = {k: [GameAsset.from_json(j) for j in v] for k, v in tmp.items()}
|
||||
except Exception as e:
|
||||
self.log.debug(f'Failed to load assets data: {e!r}')
|
||||
return None
|
||||
|
@ -191,7 +191,7 @@ class LGDLFS:
|
|||
raise ValueError('Assets is none!')
|
||||
|
||||
self._assets = assets
|
||||
json.dump([a.__dict__ for a in self._assets],
|
||||
json.dump({platform: [a.__dict__ for a in assets] for platform, assets in self._assets.items()},
|
||||
open(os.path.join(self.path, 'assets.json'), 'w'),
|
||||
indent=2, sort_keys=True)
|
||||
|
||||
|
|
Loading…
Reference in a new issue