From 8de92e7b0fa4bd23dd2de7799a8016198c89f8a9 Mon Sep 17 00:00:00 2001 From: Dan Johnson Date: Tue, 10 Oct 2023 14:41:27 -0400 Subject: [PATCH 1/3] Set an icon on the LutrisInitDialog It can be shown for quite a while, so it may as well have suitable branding. --- lutris/gui/dialogs/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lutris/gui/dialogs/__init__.py b/lutris/gui/dialogs/__init__.py index 85e243d9e..b0c927d97 100644 --- a/lutris/gui/dialogs/__init__.py +++ b/lutris/gui/dialogs/__init__.py @@ -317,6 +317,7 @@ class LutrisInitDialog(Gtk.Dialog): super().__init__() self.runtime_updater = runtime_updater + self.set_icon_name("lutris") self.set_size_request(320, 60) self.set_border_width(24) self.set_decorated(False) From d2c10a8087264bbd1374a9ee289034ee0728994d Mon Sep 17 00:00:00 2001 From: Mathieu Comandon Date: Tue, 10 Oct 2023 13:21:26 -0700 Subject: [PATCH 2/3] Add Steam account selection in account preferences --- lutris/gui/config/accounts_box.py | 30 +++++++++++++++++++++-- lutris/services/__init__.py | 2 +- lutris/services/scummvm.py | 12 +++++----- lutris/services/steam.py | 4 ++-- lutris/util/steam/config.py | 40 +++++++++++++++++++++---------- lutris/util/steam/shortcut.py | 4 ++-- 6 files changed, 67 insertions(+), 25 deletions(-) diff --git a/lutris/gui/config/accounts_box.py b/lutris/gui/config/accounts_box.py index a1c3c3723..ca9613074 100644 --- a/lutris/gui/config/accounts_box.py +++ b/lutris/gui/config/accounts_box.py @@ -2,14 +2,40 @@ from gettext import gettext as _ from gi.repository import Gtk +from lutris import settings from lutris.gui.config.base_config_box import BaseConfigBox +from lutris.util.steam.config import get_steam_users class AccountsBox(BaseConfigBox): + steam_account_setting = "active_steam_account" + def __init__(self): super().__init__() self.add(self.get_section_label(_("Steam accounts"))) frame = Gtk.Frame(visible=True, shadow_type=Gtk.ShadowType.ETCHED_IN) - listbox = Gtk.ListBox(visible=True) - frame.add(listbox) self.pack_start(frame, False, False, 12) + + vbox = Gtk.VBox(visible=True) + frame.add(vbox) + + main_radio_button = None + active_steam_account = settings.read_setting(self.steam_account_setting) + for account in get_steam_users(): + radio_button = Gtk.RadioButton.new_with_label_from_widget( + main_radio_button, + account["PersonaName"] + ) + radio_button.set_margin_top(6) + radio_button.set_margin_start(12) + radio_button.set_margin_bottom(6) + radio_button.show() + radio_button.set_active(active_steam_account == account["steamid64"]) + radio_button.connect("toggled", self.on_steam_account_toggled, account["steamid64"]) + vbox.pack_start(radio_button, False, False, 0) + if not main_radio_button: + main_radio_button = radio_button + + def on_steam_account_toggled(self, radio_button, steamid64): + """Handler for switching the active Steam account.""" + settings.write_setting(self.steam_account_setting, steamid64) diff --git a/lutris/services/__init__.py b/lutris/services/__init__.py index 2057123f9..d8196ea8d 100644 --- a/lutris/services/__init__.py +++ b/lutris/services/__init__.py @@ -14,7 +14,7 @@ from lutris.services.itchio import ItchIoService from lutris.services.lutris import LutrisService from lutris.services.mame import MAMEService from lutris.services.origin import OriginService -from lutris.services.scummvm import ScummvmService, SCUMMVM_CONFIG_FILE +from lutris.services.scummvm import SCUMMVM_CONFIG_FILE, ScummvmService from lutris.services.steam import SteamService from lutris.services.steamwindows import SteamWindowsService from lutris.services.ubisoft import UbisoftConnectService diff --git a/lutris/services/scummvm.py b/lutris/services/scummvm.py index 14af8bf2f..104f03ade 100644 --- a/lutris/services/scummvm.py +++ b/lutris/services/scummvm.py @@ -56,17 +56,17 @@ class ScummvmService(BaseService): }) game.save() - def generate_installer(self, game): - details = json.loads(game["details"]) + def generate_installer(self, db_game): + details = json.loads(db_game["details"]) return { - "name": game["name"], + "name": db_game["name"], "version": "ScummVM", - "slug": game["slug"], - "game_slug": slugify(game["lutris_slug"]), + "slug": db_game["slug"], + "game_slug": slugify(db_game["lutris_slug"]), "runner": "scummvm", "script": { "game": { - "game_id": game["game_id"], + "game_id": db_game["game_id"], "path": details["path"], "platform": "scummvm" } diff --git a/lutris/services/steam.py b/lutris/services/steam.py index 5a6c4c831..ad23f80ad 100644 --- a/lutris/services/steam.py +++ b/lutris/services/steam.py @@ -17,7 +17,7 @@ from lutris.services.service_game import ServiceGame from lutris.services.service_media import ServiceMedia from lutris.util.log import logger from lutris.util.steam.appmanifest import AppManifest, get_appmanifests -from lutris.util.steam.config import get_steam_library, get_steamapps_dirs, get_user_steam_id64 +from lutris.util.steam.config import get_most_recent_steamid64, get_steam_library, get_steamapps_dirs from lutris.util.strings import slugify @@ -91,7 +91,7 @@ class SteamService(BaseService): def load(self): """Return importable Steam games""" - steamid = get_user_steam_id64() + steamid = get_most_recent_steamid64() if not steamid: logger.error("Unable to find SteamID from Steam config") return diff --git a/lutris/util/steam/config.py b/lutris/util/steam/config.py index 9f28eb79f..aeb7e4bc9 100644 --- a/lutris/util/steam/config.py +++ b/lutris/util/steam/config.py @@ -66,7 +66,7 @@ def read_user_config(): return config -def get_config_value(config, key): +def get_config_value(config: dict, key: str): """Fetch a value from a configuration in a case insensitive way""" keymap = {k.lower(): k for k in config.keys()} if key not in keymap: @@ -77,8 +77,10 @@ def get_config_value(config, key): return config[keymap[key.lower()]] -def get_steam_users(): - """Return the list of Steam users on this system and the base path where the settings are located""" +def get_user_data_dirs(): + """Return the list of available Steam user config directories (using a SteamID32) + and the base path where the settings are located (Returns the 1st location found) + """ for steam_dir in STEAM_DATA_DIRS: userdata_path = os.path.join(os.path.expanduser(steam_dir), "userdata") if not os.path.exists(userdata_path): @@ -89,17 +91,31 @@ def get_steam_users(): return "", [] -def get_user_steam_id64(): - """Read user's SteamID64 from Steam config files""" +def get_steam_users() -> list: + """Return a list of available Steam users. + Most recently used account is 1st in the list.""" + steam_users = [] user_config = read_user_config() if not user_config or "users" not in user_config: - return - last_steam_id = None - for steam_id in user_config["users"]: - last_steam_id = steam_id - if get_config_value(user_config["users"][steam_id], "mostrecent") == "1": - return steam_id - return last_steam_id + return [] + most_recent = None + for steam_id, account in user_config["users"].items(): + account["steamid64"] = steam_id + if get_config_value(account, "mostrecent") == "1": + most_recent = account + else: + steam_users.append(account) + if most_recent: + steam_users = [most_recent] + steam_users + return steam_users + + +def get_most_recent_steamid64() -> str: + """Read user's SteamID64 from Steam config files""" + steam_users = get_steam_users() + if steam_users: + return steam_users[0]["steamid64"] + return "" def get_steam_library(steamid): diff --git a/lutris/util/steam/shortcut.py b/lutris/util/steam/shortcut.py index b91975dea..92b83dfac 100644 --- a/lutris/util/steam/shortcut.py +++ b/lutris/util/steam/shortcut.py @@ -11,12 +11,12 @@ from lutris.game import Game from lutris.util import resources, system from lutris.util.log import logger from lutris.util.steam import vdf -from lutris.util.steam.config import get_steam_users +from lutris.util.steam.config import get_user_data_dirs def get_config_path() -> str: """Return config path for a Steam user""" - userdatapath, user_ids = get_steam_users() + userdatapath, user_ids = get_user_data_dirs() if not user_ids: return "" if len(user_ids) > 1: From 28e09a6275c8aafa735fa24c88bf24c91dab8e8b Mon Sep 17 00:00:00 2001 From: Mathieu Comandon Date: Tue, 10 Oct 2023 13:45:25 -0700 Subject: [PATCH 3/3] Use prefered Steam account for Steam integration and shortcuts --- lutris/gui/config/accounts_box.py | 7 +++---- lutris/services/steam.py | 4 ++-- lutris/util/steam/config.py | 23 ++++++++++++++++++----- lutris/util/steam/shortcut.py | 15 +++++++-------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/lutris/gui/config/accounts_box.py b/lutris/gui/config/accounts_box.py index ca9613074..f93244d1c 100644 --- a/lutris/gui/config/accounts_box.py +++ b/lutris/gui/config/accounts_box.py @@ -4,11 +4,10 @@ from gi.repository import Gtk from lutris import settings from lutris.gui.config.base_config_box import BaseConfigBox -from lutris.util.steam.config import get_steam_users +from lutris.util.steam.config import STEAM_ACCOUNT_SETTING, get_steam_users class AccountsBox(BaseConfigBox): - steam_account_setting = "active_steam_account" def __init__(self): super().__init__() @@ -20,7 +19,7 @@ class AccountsBox(BaseConfigBox): frame.add(vbox) main_radio_button = None - active_steam_account = settings.read_setting(self.steam_account_setting) + active_steam_account = settings.read_setting(STEAM_ACCOUNT_SETTING) for account in get_steam_users(): radio_button = Gtk.RadioButton.new_with_label_from_widget( main_radio_button, @@ -38,4 +37,4 @@ class AccountsBox(BaseConfigBox): def on_steam_account_toggled(self, radio_button, steamid64): """Handler for switching the active Steam account.""" - settings.write_setting(self.steam_account_setting, steamid64) + settings.write_setting(STEAM_ACCOUNT_SETTING, steamid64) diff --git a/lutris/services/steam.py b/lutris/services/steam.py index ad23f80ad..2c119c724 100644 --- a/lutris/services/steam.py +++ b/lutris/services/steam.py @@ -17,7 +17,7 @@ from lutris.services.service_game import ServiceGame from lutris.services.service_media import ServiceMedia from lutris.util.log import logger from lutris.util.steam.appmanifest import AppManifest, get_appmanifests -from lutris.util.steam.config import get_most_recent_steamid64, get_steam_library, get_steamapps_dirs +from lutris.util.steam.config import get_active_steamid64, get_steam_library, get_steamapps_dirs from lutris.util.strings import slugify @@ -91,7 +91,7 @@ class SteamService(BaseService): def load(self): """Return importable Steam games""" - steamid = get_most_recent_steamid64() + steamid = get_active_steamid64() if not steamid: logger.error("Unable to find SteamID from Steam config") return diff --git a/lutris/util/steam/config.py b/lutris/util/steam/config.py index aeb7e4bc9..7a9fe20be 100644 --- a/lutris/util/steam/config.py +++ b/lutris/util/steam/config.py @@ -7,6 +7,7 @@ import requests from lutris import settings from lutris.util import system from lutris.util.log import logger +from lutris.util.steam.steamid import SteamID from lutris.util.steam.vdfutils import vdf_parse STEAM_DATA_DIRS = ( @@ -21,6 +22,7 @@ STEAM_DATA_DIRS = ( "/usr/share/steam", "/usr/local/share/steam", ) +STEAM_ACCOUNT_SETTING = "active_steam_account" def get_steam_dir(): @@ -110,14 +112,25 @@ def get_steam_users() -> list: return steam_users -def get_most_recent_steamid64() -> str: - """Read user's SteamID64 from Steam config files""" - steam_users = get_steam_users() - if steam_users: - return steam_users[0]["steamid64"] +def get_active_steamid64() -> str: + """Return the currently active Steam ID""" + steam_ids = [u["steamid64"] for u in get_steam_users()] + active_steam_id = settings.read_setting(STEAM_ACCOUNT_SETTING) + if active_steam_id in steam_ids: + return active_steam_id + if steam_ids: + return steam_ids[0] return "" +def convert_steamid64_to_steamid32(steamid64: str) -> str: + """Return the 32bit variant of SteamIDs, used for folder names in userdata""" + if not steamid64.isnumeric(): + return "" + steam_id = SteamID.from_steamid64(int(steamid64)) + return str(steam_id.get_32_bit_community_id()) + + def get_steam_library(steamid): """Return the list of games owned by a SteamID""" if not steamid: diff --git a/lutris/util/steam/shortcut.py b/lutris/util/steam/shortcut.py index 92b83dfac..b7c0937e8 100644 --- a/lutris/util/steam/shortcut.py +++ b/lutris/util/steam/shortcut.py @@ -5,13 +5,12 @@ import re import shlex import shutil -from lutris import settings from lutris.api import format_installer_url from lutris.game import Game from lutris.util import resources, system from lutris.util.log import logger from lutris.util.steam import vdf -from lutris.util.steam.config import get_user_data_dirs +from lutris.util.steam.config import convert_steamid64_to_steamid32, get_active_steamid64, get_user_data_dirs def get_config_path() -> str: @@ -19,13 +18,13 @@ def get_config_path() -> str: userdatapath, user_ids = get_user_data_dirs() if not user_ids: return "" + user_id = user_ids[0] if len(user_ids) > 1: - preferred_id = settings.read_setting("preferred_steam_id") - if preferred_id and preferred_id in user_ids: - user_id = user_ids[0] - else: - logger.warning("No preferred Steam account selected, using %s", user_ids[0]) - user_id = user_ids[0] + active_account = get_active_steamid64() + if active_account: + active_account32 = convert_steamid64_to_steamid32(active_account) + if active_account32 in user_ids: + user_id = active_account32 return os.path.join(userdatapath, user_id, "config")