示例#1
0
 def get_installer_files(self, installer, installer_file_id):
     steam_uri = "$WINESTEAM:%s:." if installer.runner == "winesteam" else "$STEAM:%s:."
     appid = str(installer.script["game"]["appid"])
     return [
         InstallerFile(installer.game_slug, "steam_game", {
             "url": steam_uri % appid,
             "filename": appid
         })
     ]
示例#2
0
文件: gog.py 项目: bsdf/lutris
 def get_installer_files(self, installer, installer_file_id):
     try:
         downloads = self.get_downloads(installer.service_appid)
         gog_installers = self.get_installers(downloads, installer.runner)
         if not gog_installers:
             return []
         if len(gog_installers) > 1:
             logger.warning(
                 "More than 1 GOG installer found, picking first.")
         _installer = gog_installers[0]
         links = self.query_download_links(_installer)
     except HTTPError:
         raise UnavailableGame(
             "Couldn't load the download links for this game")
     if not links:
         raise UnavailableGame("Could not fing GOG game")
     _installer_files = defaultdict(dict)  # keyed by filename
     for link in links:
         filename = link["filename"]
         if filename.lower().endswith(".xml"):
             if filename != installer_file_id:
                 filename = filename[:-4]
             _installer_files[filename]["checksum_url"] = link["url"]
             continue
         _installer_files[filename]["id"] = link["id"]
         _installer_files[filename]["url"] = link["url"]
         _installer_files[filename]["filename"] = filename
         _installer_files[filename]["total_size"] = link["total_size"]
     files = []
     file_id_provided = False  # Only assign installer_file_id once
     for _file_id in _installer_files:
         installer_file = _installer_files[_file_id]
         if "url" not in installer_file:
             raise ValueError("Invalid installer file %s" % installer_file)
         filename = installer_file["filename"]
         if filename.lower().endswith(
             (".exe", ".sh")) and not file_id_provided:
             file_id = installer_file_id
             file_id_provided = True
         else:
             file_id = _file_id
         files.append(
             InstallerFile(
                 installer.game_slug, file_id, {
                     "url": installer_file["url"],
                     "filename": installer_file["filename"],
                     "checksum_url": installer_file.get("checksum_url")
                 }))
     if not file_id_provided:
         raise UnavailableGame(
             "Unable to determine correct file to launch installer")
     if self.selected_extras:
         for extra_file in self.get_extra_files(downloads, installer):
             files.append(extra_file)
     return files
示例#3
0
    def get_installer_files(self, installer, installer_file_id):
        if not self.is_connected():
            self.login()
        if not self.is_connected():
            logger.warning("Not connected to GOG, not returning any files")
            return []
        try:
            downloads = self.get_downloads(installer.service_appid)
            gog_installers = self.get_installers(downloads, installer.runner)
            if not gog_installers:
                return []
            if len(gog_installers) > 1:
                logger.warning(
                    "More than 1 GOG installer found, picking first.")
            _installer = gog_installers[0]
            links = self.query_download_links(_installer)
        except HTTPError:
            raise UnavailableGame(
                "Couldn't load the download links for this game")
        if not links:
            raise UnavailableGame("Could not fing GOG game")

        files = []
        file_id_provided = False  # Only assign installer_file_id once
        for index, link in enumerate(links):
            if isinstance(link, dict):
                url = link["url"]
            else:
                url = link
            filename = link["filename"]
            if filename.lower().endswith(
                (".exe", ".sh")) and not file_id_provided:
                file_id = installer_file_id
                file_id_provided = True
            else:
                file_id = "gog_file_%s" % index
            files.append(
                InstallerFile(installer.game_slug, file_id, {
                    "url": url,
                    "filename": filename,
                }))
        if not file_id_provided:
            raise UnavailableGame(
                "Unable to determine correct file to launch installer")
        if self.selected_extras:
            for extra_file in self.get_extra_files(downloads, installer):
                files.append(extra_file)
        return files
示例#4
0
 def get_installer_files(self, installer, installer_file_id):
     """Replace the user provided file with download links from Humble Bundle"""
     try:
         link = get_humble_download_link(installer.service_appid, installer.runner)
     except Exception as ex:
         logger.exception("Failed to get Humble Bundle game: %s", ex)
         raise UnavailableGame
     if not link:
         raise UnavailableGame("No game found on Humble Bundle")
     filename = link.split("?")[0].split("/")[-1]
     return [
         InstallerFile(installer.game_slug, installer_file_id, {
             "url": link,
             "filename": filename
         })
     ]
示例#5
0
文件: gog.py 项目: bsdf/lutris
 def get_extra_files(self, downloads, installer):
     extra_files = []
     for extra in downloads["bonus_content"]:
         if str(extra["id"]) not in self.selected_extras:
             continue
         links = self.query_download_links(extra)
         for link in links:
             if link["filename"].endswith(".xml"):
                 # GOG gives a link for checksum XML files for bonus content
                 # but downloading them results in a 404 error.
                 continue
             extra_files.append(
                 InstallerFile(installer.game_slug, str(extra["id"]), {
                     "url": link["url"],
                     "filename": link["filename"],
                 }))
     return extra_files
示例#6
0
 def __init__(self, installer, interpreter, service, appid):
     self.interpreter = interpreter
     self.installer = installer
     self.version = installer["version"]
     self.slug = installer["slug"]
     self.year = installer.get("year")
     self.runner = installer["runner"]
     self.script = installer.get("script")
     self.game_name = self.script.get("custom-name") or installer["name"]
     self.game_slug = installer["game_slug"]
     self.service = self.get_service(initial=service)
     self.service_appid = self.get_appid(installer, initial=appid)
     self.files = [
         InstallerFile(self.game_slug, file_id, file_meta)
         for file_desc in self.script.get("files", [])
         for file_id, file_meta in file_desc.items()
     ]
     self.requires = self.script.get("requires")
     self.extends = self.script.get("extends")
     self.game_id = self.get_game_id()
示例#7
0
 def _format_links(self, installer, installer_file_id, links):
     _installer_files = defaultdict(dict)  # keyed by filename
     for link in links:
         try:
             filename = link["filename"]
         except KeyError:
             logger.error("Invalid link: %s", link)
             raise
         if filename.lower().endswith(".xml"):
             if filename != installer_file_id:
                 filename = filename[:-4]
             _installer_files[filename]["checksum_url"] = link["url"]
             continue
         _installer_files[filename]["id"] = link["id"]
         _installer_files[filename]["url"] = link["url"]
         _installer_files[filename]["filename"] = filename
         _installer_files[filename]["total_size"] = link["total_size"]
     files = []
     file_id_provided = False  # Only assign installer_file_id once
     for _file_id in _installer_files:
         installer_file = _installer_files[_file_id]
         if "url" not in installer_file:
             raise ValueError("Invalid installer file %s" % installer_file)
         filename = installer_file["filename"]
         if filename.lower().endswith(
             (".exe", ".sh")) and not file_id_provided:
             file_id = installer_file_id
             file_id_provided = True
         else:
             file_id = _file_id
         files.append(
             InstallerFile(
                 installer.game_slug, file_id, {
                     "url": installer_file["url"],
                     "filename": installer_file["filename"],
                     "checksum_url": installer_file.get("checksum_url")
                 }))
     if not file_id_provided:
         raise UnavailableGame(
             "Unable to determine correct file to launch installer")
     return files
示例#8
0
 def swap_humble_game_files(self):
     """Replace the user provided file with download links from Humble Bundle"""
     if not self.humbleid:
         raise UnavailableGame("This installer has no Humble Bundle ID ('humbleid' in the game section)")
     installer_file_id = self.pop_user_provided_file()
     if not installer_file_id:
         raise UnavailableGame("Installer has no user provided file")
     try:
         link = get_humble_download_link(self.humbleid, self.runner)
     except Exception as ex:
         logger.exception("Failed to get Humble Bundle game: %s", ex)
         raise UnavailableGame
     if not link:
         raise UnavailableGame("No game found on Humble Bundle")
     filename = link.split("?")[0].split("/")[-1]
     self.files.append(
         InstallerFile(self.game_slug, installer_file_id, {
             "url": link,
             "filename": filename
         })
     )
示例#9
0
    def swap_gog_game_files(self):
        if not self.gogid:
            raise UnavailableGame("The installer has no GOG ID!")
        try:
            links = self.get_gog_download_links()
        except HTTPError:
            raise UnavailableGame(
                "Couldn't load the download links for this game")
        installer_file_id = None
        if links:
            for index, file in enumerate(self.files):
                file_id = file.id
                if file.url.startswith("N/A"):
                    logger.debug("Removing file %s", file.id)
                    self.files.pop(index)
                    installer_file_id = file.id
                    break

        if not installer_file_id:
            raise ScriptingError(
                "Could not match a GOG installer file in the files")

        file_id_provided = False  # Only assign installer_file_id once
        for index, link in enumerate(links):

            filename = link.split("?")[0].split("/")[-1]

            if filename.lower().endswith(
                (".exe", ".sh")) and not file_id_provided:
                file_id = installer_file_id
                file_id_provided = True
            else:
                file_id = "gog_file_%s" % index

            logger.debug("Adding GOG file %s as %s", filename, file_id)
            self.files.append(
                InstallerFile(self.game_slug, file_id, {
                    "url": link,
                    "filename": filename,
                }))
示例#10
0
 def prepare_game_files(self, patch_version=None):
     """Gathers necessary files before iterating through them."""
     if not self.files:
         logger.info("No files to prepare")
         return
     if not self.service:
         logger.debug("No service to retrieve files from")
         return
     if self.service.online and not self.service.is_connected():
         logger.info("Not authenticated to %s", self.service.id)
         return
     installer_file_id = self.pop_user_provided_file()
     if not installer_file_id:
         logger.warning("Could not find a file for this service")
         return
     logger.info("Getting files for %s", installer_file_id)
     if self.service.has_extras:
         logger.info("Adding selected extras to downloads")
         self.service.selected_extras = self.interpreter.extras
     if patch_version:
         # If a patch version is given download the patch files instead of the installer
         installer_files = self.service.get_patch_files(
             self, installer_file_id)
     else:
         installer_files = self.service.get_installer_files(
             self, installer_file_id)
     for installer_file in installer_files:
         self.files.append(installer_file)
     if not installer_files:
         # Failed to get the service game, put back a user provided file
         logger.debug(
             "Unable to get files from service. Setting %s to manual.",
             installer_file_id)
         self.files.insert(
             0,
             InstallerFile(self.game_slug, installer_file_id, {
                 "url": "N/A: Provider installer file",
                 "filename": ""
             }))
示例#11
0
    def __init__(self, installer, interpreter):
        self.interpreter = interpreter
        self.version = installer["version"]
        self.slug = installer["slug"]
        self.year = installer.get("year")
        self.runner = installer["runner"]
        self.script = installer.get("script")
        self.game_name = self.script.get("custom-name") or installer["name"]
        self.game_slug = installer["game_slug"]
        self.steamid = installer.get("steamid")
        game_config = self.script.get("game", {})
        self.gogid = game_config.get("gogid") or installer.get("gogid")
        self.humbleid = game_config.get("humbleid") or installer.get("humblestoreid")

        self.files = [
            InstallerFile(self.game_slug, file_id, file_meta)
            for file_desc in self.script.get("files", [])
            for file_id, file_meta in file_desc.items()
        ]
        self.requires = self.script.get("requires")
        self.extends = self.script.get("extends")
        self.game_id = self.get_game_id()
示例#12
0
    def swap_gog_game_files(self):
        """Replace user provided file with downloads from GOG"""
        logger.info("Swap GOG game files")
        if not self.gogid:
            raise UnavailableGame("The installer has no GOG ID!")
        try:
            links = get_gog_download_links(self.gogid, self.runner)
        except HTTPError:
            raise UnavailableGame(
                "Couldn't load the download links for this game")
        except MultipleInstallerError:
            raise UnavailableGame(
                "Don't know how to deal with multiple installers yet.")
        if not links:
            raise UnavailableGame("Could not fing GOG game")

        installer_file_id = self.pop_user_provided_file()
        if not installer_file_id:
            raise UnavailableGame("Installer has no user provided file")

        file_id_provided = False  # Only assign installer_file_id once
        for index, link in enumerate(links):
            if isinstance(link, dict):
                url = link["url"]
            else:
                url = link
            filename = url.split("?")[0].split("/")[-1]
            if filename.lower().endswith(
                (".exe", ".sh")) and not file_id_provided:
                file_id = installer_file_id
                file_id_provided = True
            else:
                file_id = "gog_file_%s" % index
            self.files.append(
                InstallerFile(self.game_slug, file_id, {
                    "url": url,
                    "filename": filename,
                }))
示例#13
0
 def prepare_game_files(self):
     """Gathers necessary files before iterating through them."""
     # If this is a GOG installer, download required files.
     version = self.version.lower()
     if version.startswith("gog"):
         logger.debug("GOG game detected")
         try:
             self.swap_gog_game_files()
         except UnavailableGame as ex:
             logger.error("Unable to get the game from GOG: %s", ex)
     if version.startswith("humble"):
         try:
             self.swap_humble_game_files()
         except UnavailableGame as ex:
             logger.error("Unable to get the game from GOG: %s", ex)
     if self.runner in ("steam", "winesteam"):
         steam_uri = "$WINESTEAM:%s:." if self.runner == "winesteam" else "$STEAM:%s:."
         appid = str(self.script["game"]["appid"])
         self.files.append(
             InstallerFile(self.game_slug, "steam_game", {
                 "url": steam_uri % appid,
                 "filename": appid
             }))
示例#14
0
    def __init__(self, installer, parent):
        self.error = None
        self.errors = []
        self.target_path = None
        self.parent = parent
        self.game_dir_created = False  # Whether a game folder was created during the install
        self.game_files = {}
        self.game_disc = None
        self.cancelled = False
        self.abort_current_task = None
        self.user_inputs = []
        self.steam_data = {}
        self.gog_data = {}
        self.script = installer.get("script")
        if not self.script:
            raise ScriptingError(
                "This installer doesn't have a 'script' section")

        self.script_pretty = json.dumps(self.script, indent=4)

        self.install_start_time = None  # Time of the start of the install
        self.steam_poll = None  # Reference to the Steam poller that checks if games are downloaded
        self.current_command = None  # Current installer command when iterating through them
        self.current_file_id = None  # Current file when downloading / gathering files
        self.runners_to_install = []
        self.prev_states = []  # Previous states for the Steam installer

        self.version = installer["version"]
        self.slug = installer["slug"]
        self.year = installer.get("year")
        self.runner = installer["runner"]
        self.game_name = self.script.get("custom-name") or installer["name"]
        self.game_slug = installer["game_slug"]
        self.steamid = installer.get("steamid")
        self.gogid = installer.get("gogid")

        if not self.is_valid():
            raise ScriptingError(
                "Invalid script: \n{}".format("\n".join(self.errors)),
                self.script)

        self.files = [
            InstallerFile(self.game_slug, file_id, file_meta)
            for file_desc in self.script.get("files", [])
            for file_id, file_meta in file_desc.items()
        ]
        self.requires = self.script.get("requires")
        self.extends = self.script.get("extends")

        self.current_resolution = DISPLAY_MANAGER.get_current_resolution()
        self._check_binary_dependencies()
        self._check_dependency()
        if self.creates_game_folder:
            self.target_path = self.get_default_target()

        # If the game is in the library and uninstalled, the first installation
        # updates it
        existing_game = pga.get_game_by_field(self.game_slug, "slug")
        if existing_game and not existing_game["installed"]:
            self.game_id = existing_game["id"]
        else:
            self.game_id = None