Add support for finding Origin games

This commit is contained in:
Chris Bessent
2021-11-24 17:23:34 -07:00
parent 5606e4d279
commit f48495fd72
2 changed files with 70 additions and 1 deletions
+19 -1
View File
@@ -202,6 +202,7 @@ class BasicGameMappings:
savegameExtension: BasicGameMapping[str]
steamAPPId: BasicGameOptionsMapping[str]
gogAPPId: BasicGameOptionsMapping[str]
originManifestIds: BasicGameOptionsMapping[str]
@staticmethod
def _default_documents_directory(game):
@@ -299,6 +300,9 @@ class BasicGameMappings:
self.gogAPPId = BasicGameOptionsMapping(
game, "GameGogId", "gogAPPId", default=lambda g: "", apply_fn=ids_apply
)
self.originManifestIds = BasicGameOptionsMapping(
game, "GameOriginManifestIds", "originManifestIds", default=lambda g: "", apply_fn=ids_apply
)
class BasicGame(mobase.IPluginGame):
@@ -307,17 +311,20 @@ class BasicGame(mobase.IPluginGame):
to make it easier to create game plugins without having to implement
all the methods of mobase.IPluginGame."""
# List of steam and GOG games:
# List of steam, GOG, and origin games:
steam_games: Dict[str, Path]
gog_games: Dict[str, Path]
origin_games: Dict[str, Path]
@staticmethod
def setup():
from .gog_utils import find_games as find_gog_games
from .steam_utils import find_games as find_steam_games
from .origin_utils import find_games as find_origin_games
BasicGame.steam_games = find_steam_games()
BasicGame.gog_games = find_gog_games()
BasicGame.origin_games = find_origin_games()
# File containing the plugin:
_fromName: str
@@ -349,6 +356,9 @@ class BasicGame(mobase.IPluginGame):
def is_gog(self) -> bool:
return self._mappings.gogAPPId.has_value()
def is_origin(self) -> bool:
return self._mappings.originManifestIds.has_value()
# IPlugin interface:
def init(self, organizer: mobase.IOrganizer) -> bool:
@@ -390,6 +400,11 @@ class BasicGame(mobase.IPluginGame):
self.setGamePath(BasicGame.gog_games[gog_id])
return
for origin_manifest_id in self._mappings.originManifestIds.get():
if origin_manifest_id in BasicGame.origin_games:
self.setGamePath(BasicGame.origin_games[origin_manifest_id])
return
def gameName(self) -> str:
return self._mappings.gameName.get()
@@ -523,6 +538,9 @@ class BasicGame(mobase.IPluginGame):
for gogid, gogpath in BasicGame.gog_games.items():
if gogpath == path:
self._mappings.steamAPPId.set_value(gogid)
for originid, originpath in BasicGame.origin_games.items():
if originpath == path:
self._mappings.originManifestIds.set_value(originid)
def documentsDirectory(self) -> QDir:
return self._mappings.documentsDirectory.get()
+51
View File
@@ -0,0 +1,51 @@
# -*- encoding: utf-8 -*-
# Heavily influenced by https://github.com/erri120/GameFinder
import os
from pathlib import Path
from typing import Dict
from urllib import parse
from PyQt5.QtCore import QDir, QFileInfo, QStandardPaths
def find_games() -> Dict[str, Path]:
"""
Find the list of Origin games installed.
Returns:
A mapping from Origin manifest IDs to install locations for available
Origin games.
"""
games: Dict[str, Path] = {}
local_content_path = Path(os.path.expandvars("%PROGRAMDATA%")).joinpath("Origin", "LocalContent")
for manifest in local_content_path.glob("**/*.mfst"):
# Skip any manifest file with '@steam'
if '@steam' in manifest.name.lower():
continue
# Read the file and look for &id= and &dipinstallpath=
with open(manifest, 'r') as f:
manifest_query = f.read()
url = parse.urlparse(manifest_query)
query = parse.parse_qs(url.query)
if 'id' not in query:
# If id is not present, we have no clue what to do.
continue
if 'dipinstallpath' not in query:
# We could query the Origin server for the install location but... no?
continue
for id_ in query['id']:
for path_ in query['dipinstallpath']:
games[id_] = Path(path_)
return games
if __name__ == "__main__":
games = find_games()
for k, v in games.items():
print("Found game with id {} at {}.".format(k, v))