def match_games(self): """Matching lutris games is much simpler... No API call needed.""" service_games = { str(game["appid"]): game for game in ServiceGameCollection.get_for_service(self.id) } for lutris_game in get_games(): self.match_game(service_games.get(lutris_game["slug"]), lutris_game)
def get_service_games(self, service_name): """Switch the current service to service_name and return games if available""" service_games = ServiceGameCollection.get_for_service(service_name) if service_name == "lutris": lutris_games = {g["slug"]: g for g in games_db.get_games()} else: lutris_games = { g["service_id"]: g for g in games_db.get_games( filters={"service": self.service.id}) } def get_sort_value(game): sort_defaults = { "name": "", "year": 0, "lastplayed": 0.0, "installed_at": 0.0, "playtime": 0.0, } lutris_game = lutris_games.get(game["appid"]) if not lutris_game: return sort_defaults[self.view_sorting] value = lutris_game[self.view_sorting] if value: return value return sort_defaults[self.view_sorting] return [ self.combine_games(game, lutris_games.get(game["appid"])) for game in sorted(service_games, key=get_sort_value, reverse=not self.view_sorting_ascending) if self.game_matches(game) ]
def on_game_activated(self, view, game_id): """Handles view activations (double click, enter press)""" if self.service: logger.debug("Looking up %s game %s", self.service.id, game_id) db_game = games_db.get_game_for_service(self.service.id, game_id) if self.service.id == "lutris": if not db_game or not db_game["installed"]: self.service.install(game_id) return game_id = db_game["id"] else: if db_game and db_game["installed"]: game_id = db_game["id"] else: service_game = ServiceGameCollection.get_game( self.service.id, game_id) if not service_game: logger.error("No game %s found for %s", game_id, self.service.id) return game_id = self.service.install(service_game) if game_id: game = Game(game_id) if game.is_installed: game.emit("game-launch") else: game.emit("game-install")
def on_game_activated(self, view, game_id): """Handles view activations (double click, enter press)""" if self.service: if self.service.id != "lutris": db_game = games_db.get_game_for_service( self.service.id, game_id) if db_game: game_id = db_game["id"] else: db_game = ServiceGameCollection.get_game( self.service.id, game_id) if db_game: game_id = self.service.install(db_game) else: game_id = self.service.install(game_id) else: db_game = games_db.get_game_by_field(game_id) if not db_game: self.service.install(game_id) return if db_game["installed"] != 1: self.service.install(game_id) return game_id = db_game["id"] if game_id: game = Game(game_id) game.emit("game-launch")
def install_from_origin(self, origin_game, manifest): offer_id = manifest["id"].split("@")[0] logger.debug("Installing Origin game %s", offer_id) service_game = ServiceGameCollection.get_game("origin", offer_id) if not service_game: logger.error( "Aborting install, %s is not present in the game library.", offer_id) return lutris_game_id = slugify(service_game["name"]) + "-" + self.id existing_game = get_game_by_field(lutris_game_id, "installer_slug") if existing_game: return game_config = LutrisConfig( game_config_id=origin_game["configpath"]).game_level game_config["game"]["args"] = get_launch_arguments(manifest["id"]) configpath = write_game_config(lutris_game_id, game_config) game_id = add_game( name=service_game["name"], runner=origin_game["runner"], slug=slugify(service_game["name"]), directory=origin_game["directory"], installed=1, installer_slug=lutris_game_id, configpath=configpath, service=self.id, service_id=offer_id, ) return game_id
def install_from_steam(self, manifest): """Create a new Lutris game based on an existing Steam install""" if not manifest.is_installed(): return appid = manifest.steamid if appid in self.excluded_appids: return service_game = ServiceGameCollection.get_game(self.id, appid) if not service_game: return lutris_game_id = "%s-%s" % (self.id, appid) existing_game = get_game_by_field(lutris_game_id, "slug") if existing_game: return game_config = LutrisConfig().game_level game_config["game"]["appid"] = appid configpath = write_game_config(lutris_game_id, game_config) game_id = add_game( name=service_game["name"], runner="steam", slug=slugify(service_game["name"]), installed=1, installer_slug=lutris_game_id, configpath=configpath, platform="Linux", service=self.id, service_id=appid, ) return game_id
def install_from_egs(self, egs_game, manifest): """Create a new Lutris game based on an existing EGS install""" app_name = manifest["AppName"] logger.debug("Installing EGS game %s", app_name) service_game = ServiceGameCollection.get_game("egs", app_name) if not service_game: logger.error("Aborting install, %s is not present in the game library.", app_name) return lutris_game_id = slugify(service_game["name"]) + "-" + self.id existing_game = get_game_by_field(lutris_game_id, "installer_slug") if existing_game: return game_config = LutrisConfig(game_config_id=egs_game["configpath"]).game_level game_config["game"]["args"] = get_launch_arguments(app_name) configpath = write_game_config(lutris_game_id, game_config) game_id = add_game( name=service_game["name"], runner=egs_game["runner"], slug=slugify(service_game["name"]), directory=egs_game["directory"], installed=1, installer_slug=lutris_game_id, configpath=configpath, service=self.id, service_id=app_name, ) return game_id
def on_game_selection_changed(self, view, selection): if not selection: GLib.idle_add(self.update_revealer) return False game_id = view.get_model().get_value(selection, COL_ID) if not game_id: GLib.idle_add(self.update_revealer) return False if self.service: game = ServiceGameCollection.get_game(self.service.id, game_id) else: game = games_db.get_game_by_field(int(game_id), "id") if not game: game = { "id": game_id, "appid": game_id, "name": view.get_model().get_value(selection, COL_NAME), "slug": game_id, "service": self.service.id if self.service else None, } logger.warning("No game found. Replacing with placeholder %s", game) GLib.idle_add(self.update_revealer, game) return False
def on_game_install(self, game): """Request installation of a game""" if game.service and game.service != "lutris": service = get_enabled_services()[game.service]() db_game = ServiceGameCollection.get_game(service.id, game.appid) try: game_id = service.install(db_game) except ValueError as e: logger.debug(e) game_id = None if game_id: game = Game(game_id) game.launch() else: ErrorDialog(message=_("Could not retrieve game installer."), parent=self.window) return True if not game.slug: raise ValueError("Invalid game passed: %s" % game) # return True installers = get_installers(game_slug=game.slug) if installers: self.show_installer_window(installers) else: logger.debug("Should generate automagical installer here but....") logger.debug("Wait? how did you get here?") return True
def get_games_from_filters(self): service_name = self.filters.get("service") if service_name in services.get_services(): self.set_service(service_name) service_games = ServiceGameCollection.get_for_service(service_name) if service_games: return [ game for game in sorted(service_games, key=lambda game: game.get( self.view_sorting) or game["name"], reverse=not self.view_sorting_ascending) if self.game_matches(game) ] if self.service.online and not self.service.is_connected(): self.show_label( _("Connect your %s account to access your games") % self.service.name) return self.unset_service() dynamic_categories = { "running": self.get_running_games, "installed": self.get_installed_games } if self.filters.get("dynamic_category") in dynamic_categories: return dynamic_categories[self.filters["dynamic_category"]]() if self.filters.get("category"): game_ids = categories_db.get_game_ids_for_category( self.filters["category"]) return games_db.get_games_by_ids(game_ids) searches, filters, excludes = self.get_sql_filters() return games_db.get_games(searches=searches, filters=filters, excludes=excludes, sorts=self.sort_params)
def on_game_install(self, game): """Request installation of a game""" if game.service and game.service != "lutris": service = get_enabled_services()[game.service]() db_game = ServiceGameCollection.get_game(service.id, game.appid) try: game_id = service.install(db_game) except ValueError as e: logger.debug(e) game_id = None if game_id: game = Game(game_id) game.launch() return True if not game.slug: raise ValueError("Invalid game passed: %s" % game) # return True installers = get_installers(game_slug=game.slug) if installers: self.show_installer_window(installers) else: ErrorDialog(_("There is no installer available for %s.") % game.name, parent=self.window) return True
def match_games(self): """Matching of service games to lutris games""" service_games = { str(game["appid"]): game for game in ServiceGameCollection.get_for_service(self.id) } logger.debug("Matching games %s", service_games) lutris_games = api.get_api_games(list(service_games.keys()), service=self.id) for lutris_game in lutris_games: for provider_game in lutris_game["provider_games"]: if provider_game["service"] != self.id: continue self.match_game(service_games.get(provider_game["slug"]), lutris_game) unmatched_service_games = get_games( searches={"installer_slug": self.matcher}, excludes={"service": self.id}) for lutris_game in api.get_api_games( game_slugs=[g["slug"] for g in unmatched_service_games]): for provider_game in lutris_game["provider_games"]: if provider_game["service"] != self.id: continue self.match_game(service_games.get(provider_game["slug"]), lutris_game)
def get_games_from_filters(self): if self.filters.get("service"): service_name = self.filters["service"] if service_name in services.get_services(): self.service = services.get_services()[service_name]() if self.service.online: self.service.connect("service-login", self.on_service_games_updated) self.service.connect("service-logout", self.on_service_logout) self.service.connect("service-games-loaded", self.on_service_games_updated) service_games = ServiceGameCollection.get_for_service( service_name) if service_games: return [ game for game in sorted( service_games, key=lambda game: game.get(self.view_sorting) or game["name"], reverse=not self.view_sorting_ascending, ) if self.game_matches(game) ] if not self.service.online or self.service.is_connected(): AsyncCall(self.service.load, None) spinner = Gtk.Spinner(visible=True) spinner.start() self.blank_overlay.add(spinner) else: self.blank_overlay.add( Gtk.Label( _("Connect your %s account to access your games") % self.service.name, visible=True, )) self.blank_overlay.props.visible = True return self.unset_service() dynamic_categories = { "running": self.get_running_games, "installed": self.get_installed_games, } if self.filters.get("dynamic_category") in dynamic_categories: return dynamic_categories[self.filters["dynamic_category"]]() self.unset_service() if self.filters.get("category"): game_ids = categories_db.get_game_ids_for_category( self.filters["category"]) return games_db.get_games_by_ids(game_ids) searches, filters, excludes = self.get_sql_filters() return games_db.get_games( searches=searches, filters=filters, excludes=excludes, sorts=self.sort_params, )
def switch_to_service(self, service_name): """Switch the current service to service_name and return games if available""" def combine_games(service_game, lutris_game): if not lutris_game or service_game["appid"] != lutris_game[ "service_id"]: return service_game for field in ("platform", "runner", "year", "installed_at", "lastplayed", "playtime", "installed"): service_game[field] = lutris_game[field] return service_game self.set_service(service_name) if service_name == "lutris": self.tabs_box.show( ) # Only the lutris service has the ability to search through all games. if self.website_button.props.active: return self.get_api_games() else: self.tabs_box.hide() service_games = ServiceGameCollection.get_for_service(service_name) if service_name == "lutris": lutris_games = {g["slug"]: g for g in games_db.get_games()} else: lutris_games = { g["service_id"]: g for g in games_db.get_games( filters={"service": self.service.id}) } def get_sort_value(game): sort_defaults = { "name": "", "year": 0, "lastplayed": 0.0, "installed_at": 0.0, "playtime": 0.0, } lutris_game = lutris_games.get(game["appid"]) if not lutris_game: return sort_defaults[self.view_sorting] value = lutris_game[self.view_sorting] if value: return value return sort_defaults[self.view_sorting] if service_games: return [ combine_games(game, lutris_games.get(game["appid"])) for game in sorted(service_games, key=get_sort_value, reverse=not self.view_sorting_ascending) if self.game_matches(game) ] if self.service.online and not self.service.is_connected(): self.show_label( _("Connect your %s account to access your games") % self.service.name) return
def on_game_selection_changed(self, view, game_id): if not game_id: GLib.idle_add(self.update_revealer) return False if self.service: game = ServiceGameCollection.get_game(self.service.id, game_id) else: game = games_db.get_game_by_field(int(game_id), "id") GLib.idle_add(self.update_revealer, game) return False
def on_game_updated(self, game): if game.appid and self.service: db_game = ServiceGameCollection.get_game(self.service.id, game.appid) else: db_game = games_db.get_game_by_field(game.id, "id") updated = self.game_store.update(db_game) if not updated: self.game_store.add_game(db_game) return True
def match_existing_game(self, db_games, appid): """Checks if a game is already installed and populates the service info""" for _game in db_games: logger.debug("Matching %s with existing install: %s", appid, _game) game = Game(_game["id"]) game.appid = appid game.service = self.id game.save() service_game = ServiceGameCollection.get_game(self.id, appid) sql.db_update(PGA_DB, "service_games", {"lutris_slug": game["slug"]}, {"id": service_game["id"]}) return game
def get_media_urls(self): """Return URLs for icons and logos from a service""" if self.source == "local": return {} service_games = ServiceGameCollection.get_for_service(self.service) medias = {} for game in service_games: if not game["details"]: continue details = json.loads(game["details"]) medias[game["slug"]] = self.url_pattern % details[self.api_field] return medias
def add_installed_games(self): ubisoft_connect = get_game_by_field(self.client_installer, "slug") if not ubisoft_connect: logger.warning("Ubisoft Connect not installed") return prefix_path = ubisoft_connect["directory"].split("drive_c")[0] prefix = WinePrefixManager(prefix_path) for game in ServiceGameCollection.get_for_service(self.id): details = json.loads(game["details"]) install_path = get_ubisoft_registry(prefix, details.get("registryPath")) exe = get_ubisoft_registry(prefix, details.get("exe")) if install_path and exe: self.install_from_ubisoft(ubisoft_connect, game)
def match_games(self): """Matching of service games to lutris games""" service_games = { str(game["appid"]): game for game in ServiceGameCollection.get_for_service(self.id) } lutris_games = api.get_api_games(list(service_games.keys()), service=self.id) for lutris_game in lutris_games: for provider_game in lutris_game["provider_games"]: if provider_game["service"] != self.id: continue self.match_game(service_games.get(provider_game["slug"]), lutris_game["slug"])
def on_game_updated(self, game): """Updates an individual entry in the view when a game is updated""" if game.appid and self.service: db_game = ServiceGameCollection.get_game(self.service.id, game.appid) else: db_game = games_db.get_game_by_field(game.id, "id") if not self.is_game_displayed(game): self.game_store.remove_game(db_game["id"]) return True updated = self.game_store.update(db_game) if not updated: self.update_store() return True
def on_game_install(self, game): """Request installation of a game""" if game.service: service = get_services()[game.service]() db_game = ServiceGameCollection.get_game(service.id, game.appid) service.install(db_game) return True installers = get_installers(game_slug=game.slug) if installers: self.show_installer_window(installers) else: logger.debug("Should generate automagical installer here but....") logger.debug("Wait? how did you get here?") return True
def on_game_activated(self, view, game_id): """Handles view activations (double click, enter press)""" if self.service: db_game = games_db.get_game_for_service(self.service.id, game_id) if db_game: game_id = db_game["id"] else: db_game = ServiceGameCollection.get_game( self.service.id, game_id) self.service.install(db_game) return game = Game(game_id) if game.is_installed: logger.info("Game is installed") game.emit("game-launch")
def save(self): """Save this game to database""" game_data = { "service": self.service, "appid": self.appid, "name": self.name, "slug": self.slug, "lutris_slug": self.lutris_slug, "icon": self.icon, "logo": self.logo, "details": str(self.details), } existing_game = ServiceGameCollection.get_game(self.service, self.appid) if existing_game: sql.db_update(PGA_DB, "service_games", game_data, {"id": existing_game["id"]}) else: sql.db_insert(PGA_DB, "service_games", game_data)
def on_game_install(self, game): """Request installation of a game""" if game.service: service = get_enabled_services()[game.service]() db_game = ServiceGameCollection.get_game(service.id, game.appid) game_id = service.install(db_game) if game_id: game = Game(game_id) game.launch() return True if not game.slug: raise ValueError("Invalid game passed: %s" % game) # return True installers = get_installers(game_slug=game.slug) if installers: self.show_installer_window(installers) else: logger.debug("Should generate automagical installer here but....") logger.debug("Wait? how did you get here?") return True
def on_game_install(self, game): """Request installation of a game""" if game.service: service = get_services()[game.service]() db_game = ServiceGameCollection.get_game(service.id, game.appid) game_id = service.install(db_game) if game_id: game = Game(game_id) game.launch() return True if not game.slug: logger.error("%s doesn't have a slug set, can't query installers", game) return True installers = get_installers(game_slug=game.slug) if installers: self.show_installer_window(installers) else: logger.debug("Should generate automagical installer here but....") logger.debug("Wait? how did you get here?") return True
def get_service_games(self, service_name): """Switch the current service to service_name and return games if available""" service_games = ServiceGameCollection.get_for_service(service_name) if service_name == "lutris": lutris_games = {g["slug"]: g for g in games_db.get_games()} else: lutris_games = { g["service_id"]: g for g in games_db.get_games( filters={"service": self.service.id}) } def get_sort_value(game): sort_defaults = { "name": "", "year": 0, "lastplayed": 0.0, "installed_at": 0.0, "playtime": 0.0, } view_sorting = self.view_sorting lutris_game = lutris_games.get(game["appid"]) if not lutris_game: return sort_defaults.get(view_sorting, "") value = lutris_game.get(view_sorting) if value: return value # Users may have obsolete view_sorting settings, so # we must tolerate them. We treat them all as blank. return sort_defaults.get(view_sorting, "") return [ self.combine_games(game, lutris_games.get(game["appid"])) for game in sorted(service_games, key=get_sort_value, reverse=not self.view_sorting_ascending) if self.game_matches(game) ]
def get_pixbuf(self): """Pixbuf varying on icon type""" if self._game_data.get("icon"): image_path = self._game_data["icon"] else: image_path = self.service_media.get_absolute_path(self.slug) if not system.path_exists(image_path): service = self._game_data.get("service") appid = self._game_data.get("service_id") if appid: service_game = ServiceGameCollection.get_game( service, appid) else: service_game = None if service_game: image_path = self.service_media.get_absolute_path( service_game["slug"]) if system.path_exists(image_path): return get_pixbuf(image_path, self.service_media.size, is_installed=self.installed) return self.service_media.get_pixbuf_for_game(self._game_data["slug"], self.installed)
def match_games(self): """Matching of service games to lutris games""" service_games = { str(game["appid"]): game for game in ServiceGameCollection.get_for_service(self.id) } lutris_games = api.get_api_games(list(service_games.keys()), service=self.id) for lutris_game in lutris_games: for provider_game in lutris_game["provider_games"]: if provider_game["service"] != self.id: continue service_game = service_games.get(provider_game["slug"]) if not service_game: continue conditions = { "appid": service_game["appid"], "service": self.id } sql.db_update(PGA_DB, "service_games", {"lutris_slug": lutris_game["slug"]}, conditions=conditions)
def install_from_egs(self, egs_game, manifest): """Create a new Lutris game based on an existing EGS install""" app_name = manifest["AppName"] service_game = ServiceGameCollection.get_game("egs", app_name) lutris_game_id = "egs-" + app_name existing_game = get_game_by_field(lutris_game_id, "slug") if existing_game: return game_config = LutrisConfig( game_config_id=egs_game["configpath"]).game_level game_config["game"]["args"] = get_launch_arguments(app_name) configpath = write_game_config(lutris_game_id, game_config) game_id = add_game( name=service_game["name"], runner=egs_game["runner"], slug="egs-" + app_name, directory=egs_game["directory"], installed=1, installer_slug="egs-" + app_name, configpath=configpath, service=self.id, service_id=app_name, ) return game_id