diff --git a/README.md b/README.md index ffe8ea7..8beaf2a 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ Legendary (named after the next highest tier [in item rarity](https://wow.gamepe Right now it is in an early public pre-release stage and still needs a lot of work to work. But it does work! -**Currently implemented:** - - Authenticate with Epic (can import authentication from EGS installation [Windows only]) +**What works:** + - Authenticate with Epic - Download and install games - - Update installed games (not well tested/potentially buggy) + - Update installed games and their DLC - Launch games with online authentication **Planned:** diff --git a/legendary/cli.py b/legendary/cli.py index fda3a56..0d2f43e 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -60,12 +60,16 @@ def main(): download_group = parser.add_argument_group('Downloading options') download_group.add_argument('--base-path', dest='base_path', action='store', metavar='', help='Path for game installations (defaults to ~/legendary)') + download_group.add_argument('--game-folder', dest='game_folder', action='store', metavar='', + help='Folder for game installation (defaults to folder in metadata)') download_group.add_argument('--max-shared-memory', dest='shared_memory', action='store', metavar='', type=int, help='Maximum amount of shared memory to use (in MiB), default: 1 GiB') download_group.add_argument('--max-workers', dest='max_workers', action='store', metavar='', type=int, help='Maximum amount of download workers, default: 2 * logical CPU') download_group.add_argument('--manifest', dest='override_manifest', action='store', metavar='', help='Manifest URL or path to use instead of the CDN one (e.g. for downgrading)') + download_group.add_argument('--old-manifest', dest='override_old_manifest', action='store', metavar='', + help='Manifest URL or path to use as the old one (e.g. for testing patching)') download_group.add_argument('--base-url', dest='override_base_url', action='store', metavar='', help='Base URL to download from (e.g. to test or switch to a different CDNs)') download_group.add_argument('--force', dest='force', action='store_true', @@ -255,9 +259,10 @@ def main(): # todo use status queue to print progress from CLI dlm, analysis, igame = core.prepare_download(game=game, base_game=base_game, base_path=args.base_path, force=args.force, max_shm=args.shared_memory, - max_workers=args.max_workers, + max_workers=args.max_workers, game_folder=args.game_folder, disable_patching=args.disable_patching, override_manifest=args.override_manifest, + override_old_manifest=args.override_old_manifest, override_base_url=args.override_base_url) # game is either up to date or hasn't changed, so we have nothing to do diff --git a/legendary/core.py b/legendary/core.py index 76abfcc..487ea88 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -292,7 +292,8 @@ class LegendaryCore: def prepare_download(self, game: Game, base_game: Game = None, base_path: str = '', max_shm: int = 0, max_workers: int = 0, force: bool = False, - disable_patching: bool = False, override_manifest: str = '', + disable_patching: bool = False, game_folder: str = '', + override_manifest: str = '', override_old_manifest: str = '', override_base_url: str = '') -> (DLManager, AnalysisResult, ManifestMeta): # load old manifest @@ -300,7 +301,16 @@ class LegendaryCore: new_manifest_data = b'' # load old manifest if we have one - if not disable_patching and not force and self.is_installed(game.app_name): + if override_old_manifest: + if override_old_manifest.startswith('http'): + r = self.egs.unauth_session.get(override_old_manifest) + r.raise_for_status() + old_manifest_data = r.content + else: + with open(override_old_manifest, 'rb') as f: + old_manifest_data = f.read() + old_manifest = self.load_manfiest(old_manifest_data) + elif not disable_patching and not force and self.is_installed(game.app_name): if old_bytes := self.lgd.get_manifest(game.app_name): old_manifest = self.load_manfiest(old_bytes) @@ -349,16 +359,17 @@ class LegendaryCore: self.lgd.save_manifest(game.app_name, new_manifest_data, filename=f'{game.app_name}_{new_manifest.meta.build_version}', old=True) + if not game_folder: + if game.is_dlc: + game_folder = base_game.metadata.get('customAttributes', {}).\ + get('FolderName', {}).get('value', base_game.app_name) + else: + game_folder = game.metadata.get('customAttributes', {}).\ + get('FolderName', {}).get('value', game.app_name) + if not base_path: base_path = self.get_default_install_dir() - if game.is_dlc: - game_folder = base_game.metadata.get('customAttributes', {}).\ - get('FolderName', {}).get('value', base_game.app_name) - else: - game_folder = game.metadata.get('customAttributes', {}).\ - get('FolderName', {}).get('value', game.app_name) - install_path = os.path.join(base_path, game_folder) if not os.path.exists(install_path):