示例#1
0
 def runner(self):
     """Return the runner instance used by this install"""
     if not self._runner:
         if self.platform == "windows":
             self._runner = winesteam.winesteam()
         self._runner = steam.steam()
     return self._runner
示例#2
0
 def check_steam_install(self):
     """Checks that the required version of Steam is installed.
     Return a boolean indicating whether is it or not.
     """
     if self.steam_data['platform'] == 'windows':
         # Check that wine is installed
         wine_runner = wine.wine()
         if not wine_runner.is_installed():
             logger.debug('Wine is not installed')
             wine_runner.install(
                 downloader=self.parent.start_download,
                 callback=self.check_steam_install
             )
             return False
         # Getting data from Wine Steam
         steam_runner = winesteam.winesteam()
         if not steam_runner.is_installed():
             logger.debug('Winesteam not installed')
             winesteam.download_steam(
                 downloader=self.parent.start_download,
                 callback=self.on_steam_downloaded
             )
             return False
         return True
     else:
         steam_runner = steam.steam()
         if not steam_runner.is_installed():
             raise ScriptingError(
                 "Install Steam for Linux and start installer again"
             )
         return True
示例#3
0
 def _download_steam_data(self, file_uri, file_id):
     try:
         parts = file_uri.split(":", 2)
         steam_rel_path = parts[2].strip()
     except IndexError:
         raise ScriptingError("Malformed steam path: %s" % file_uri)
     if steam_rel_path == "/":
         steam_rel_path = "."
     self.steam_data = {"appid": parts[1], "steam_rel_path": steam_rel_path, "file_id": file_id}
     if parts[0] == "$WINESTEAM":
         appid = self.steam_data["appid"]
         logger.debug("Getting Wine Steam data for appid %s" % appid)
         self.parent.set_status("Getting Wine Steam game data")
         self.steam_data["platform"] = "windows"
         # Check that wine is installed
         wine_runner = wine.wine()
         if not wine_runner.is_installed():
             wine_runner.install()
         # Getting data from Wine Steam
         steam_runner = winesteam.winesteam()
         if not steam_runner.is_installed():
             winesteam.download_steam(
                 downloader=self.parent.start_download, callback=self.parent.on_steam_downloaded
             )
         else:
             self.install_steam_game(winesteam.winesteam)
     else:
         # Getting data from Linux Steam
         self.parent.set_status("Getting Steam game data")
         self.steam_data["platform"] = "linux"
         self.install_steam_game(steam.steam)
示例#4
0
 def complete_steam_install(self, dest, appid):
     self.parent.wait_for_user_action(
         "Steam will now install, press Ok when install is finished",
         self.on_winesteam_installed,
         appid
     )
     steam_runner = winesteam.winesteam()
     async_call(steam_runner.install, None, dest)
示例#5
0
文件: sync.py 项目: prettyv/lutris
    def sync_steam_local(self):
        """Sync Steam games in library with Steam and Wine Steam"""
        steamrunner = steam()
        winesteamrunner = winesteam()
        installed = set()
        uninstalled = set()

        # Get installed steamapps
        installed_steamapps = self.get_installed_steamapps(steamrunner)
        installed_winesteamapps = self.get_installed_steamapps(winesteamrunner)

        for game_info in self.library:
            slug = game_info['slug']
            runner = game_info['runner']
            steamid = game_info['steamid']
            installed_in_steam = steamid in installed_steamapps
            installed_in_winesteam = steamid in installed_winesteamapps

            # Set installed
            if not game_info['installed']:
                if not installed_in_steam:  # (Linux Steam only)
                    continue
                logger.debug("Setting %s as installed" % game_info['name'])
                config_id = (game_info['configpath']
                             or config.make_game_config_id(slug))
                game_id = pga.add_or_update(
                    name=game_info['name'],
                    runner='steam',
                    slug=slug,
                    installed=1,
                    configpath=config_id,
                )
                game_config = config.LutrisConfig(
                    runner_slug='steam',
                    game_config_id=config_id,
                )
                game_config.raw_game_config.update({'appid': str(steamid)})
                game_config.save()
                installed.add(game_id)

            # Set uninstalled
            elif not (installed_in_steam or installed_in_winesteam):
                if runner not in ['steam', 'winesteam']:
                    continue
                if runner == 'steam' and not steamrunner.is_installed():
                    continue
                if runner == 'winesteam' and not winesteamrunner.is_installed():
                    continue
                logger.debug("Setting %(name)s (%(steamid)s) as uninstalled", game_info)

                game_id = pga.add_or_update(
                    name=game_info['name'],
                    runner='',
                    slug=game_info['slug'],
                    installed=0
                )
                uninstalled.add(game_id)
        return (installed, uninstalled)
示例#6
0
def get_steamapps_paths(flat=False):
    from lutris.runners import winesteam, steam
    if flat:
        steamapps_paths = []
    else:
        steamapps_paths = {'linux': [], 'windows': []}
    winesteam_runner = winesteam.winesteam()
    steam_runner = steam.steam()
    for folder in steam_runner.get_steamapps_dirs():
        if flat:
            steamapps_paths.append(folder)
        else:
            steamapps_paths['linux'].append(folder)
    for folder in winesteam_runner.get_steamapps_dirs():
        if flat:
            steamapps_paths.append(folder)
        else:
            steamapps_paths['windows'].append(folder)
    return steamapps_paths
示例#7
0
    def sync_steam_local(self, caller):
        """Sync Steam games in library with Steam and Wine Steam"""
        logger.debug("Syncing local steam games")
        steamrunner = steam()
        winesteamrunner = winesteam()

        # Get installed steamapps
        installed_steamapps = self._get_installed_steamapps(steamrunner)
        installed_winesteamapps = self._get_installed_steamapps(winesteamrunner)

        for game_info in self.library:
            runner = game_info['runner']
            game = Game(game_info['slug'])
            steamid = game_info['steamid']
            installed_in_steam = steamid in installed_steamapps
            installed_in_winesteam = steamid in installed_winesteamapps

            # Set installed
            if not game_info['installed']:
                if not installed_in_steam:  # (Linux Steam only)
                    continue
                logger.debug("Setting %s as installed" % game_info['name'])
                pga.add_or_update(game_info['name'], 'steam',
                                  game_info['slug'],
                                  installed=1)
                game.config.game_config.update({'game':
                                                {'appid': str(steamid)}})
                game.config.save()
                caller.view.set_installed(Game(game_info['slug']))

            # Set uninstalled
            elif not (installed_in_steam or installed_in_winesteam):
                if runner not in ['steam', 'winesteam']:
                    continue
                if runner == 'steam' and not steamrunner.is_installed():
                    continue
                if runner == 'winesteam' and not winesteamrunner.is_installed():
                    continue
                logger.debug("Setting %s as uninstalled" % game_info['name'])
                pga.add_or_update(game_info['name'], '',
                                  game_info['slug'],
                                  installed=0)
                caller.view.set_uninstalled(game_info['slug'])
示例#8
0
    def sync_steam_local(self):
        """Sync Steam games in library with Steam and Wine Steam"""
        logger.debug("Syncing local steam games")
        steamrunner = steam()
        winesteamrunner = winesteam()
        installed = set()
        uninstalled = set()

        # Get installed steamapps
        installed_steamapps = self._get_installed_steamapps(steamrunner)
        installed_winesteamapps = self._get_installed_steamapps(winesteamrunner)

        for game_info in self.library:
            slug = game_info["slug"]
            runner = game_info["runner"]
            steamid = game_info["steamid"]
            installed_in_steam = steamid in installed_steamapps
            installed_in_winesteam = steamid in installed_winesteamapps

            # Set installed
            if not game_info["installed"]:
                if not installed_in_steam:  # (Linux Steam only)
                    continue
                logger.debug("Setting %s as installed" % game_info["name"])
                pga.add_or_update(game_info["name"], "steam", slug, installed=1)
                game_config = config.LutrisConfig(runner_slug="steam", game_slug=game_info["slug"])
                game_config.raw_game_config.update({"appid": str(steamid)})
                game_config.save()
                installed.add(slug)

            # Set uninstalled
            elif not (installed_in_steam or installed_in_winesteam):
                if runner not in ["steam", "winesteam"]:
                    continue
                if runner == "steam" and not steamrunner.is_installed():
                    continue
                if runner == "winesteam" and not winesteamrunner.is_installed():
                    continue
                logger.debug("Setting %s as uninstalled" % game_info["name"])
                pga.add_or_update(game_info["name"], "", game_info["slug"], installed=0)
                uninstalled.add(slug)
        return (installed, uninstalled)
示例#9
0
文件: steam.py 项目: RobLoach/lutris
def get_steamapps_paths(flat=False):
    from lutris.runners import winesteam, steam
    if flat:
        steamapps_paths = []
    else:
        steamapps_paths = {
            'linux': [],
            'windows': []
        }
    winesteam_runner = winesteam.winesteam()
    steam_runner = steam.steam()
    for folder in steam_runner.get_steamapps_dirs():
        if flat:
            steamapps_paths.append(folder)
        else:
            steamapps_paths['linux'].append(folder)
    for folder in winesteam_runner.get_steamapps_dirs():
        if flat:
            steamapps_paths.append(folder)
        else:
            steamapps_paths['windows'].append(folder)
    return steamapps_paths
示例#10
0
文件: installer.py 项目: ERIIX/lutris
 def _download_steam_data(self, file_uri, file_id):
     try:
         parts = file_uri.split(":", 2)
         steam_rel_path = parts[2].strip()
     except IndexError:
         raise ScriptingError("Malformed steam path: %s" % file_uri)
     if steam_rel_path == "/":
         steam_rel_path = "."
     self.steam_data = {
         'appid': parts[1],
         'steam_rel_path': steam_rel_path,
         'file_id': file_id
     }
     if parts[0] == '$WINESTEAM':
         appid = self.steam_data['appid']
         logger.debug("Getting Wine Steam data for appid %s" % appid)
         self.parent.set_status('Getting Wine Steam game data')
         self.steam_data['platform'] = "windows"
         # Check that wine is installed
         wine_runner = wine.wine()
         if not wine_runner.is_installed():
             wine_runner.install()
         # Getting data from Wine Steam
         steam_runner = winesteam.winesteam()
         if not steam_runner.is_installed():
             winesteam.download_steam(
                 downloader=self.parent.start_download,
                 callback=self.parent.on_steam_downloaded
             )
         else:
             self.install_steam_game(winesteam.winesteam)
     else:
         # Getting data from Linux Steam
         self.parent.set_status('Getting Steam game data')
         self.steam_data['platform'] = "linux"
         self.install_steam_game(steam.steam)
     self.iter_game_files()
     return True
示例#11
0
    def _download_file(self, game_file):
        """Download a file referenced in the installer script

           Game files can be either a string, containing the location of the
           file to fetch or a dict with the following keys:
           - url : location of file, if not present, filename will be used
                   this should be the case for local files
           - filename : force destination filename when url is present or path
                        of local file
        """
        # Setup file_id, file_uri and local filename
        file_id = game_file.keys()[0]
        if isinstance(game_file[file_id], dict):
            filename = game_file[file_id]['filename']
            file_uri = game_file[file_id]['url']
        else:
            file_uri = game_file[file_id]
            filename = os.path.basename(file_uri)
        if file_uri.startswith("/"):
            file_uri = "file://" + file_uri
        elif file_uri.startswith(("$WINESTEAM", "$STEAM")):
            # Download Steam data
            try:
                parts = file_uri.split(":", 2)
                steam_rel_path = parts[2].strip()
            except IndexError:
                raise ScriptingError("Malformed steam path: %s" % file_uri)
            if steam_rel_path == "/":
                steam_rel_path = "."
            self.steam_data = {
                'appid': parts[1],
                'steam_rel_path': steam_rel_path,
                'file_id': file_id
            }
            if parts[0] == '$WINESTEAM':
                appid = self.steam_data['appid']
                logger.debug("Getting Wine Steam data for appid %s" % appid)
                self.parent.set_status('Getting Wine Steam game data')
                self.steam_data['platform'] = "windows"
                # Check that wine is installed
                wine_runner = wine.wine()
                if not wine_runner.is_installed():
                    wine_runner.install()
                # Getting data from Wine Steam
                steam_runner = winesteam.winesteam()
                if not steam_runner.is_installed():
                    winesteam.download_steam(
                        downloader=self.parent.start_download,
                        callback=self.parent.on_steam_downloaded
                    )
                else:
                    self.install_steam_game(winesteam.winesteam)
                return
            else:
                # Getting data from Linux Steam
                self.parent.set_status('Getting Steam game data')
                self.steam_data['platform'] = "linux"
                self.install_steam_game(steam.steam)
                return
        logger.debug("Fetching [%s]: %s" % (file_id, file_uri))

        # Check for file availability in PGA
        pga_uri = pga.check_for_file(self.game_slug, file_id)
        if pga_uri:
            file_uri = pga_uri

        # Setup destination path
        dest_file = os.path.join(self.download_cache_path, filename)

        if file_uri.startswith("N/A"):
            # Ask the user where is the file located
            parts = file_uri.split(":", 1)
            if len(parts) == 2:
                message = parts[1]
            else:
                message = "Please select file '%s'" % file_id
            self.current_file_id = file_id
            self.parent.ask_user_for_file(message)
            return

        if os.path.exists(dest_file):
            logger.debug("Destination file exists")
            if settings.KEEP_CACHED_ASSETS:
                self.game_files[file_id] = dest_file
                self.iter_game_files()
                return
            else:
                os.remove(dest_file)

        # Change parent's status
        self.parent.set_status('Fetching %s' % file_uri)
        self.game_files[file_id] = dest_file
        self.parent.start_download(file_uri, dest_file)
示例#12
0
 def complete_steam_install(self, dest):
     winesteam_runner = winesteam.winesteam()
     async_call(winesteam_runner.install, self.on_winesteam_installed, dest)
示例#13
0
 def on_steam_downloaded(self, *args):
     logger.debug("Steam downloaded")
     dest = winesteam.get_steam_installer_dest()
     winesteam_runner = winesteam.winesteam()
     AsyncCall(winesteam_runner.install, self.on_winesteam_installed, dest)
示例#14
0
def create_prefix(
        prefix,
        wine_path=None,
        arch=WINE_DEFAULT_ARCH,
        overrides={},
        install_gecko=None,
        install_mono=None,
):
    """Create a new Wine prefix."""
    if not prefix:
        raise ValueError("No Wine prefix path given")
    logger.info("Creating a %s prefix in %s", arch, prefix)

    # Follow symlinks, don't delete existing ones as it would break some setups
    if os.path.islink(prefix):
        prefix = os.readlink(prefix)

    # Avoid issue of 64bit Wine refusing to create win32 prefix
    # over an existing empty folder.
    if os.path.isdir(prefix) and not os.listdir(prefix):
        os.rmdir(prefix)

    if not wine_path:
        wine = import_runner("wine")
        wine_path = wine().get_executable()
    if not wine_path:
        logger.error("Wine not found, can't create prefix")
        return
    wineboot_path = os.path.join(os.path.dirname(wine_path), "wineboot")
    if not system.path_exists(wineboot_path):
        logger.error(
            "No wineboot executable found in %s, "
            "your wine installation is most likely broken",
            wine_path,
        )
        return

    if install_gecko == "False":
        overrides["mshtml"] = "disabled"
    if install_mono == "False":
        overrides["mscoree"] = "disabled"

    wineenv = {
        "WINEARCH": arch,
        "WINEPREFIX": prefix,
        "WINEDLLOVERRIDES": get_overrides_env(overrides),
    }

    system.execute([wineboot_path], env=wineenv)
    for loop_index in range(50):
        time.sleep(0.25)
        if system.path_exists(os.path.join(prefix, "user.reg")):
            break
        if loop_index == 20:
            logger.warning("Wine prefix creation is taking longer than expected...")
    if not os.path.exists(os.path.join(prefix, "user.reg")):
        logger.error(
            "No user.reg found after prefix creation. " "Prefix might not be valid"
        )
        return
    logger.info("%s Prefix created in %s", arch, prefix)
    prefix_manager = WinePrefixManager(prefix)
    prefix_manager.setup_defaults()
    if 'steamapps/common' in prefix.lower():
        from lutris.runners.winesteam import winesteam
        runner = winesteam()
        logger.info("Transfering Steam information from default prefix to new prefix")
        dest_path = '/tmp/steam.reg'
        default_prefix = runner.get_default_prefix(runner.default_arch)
        wineexec(
            "regedit",
            args=r"/E '%s' 'HKEY_CURRENT_USER\Software\Valve\Steam'" % dest_path,
            prefix=default_prefix
        )
        set_regedit_file(
            dest_path,
            wine_path=wine_path,
            prefix=prefix,
            arch=arch
        )
        try:
            os.remove(dest_path)
        except FileNotFoundError:
            logger.error("File %s was already removed", dest_path)
        steam_drive_path = os.path.join(prefix, 'dosdevices', 's:')
        if not system.path_exists(steam_drive_path):
            logger.info("Linking Steam default prefix to drive S:")
            os.symlink(os.path.join(default_prefix, 'drive_c'), steam_drive_path)
示例#15
0
    def _download_file(self, game_file):
        """Download a file referenced in the installer script

           Game files can be either a string, containing the location of the
           file to fetch or a dict with the following keys:
           - url : location of file, if not present, filename will be used
                   this should be the case for local files
           - filename : force destination filename when url is present or path
                        of local file
        """
        # Setup file_id, file_uri and local filename
        file_id = game_file.keys()[0]
        if isinstance(game_file[file_id], dict):
            filename = game_file[file_id]['filename']
            file_uri = game_file[file_id]['url']
        else:
            file_uri = game_file[file_id]
            filename = os.path.basename(file_uri)
        if file_uri.startswith("/"):
            file_uri = "file://" + file_uri
        elif file_uri.startswith(("$WINESTEAM", "$STEAM")):
            # Download Steam data
            try:
                parts = file_uri.split(":", 2)
                steam_rel_path = parts[2].strip()
            except IndexError:
                raise ScriptingError("Malformed steam path: %s" % file_uri)
            if steam_rel_path == "/":
                steam_rel_path = "."
            self.steam_data = {
                'appid': parts[1],
                'steam_rel_path': steam_rel_path,
                'file_id': file_id
            }
            if parts[0] == '$WINESTEAM':
                self.steam_data['platform'] = "windows"
                # Getting data from Wine Steam
                steam_runner = winesteam.winesteam()
                if not steam_runner.is_installed():
                    # Downoad Steam for Windows
                    steam_installer_path = os.path.join(
                        settings.TMP_PATH, "SteamInstall.msi"
                    )
                    self.parent.start_download(
                        winesteam.winesteam.installer_url,
                        steam_installer_path,
                        self.parent.on_steam_downloaded,
                        self.steam_data['appid']
                    )
                else:
                    self.install_steam_game(winesteam.winesteam)
                return
            else:
                # Getting data from Linux Steam
                self.steam_data['platform'] = "linux"
                self.install_steam_game(steam.steam)
                return
        logger.debug("Fetching [%s]: %s" % (file_id, file_uri))

        # Check for file availability in PGA
        pga_uri = pga.check_for_file(self.game_slug, file_id)
        if pga_uri:
            file_uri = pga_uri

        # Setup destination path
        dest_file = os.path.join(self.download_cache_path, filename)

        if file_uri.startswith("N/A"):
            # Ask the user where is the file located
            parts = file_uri.split(":", 1)
            if len(parts) == 2:
                message = parts[1]
            else:
                message = "Please select file '%s'" % file_id
            self.current_file_id = file_id
            self.parent.ask_user_for_file(message)
            return

        if os.path.exists(dest_file):
            logger.debug("Destination file exists")
            if settings.KEEP_CACHED_ASSETS:
                self.game_files[file_id] = dest_file
                self.iter_game_files()
                return
            else:
                os.remove(dest_file)

        # Change parent's status
        self.parent.set_status('Fetching %s' % file_uri)
        self.game_files[file_id] = dest_file
        self.parent.start_download(file_uri, dest_file)
示例#16
0
 def complete_steam_install(self, dest):
     winesteam_runner = winesteam.winesteam()
     AsyncCall(winesteam_runner.install, self.on_winesteam_installed, dest)
示例#17
0
def create_prefix(
    prefix,
    wine_path=None,
    arch=WINE_DEFAULT_ARCH,
    overrides={},
    install_gecko=None,
    install_mono=None,
):
    """Create a new Wine prefix."""
    if not prefix:
        raise ValueError("No Wine prefix path given")
    logger.info("Creating a %s prefix in %s", arch, prefix)

    # Follow symlinks, don't delete existing ones as it would break some setups
    if os.path.islink(prefix):
        prefix = os.readlink(prefix)

    # Avoid issue of 64bit Wine refusing to create win32 prefix
    # over an existing empty folder.
    if os.path.isdir(prefix) and not os.listdir(prefix):
        os.rmdir(prefix)

    if not wine_path:
        wine = import_runner("wine")
        wine_path = wine().get_executable()
    if not wine_path:
        logger.error("Wine not found, can't create prefix")
        return
    wineboot_path = os.path.join(os.path.dirname(wine_path), "wineboot")
    if not system.path_exists(wineboot_path):
        logger.error(
            "No wineboot executable found in %s, "
            "your wine installation is most likely broken",
            wine_path,
        )
        return

    if install_gecko == "False":
        overrides["mshtml"] = "disabled"
    if install_mono == "False":
        overrides["mscoree"] = "disabled"

    wineenv = {
        "WINEARCH": arch,
        "WINEPREFIX": prefix,
        "WINEDLLOVERRIDES": get_overrides_env(overrides),
    }

    system.execute([wineboot_path], env=wineenv)
    for loop_index in range(50):
        time.sleep(0.25)
        if system.path_exists(os.path.join(prefix, "user.reg")):
            break
        if loop_index == 20:
            logger.warning(
                "Wine prefix creation is taking longer than expected...")
    if not os.path.exists(os.path.join(prefix, "user.reg")):
        logger.error("No user.reg found after prefix creation. "
                     "Prefix might not be valid")
        return
    logger.info("%s Prefix created in %s", arch, prefix)
    prefix_manager = WinePrefixManager(prefix)
    prefix_manager.setup_defaults()
    if 'steamapps/common' in prefix.lower():
        from lutris.runners.winesteam import winesteam
        runner = winesteam()
        logger.info(
            "Transfering Steam information from default prefix to new prefix")
        dest_path = '/tmp/steam.reg'
        default_prefix = runner.get_default_prefix(runner.default_arch)
        wineexec("regedit",
                 args=r"/E '%s' 'HKEY_CURRENT_USER\Software\Valve\Steam'" %
                 dest_path,
                 prefix=default_prefix)
        set_regedit_file(dest_path,
                         wine_path=wine_path,
                         prefix=prefix,
                         arch=arch)
        try:
            os.remove(dest_path)
        except FileNotFoundError:
            logger.error("File %s was already removed", dest_path)
        steam_drive_path = os.path.join(prefix, 'dosdevices', 's:')
        if not system.path_exists(steam_drive_path):
            logger.info("Linking Steam default prefix to drive S:")
            os.symlink(os.path.join(default_prefix, 'drive_c'),
                       steam_drive_path)