From 54a57d845258c3d22b956df94d9523bf4d730499 Mon Sep 17 00:00:00 2001 From: Stelios Tsampas Date: Wed, 15 Apr 2026 22:34:31 +0300 Subject: [PATCH 1/4] [cli/core]: report grant date information with `info` Entitlements are updated only when there is an asset update. If no matching entitlement is found, the creation date from the game's metadata is returned instead. --- legendary/cli.py | 8 ++++++-- legendary/core.py | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/legendary/cli.py b/legendary/cli.py index 0a5df55..10cc967 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -1652,7 +1652,7 @@ class LegendaryCLI: args.offline = True manifest_data = None - entitlements = None + entitlements = [] is_preloaded = False manifest_secrets = dict() # load installed manifest or URI @@ -1669,7 +1669,7 @@ class LegendaryCLI: else: logger.info('Game not installed and offline mode enabled, cannot load manifest.') elif game: - entitlements = self.core.egs.get_user_entitlements_full() + entitlements = self.core.lgd.entitlements if self.core.lgd.entitlements else [] egl_meta = self.core.egs.get_game_info(game.namespace, game.catalog_item_id) game.metadata = egl_meta # Get manifest if asset exists for current platform @@ -1683,6 +1683,10 @@ class LegendaryCLI: 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)) + # Grant date from entitlements + entitlement = next((ent for ent in entitlements if ent['namespace'] == game.namespace), None) + grant_date = entitlement["grantDate"] if entitlement else game.metadata["creationDate"] + game_infos.append(InfoItem('Grant date', 'grant_date', grant_date, grant_date)) # Cloud save support for Mac and Windows game_infos.append(InfoItem('Cloud saves supported', 'cloud_saves_supported', game.supports_cloud_saves or game.supports_mac_cloud_saves, diff --git a/legendary/core.py b/legendary/core.py index d2d8214..31872bf 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -499,6 +499,10 @@ class LegendaryCore: elif not any(i['path'] == 'mods' for i in game.metadata.get('categories', [])) and platform in app_assets: _ret.append(game) + if meta_updated: + self.log.info('Updating entitlements.') + self.lgd.entitlements = self.egs.get_user_entitlements_full() + self.update_aliases(force=meta_updated) if meta_updated: self._prune_metadata() From 5a61ae604c91045e37288f3e1b05f8b18b53b6b2 Mon Sep 17 00:00:00 2001 From: Stelios Tsampas Date: Thu, 16 Apr 2026 00:37:20 +0300 Subject: [PATCH 2/4] [cli] replace missed use of entitlements with cached/on-disk data --- legendary/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legendary/cli.py b/legendary/cli.py index 10cc967..b6d642e 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -2066,7 +2066,7 @@ class LegendaryCLI: redeemed = {k['gameId'] for k in key_list if k['redeemedOnUplay']} games = self.core.get_game_list() - entitlements = self.core.egs.get_user_entitlements_full() + entitlements = self.core.lgd.entitlements if self.core.lgd.entitlements else [] owned_entitlements = {i['entitlementName'] for i in entitlements} uplay_games = [] From 9cf6fd21ce647b1d569ff77dd29edd6bc8b2ff42 Mon Sep 17 00:00:00 2001 From: Stelios Tsampas Date: Thu, 16 Apr 2026 00:58:06 +0300 Subject: [PATCH 3/4] [core] update entitlements only when there are new assets. --- legendary/core.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/legendary/core.py b/legendary/core.py index 31872bf..52ea1a0 100644 --- a/legendary/core.py +++ b/legendary/core.py @@ -360,6 +360,11 @@ class LegendaryCore: ] }) + # only get entitlements if there was an asset update + if self.lgd.assets != assets or not self.lgd.entitlements: + self.log.info('Updating entitlements.') + self.lgd.entitlements = self.egs.get_user_entitlements_full() + # only save (and write to disk) if there were changes if self.lgd.assets != assets: self.lgd.assets = assets @@ -499,10 +504,6 @@ class LegendaryCore: elif not any(i['path'] == 'mods' for i in game.metadata.get('categories', [])) and platform in app_assets: _ret.append(game) - if meta_updated: - self.log.info('Updating entitlements.') - self.lgd.entitlements = self.egs.get_user_entitlements_full() - self.update_aliases(force=meta_updated) if meta_updated: self._prune_metadata() From 1ea25253a5db8d5ddf1f5f79e8e4a9aed745602e Mon Sep 17 00:00:00 2001 From: Stelios Tsampas Date: Thu, 16 Apr 2026 12:11:04 +0300 Subject: [PATCH 4/4] [cli] correctly pass `get_assets` platform argument --- legendary/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legendary/cli.py b/legendary/cli.py index b6d642e..619c539 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -1734,7 +1734,7 @@ class LegendaryCLI: # list all owned DLC based on entitlements if entitlements and not game.is_dlc: owned_entitlements = {i['entitlementName'] for i in entitlements} - owned_app_names = {g.app_name for g in self.core.get_assets(args.platform)} + owned_app_names = {g.app_name for g in self.core.get_assets(platform=args.platform)} owned_dlc = [] for dlc in game.metadata.get('dlcItemList', []): installable = dlc.get('releaseInfo', None)