Beispiel #1
0
def mark_as_installed(appid, runner_name, game_info):
    for key in ['name', 'slug']:
        assert game_info[key]
    logger.info("Setting %s as installed" % game_info['name'])
    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))
    game_id = pga.add_or_update(
        name=game_info['name'],
        runner=runner_name,
        slug=game_info['slug'],
        installed=1,
        configpath=config_id,
        installer_slug=game_info['installer_slug']
    )

    config = LutrisConfig(
        runner_slug=runner_name,
        game_config_id=config_id,
    )
    config.raw_game_config.update({
        'appid': appid,
        'exe': game_info['exe'],
        'args': game_info['args']
    })
    config.raw_system_config.update({
        'disable_runtime': True
    })
    config.save()
    return game_id
Beispiel #2
0
def mark_as_installed(appid, runner_name, game_info):
    for key in ['name', 'slug']:
        assert game_info[key]
    logger.info("Setting %s as installed", game_info['name'])
    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))
    game_id = pga.add_or_update(
        name=game_info['name'],
        runner=runner_name,
        slug=game_info['slug'],
        installed=1,
        configpath=config_id,
        installer_slug=game_info['installer_slug']
    )

    config = LutrisConfig(
        runner_slug=runner_name,
        game_config_id=config_id,
    )
    config.raw_game_config.update({
        'appid': appid,
        'exe': game_info['exe'],
        'args': game_info['args']
    })
    config.raw_system_config.update({
        'disable_runtime': True
    })
    config.save()
    return game_id
Beispiel #3
0
    def on_save(self, _button):
        """Save game info and destroy widget. Return True if success."""
        if not self.is_valid():
            logger.warning(_("Current configuration is not valid, ignoring save request"))
            return False
        name = self.name_entry.get_text()

        if not self.slug:
            self.slug = slugify(name)

        if not self.game:
            self.game = Game()

        year = None
        if self.year_entry.get_text():
            year = int(self.year_entry.get_text())

        if not self.lutris_config.game_config_id:
            self.lutris_config.game_config_id = make_game_config_id(self.slug)

        runner_class = runners.import_runner(self.runner_name)
        runner = runner_class(self.lutris_config)

        self.game.name = name
        self.game.slug = self.slug
        self.game.year = year
        self.game.game_config_id = self.lutris_config.game_config_id
        self.game.runner = runner
        self.game.runner_name = self.runner_name
        self.game.is_installed = True
        self.game.config = self.lutris_config
        self.game.save(save_config=True)
        self.destroy()
        self.saved = True
        return True
Beispiel #4
0
    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)
Beispiel #5
0
 def write_game_config(self):
     configpath = make_game_config_id(self.slug)
     config_filename = os.path.join(settings.CONFIG_DIR, "games/%s.yml" % configpath)
     config = self.get_game_config()
     yaml_config = yaml.safe_dump(config, default_flow_style=False)
     with open(config_filename, "w") as config_file:
         logger.debug("Writing game config to %s", config_filename)
         config_file.write(yaml_config)
     return configpath
Beispiel #6
0
    def on_save(self, _button):
        """Save game info and destroy widget. Return True if success."""

        try:
            if self.slug_entry.get_sensitive() and self.slug != self.slug_entry.get_text():
                # Warn the user they made changes to the slug that need to be applied
                dlg = QuestionDialog(
                    {
                        "question":
                        _("You have modified the idenitifier, but not applied it."
                          "Would you like to apply those changes now?"),
                        "title":
                        _("Confirm pending identifier change"),
                    }
                )
                if dlg.result == Gtk.ResponseType.YES:
                    self.change_game_slug()
        except AttributeError:
            pass

        if not self.is_valid():
            logger.warning(_("Current configuration is not valid, ignoring save request"))
            return False
        name = self.name_entry.get_text()

        if not self.slug:
            self.slug = slugify(name)

        if not self.game:
            self.game = Game()

        year = None
        if self.year_entry.get_text():
            year = int(self.year_entry.get_text())

        if not self.lutris_config.game_config_id:
            self.lutris_config.game_config_id = make_game_config_id(self.slug)

        runner_class = runners.import_runner(self.runner_name)
        runner = runner_class(self.lutris_config)

        self.game.name = name
        self.game.slug = self.slug
        self.game.year = year
        self.game.game_config_id = self.lutris_config.game_config_id
        self.game.runner = runner
        self.game.runner_name = self.runner_name
        self.game.directory = runner.game_path
        self.game.is_installed = True
        if self.runner_name in ("steam", "winesteam"):
            self.game.steamid = self.lutris_config.game_config["appid"]

        self.game.config = self.lutris_config
        self.game.save()
        self.destroy()
        self.saved = True
        return True
Beispiel #7
0
def mark_as_installed(scummvm_id, name, path):
    """Add scummvm from the auto-import"""
    logger.info("Setting %s as installed" % name)
    slug = slugify(name)
    config_id = make_game_config_id(slug)
    game_id = pga.add_or_update(name=name,
                                runner='scummvm',
                                installer_slug=INSTALLER_SLUG,
                                slug=slug,
                                installed=1,
                                configpath=config_id,
                                directory=path)
    config = LutrisConfig(runner_slug='scummvm', game_config_id=config_id)
    config.raw_game_config.update({'game_id': scummvm_id, 'path': path})
    config.save()
    return game_id
Beispiel #8
0
def mark_as_installed(scummvm_id, name, path):
    """Add scummvm from the auto-import"""
    logger.info("Setting %s as installed", name)
    slug = slugify(name)
    config_id = make_game_config_id(slug)
    game_id = pga.add_or_update(
        name=name,
        runner="scummvm",
        installer_slug=INSTALLER_SLUG,
        slug=slug,
        installed=1,
        configpath=config_id,
        directory=path,
    )
    config = LutrisConfig(runner_slug="scummvm", game_config_id=config_id)
    config.raw_game_config.update({"game_id": scummvm_id, "path": path})
    config.save()
    return game_id
def migrate():
    games = pga.get_games(filter_installed=True)
    for game_info in games:
        if game_info["runner"] != "steam" or game_info["configpath"]:
            continue
        slug = game_info["slug"]
        config_id = make_game_config_id(slug)

        # Add configpath to db
        pga.add_or_update(name=game_info["name"],
                          runner="steam",
                          slug=slug,
                          configpath=config_id)

        # Add appid to config
        game_config = LutrisConfig(runner_slug="steam",
                                   game_config_id=config_id)
        game_config.raw_game_config.update(
            {"appid": str(game_info["steamid"])})
        game_config.save()
Beispiel #10
0
def mark_as_installed(steamid, runner_name, game_info):
    for key in ['name', 'slug']:
        assert game_info[key]
    logger.info("Setting %s as installed" % game_info['name'])
    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))
    game_id = pga.add_or_update(
        steamid=int(steamid),
        name=game_info['name'],
        runner=runner_name,
        slug=game_info['slug'],
        installed=1,
        configpath=config_id,
    )

    game_config = LutrisConfig(
        runner_slug=runner_name,
        game_config_id=config_id,
    )
    game_config.raw_game_config.update({'appid': steamid})
    game_config.save()
    return game_id
Beispiel #11
0
def mark_as_installed(steamid, runner_name, game_info):
    for key in ['name', 'slug']:
        assert game_info[key]
    logger.info("Setting %s as installed" % game_info['name'])
    config_id = (game_info.get('config_path') or make_game_config_id(game_info['slug']))
    game_id = pga.add_or_update(
        steamid=int(steamid),
        name=game_info['name'],
        runner=runner_name,
        slug=game_info['slug'],
        installed=1,
        configpath=config_id,
    )

    game_config = LutrisConfig(
        runner_slug=runner_name,
        game_config_id=config_id,
    )
    game_config.raw_game_config.update({'appid': steamid})
    game_config.save()
    return game_id
Beispiel #12
0
    def on_save(self, _button):
        """Save game info and destroy widget. Return True if success."""
        if not self.is_valid():
            return False
        name = self.name_entry.get_text()

        if not self.slug:
            self.slug = slugify(name)

        if not self.game:
            self.game = Game()

        year = None
        if self.year_entry.get_text():
            year = int(self.year_entry.get_text())

        if not self.lutris_config.game_config_id:
            self.lutris_config.game_config_id = make_game_config_id(self.slug)

        runner_class = runners.import_runner(self.runner_name)
        runner = runner_class(self.lutris_config)

        self.game.runner_name = self.runner_name

        self.game.name = name
        self.game.slug = self.slug
        self.game.year = year
        self.game.game_config_id = self.lutris_config.game_config_id
        self.game.runner_name = self.runner_name
        self.game.directory = runner.game_path
        self.game.is_installed = True
        if self.runner_name in ("steam", "winesteam"):
            self.game.steamid = self.lutris_config.game_config["appid"]

        self.game.set_platform_from_runner()
        self.game.config = self.lutris_config
        self.game.save()
        self.destroy()
        self.saved = True
        self.game.emit("game-updated")
Beispiel #13
0
    def _write_config(self):
        """Write the game configuration in the DB and config file."""
        if self.extends:
            logger.info('This is an extension to %s, not creating a new game entry',
                        self.extends)
            return
        configpath = make_game_config_id(self.script['slug'])
        config_filename = os.path.join(settings.CONFIG_DIR, "games/%s.yml" % configpath)

        if self.requires:
            # Load the base game config
            required_game = pga.get_game_by_field(self.requires, field='installer_slug')
            base_config = LutrisConfig(
                runner_slug=self.runner,
                game_config_id=required_game['configpath']
            )
            config = base_config.game_level
        else:
            config = {
                'game': {},
            }

        self.game_id = pga.add_or_update(
            name=self.script['name'],
            runner=self.runner,
            slug=self.game_slug,
            directory=self.target_path,
            installed=1,
            installer_slug=self.script['slug'],
            parent_slug=self.requires,
            year=self.script.get('year'),
            steamid=self.script.get('steamid'),
            configpath=configpath,
            id=self.game_id
        )
        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if 'system' in self.script:
            config['system'] = self._substitute_config(self.script['system'])
        if self.runner in self.script and self.script[self.runner]:
            config[self.runner] = self._substitute_config(
                self.script[self.runner]
            )

        # Game options such as exe or main_file can be added at the root of the
        # script as a shortcut, this integrates them into the game config
        # properly
        launcher, launcher_value = self._get_game_launcher()
        if type(launcher_value) == list:
            game_files = []
            for game_file in launcher_value:
                if game_file in self.game_files:
                    game_files.append(self.game_files[game_file])
                else:
                    game_files.append(game_file)
            config['game'][launcher] = game_files
        elif launcher_value:
            if launcher_value in self.game_files:
                launcher_value = (
                    self.game_files[launcher_value]
                )
            elif self.target_path and os.path.exists(
                os.path.join(self.target_path, launcher_value)
            ):
                launcher_value = os.path.join(self.target_path, launcher_value)
            config['game'][launcher] = launcher_value

        if 'game' in self.script:
            config['game'].update(self.script['game'])
            config['game'] = self._substitute_config(config['game'])

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)
Beispiel #14
0
 def config_id(self):
     return make_game_config_id(self.slug)
Beispiel #15
0
    def _write_config(self):
        """Write the game configuration in the DB and config file."""
        if self.extends:
            logger.info(
                'This is an extension to %s, not creating a new game entry',
                self.extends)
            return
        configpath = make_game_config_id(self.slug)
        config_filename = os.path.join(settings.CONFIG_DIR,
                                       "games/%s.yml" % configpath)

        if self.requires:
            # Load the base game config
            required_game = pga.get_game_by_field(self.requires,
                                                  field='installer_slug')
            base_config = LutrisConfig(
                runner_slug=self.runner,
                game_config_id=required_game['configpath'])
            config = base_config.game_level
        else:
            config = {
                'game': {},
            }

        self.game_id = pga.add_or_update(name=self.name,
                                         runner=self.runner,
                                         slug=self.game_slug,
                                         directory=self.target_path,
                                         installed=1,
                                         installer_slug=self.slug,
                                         parent_slug=self.requires,
                                         year=self.year,
                                         steamid=self.steamid,
                                         configpath=configpath,
                                         id=self.game_id)

        game = Game(self.game_id)
        game.set_platform_from_runner()
        game.save()

        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if 'system' in self.script:
            config['system'] = self._substitute_config(self.script['system'])
        if self.runner in self.script and self.script[self.runner]:
            config[self.runner] = self._substitute_config(
                self.script[self.runner])

        # Game options such as exe or main_file can be added at the root of the
        # script as a shortcut, this integrates them into the game config
        # properly
        launcher, launcher_value = self._get_game_launcher()
        if type(launcher_value) == list:
            game_files = []
            for game_file in launcher_value:
                if game_file in self.game_files:
                    game_files.append(self.game_files[game_file])
                else:
                    game_files.append(game_file)
            config['game'][launcher] = game_files
        elif launcher_value:
            if launcher_value in self.game_files:
                launcher_value = (self.game_files[launcher_value])
            elif self.target_path and os.path.exists(
                    os.path.join(self.target_path, launcher_value)):
                launcher_value = os.path.join(self.target_path, launcher_value)
            config['game'][launcher] = launcher_value

        if 'game' in self.script:
            config['game'].update(self.script['game'])
            config['game'] = self._substitute_config(config['game'])

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)
Beispiel #16
0
 def config_id(self):
     return make_game_config_id(self.slug)
Beispiel #17
0
    def _write_config(self):
        """Write the game configuration in the DB and config file.

        This needs to be unfucked
        """
        if self.extends:
            logger.info(
                "This is an extension to %s, not creating a new game entry",
                self.extends,
            )
            return
        configpath = make_game_config_id(self.slug)
        config_filename = os.path.join(settings.CONFIG_DIR, "games/%s.yml" % configpath)

        if self.requires:
            # Load the base game config
            required_game = pga.get_game_by_field(self.requires, field="installer_slug")
            base_config = LutrisConfig(
                runner_slug=self.runner, game_config_id=required_game["configpath"]
            )
            config = base_config.game_level
        else:
            config = {"game": {}}

        self.game_id = pga.add_or_update(
            name=self.game_name,
            runner=self.runner,
            slug=self.game_slug,
            directory=self.target_path,
            installed=1,
            installer_slug=self.slug,
            parent_slug=self.requires,
            year=self.year,
            steamid=self.steamid,
            configpath=configpath,
            id=self.game_id,
        )

        game = Game(self.game_id)
        game.set_platform_from_runner()
        game.save()

        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if "system" in self.script:
            config["system"] = self._substitute_config(self.script["system"])
        if self.runner in self.script and self.script[self.runner]:
            config[self.runner] = self._substitute_config(self.script[self.runner])

        # Game options such as exe or main_file can be added at the root of the
        # script as a shortcut, this integrates them into the game config
        # properly
        launcher, launcher_value = _get_game_launcher(self.script)
        if isinstance(launcher_value, list):
            game_files = []
            for game_file in launcher_value:
                if game_file in self.game_files:
                    game_files.append(self.game_files[game_file])
                else:
                    game_files.append(game_file)
            config["game"][launcher] = game_files
        elif launcher_value:
            if launcher_value in self.game_files:
                launcher_value = self.game_files[launcher_value]
            elif self.target_path and os.path.exists(
                    os.path.join(self.target_path, launcher_value)
            ):
                launcher_value = os.path.join(self.target_path, launcher_value)
            config["game"][launcher] = launcher_value

        if "game" in self.script:
            try:
                config["game"].update(self.script["game"])
            except ValueError:
                raise ScriptingError("Invalid 'game' section", self.script["game"])
            config["game"] = self._substitute_config(config["game"])

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)
        if not self.extends:
            game.emit("game-installed")
Beispiel #18
0
 def get_config_id(self):
     """For new games, create a special config type that won't be read
     from disk.
     """
     return make_game_config_id(self.slug) if self.slug else TEMP_CONFIG
Beispiel #19
0
 def get_config_id(self):
     """For new games, create a special config type that won't be read
     from disk.
     """
     return make_game_config_id(self.slug) if self.slug else TEMP_CONFIG
Beispiel #20
0
    def _write_config(self):
        """Write the game configuration in the DB and config file.

        This needs to be unfucked
        """
        if self.extends:
            logger.info(
                "This is an extension to %s, not creating a new game entry",
                self.extends,
            )
            return
        configpath = make_game_config_id(self.slug)
        config_filename = os.path.join(settings.CONFIG_DIR, "games/%s.yml" % configpath)

        if self.requires:
            # Load the base game config
            required_game = pga.get_game_by_field(self.requires, field="installer_slug")
            base_config = LutrisConfig(
                runner_slug=self.runner, game_config_id=required_game["configpath"]
            )
            config = base_config.game_level
        else:
            config = {"game": {}}

        self.game_id = pga.add_or_update(
            name=self.game_name,
            runner=self.runner,
            slug=self.game_slug,
            directory=self.target_path,
            installed=1,
            installer_slug=self.slug,
            parent_slug=self.requires,
            year=self.year,
            steamid=self.steamid,
            configpath=configpath,
            id=self.game_id,
        )

        game = Game(self.game_id)
        game.save()

        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if "system" in self.script:
            config["system"] = self._substitute_config(self.script["system"])
        if self.runner in self.script and self.script[self.runner]:
            config[self.runner] = self._substitute_config(self.script[self.runner])

        # Game options such as exe or main_file can be added at the root of the
        # script as a shortcut, this integrates them into the game config
        # properly
        launcher, launcher_value = _get_game_launcher(self.script)
        if isinstance(launcher_value, list):
            game_files = []
            for game_file in launcher_value:
                if game_file in self.game_files:
                    game_files.append(self.game_files[game_file])
                else:
                    game_files.append(game_file)
            config["game"][launcher] = game_files
        elif launcher_value:
            if launcher_value in self.game_files:
                launcher_value = self.game_files[launcher_value]
            elif self.target_path and os.path.exists(
                    os.path.join(self.target_path, launcher_value)
            ):
                launcher_value = os.path.join(self.target_path, launcher_value)
            config["game"][launcher] = launcher_value

        if "game" in self.script:
            try:
                config["game"].update(self.script["game"])
            except ValueError:
                raise ScriptingError("Invalid 'game' section", self.script["game"])
            config["game"] = self._substitute_config(config["game"])

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)
Beispiel #21
0
    def _write_config(self):
        """Write the game configuration in the DB and config file."""

        configpath = make_game_config_id(self.script['slug'])
        config_filename = os.path.join(settings.CONFIG_DIR,
                                       "games/%s.yml" % configpath)
        if self.requires:  # and os.path.exists(config_filename):
            # The installer is patching an existing game, update its config
            # XXX Maybe drop the self.requires condition and always update
            #     the existing config?
            # XXX Now it's not going to update configs ever again since we
            # create a unique config_id so how do we deal with that?

            # is that okay?
            required_game = pga.get_game_by_field(self.requires,
                                                  field='installer_slug')
            lutris_config = LutrisConfig(
                runner_slug=self.runner,
                game_config_id=required_game['configpath']
            )
            config = lutris_config.game_level
        else:
            config = {
                'game': {},
            }

        self.game_id = pga.add_or_update(
            name=self.script['name'],
            runner=self.runner,
            slug=self.game_slug,
            directory=self.target_path,
            installed=1,
            installer_slug=self.script['slug'],
            parent_slug=self.requires,
            year=self.script.get('year'),
            steamid=self.script.get('steamid'),
            configpath=configpath,
            id=self.game_id
        )
        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if 'system' in self.script:
            config['system'] = self._substitute_config(self.script['system'])
        if self.runner in self.script:
            config[self.runner] = self._substitute_config(
                self.script[self.runner]
            )
        if 'game' in self.script:
            config['game'].update(self._substitute_config(self.script['game']))

        launcher, launcher_value = self._get_game_launcher()
        if type(launcher_value) == list:
            game_files = []
            for game_file in launcher_value:
                if game_file in self.game_files:
                    game_files.append(self.game_files[game_file])
                else:
                    game_files.append(game_file)
            config['game'][launcher] = game_files
        elif launcher_value:
            if launcher_value in self.game_files:
                launcher_value = (
                    self.game_files[launcher_value]
                )
            elif self.target_path and os.path.exists(
                os.path.join(self.target_path, launcher_value)
            ):
                launcher_value = os.path.join(self.target_path, launcher_value)
            config['game'][launcher] = launcher_value

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        logger.debug(yaml_config)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)
Beispiel #22
0
    def write_config(self):
        """Write the game configuration in the DB and config file"""
        if self.extends:
            logger.info(
                "This is an extension to %s, not creating a new game entry",
                self.extends,
            )
            return
        configpath = make_game_config_id(self.slug)
        config_filename = os.path.join(settings.CONFIG_DIR,
                                       "games/%s.yml" % configpath)

        if self.requires:
            # Load the base game config
            required_game = pga.get_game_by_field(self.requires,
                                                  field="installer_slug")
            base_config = LutrisConfig(
                runner_slug=self.runner,
                game_config_id=required_game["configpath"])
            config = base_config.game_level
        else:
            config = {"game": {}}

        self.game_id = pga.add_or_update(
            name=self.game_name,
            runner=self.runner,
            slug=self.game_slug,
            directory=self.interpreter.target_path,
            installed=1,
            installer_slug=self.slug,
            parent_slug=self.requires,
            year=self.year,
            steamid=self.steamid,
            configpath=configpath,
            id=self.game_id,
        )

        game = Game(self.game_id)
        game.save()

        logger.debug("Saved game entry %s (%d)", self.game_slug, self.game_id)

        # Config update
        if "system" in self.script:
            config["system"] = self._substitute_config(self.script["system"])
        if self.runner in self.script and self.script[self.runner]:
            config[self.runner] = self._substitute_config(
                self.script[self.runner])
        launcher, launcher_config = self.get_game_launcher_config(
            self.interpreter.game_files)
        if launcher:
            config["game"][launcher] = launcher_config

        if "game" in self.script:
            try:
                config["game"].update(self.script["game"])
            except ValueError:
                raise ScriptingError("Invalid 'game' section",
                                     self.script["game"])
            config["game"] = self._substitute_config(config["game"])

        yaml_config = yaml.safe_dump(config, default_flow_style=False)
        with open(config_filename, "w") as config_file:
            config_file.write(yaml_config)