diff --git a/lutris/game.py b/lutris/game.py index caf2e5094..d5f1a1408 100644 --- a/lutris/game.py +++ b/lutris/game.py @@ -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 diff --git a/lutris/services/amazon.py b/lutris/services/amazon.py index b6f8d4622..07349cc41 100644 --- a/lutris/services/amazon.py +++ b/lutris/services/amazon.py @@ -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 diff --git a/lutris/services/base.py b/lutris/services/base.py index 9a3169f60..50fa6b2cc 100644 --- a/lutris/services/base.py +++ b/lutris/services/base.py @@ -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. diff --git a/lutris/services/battlenet.py b/lutris/services/battlenet.py index 882e5e7f7..577e3fd16 100644 --- a/lutris/services/battlenet.py +++ b/lutris/services/battlenet.py @@ -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() diff --git a/lutris/services/dolphin.py b/lutris/services/dolphin.py index 32dce51a7..2d5678be4 100644 --- a/lutris/services/dolphin.py +++ b/lutris/services/dolphin.py @@ -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"]) diff --git a/lutris/services/ea_app.py b/lutris/services/ea_app.py index e27b2ea78..4705a3c24 100644 --- a/lutris/services/ea_app.py +++ b/lutris/services/ea_app.py @@ -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() diff --git a/lutris/services/egs.py b/lutris/services/egs.py index 4338571b2..d7b47af7e 100644 --- a/lutris/services/egs.py +++ b/lutris/services/egs.py @@ -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() diff --git a/lutris/services/flathub.py b/lutris/services/flathub.py index cb263e310..e8ae24f4d 100644 --- a/lutris/services/flathub.py +++ b/lutris/services/flathub.py @@ -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")) diff --git a/lutris/services/gog.py b/lutris/services/gog.py index ffd15fe48..235661fe5 100644 --- a/lutris/services/gog.py +++ b/lutris/services/gog.py @@ -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/"}}] diff --git a/lutris/services/humblebundle.py b/lutris/services/humblebundle.py index 0b6e50f2f..43112a0e6 100644 --- a/lutris/services/humblebundle.py +++ b/lutris/services/humblebundle.py @@ -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 diff --git a/lutris/services/itchio.py b/lutris/services/itchio.py index f5df2c5ca..57a11b2c5 100644 --- a/lutris/services/itchio.py +++ b/lutris/services/itchio.py @@ -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: diff --git a/lutris/services/origin.py b/lutris/services/origin.py index db1d668f2..9d8d4d52b 100644 --- a/lutris/services/origin.py +++ b/lutris/services/origin.py @@ -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() diff --git a/lutris/services/scummvm.py b/lutris/services/scummvm.py index e4f4be0d6..be5990cea 100644 --- a/lutris/services/scummvm.py +++ b/lutris/services/scummvm.py @@ -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" diff --git a/lutris/services/steam.py b/lutris/services/steam.py index d3ca661b2..657bd26e0 100644 --- a/lutris/services/steam.py +++ b/lutris/services/steam.py @@ -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}) diff --git a/lutris/services/steamwindows.py b/lutris/services/steamwindows.py index af9b30e1e..4309f12a5 100644 --- a/lutris/services/steamwindows.py +++ b/lutris/services/steamwindows.py @@ -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: diff --git a/lutris/services/ubisoft.py b/lutris/services/ubisoft.py index 035a1bc91..818626a38 100644 --- a/lutris/services/ubisoft.py +++ b/lutris/services/ubisoft.py @@ -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") diff --git a/lutris/services/xdg.py b/lutris/services/xdg.py index f2081c6e6..278da2dca 100644 --- a/lutris/services/xdg.py +++ b/lutris/services/xdg.py @@ -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"])