Exemple #1
0
 def get_command(self):
     """Return the command used to launch a Steam game"""
     game_args = self.game_config.get("args") or ""
     game_binary = self.game_config.get("steamless_binary")
     if self.game_config.get("run_without_steam") and game_binary:
         # Start without steam
         if not system.path_exists(game_binary):
             raise FileNotFoundError(2, "Game binary not found",
                                     game_binary)
         command = [self.get_executable(), game_binary]
         for arg in split_arguments(game_args):
             command.append(arg)
     else:
         # Start through steam
         command = self.launch_args
         if self.game_config.get("nolaunch"):
             command.append("steam://open/games/details")
         elif not game_args:
             command.append("steam://rungameid/%s" % self.appid)
         else:
             command.append("-applaunch")
             command.append(self.appid)
             for arg in split_arguments(game_args):
                 command.append(arg)
     return command
Exemple #2
0
    def launch_args(self):
        if self.is_native:
            args = [self.get_executable()]
            args.append("-windowed")
            args.append("0" if self.runner_config.get("fullscreen") else "1")
            if self.runner_config.get("splore"):
                args.append("-splore")

            size = self.runner_config.get("window_size").split("x")
            if len(size) == 2:
                args.append("-width")
                args.append(size[0])
                args.append("-height")
                args.append(size[1])
            extra_args = self.runner_config.get("args", "")
            for arg in split_arguments(extra_args):
                args.append(arg)
        else:
            args = [
                self.get_executable(),
                os.path.join(settings.RUNNER_DIR, "pico8/web/player.html"),
                "--window-size",
                self.runner_config.get("window_size"),
            ]
        return args
Exemple #3
0
    def play(self):
        """Run native game."""
        launch_info = {}

        if not self.game_exe or not system.path_exists(self.game_exe):
            return {"error": "FILE_NOT_FOUND", "file": self.game_exe}

        # Quit if the file is not executable
        mode = os.stat(self.game_exe).st_mode
        if not mode & stat.S_IXUSR:
            return {"error": "NOT_EXECUTABLE", "file": self.game_exe}

        if not system.path_exists(self.game_exe):
            return {"error": "FILE_NOT_FOUND", "file": self.game_exe}

        ld_preload = self.game_config.get("ld_preload")
        if ld_preload:
            launch_info["ld_preload"] = ld_preload

        ld_library_path = self.game_config.get("ld_library_path")
        if ld_library_path:
            launch_info["ld_library_path"] = os.path.expanduser(
                ld_library_path)

        command = [self.get_relative_exe()]

        args = self.game_config.get("args") or ""
        for arg in split_arguments(args):
            command.append(arg)
        launch_info["command"] = command
        return launch_info
Exemple #4
0
    def play(self):
        command = self.get_command()

        # Options
        if self.runner_config.get("aspect"):
            command.append("--aspect-ratio")

        if self.game_config.get("subtitles"):
            command.append("--subtitles")

        if self.runner_config.get("fullscreen"):
            command.append("--fullscreen")
        else:
            command.append("--no-fullscreen")

        mode = self.runner_config.get("gfx-mode")
        if mode:
            command.append("--gfx-mode=%s" % mode)
        # /Options
        command.append("--path=%s" % self.game_path)
        args = self.game_config.get("args") or ""
        for arg in split_arguments(args):
            command.append(arg)
        command.append(self.game_config.get("game_id"))
        launch_info = {"command": command, "ld_library_path": self.libs_dir}

        return launch_info
Exemple #5
0
    def play(self):  # pylint: disable=too-many-return-statements # noqa: C901
        game_exe = self.game_exe
        arguments = self.game_config.get("args", "")
        launch_info = {"env": self.get_env(os_env=False)}
        using_dxvk = self.runner_config.get("dxvk")

        if using_dxvk:
            # Set this to 1 to enable access to more RAM for 32bit applications
            launch_info["env"]["WINE_LARGE_ADDRESS_AWARE"] = "1"
            if not is_vulkan_supported():
                if not display_vulkan_error(True):
                    return {"error": "VULKAN_NOT_FOUND"}

        if not system.path_exists(game_exe):
            return {"error": "FILE_NOT_FOUND", "file": game_exe}

        if launch_info["env"].get("WINEESYNC") == "1":
            limit_set = is_esync_limit_set()
            wine_ver = is_version_esync(self.get_executable())

            if not limit_set and not wine_ver:
                esync_display_version_warning(True)
                esync_display_limit_warning()
                return {"error": "ESYNC_LIMIT_NOT_SET"}
            if not is_esync_limit_set():
                esync_display_limit_warning()
                return {"error": "ESYNC_LIMIT_NOT_SET"}
            if not wine_ver:
                if not esync_display_version_warning(True):
                    return {"error": "NON_ESYNC_WINE_VERSION"}

        if launch_info["env"].get("WINEFSYNC") == "1":
            fsync_supported = is_fsync_supported()
            wine_ver = is_version_fsync(self.get_executable())

            if not fsync_supported and not wine_ver:
                fsync_display_version_warning(True)
                fsync_display_support_warning()
                return {"error": "FSYNC_NOT_SUPPORTED"}
            if not fsync_supported:
                fsync_display_support_warning()
                return {"error": "FSYNC_NOT_SUPPORTED"}
            if not wine_ver:
                if not fsync_display_version_warning(True):
                    return {"error": "NON_FSYNC_WINE_VERSION"}

        command = [self.get_executable()]

        game_exe, args, _working_dir = get_real_executable(
            game_exe, self.working_dir)
        command.append(game_exe)
        if args:
            command = command + args

        if arguments:
            for arg in split_arguments(arguments):
                command.append(arg)
        launch_info["command"] = command
        return launch_info
Exemple #6
0
 def launch_args(self):
     """Provide launch arguments for Steam"""
     args = [self.get_executable()]
     if system.LINUX_SYSTEM.is_flatpak:
         return args
     if self.runner_config.get("start_in_big_picture"):
         args.append("-bigpicture")
     return args + split_arguments(self.runner_config.get("args") or "")
Exemple #7
0
 def launch_args(self):
     """Provide launch arguments for Steam"""
     return [
         self.get_executable(),
         self.get_steam_path(),
         "-no-cef-sandbox",
         "-console",
     ] + split_arguments(self.runner_config.get("args") or "")
Exemple #8
0
 def launch_args(self):
     """Provide launch arguments for Steam"""
     steam_path = self.get_steam_path()
     if not steam_path:
         raise RuntimeError("Can't find a Steam executable")
     return [
         self.get_executable(),
         steam_path,
         "-no-cef-sandbox",
         "-console",
     ] + split_arguments(self.runner_config.get("args") or "")
Exemple #9
0
 def play(self):
     command = self.get_command()
     for option, cmdline in self.option_map.items():
         self.inject_runner_option(command, option, cmdline,
                                   self.option_empty_map.get(option))
     command.append("--path=%s" % self.game_path)
     args = self.game_config.get("args") or ""
     for arg in split_arguments(args):
         command.append(arg)
     command.append(self.game_config.get("game_id"))
     return {"command": command, "ld_library_path": self.libs_dir}
Exemple #10
0
    def play(self):
        command = [
            self.get_executable(), "-skip_gameinfo", "-inipath",
            self.config_dir
        ]
        if self.runner_config.get("video"):
            command += ["-video", self.runner_config["video"]]
        if not self.runner_config.get("fullscreen"):
            command.append("-window")
        if self.runner_config.get("waitvsync"):
            command.append("-waitvsync")
        if self.runner_config.get("uimodekey"):
            command += ["-uimodekey", self.runner_config["uimodekey"]]

        if self.game_config.get("machine"):
            rompath = self.runner_config.get("rompath")
            if rompath:
                command += ["-rompath", rompath]
            command.append(self.game_config["machine"])
            device = self.game_config.get("device")
            if not device:
                return {
                    "error":
                    "CUSTOM",
                    "text":
                    "No device is set for machine %s" %
                    self.game_config["machine"],
                }
            rom = self.game_config["main_file"]
            command += ["-" + device, rom]
        else:
            rompath = os.path.dirname(self.game_config.get("main_file"))
            if not rompath:
                rompath = self.runner_config.get("rompath")
            rom = os.path.basename(self.game_config.get("main_file"))
            if not rompath:
                return {"error": "PATH_NOT_SET", "path": "rompath"}
            command += ["-rompath", rompath, rom]

        if self.game_config.get("autoboot_command"):
            command += [
                "-autoboot_command",
                self.game_config["autoboot_command"] + "\\n",
            ]
            if self.game_config.get("autoboot_delay"):
                command += [
                    "-autoboot_delay",
                    str(self.game_config["autoboot_delay"])
                ]

        for arg in split_arguments(self.game_config.get("args")):
            command.append(arg)

        return {"command": command}
Exemple #11
0
    def play(self):
        command = [self.get_executable(), "-skip_gameinfo", "-inipath", self.config_dir]
        if self.runner_config.get("video"):
            command += ["-video", self.runner_config["video"]]
        if not self.runner_config.get("fullscreen"):
            command.append("-window")
        if self.runner_config.get("waitvsync"):
            command.append("-waitvsync")
        if self.runner_config.get("uimodekey"):
            command += ["-uimodekey", self.runner_config["uimodekey"]]

        if self.runner_config.get("crt"):
            command += self.get_shader_params("CRT-geom", ["Gaussx", "Gaussy", "CRT-geom-halation"])
            command += ["-nounevenstretch"]

        if self.game_config.get("machine"):
            rompath = self.runner_config.get("rompath")
            if rompath:
                command += ["-rompath", rompath]
            command.append(self.game_config["machine"])
            device = self.game_config.get("device")
            if not device:
                return {'error': "CUSTOM", "text": "No device is set for machine %s" % self.game_config["machine"]}
            rom = self.game_config.get("main_file")
            if rom:
                command += ["-" + device, rom]
        else:
            rompath = os.path.dirname(self.game_config.get("main_file"))
            if not rompath:
                rompath = self.runner_config.get("rompath")
            rom = os.path.basename(self.game_config.get("main_file"))
            if not rompath:
                return {'error': 'PATH_NOT_SET', 'path': 'rompath'}
            command += ["-rompath", rompath, rom]

        if self.game_config.get("autoboot_command"):
            command += ["-autoboot_command", self.game_config["autoboot_command"] + "\\n"]
            if self.game_config.get("autoboot_delay"):
                command += ["-autoboot_delay", str(self.game_config["autoboot_delay"])]

        for arg in split_arguments(self.game_config.get("args")):
            command.append(arg)

        return {"command": command}
Exemple #12
0
    def play(self):
        game_args = self.game_config.get("args") or ""

        binary_path = self.game_config.get("steamless_binary")
        if self.game_config.get("run_without_steam") and binary_path:
            # Start without steam
            if not system.path_exists(binary_path):
                return {"error": "FILE_NOT_FOUND", "file": binary_path}
            self.original_steampid = None
            command = [binary_path]
        else:
            # Start through steam

            if system.LINUX_SYSTEM.is_flatpak:
                if game_args:
                    steam_uri = "steam://run/%s//%s/" % (self.appid, game_args)
                else:
                    steam_uri = "steam://rungameid/%s" % self.appid
                return {
                    "command": self.launch_args + [steam_uri],
                    "env": self.get_env(),
                }

            # Get current steam pid to act as the root pid instead of lutris
            self.original_steampid = get_steam_pid()
            command = self.launch_args

            if self.runner_config.get("start_in_big_picture") or not game_args:
                command.append("steam://rungameid/%s" % self.appid)
            else:
                command.append("-applaunch")
                command.append(self.appid)

        if game_args:
            for arg in split_arguments(game_args):
                command.append(arg)

        return {
            "command": command,
            "env": self.get_env(),
        }
Exemple #13
0
    def get_gameplay_info(self):
        """Return the information provided by a runner's play method.
        Checks for possible errors.
        """
        if not self.runner:
            logger.warning("Trying to launch %s without a runner", self)
            return {}
        gameplay_info = self.runner.play()
        if self.config.game_level.get("game", {}).get("launch_configs"):
            configs = self.config.game_level["game"]["launch_configs"]
            dlg = dialogs.LaunchConfigSelectDialog(self, configs)
            if dlg.config_index:
                config = configs[dlg.config_index - 1]
                gameplay_info["command"] = [gameplay_info["command"][0], config["exe"]]
                if config.get("args"):
                    gameplay_info["command"] += strings.split_arguments(config["args"])

        if "error" in gameplay_info:
            self.show_error_message(gameplay_info)
            self.state = self.STATE_STOPPED
            self.emit("game-stop")
            return
        return gameplay_info
Exemple #14
0
    def play(self):  # noqa: C901
        command = [self.get_executable()]

        resolution = self.runner_config.get("resolution")
        if resolution:
            if resolution == "desktop":
                width, height = display.DISPLAY_MANAGER.get_current_resolution(
                )
            else:
                width, height = resolution.split("x")
            command.append("-width")
            command.append(width)
            command.append("-height")
            command.append(height)

        # Append any boolean options.
        bool_options = ["2", "4", "nostartup"]
        for option in bool_options:
            if self.runner_config.get(option):
                command.append("-%s" % option)

        # Append the skill level.
        skill = self.runner_config.get("skill")
        if skill:
            command.append("-skill")
            command.append(skill)

        # Append directory for configuration file, if provided.
        config = self.runner_config.get("config")
        if config:
            command.append("-config")
            command.append(config)

        # Append the warp arguments.
        warp = self.game_config.get("warp")
        if warp:
            command.append("-warp")
            for warparg in warp.split(" "):
                command.append(warparg)

        # Append directory for save games, if provided.
        savedir = self.game_config.get("savedir")
        if savedir:
            command.append("-savedir")
            command.append(savedir)

        # Append the wad file to load, if provided.
        wad = self.game_config.get("main_file")
        if wad:
            command.append("-iwad")
            command.append(wad)

        # Append the pwad files to load, if provided.
        files = self.game_config.get("files") or []
        pwads = [
            f for f in files
            if f.lower().endswith(".wad") or f.lower().endswith(".pk3")
        ]
        deh = [f for f in files if f.lower().endswith(".deh")]
        bex = [f for f in files if f.lower().endswith(".bex")]
        if deh:
            command.append("-deh")
            command.append(deh[0])
        if bex:
            command.append("-bex")
            command.append(bex[0])
        if pwads:
            command.append("-file")
            for pwad in pwads:
                command.append(pwad)

        # Append additional arguments, if provided.
        args = self.game_config.get("args") or ""
        for arg in split_arguments(args):
            command.append(arg)

        return {"command": command}
Exemple #15
0
    def play(self):
        url = self.game_config.get("main_file")
        if not url:
            return {
                "error":
                "CUSTOM",
                "text":
                _("The web address is empty, \n"
                  "verify the game's configuration."),
            }

        # check if it's an url or a file
        is_url = urlparse(url).scheme != ""

        if not is_url:
            if not system.path_exists(url):
                return {
                    "error":
                    "CUSTOM",
                    "text":
                    _("The file %s does not exist, \n"
                      "verify the game's configuration.") % url,
                }
            url = "file://" + url

        game_data = get_game_by_field(self.config.game_config_id, "configpath")

        # keep the old behavior from browser runner, but with support for extra arguments!
        if self.runner_config.get("external_browser"):
            # is it possible to disable lutris runtime here?
            browser = self.runner_config.get(
                "custom_browser_executable") or "xdg-open"

            args = self.runner_config.get("custom_browser_args")
            args = args or '"$GAME"'
            arguments = string.Template(args).safe_substitute({
                "GAME": url,
                "URL": url
            })

            command = [browser]

            for arg in split_arguments(arguments):
                command.append(arg)

            return {"command": command}

        icon = resources.get_icon_path(game_data.get("slug"))
        if not system.path_exists(icon):
            icon = DEFAULT_ICON

        command = [
            self.get_executable(),
            os.path.join(settings.RUNNER_DIR,
                         "web/electron/resources/app.asar"),
            url,
            "--name",
            game_data.get("name"),
            "--icon",
            icon,
        ]

        for key in [
                "fullscreen",
                "frameless",
                "devtools",
                "disable_resizing",
                "disable_menu_bar",
                "maximize_window",
                "disable_scrolling",
                "hide_cursor",
                "open_links",
                "remove_margin",
        ]:
            if self.runner_config.get(key):
                converted_opt_name = key.replace("_", "-")
                command.append("--{option}".format(option=converted_opt_name))

        if self.runner_config.get("window_size"):
            command.append("--window-size")
            command.append(self.runner_config.get("window_size"))
        if self.runner_config.get("user_agent"):
            command.append("--user-agent")
            command.append(self.runner_config.get("user_agent"))
        if linux.LINUX_SYSTEM.is_flatpak:
            command.append("--no-sandbox")

        return {"command": command, "env": self.get_env(False)}
Exemple #16
0
def wineexec(  # noqa: C901
    executable,
    args="",
    wine_path=None,
    prefix=None,
    arch=None,
    working_dir=None,
    winetricks_wine="",
    blocking=False,
    config=None,
    include_processes=None,
    exclude_processes=None,
    disable_runtime=False,
    env=None,
    overrides=None,
):
    """
    Execute a Wine command.

    Args:
        executable (str): wine program to run, pass None to run wine itself
        args (str): program arguments
        wine_path (str): path to the wine version to use
        prefix (str): path to the wine prefix to use
        arch (str): wine architecture of the prefix
        working_dir (str): path to the working dir for the process
        winetricks_wine (str): path to the wine version used by winetricks
        blocking (bool): if true, do not run the process in a thread
        config (LutrisConfig): LutrisConfig object for the process context
        watch (list): list of process names to monitor (even when in a ignore list)

    Returns:
        Process results if the process is running in blocking mode or
        MonitoredCommand instance otherwise.
    """
    if env is None:
        env = {}
    if exclude_processes is None:
        exclude_processes = []
    if include_processes is None:
        include_processes = []
    executable = str(executable) if executable else ""
    if isinstance(include_processes, str):
        include_processes = shlex.split(include_processes)
    if isinstance(exclude_processes, str):
        exclude_processes = shlex.split(exclude_processes)
    if not wine_path:
        wine = import_runner("wine")
        wine_path = wine().get_executable()
    if not wine_path:
        raise RuntimeError("Wine is not installed")

    if not working_dir:
        if os.path.isfile(executable):
            working_dir = os.path.dirname(executable)

    executable, _args, working_dir = get_real_executable(
        executable, working_dir)
    if _args:
        args = '{} "{}"'.format(_args[0], _args[1])

    # Create prefix if necessary
    if arch not in ("win32", "win64"):
        arch = detect_arch(prefix, wine_path)
    if not detect_prefix_arch(prefix):
        wine_bin = winetricks_wine if winetricks_wine else wine_path
        create_prefix(prefix, wine_path=wine_bin, arch=arch)

    wineenv = {"WINEARCH": arch}
    if winetricks_wine:
        wineenv["WINE"] = winetricks_wine
    else:
        wineenv["WINE"] = wine_path

    if prefix:
        wineenv["WINEPREFIX"] = prefix

    wine_config = config or LutrisConfig(runner_slug="wine")
    disable_runtime = disable_runtime or wine_config.system_config[
        "disable_runtime"]
    if use_lutris_runtime(wine_path=wineenv["WINE"],
                          force_disable=disable_runtime):
        if WINE_DIR in wine_path:
            wine_root_path = os.path.dirname(os.path.dirname(wine_path))
        elif WINE_DIR in winetricks_wine:
            wine_root_path = os.path.dirname(os.path.dirname(winetricks_wine))
        else:
            wine_root_path = None
        wineenv["LD_LIBRARY_PATH"] = ":".join(
            runtime.get_paths(
                prefer_system_libs=wine_config.
                system_config["prefer_system_libs"],
                wine_path=wine_root_path,
            ))

    if overrides:
        wineenv["WINEDLLOVERRIDES"] = get_overrides_env(overrides)

    if env:
        wineenv.update(env)

    command_parameters = [wine_path]
    if executable:
        command_parameters.append(executable)
    command_parameters += split_arguments(args)
    if blocking:
        return system.execute(command_parameters, env=wineenv, cwd=working_dir)
    wine = import_runner("wine")
    command = MonitoredCommand(
        command_parameters,
        runner=wine(),
        env=wineenv,
        cwd=working_dir,
        include_processes=include_processes,
        exclude_processes=exclude_processes,
    )
    command.start()
    return command