From d16b3d5d68408b8afc8f08e55a5f6f45c8f9c546 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 | 8 +- rare/shared/wrappers.py | 4 +- rare/utils/compat/{proton.py => steam.py} | 92 ++++++++++++++----- rare/utils/compat/utils.py | 2 +- 7 files changed, 82 insertions(+), 40 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 b8f39e26..d6332218 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 @@ if platform.system() != "Windows": 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 069eb49c..d6c2f9f2 100644 --- a/rare/components/tabs/settings/widgets/proton.py +++ b/rare/components/tabs/settings/widgets/proton.py @@ -4,13 +4,13 @@ from typing import Tuple, Union, Optional 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 @@ class ProtonSettings(QGroupBox): 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 @@ class ProtonSettings(QGroupBox): 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 38e5780e..b54acb46 100644 --- a/rare/components/tabs/settings/widgets/wrappers.py +++ b/rare/components/tabs/settings/widgets/wrappers.py @@ -25,7 +25,7 @@ from rare.utils.misc import icon 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 @@ class WrapperSettings(QWidget): 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 55b05faa..17465314 100644 --- a/rare/shared/workers/wine_resolver.py +++ b/rare/shared/workers/wine_resolver.py @@ -20,7 +20,7 @@ if platform.system() == "Windows": 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") @@ -38,20 +38,20 @@ class WinePathResolver(Worker): @staticmethod def _configure_process(core: LegendaryCore, app_name: str) -> Tuple[List, Dict]: - tool: proton.CompatibilityTool = None + tool: steam.CompatibilityTool = None if config.get_boolean(app_name, "no_wine"): wrappers = Wrappers() for w in wrappers.get_game_wrapper_list(app_name): if w.is_compat_tool: - for t in proton.find_tools(): + for t in steam.find_tools(): if t.checksum == w.checksum: tool = t break cmd = core.get_app_launch_command( app_name, - wrapper=tool.as_str(proton.SteamVerb.RUN_IN_PREFIX) if tool is not None else None, + wrapper=tool.as_str(steam.SteamVerb.RUN_IN_PREFIX) if tool is not None else None, disable_wine=config.get_boolean(app_name, "no_wine") ) env = core.get_app_environment(app_name, disable_wine=config.get_boolean(app_name, "no_wine")) diff --git a/rare/shared/wrappers.py b/rare/shared/wrappers.py index bf17ce36..c7c70fe3 100644 --- a/rare/shared/wrappers.py +++ b/rare/shared/wrappers.py @@ -122,7 +122,7 @@ if __name__ == "__main__": 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 @@ -156,7 +156,7 @@ if __name__ == "__main__": game_wrappers = wr.get_game_wrapper_list("testgame2") pprint(game_wrappers) - for i, tool in enumerate(proton.find_tools()): + for i, tool in enumerate(steam.find_tools()): wt = Wrapper(command=tool.command(), name=tool.name, wtype=WrapperType.COMPAT_TOOL) wr.set_game_wrapper_list(f"compat_game_{i}", [wt]) print(wt.as_str) 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 87b79d2c..624d5539 100644 --- a/rare/utils/compat/proton.py +++ b/rare/utils/compat/steam.py @@ -67,11 +67,15 @@ class SteamBase: @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 @@ class CompatibilityTool(SteamBase): @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 @@ if __name__ == "__main__": _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 929a5057..92b8e6a3 100644 --- a/rare/utils/compat/utils.py +++ b/rare/utils/compat/utils.py @@ -11,7 +11,7 @@ from rare.utils import config_helper as config if platform.system() != "Windows": from . import wine if platform.system() != "Darwin": - from . import proton + from . import steam logger = getLogger("CompatUtils")