mirror of
https://github.com/derrod/legendary.git
synced 2024-12-22 01:45:28 +00:00
[api/core/models] Add support for "Ownership Token"
Ownership verification tokens appear to be part of EPIC's DRM scheme, they're basically just a JSON file with a token in it that's downloaded from their API before launching. This fixes launching games such as Just Cause 4.
This commit is contained in:
parent
ce28ce2914
commit
5eb51dfd11
|
@ -19,6 +19,7 @@ class EPCAPI:
|
|||
_launcher_host = 'launcher-public-service-prod06.ol.epicgames.com'
|
||||
_entitlements_host = 'entitlement-public-service-prod08.ol.epicgames.com'
|
||||
_catalog_host = 'catalog-public-service-prod06.ol.epicgames.com'
|
||||
_ecommerce_host = 'ecommerceintegration-public-service-ecomprod02.ol.epicgames.com'
|
||||
|
||||
def __init__(self):
|
||||
self.session = requests.session()
|
||||
|
@ -71,6 +72,14 @@ class EPCAPI:
|
|||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def get_ownership_token(self, namespace, catalog_item_id):
|
||||
user_id = self.user.get('account_id')
|
||||
r = self.session.post(f'https://{self._ecommerce_host}/ecommerceintegration/api/public/'
|
||||
f'platforms/EPIC/identities/{user_id}/ownershipToken',
|
||||
data=dict(nsCatalogItemId=f'{namespace}:{catalog_item_id}'))
|
||||
r.raise_for_status()
|
||||
return r.content
|
||||
|
||||
def get_game_assets(self):
|
||||
r = self.session.get(f'https://{self._launcher_host}/launcher/api/public/assets/Windows',
|
||||
params=dict(label='Live'))
|
||||
|
|
|
@ -320,5 +320,5 @@ def main():
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
multiprocessing.freeze_support()
|
||||
multiprocessing.freeze_support() # required for pyinstaller
|
||||
main()
|
||||
|
|
|
@ -162,11 +162,14 @@ class LegendaryCore:
|
|||
def get_launch_parameters(self, app_name: str, offline: bool = False,
|
||||
user: str = None, extra_args: list = None) -> (list, str, dict):
|
||||
install = self.lgd.get_installed_game(app_name)
|
||||
game = self.lgd.get_game_meta(app_name)
|
||||
|
||||
game_token = ''
|
||||
if not offline:
|
||||
self.log.info('Getting authentication token...')
|
||||
game_token = self.egs.get_game_token()['code']
|
||||
elif not install.can_run_offline:
|
||||
self.log.warning('Game is not approved for offline use and may not work correctly.')
|
||||
|
||||
user_name = self.lgd.userdata['displayName']
|
||||
account_id = self.lgd.userdata['account_id']
|
||||
|
@ -191,7 +194,19 @@ class LegendaryCore:
|
|||
f'-AUTH_PASSWORD={game_token}',
|
||||
'-AUTH_TYPE=exchangecode',
|
||||
f'-epicapp={app_name}',
|
||||
'-epicenv=Prod',
|
||||
'-epicenv=Prod'])
|
||||
|
||||
if install.requires_ot and not offline:
|
||||
self.log.info('Getting ownership token.')
|
||||
ovt = self.egs.get_ownership_token(game.asset_info.namespace,
|
||||
game.asset_info.catalog_item_id)
|
||||
ovt_path = os.path.join(self.lgd.get_tmp_path(),
|
||||
f'{game.asset_info.namespace}{game.asset_info.catalog_item_id}.ovt')
|
||||
with open(ovt_path, 'wb') as f:
|
||||
f.write(ovt)
|
||||
params.append(f'-epicovt={ovt_path}')
|
||||
|
||||
params.extend([
|
||||
'-EpicPortal',
|
||||
f'-epicusername={user_name}',
|
||||
f'-epicuserid={account_id}',
|
||||
|
@ -333,10 +348,14 @@ class LegendaryCore:
|
|||
prereq = dict(ids=new_manifest.meta.prereq_ids, name=new_manifest.meta.prereq_name,
|
||||
path=new_manifest.meta.prereq_path, args=new_manifest.meta.prereq_args)
|
||||
|
||||
offline = game.metadata.get('customAttributes', {}).get('CanRunOffline', {}).get('value', 'true')
|
||||
ot = game.metadata.get('customAttributes', {}).get('OwnershipToken', {}).get('value', 'false')
|
||||
|
||||
igame = InstalledGame(app_name=game.app_name, title=game.app_title, version=game.app_version,
|
||||
prereq_info=prereq, manifest_path=override_manifest, base_urls=base_urls,
|
||||
install_path=install_path, executable=new_manifest.meta.launch_exe,
|
||||
launch_parameters=new_manifest.meta.launch_command)
|
||||
launch_parameters=new_manifest.meta.launch_command,
|
||||
can_run_offline=offline == 'true', requires_ot=ot == 'true')
|
||||
|
||||
return dlm, anlres, igame
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ class Game:
|
|||
|
||||
class InstalledGame:
|
||||
def __init__(self, app_name='', title='', version='', manifest_path='', base_urls=None,
|
||||
install_path='', executable='', launch_parameters='', prereq_info=None):
|
||||
install_path='', executable='', launch_parameters='', prereq_info=None,
|
||||
can_run_offline=False, requires_ot=False):
|
||||
self.app_name = app_name
|
||||
self.title = title
|
||||
self.version = version
|
||||
|
@ -79,6 +80,8 @@ class InstalledGame:
|
|||
self.executable = executable
|
||||
self.launch_parameters = launch_parameters
|
||||
self.prereq_info = prereq_info
|
||||
self.can_run_offline = can_run_offline
|
||||
self.requires_ot = requires_ot
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
|
@ -93,4 +96,7 @@ class InstalledGame:
|
|||
tmp.executable = json.get('executable', '')
|
||||
tmp.launch_parameters = json.get('launch_parameters', '')
|
||||
tmp.prereq_info = json.get('prereq_info', None)
|
||||
|
||||
tmp.can_run_offline = json.get('can_run_offline', True)
|
||||
tmp.requires_ot = json.get('requires_ot', False)
|
||||
return tmp
|
||||
|
|
Loading…
Reference in a new issue