From 37dffa1115eeca3b1d3ffd50123b4a90a3c567a0 Mon Sep 17 00:00:00 2001 From: loathingKernel <142770+loathingKernel@users.noreply.github.com> Date: Sun, 18 Feb 2024 12:44:04 +0200 Subject: [PATCH] Runners: rename proton to steam --- .../tabs/settings/widgets/env_vars_model.py | 2 +- .../tabs/settings/widgets/proton.py | 10 +- .../tabs/settings/widgets/wrappers.py | 4 +- rare/shared/workers/wine_resolver.py | 2 +- rare/shared/wrappers.py | 2 +- rare/utils/compat/{proton.py => steam.py} | 92 ++++++++++++++----- rare/utils/compat/utils.py | 2 +- 7 files changed, 78 insertions(+), 36 deletions(-) rename rare/utils/compat/{proton.py => steam.py} (78%) diff --git a/rare/components/tabs/settings/widgets/env_vars_model.py b/rare/components/tabs/settings/widgets/env_vars_model.py index b8f39e263..d6332218c 100644 --- a/rare/components/tabs/settings/widgets/env_vars_model.py +++ b/rare/components/tabs/settings/widgets/env_vars_model.py @@ -14,7 +14,7 @@ from rare.utils.compat.wine import get_wine_environment if platform.system() in {"Linux", "FreeBSD"}: - from rare.utils.compat.proton import get_steam_environment + from rare.utils.compat.steam import get_steam_environment class EnvVarsTableModel(QAbstractTableModel): diff --git a/rare/components/tabs/settings/widgets/proton.py b/rare/components/tabs/settings/widgets/proton.py index 069eb49c5..d6c2f9f2f 100644 --- a/rare/components/tabs/settings/widgets/proton.py +++ b/rare/components/tabs/settings/widgets/proton.py @@ -4,13 +4,13 @@ from PyQt5.QtCore import pyqtSignal, Qt from PyQt5.QtGui import QShowEvent -from PyQt5.QtWidgets import QGroupBox, QFileDialog, QFormLayout, QComboBox, QLabel +from PyQt5.QtWidgets import QGroupBox, QFileDialog, QFormLayout, QComboBox from rare.models.wrapper import Wrapper, WrapperType from rare.shared import RareCore from rare.shared.wrappers import Wrappers from rare.utils import config_helper as config -from rare.utils.compat import proton +from rare.utils.compat import steam from rare.utils.paths import proton_compat_dir from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon @@ -57,7 +57,7 @@ def showEvent(self, a0: QShowEvent) -> None: self.tool_combo.blockSignals(True) self.tool_combo.clear() self.tool_combo.addItem(self.tr("Don't use a compatibility tool"), None) - tools = proton.find_tools() + tools = steam.find_tools() for tool in tools: self.tool_combo.addItem(tool.name, tool) try: @@ -81,9 +81,9 @@ def showEvent(self, a0: QShowEvent) -> None: super().showEvent(a0) def __on_proton_changed(self, index): - steam_tool: Union[proton.ProtonTool, proton.CompatibilityTool] = self.tool_combo.itemData(index) + steam_tool: Union[steam.ProtonTool, steam.CompatibilityTool] = self.tool_combo.itemData(index) - steam_environ = proton.get_steam_environment(steam_tool, self.tool_prefix.text()) + steam_environ = steam.get_steam_environment(steam_tool, self.tool_prefix.text()) for key, value in steam_environ.items(): config.save_envvar(self.app_name, key, value) self.environ_changed.emit(key) diff --git a/rare/components/tabs/settings/widgets/wrappers.py b/rare/components/tabs/settings/widgets/wrappers.py index 38e5780eb..b54acb468 100644 --- a/rare/components/tabs/settings/widgets/wrappers.py +++ b/rare/components/tabs/settings/widgets/wrappers.py @@ -25,7 +25,7 @@ from rare.widgets.dialogs import ButtonDialog, game_title if pf.system() in {"Linux", "FreeBSD"}: - from rare.utils.compat import proton + from rare.utils.compat import steam logger = getLogger("WrapperSettings") @@ -295,7 +295,7 @@ def add_user_wrapper(self, wrapper: Wrapper, position: int = -1): return if pf.system() in {"Linux", "FreeBSD"}: - compat_cmds = [tool.command() for tool in proton.find_tools()] + compat_cmds = [tool.command() for tool in steam.find_tools()] if wrapper.as_str in compat_cmds: QMessageBox.warning( self, diff --git a/rare/shared/workers/wine_resolver.py b/rare/shared/workers/wine_resolver.py index 55b05faa9..a48e1252f 100644 --- a/rare/shared/workers/wine_resolver.py +++ b/rare/shared/workers/wine_resolver.py @@ -20,7 +20,7 @@ import winreg # pylint: disable=E0401 from legendary.lfs import windows_helpers else: - from rare.utils.compat import utils as compat_utils, proton + from rare.utils.compat import utils as compat_utils, steam logger = getLogger("WineResolver") diff --git a/rare/shared/wrappers.py b/rare/shared/wrappers.py index bf17ce36f..d07af16a4 100644 --- a/rare/shared/wrappers.py +++ b/rare/shared/wrappers.py @@ -122,7 +122,7 @@ def __save_wrappers(self): from pprint import pprint from argparse import Namespace - from rare.utils.compat import proton + from rare.utils.compat import steam global config_dir config_dir = os.getcwd diff --git a/rare/utils/compat/proton.py b/rare/utils/compat/steam.py similarity index 78% rename from rare/utils/compat/proton.py rename to rare/utils/compat/steam.py index 87b79d2cc..624d5539d 100644 --- a/rare/utils/compat/proton.py +++ b/rare/utils/compat/steam.py @@ -67,11 +67,15 @@ def __hash__(self): @property def required_tool(self) -> Optional[str]: - return self.toolmanifest["manifest"].get("require_tool_appid", None) + return self.toolmanifest.get("require_tool_appid", None) + + @property + def layer(self) -> Optional[str]: + return self.toolmanifest.get("compatmanager_layer_name", None) def command(self, verb: SteamVerb = SteamVerb.DEFAULT) -> List[str]: tool_path = os.path.normpath(self.tool_path) - cmd = "".join([shlex.quote(tool_path), self.toolmanifest["manifest"]["commandline"]]) + cmd = "".join([shlex.quote(tool_path), self.toolmanifest["commandline"]]) # NOTE: "waitforexitandrun" seems to be the verb used in by steam to execute stuff # `run` is used when setting up the environment, so use that if we are setting up the prefix. cmd = cmd.replace("%verb%", str(verb)) @@ -126,8 +130,7 @@ def __bool__(self) -> bool: @property def name(self) -> str: - name, data = list(self.compatibilitytool["compatibilitytools"]["compat_tools"].items())[0] - return data["display_name"] + return self.compatibilitytool["display_name"] def command(self, verb: SteamVerb = SteamVerb.DEFAULT) -> List[str]: cmd = self.runtime.command(verb) if self.runtime is not None else [] @@ -162,7 +165,7 @@ def find_protons(steam_path: str, library: str) -> List[ProtonTool]: steam_library=library, appmanifest=appmanifest, tool_path=tool_path, - toolmanifest=toolmanifest, + toolmanifest=toolmanifest["manifest"], ) ) return protons @@ -181,23 +184,43 @@ def find_compatibility_tools(steam_path: str) -> List[CompatibilityTool]: tools = [] for path in compatibilitytools_paths: for entry in os.scandir(path): + entry_path = os.path.join(path, entry.name) if entry.is_dir(): - tool_path = os.path.join(path, entry.name) - tool_vdf = os.path.join(tool_path, "compatibilitytool.vdf") + tool_vdf = os.path.join(entry_path, "compatibilitytool.vdf") + elif entry.is_file() and entry.name.endswith(".vdf"): + tool_vdf = entry_path + else: + continue + + if not os.path.isfile(tool_vdf): + continue + + with open(tool_vdf, "r") as f: + compatibilitytool = vdf.load(f) + + entry_tools = compatibilitytool["compatibilitytools"]["compat_tools"] + for entry_tool in entry_tools.values(): + if entry_tool["from_oslist"] != "windows" and entry_tool["to_oslist"] != "linux": + continue + + install_path = entry_tool["install_path"] + tool_path = os.path.abspath(os.path.join(os.path.dirname(tool_vdf), install_path)) manifest_vdf = os.path.join(tool_path, "toolmanifest.vdf") - if os.path.isfile(tool_vdf) and os.path.isfile(manifest_vdf): - with open(tool_vdf, "r") as f: - compatibilitytool = vdf.load(f) - with open(manifest_vdf, "r") as f: - manifest = vdf.load(f) - tools.append( - CompatibilityTool( - steam_path=steam_path, - tool_path=tool_path, - toolmanifest=manifest, - compatibilitytool=compatibilitytool, - ) + + if not os.path.isfile(manifest_vdf): + continue + + with open(manifest_vdf, "r") as f: + manifest = vdf.load(f) + + tools.append( + CompatibilityTool( + steam_path=steam_path, + tool_path=tool_path, + toolmanifest=manifest["manifest"], + compatibilitytool=entry_tool, ) + ) return tools @@ -212,6 +235,7 @@ def find_runtimes(steam_path: str, library: str) -> Dict[str, SteamRuntime]: with open(vdf_file, "r") as f: toolmanifest = vdf.load(f) if toolmanifest["manifest"]["compatmanager_layer_name"] == "container-runtime": + print(toolmanifest["manifest"]) runtimes.update( { appmanifest["AppState"]["appid"]: SteamRuntime( @@ -219,7 +243,7 @@ def find_runtimes(steam_path: str, library: str) -> Dict[str, SteamRuntime]: steam_library=library, appmanifest=appmanifest, tool_path=tool_path, - toolmanifest=toolmanifest, + toolmanifest=toolmanifest["manifest"], ) } ) @@ -235,6 +259,24 @@ def find_runtime( return runtimes.get(required_tool, None) +def get_ulwgl_environment( + tool: Optional[ProtonTool] = None, compat_path: Optional[str] = None +) -> Dict: + # If the tool is unset, return all affected env variable names + # IMPORTANT: keep this in sync with the code below + environ = {"WINEPREFIX": compat_path if compat_path else ""} + if tool is None: + environ["WINEPREFIX"] = "" + environ["PROTONPATH"] = "" + environ["GAMEID"] = "" + environ["STORE"] = "" + return environ + + environ["PROTONPATH"] = tool.tool_path + environ["STORE"] = "egs" + return environ + + def get_steam_environment( tool: Optional[Union[ProtonTool, CompatibilityTool]] = None, compat_path: Optional[str] = None ) -> Dict: @@ -293,8 +335,8 @@ def find_tools() -> List[Union[ProtonTool, CompatibilityTool]]: _tools = find_tools() pprint(_tools) - for tool in _tools: - print(get_steam_environment(tool)) - print(tool.name) - print(tool.command(SteamVerb.RUN)) - print(" ".join(tool.command(SteamVerb.RUN_IN_PREFIX))) + for _tool in _tools: + print(get_steam_environment(_tool)) + print(_tool.name) + print(_tool.command(SteamVerb.RUN)) + print(" ".join(_tool.command(SteamVerb.RUN_IN_PREFIX))) diff --git a/rare/utils/compat/utils.py b/rare/utils/compat/utils.py index 929a5057b..92b8e6a39 100644 --- a/rare/utils/compat/utils.py +++ b/rare/utils/compat/utils.py @@ -11,7 +11,7 @@ if platform.system() != "Windows": from . import wine if platform.system() != "Darwin": - from . import proton + from . import steam logger = getLogger("CompatUtils")