Add code to predict the runner to use for service games, when installed.

This lets 'Locate Installed Game' provide a runner selected for you.

This does not work for Lutris service games; this seems much trickier then just doing whatever generate_installer() does.
This commit is contained in:
Daniel Johnson 2023-11-10 07:23:09 -05:00
parent 616b96f310
commit fc4753464a
17 changed files with 97 additions and 14 deletions

View file

@ -125,6 +125,7 @@ class Game(GObject.Object):
game = Game()
game.name = db_game["name"]
game.slug = service.get_installed_slug(db_game)
game.runner_name = service.get_installed_runner_name(db_game)
if "service_id" in db_game:
game.appid = db_game["service_id"]
@ -338,7 +339,7 @@ class Game(GObject.Object):
@runner_name.setter
def runner_name(self, value):
self._runner_name = value
self._runner_name = value or ""
if self._runner and self._runner.name != value:
self._runner = None

View file

@ -64,6 +64,7 @@ class AmazonService(OnlineService):
id = "amazon"
name = _("Amazon Prime Gaming")
icon = "amazon"
runner = "wine"
has_extras = False
drm_free = False
medias = {
@ -680,7 +681,7 @@ class AmazonService(OnlineService):
"version": _("Amazon Prime Gaming"),
"slug": slugify(details["product"]["title"]),
"game_slug": slugify(details["product"]["title"]),
"runner": "wine",
"runner": self.get_installed_runner_name(db_game),
"script": {
"game": {
"exe": f"$GAMEDIR/drive_c/game/{game_cmd}",
@ -693,3 +694,6 @@ class AmazonService(OnlineService):
"installer": installer
}
}
def get_installed_runner_name(self, db_game):
return self.runner

View file

@ -255,6 +255,11 @@ class BaseService(GObject.Object):
the Game's name, but services override this if they provide the slug."""
return db_game.get("lutris_slug") or slugify(db_game["name"])
def get_installed_runner_name(self, db_game):
"""Returns the name of the runner this game will have after installation, or
blank if this is not known."""
return ""
def install(self, db_game, update=False):
"""Install a service game, or starts the installer of the game.

View file

@ -161,7 +161,7 @@ class BattleNetService(BaseService):
"version": self.name,
"slug": db_game["slug"] + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -184,6 +184,9 @@ class BattleNetService(BaseService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
bnet_game = get_game_by_field(self.client_installer, "slug")
application = Gio.Application.get_default()

View file

@ -27,6 +27,7 @@ class DolphinService(BaseService):
id = "dolphin"
icon = "dolphin"
name = _("Dolphin")
runner = "dolphin"
local = True
medias = {
"icon": DolphinBanner
@ -48,7 +49,7 @@ class DolphinService(BaseService):
"version": "Dolphin",
"slug": db_game["slug"],
"game_slug": self.get_installed_slug(db_game),
"runner": "dolphin",
"runner": self.get_installed_runner_name(db_game),
"script": {
"game": {
"main_file": details["path"],
@ -57,6 +58,9 @@ class DolphinService(BaseService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def get_game_directory(self, installer):
"""Pull install location from installer"""
return os.path.dirname(installer["script"]["game"]["main_file"])

View file

@ -357,7 +357,7 @@ class EAAppService(OnlineService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -378,6 +378,9 @@ class EAAppService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
ea_app_game = get_game_by_field(self.client_installer, "slug")
application = Gio.Application.get_default()

View file

@ -372,7 +372,7 @@ class EpicGamesStoreService(OnlineService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -395,6 +395,9 @@ class EpicGamesStoreService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
egs_game = get_game_by_field(self.client_installer, "slug")
application = Gio.Application.get_default()

View file

@ -166,7 +166,7 @@ class FlathubService(BaseService):
"slug": slugify(db_game["name"]) + "-" + self.id,
"name": db_game["name"],
"version": "Flathub",
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"script": {
"game": {
"appid": db_game["appid"],
@ -192,6 +192,9 @@ class FlathubService(BaseService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def get_game_directory(self, _installer):
install_type, application, arch, branch = (_installer["script"]["game"][key] for key in
("install_type", "application", "arch", "branch"))

View file

@ -537,6 +537,10 @@ class GOGService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
platforms = [platform.casefold() for platform in self.get_game_platforms(db_game)]
return "linux" if "linux" in platforms else "wine"
def get_games_owned(self):
"""Return IDs of games owned by user"""
url = "{}/user/data/games".format(self.embed_url)
@ -559,7 +563,7 @@ class GOGService(OnlineService):
for file in installfiles:
# supports linux
if file["os"].lower() == "linux":
if file["os"].casefold() == "linux":
runner = "linux"
script = [{"extract": {"dst": "$CACHE/GOG", "file": dlc_id, "format": "zip"}},
{"merge": {"dst": "$GAMEDIR", "src": "$CACHE/GOG/data/noarch/"}}]

View file

@ -326,6 +326,18 @@ class HumbleBundleService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
details = json.loads(db_game["details"])
platforms = [download["platform"] for download in details["downloads"]]
if "linux" in platforms and self.platform_has_downloads(details["downloads"], "linux"):
return "linux"
if "windows" in platforms:
return "wine"
return ""
def pick_download_url_from_download_info(download_info):
"""From a list of downloads in Humble Bundle, pick the most appropriate one

View file

@ -355,6 +355,28 @@ class ItchIoService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
details = json.loads(db_game["details"])
if "p_linux" in details["traits"]:
return "linux"
if "p_windows" in details["traits"]:
return "wine"
return ""
def get_game_platforms(self, db_game):
platforms = []
details = json.loads(db_game["details"])
if "p_linux" in details["traits"]:
platforms.append("Linux")
if "p_windows" in details["traits"]:
platforms.append("Windows")
return platforms
def _check_update_with_db(self, db_game, key, upload=None):
stamp = 0
if upload:

View file

@ -349,7 +349,7 @@ class OriginService(OnlineService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -370,6 +370,9 @@ class OriginService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
origin_game = get_game_by_field(self.client_installer, "slug")
application = Gio.Application.get_default()

View file

@ -62,7 +62,7 @@ class ScummvmService(BaseService):
"version": "ScummVM",
"slug": db_game["slug"],
"game_slug": self.get_installed_slug(db_game),
"runner": "scummvm",
"runner": self.get_installed_runner_name(db_game),
"script": {
"game": {
"game_id": db_game["appid"],
@ -71,6 +71,9 @@ class ScummvmService(BaseService):
}
}
def get_installed_runner_name(self, db_game):
return "scummvm"
class ScummvmGame(ServiceGame):
service = "scummvm"

View file

@ -206,13 +206,16 @@ class SteamService(BaseService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"game": {"appid": db_game["appid"]}
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
appid = db_game["appid"]
db_games = get_games(filters={"service_id": appid, "installed": "1", "service": self.id})

View file

@ -35,7 +35,7 @@ class SteamWindowsService(SteamService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -47,6 +47,9 @@ class SteamWindowsService(SteamService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def get_steam(self):
db_entry = get_game_by_field(self.client_installer, "installer_slug")
if db_entry:

View file

@ -245,7 +245,7 @@ class UbisoftConnectService(OnlineService):
"version": self.name,
"slug": slugify(db_game["name"]) + "-" + self.id,
"game_slug": self.get_installed_slug(db_game),
"runner": self.runner,
"runner": self.get_installed_runner_name(db_game),
"appid": db_game["appid"],
"script": {
"requires": self.client_installer,
@ -267,6 +267,9 @@ class UbisoftConnectService(OnlineService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def install(self, db_game):
"""Install a game or Ubisoft Connect if not already installed"""
ubisoft_connect = get_game_by_field(self.client_installer, "slug")

View file

@ -43,6 +43,7 @@ class XDGService(BaseService):
id = "xdg"
name = _("Local")
icon = "linux"
runner = "linux"
online = False
local = True
medias = {
@ -111,7 +112,7 @@ class XDGService(BaseService):
"version": "XDG",
"slug": db_game["slug"],
"game_slug": self.get_installed_slug(db_game),
"runner": "linux",
"runner": self.get_installed_runner_name(db_game),
"script": {
"game": {
"exe": details["exe"],
@ -121,6 +122,9 @@ class XDGService(BaseService):
}
}
def get_installed_runner_name(self, db_game):
return self.runner
def get_game_directory(self, installer):
"""Pull install location from installer"""
return os.path.dirname(installer["script"]["game"]["exe"])