Skip to content

Commit 56a2314

Browse files
committed
[core/models] Implement Sidecar config and epicdeploymentid parameter
1 parent 4d63dcc commit 56a2314

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

legendary/core.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -431,26 +431,40 @@ def get_game_and_dlc_list(self, update_assets=True, platform='Windows',
431431
continue
432432

433433
game = self.lgd.get_game_meta(app_name)
434-
asset_updated = False
434+
asset_updated = sidecar_updated = False
435435
if game:
436436
asset_updated = any(game.app_version(_p) != app_assets[_p].build_version for _p in app_assets.keys())
437+
# assuming sidecar data is the same for all platforms, just check the baseline (Windows) for updates.
438+
sidecar_updated = (app_assets['Windows'].sidecar_rev > 0 and
439+
(not game.sidecar or game.sidecar.rev != app_assets['Windows'].sidecar_rev))
437440
games[app_name] = game
438441

439-
if update_assets and (not game or force_refresh or (game and asset_updated)):
442+
if update_assets and (not game or force_refresh or (game and (asset_updated or sidecar_updated))):
440443
self.log.debug(f'Scheduling metadata update for {app_name}')
441444
# namespace/catalog item are the same for all platforms, so we can just use the first one
442445
_ga = next(iter(app_assets.values()))
443-
fetch_list.append((app_name, _ga.namespace, _ga.catalog_item_id))
446+
fetch_list.append((app_name, _ga.namespace, _ga.catalog_item_id, sidecar_updated))
444447
meta_updated = True
445448

446449
def fetch_game_meta(args):
447-
app_name, namespace, catalog_item_id = args
450+
app_name, namespace, catalog_item_id, update_sidecar = args
448451
eg_meta = self.egs.get_game_info(namespace, catalog_item_id, timeout=10.0)
449452
if not eg_meta:
450453
self.log.warning(f'App {app_name} does not have any metadata!')
451454
eg_meta = dict(title='Unknown')
452455

453-
game = Game(app_name=app_name, app_title=eg_meta['title'], metadata=eg_meta, asset_infos=assets[app_name])
456+
sidecar = None
457+
if update_sidecar:
458+
self.log.debug(f'Updating sidecar information for {app_name}...')
459+
manifest_api_response = self.egs.get_game_manifest(namespace, catalog_item_id, app_name)
460+
# sidecar data is a JSON object encoded as a string for some reason
461+
manifest_info = manifest_api_response['elements'][0]
462+
if 'sidecar' in manifest_info:
463+
sidecar_json = json.loads(manifest_info['sidecar']['config'])
464+
sidecar = Sidecar(config=sidecar_json, rev=manifest_info['sidecar']['rvn'])
465+
466+
game = Game(app_name=app_name, app_title=eg_meta['title'], metadata=eg_meta, asset_infos=assets[app_name],
467+
sidecar=sidecar)
454468
self.lgd.set_game_meta(game.app_name, game)
455469
games[app_name] = game
456470
try:
@@ -477,7 +491,7 @@ def fetch_game_meta(args):
477491
if use_threads:
478492
self.log.warning(f'Fetching metadata for {app_name} failed, retrying')
479493
_ga = next(iter(app_assets.values()))
480-
fetch_game_meta((app_name, _ga.namespace, _ga.catalog_item_id))
494+
fetch_game_meta((app_name, _ga.namespace, _ga.catalog_item_id, True))
481495
game = games[app_name]
482496

483497
if game.is_dlc and platform in app_assets:
@@ -784,6 +798,10 @@ def get_launch_parameters(self, app_name: str, offline: bool = False,
784798
f'-epicsandboxid={game.namespace}'
785799
])
786800

801+
if sidecar := game.sidecar:
802+
if deployment_id := sidecar.config.get('deploymentId', None):
803+
params.egl_parameters.append(f'-epicdeploymentid={deployment_id}')
804+
787805
if extra_args:
788806
params.user_parameters.extend(extra_args)
789807

legendary/models/game.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class GameAsset:
1818
label_name: str = ''
1919
namespace: str = ''
2020
metadata: Dict = field(default_factory=dict)
21+
sidecar_rev: int = 0
2122

2223
@classmethod
2324
def from_egs_json(cls, json):
@@ -29,6 +30,7 @@ def from_egs_json(cls, json):
2930
tmp.label_name = json.get('labelName', '')
3031
tmp.namespace = json.get('namespace', '')
3132
tmp.metadata = json.get('metadata', {})
33+
tmp.sidecar_rev = json.get('sidecarRvn', 0)
3234
return tmp
3335

3436
@classmethod
@@ -41,9 +43,26 @@ def from_json(cls, json):
4143
tmp.label_name = json.get('label_name', '')
4244
tmp.namespace = json.get('namespace', '')
4345
tmp.metadata = json.get('metadata', {})
46+
tmp.sidecar_rev = json.get('sidecar_rev', 0)
4447
return tmp
4548

4649

50+
@dataclass
51+
class Sidecar:
52+
"""
53+
App sidecar data
54+
"""
55+
config: Dict
56+
rev: int
57+
58+
@classmethod
59+
def from_json(cls, json):
60+
return cls(
61+
config=json.get('config', {}),
62+
rev=json.get('rev', 0)
63+
)
64+
65+
4766
@dataclass
4867
class Game:
4968
"""
@@ -55,6 +74,7 @@ class Game:
5574
asset_infos: Dict[str, GameAsset] = field(default_factory=dict)
5675
base_urls: List[str] = field(default_factory=list)
5776
metadata: Dict = field(default_factory=dict)
77+
sidecar: Optional[Sidecar] = None
5878

5979
def app_version(self, platform='Windows'):
6080
if platform not in self.asset_infos:
@@ -132,15 +152,19 @@ def from_json(cls, json):
132152
# Migrate old asset_info to new asset_infos
133153
tmp.asset_infos['Windows'] = GameAsset.from_json(json.get('asset_info', dict()))
134154

155+
if sidecar := json.get('sidecar', None):
156+
tmp.sidecar = Sidecar.from_json(sidecar)
157+
135158
tmp.base_urls = json.get('base_urls', list())
136159
return tmp
137160

138161
@property
139162
def __dict__(self):
140163
"""This is just here so asset_infos gets turned into a dict as well"""
141164
assets_dictified = {k: v.__dict__ for k, v in self.asset_infos.items()}
165+
sidecar_dictified = self.sidecar.__dict__ if self.sidecar else None
142166
return dict(metadata=self.metadata, asset_infos=assets_dictified, app_name=self.app_name,
143-
app_title=self.app_title, base_urls=self.base_urls)
167+
app_title=self.app_title, base_urls=self.base_urls, sidecar=sidecar_dictified)
144168

145169

146170
@dataclass

0 commit comments

Comments
 (0)