From 1d7d0eaa3879da5509912be0147b2fd6076c9c55 Mon Sep 17 00:00:00 2001 From: derrod Date: Fri, 29 May 2020 00:19:57 +0200 Subject: [PATCH] [core/cli] Import games installed via EGL w/o verification --- legendary/cli.py | 9 +++++--- legendary/core.py | 54 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/legendary/cli.py b/legendary/cli.py index bedf69a..9aaba4c 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -720,7 +720,6 @@ class LegendaryCLI: logger.fatal(f'Did not find game "{args.app_name}" on account.') exit(1) - # todo: if there is an Epic Games Launcher manifest in the install path use that instead # get everything needed for import from core, then run additional checks. manifest, igame = self.core.import_game(game, args.app_path) exe_path = os.path.join(args.app_path, manifest.meta.launch_exe.lstrip('/')) @@ -742,8 +741,12 @@ class LegendaryCLI: logger.info('Game install appears to be complete.') self.core.install_game(igame) - logger.info(f'NOTE: The game installation will have to be verified before it can be updated with legendary. ' - f'Run "legendary repair {args.app_name}" to do so.') + if igame.needs_verification: + logger.info(f'NOTE: The game installation will have to be verified before it can be updated ' + f'with legendary. Run "legendary repair {args.app_name}" to do so.') + else: + logger.info(f'Installation had Epic Games Launcher metadata for version "{igame.version}", ' + f'verification will not be requried.') logger.info('Game has been imported.') diff --git a/legendary/core.py b/legendary/core.py index 5fdf9cc..81b7a4b 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -755,18 +755,58 @@ class LegendaryCore: igame.prereq_info['installed'] = True self.lgd.set_installed_game(app_name, igame) - def import_game(self, game: Game, app_path: str) -> (Manifest, InstalledGame): - self.log.info(f'Downloading latest manifest for "{game.app_name}"') - manifest_data, base_urls = self.get_cdn_manifest(game) - if not game.base_urls: - game.base_urls = base_urls - self.lgd.set_game_meta(game.app_name, game) + def import_game(self, game: Game, app_path: str, egl_guid='') -> (Manifest, InstalledGame): + needs_verify = True + manifest_data = None + + # check if the game is from an EGL installation, load manifest if possible + if os.path.exists(os.path.join(app_path, '.egstore')): + mf = None + if not egl_guid: + for f in os.listdir(os.path.join(app_path, '.egstore')): + if not f.endswith('.mancpn'): + continue + + self.log.debug(f'Checking mancpn file "{f}"...') + mancpn = json.load(open(os.path.join(app_path, '.egstore', f), 'rb')) + if mancpn['AppName'] == game.app_name: + self.log.info('Found EGL install metadata, verifying...') + mf = f.replace('.mancpn', '.manifest') + break + else: + mf = f'{egl_guid}.manifest' + + if mf and os.path.exists(os.path.join(app_path, '.egstore', mf)): + manifest_data = open(os.path.join(app_path, '.egstore', mf), 'rb').read() + else: + self.log.warning('.egstore folder exists but manifest file is missing, contiuing as regular import...') + + # If there's no in-progress installation assume the game doesn't need to be verified + if mf and not os.path.exists(os.path.join(app_path, '.egstore', 'bps')): + needs_verify = False + if os.path.exists(os.path.join(app_path, '.egstore', 'Pending')): + if os.listdir(os.path.join(app_path, '.egstore', 'Pending')): + needs_verify = True + + if not needs_verify: + self.log.debug(f'No in-progress installation found, assuming complete...') + + if not manifest_data: + self.log.info(f'Downloading latest manifest for "{game.app_name}"') + manifest_data, base_urls = self.get_cdn_manifest(game) + if not game.base_urls: + game.base_urls = base_urls + self.lgd.set_game_meta(game.app_name, game) + else: + # base urls being empty isn't an issue, they'll be fetched when updating/repairing the game + base_urls = game.base_urls # parse and save manifest to disk for verification step of import new_manifest = self.load_manfiest(manifest_data) self.lgd.save_manifest(game.app_name, manifest_data) self.lgd.save_manifest(game.app_name, manifest_data, version=new_manifest.meta.build_version) + install_size = sum(fm.file_size for fm in new_manifest.file_manifest_list.elements) prereq = None if new_manifest.meta.prereq_ids: @@ -779,7 +819,7 @@ class LegendaryCore: install_path=app_path, version=new_manifest.meta.build_version, is_dlc=game.is_dlc, executable=new_manifest.meta.launch_exe, can_run_offline=offline == 'true', launch_parameters=new_manifest.meta.launch_command, requires_ot=ot == 'true', - needs_verification=True) + needs_verification=needs_verify, install_size=install_size, egl_guid=egl_guid) return new_manifest, igame