diff --git a/lmm/cli.py b/lmm/cli.py index 3bef423..a7be6a4 100644 --- a/lmm/cli.py +++ b/lmm/cli.py @@ -1,6 +1,7 @@ import os from typing import Optional +from lmm.config import LMMConfig from lmm.const import LMM_GAMES_PATH from lmm.games.config import load_game_configs from lmm.games.game import Game @@ -148,6 +149,7 @@ def list(): def main(): + LMMConfig.init() cli() diff --git a/lmm/config.py b/lmm/config.py new file mode 100644 index 0000000..54ecf1e --- /dev/null +++ b/lmm/config.py @@ -0,0 +1,24 @@ +from lmm.const import LMM_PATH + +import yaml + + +class LMMConfig: + use_fuse: bool + overlayfs_command: str + fusermount_command: str + + @classmethod + def init(cls): + # Load the config file + config = LMM_PATH / "config.yaml" + if config.exists(): + with open(config, "r") as f: + data = yaml.load(f, Loader=yaml.CLoader) + else: + data = {} + + fuse = data.get("fuse", {}) + cls.use_fuse = fuse.get("enable", False) + cls.overlayfs_command = fuse.get("overlayfs", "fuse-overlayfs") + cls.fusermount_command = fuse.get("fusermount", "fusermount") diff --git a/lmm/games/game.py b/lmm/games/game.py index 368cd2f..99cadbd 100644 --- a/lmm/games/game.py +++ b/lmm/games/game.py @@ -115,11 +115,21 @@ class ProtonGame(Game, abc.ABC): with open(proc_path, "r") as f: cmdline = f.read() + # Workaround for Baldur's Gate 3, which launches "../bin/bg3_dx11.exe", when launched from + # the Larion Launcher. + if cmdline.startswith(".."): + cmdline = os.path.join( + os.readlink(proc / dir / "cwd"), cmdline + ).replace("\\", "/") + # Workaround for games like Baldur's Gate 3 that have a relative path in the cmdline. # Note that the cmdline contains null bytes that we have to remove. abs_cmdline = os.path.abspath(cmdline).replace("\x00", "") - if cmdline.startswith(wine_exe_path) or abs_cmdline == str( - self.game_executable + + if ( + cmdline.startswith(wine_exe_path) + or abs_cmdline == str(self.game_executable) + or abs_cmdline.startswith(str(self.game_executable)) ): self._pid = dir break diff --git a/lmm/overlayfs.py b/lmm/overlayfs.py index 310c9d5..ee159cc 100644 --- a/lmm/overlayfs.py +++ b/lmm/overlayfs.py @@ -2,7 +2,8 @@ from pathlib import Path import tempfile from typing import Optional -from lmm.cmd import run_sudo_cmd +from lmm.config import LMMConfig +from lmm.cmd import run_sudo_cmd, run_cmd def compute_workdirs_location(mount: Path) -> Path: @@ -71,18 +72,29 @@ class OverlayFSMount: workdir = self.create_workdir() options += f",upperdir={self.upper},workdir={workdir}" - result = run_sudo_cmd( - [ - "mount", - "-t", - "overlay", - "overlay", - "-o", - options, - str(self.mount_path), - ], - cd=self.cd, - ) + if LMMConfig.use_fuse: + result = run_cmd( + [ + LMMConfig.overlayfs_command, + "-o", + options, + str(self.mount_path), + ], + cd=self.cd, + ) + else: + result = run_sudo_cmd( + [ + "mount", + "-t", + "overlay", + "overlay", + "-o", + options, + str(self.mount_path), + ], + cd=self.cd, + ) print("Mount result:", result) if not result == 0: return None @@ -95,12 +107,21 @@ class OverlayFSMount: print("Unmounting...") # Remove the mount - run_sudo_cmd( - [ - "umount", - str(self.mount_path), - ] - ) + if LMMConfig.use_fuse: + run_cmd( + [ + LMMConfig.fusermount_command, + "-u", + str(self.mount_path), + ] + ) + else: + run_sudo_cmd( + [ + "umount", + str(self.mount_path), + ] + ) # Remove the temporary workdir if self.workdir is not None: