Skip to content

Commit

Permalink
[core/models] Implement Sidecar config and epicdeploymentid parameter
Browse files Browse the repository at this point in the history
derrod committed Aug 23, 2024
1 parent 4d63dcc commit 56a2314
Showing 2 changed files with 49 additions and 7 deletions.
30 changes: 24 additions & 6 deletions legendary/core.py
Original file line number Diff line number Diff line change
@@ -431,26 +431,40 @@ def get_game_and_dlc_list(self, update_assets=True, platform='Windows',
continue

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

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

def fetch_game_meta(args):
app_name, namespace, catalog_item_id = args
app_name, namespace, catalog_item_id, update_sidecar = args
eg_meta = self.egs.get_game_info(namespace, catalog_item_id, timeout=10.0)
if not eg_meta:
self.log.warning(f'App {app_name} does not have any metadata!')
eg_meta = dict(title='Unknown')

game = Game(app_name=app_name, app_title=eg_meta['title'], metadata=eg_meta, asset_infos=assets[app_name])
sidecar = None
if update_sidecar:
self.log.debug(f'Updating sidecar information for {app_name}...')
manifest_api_response = self.egs.get_game_manifest(namespace, catalog_item_id, app_name)
# sidecar data is a JSON object encoded as a string for some reason
manifest_info = manifest_api_response['elements'][0]
if 'sidecar' in manifest_info:
sidecar_json = json.loads(manifest_info['sidecar']['config'])
sidecar = Sidecar(config=sidecar_json, rev=manifest_info['sidecar']['rvn'])

game = Game(app_name=app_name, app_title=eg_meta['title'], metadata=eg_meta, asset_infos=assets[app_name],
sidecar=sidecar)
self.lgd.set_game_meta(game.app_name, game)
games[app_name] = game
try:
@@ -477,7 +491,7 @@ def fetch_game_meta(args):
if use_threads:
self.log.warning(f'Fetching metadata for {app_name} failed, retrying')
_ga = next(iter(app_assets.values()))
fetch_game_meta((app_name, _ga.namespace, _ga.catalog_item_id))
fetch_game_meta((app_name, _ga.namespace, _ga.catalog_item_id, True))
game = games[app_name]

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

if sidecar := game.sidecar:
if deployment_id := sidecar.config.get('deploymentId', None):
params.egl_parameters.append(f'-epicdeploymentid={deployment_id}')

if extra_args:
params.user_parameters.extend(extra_args)

26 changes: 25 additions & 1 deletion legendary/models/game.py
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ class GameAsset:
label_name: str = ''
namespace: str = ''
metadata: Dict = field(default_factory=dict)
sidecar_rev: int = 0

@classmethod
def from_egs_json(cls, json):
@@ -29,6 +30,7 @@ def from_egs_json(cls, json):
tmp.label_name = json.get('labelName', '')
tmp.namespace = json.get('namespace', '')
tmp.metadata = json.get('metadata', {})
tmp.sidecar_rev = json.get('sidecarRvn', 0)
return tmp

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


@dataclass
class Sidecar:
"""
App sidecar data
"""
config: Dict
rev: int

@classmethod
def from_json(cls, json):
return cls(
config=json.get('config', {}),
rev=json.get('rev', 0)
)


@dataclass
class Game:
"""
@@ -55,6 +74,7 @@ class Game:
asset_infos: Dict[str, GameAsset] = field(default_factory=dict)
base_urls: List[str] = field(default_factory=list)
metadata: Dict = field(default_factory=dict)
sidecar: Optional[Sidecar] = None

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

if sidecar := json.get('sidecar', None):
tmp.sidecar = Sidecar.from_json(sidecar)

tmp.base_urls = json.get('base_urls', list())
return tmp

@property
def __dict__(self):
"""This is just here so asset_infos gets turned into a dict as well"""
assets_dictified = {k: v.__dict__ for k, v in self.asset_infos.items()}
sidecar_dictified = self.sidecar.__dict__ if self.sidecar else None
return dict(metadata=self.metadata, asset_infos=assets_dictified, app_name=self.app_name,
app_title=self.app_title, base_urls=self.base_urls)
app_title=self.app_title, base_urls=self.base_urls, sidecar=sidecar_dictified)


@dataclass

0 comments on commit 56a2314

Please sign in to comment.