Пример #1
0
    def load_soundscript_manifest(self, cache_file: str=None) -> None:
        """Read the soundscript manifest, and read all mentioned scripts.

        If cache_file is provided, it should be a path to a file used to
        cache the file reading for later use. 
        """
        try:
            man = self.fsys.read_prop('scripts/game_sounds_manifest.txt')
        except FileNotFoundError:
            return

        cache_data = {}  # type: Dict[str, Tuple[int, Property]]
        if cache_file is not None:
            # If the file doesn't exist or is corrupt, that's
            # fine. We'll just parse the soundscripts the slow
            # way.
            try:
                with open(cache_file) as f:
                    old_cache = Property.parse(f, cache_file)
                if man['version'] != SOUND_CACHE_VERSION:
                    raise LookupError
            except (FileNotFoundError, KeyValError, LookupError):
                pass
            else:
                for cache_prop in old_cache.find_children('Sounds'):
                    cache_data[cache_prop.name] = (
                        cache_prop.int('cache_key'),
                        cache_prop.find_key('files')
                    )

            # Regenerate from scratch each time - that way we remove old files
            # from the list.
            new_cache_sounds = Property('Sounds', [])
            new_cache_data = Property(None, [
                Property('version', SOUND_CACHE_VERSION),
                new_cache_sounds,
            ])
        else:
            new_cache_data = new_cache_sounds = None

        with self.fsys:
            for prop in man.find_children('game_sounds_manifest'):
                if not prop.name.endswith('_file'):
                    continue
                try:
                    cache_key, cache_files = cache_data[prop.value.casefold()]
                except KeyError:
                    cache_key = -1
                    cache_files = None

                try:
                    file = self.fsys[prop.value]
                except FileNotFoundError:
                    LOGGER.warning('Soundscript "{}" does not exist!', prop.value)
                    # Don't write anything into the cache, so we check this
                    # every time.
                    continue
                cur_key = file.cache_key()

                if cache_key != cur_key or cache_key == -1:
                    sounds = self.load_soundscript(file, always_include=True)
                else:
                    # Read from cache.
                    sounds = []
                    for cache_prop in cache_files:
                        sounds.append(cache_prop.real_name)
                        self.soundscripts[cache_prop.real_name] = (prop.value, [
                            snd.value
                            for snd in cache_prop
                        ])

                # The soundscripts in the manifests are always included,
                # since many would be part of the core code (physics, weapons,
                # ui, etc). Just keep those loaded, no harm since vanilla does.
                self.soundscript_files[file.path] = SoundScriptMode.INCLUDE

                if new_cache_sounds is not None:
                    new_cache_sounds.append(Property(prop.value, [
                        Property('cache_key', str(cur_key)),
                        Property('Files', [
                            Property(snd, [
                                Property('snd', raw)
                                for raw in self.soundscripts[snd][1]
                            ])
                            for snd in sounds
                        ])
                    ]))

        if cache_file is not None:
            # Write back out our new cache with updated data.
            with srctools.AtomicWriter(cache_file) as f:
                for line in new_cache_data.export():
                    f.write(line)
Пример #2
0
    def load_soundscript_manifest(self, cache_file: str = None) -> None:
        """Read the soundscript manifest, and read all mentioned scripts.

        If cache_file is provided, it should be a path to a file used to
        cache the file reading for later use.
        """
        try:
            man = self.fsys.read_prop('scripts/game_sounds_manifest.txt')
        except FileNotFoundError:
            return

        cache_data = {}  # type: Dict[str, Tuple[int, Property]]
        if cache_file is not None:
            try:
                f = open(cache_file)
            except FileNotFoundError:
                pass
            else:
                with f:
                    old_cache = Property.parse(f, cache_file)
                for cache_prop in old_cache:
                    cache_data[cache_prop.name] = (
                        cache_prop.int('cache_key'),
                        cache_prop.find_key('files'))

            # Regenerate from scratch each time - that way we remove old files
            # from the list.
            new_cache_data = Property(None, [])
        else:
            new_cache_data = None

        with self.fsys:
            for prop in man.find_children('game_sounds_manifest'):
                if not prop.name.endswith('_file'):
                    continue
                try:
                    cache_key, cache_files = cache_data[prop.value.casefold()]
                except KeyError:
                    cache_key = -1
                    cache_files = None

                file = self.fsys[prop.value]
                cur_key = file.cache_key()

                if cache_key != cur_key or cache_key == -1:
                    sounds = self.load_soundscript(file, always_include=True)
                else:
                    # Read from cache.
                    sounds = []
                    for cache_prop in cache_files:
                        sounds.append(cache_prop.real_name)
                        self.soundscripts[cache_prop.real_name] = (
                            prop.value, [snd.value for snd in cache_prop])

                # The soundscripts in the manifests are always included,
                # since many would be part of the core code (physics, weapons,
                # ui, etc). Just keep those loaded, no harm since vanilla does.
                self.soundscript_files[file.path] = SoundScriptMode.INCLUDE

                if new_cache_data is not None:
                    new_cache_data.append(
                        Property(prop.value, [
                            Property('cache_key', str(cur_key)),
                            Property('Files', [
                                Property(snd, [
                                    Property('snd', raw)
                                    for raw in self.soundscripts[snd][1]
                                ]) for snd in sounds
                            ])
                        ]))

        if cache_file is not None:
            # Write back out our new cache with updated data.
            with open(cache_file, 'w') as f:
                for line in new_cache_data.export():
                    f.write(line)
Пример #3
0
    def load_soundscript_manifest(self, cache_file: str=None) -> None:
        """Read the soundscript manifest, and read all mentioned scripts.

        If cache_file is provided, it should be a path to a file used to
        cache the file reading for later use.
        """
        try:
            man = self.fsys.read_prop('scripts/game_sounds_manifest.txt')
        except FileNotFoundError:
            return

        cache_data = {}  # type: Dict[str, Tuple[int, Property]]
        if cache_file is not None:
            try:
                f = open(cache_file)
            except FileNotFoundError:
                pass
            else:
                with f:
                    old_cache = Property.parse(f, cache_file)
                for cache_prop in old_cache:
                    cache_data[cache_prop.name] = (
                        cache_prop.int('cache_key'),
                        cache_prop.find_key('files')
                    )

            # Regenerate from scratch each time - that way we remove old files
            # from the list.
            new_cache_data = Property(None, [])
        else:
            new_cache_data = None

        with self.fsys:
            for prop in man.find_children('game_sounds_manifest'):
                if not prop.name.endswith('_file'):
                    continue
                try:
                    cache_key, cache_files = cache_data[prop.value.casefold()]
                except KeyError:
                    cache_key = -1
                    cache_files = None

                file = self.fsys[prop.value]
                cur_key = file.cache_key()

                if cache_key != cur_key or cache_key == -1:
                    sounds = self.load_soundscript(file, always_include=True)
                else:
                    # Read from cache.
                    sounds = []
                    for cache_prop in cache_files:
                        sounds.append(cache_prop.real_name)
                        self.soundscripts[cache_prop.real_name] = (prop.value, [
                            snd.value
                            for snd in cache_prop
                        ])

                # The soundscripts in the manifests are always included,
                # since many would be part of the core code (physics, weapons,
                # ui, etc). Just keep those loaded, no harm since vanilla does.
                self.soundscript_files[file.path] = SoundScriptMode.INCLUDE

                if new_cache_data is not None:
                    new_cache_data.append(Property(prop.value, [
                        Property('cache_key', str(cur_key)),
                        Property('Files', [
                            Property(snd, [
                                Property('snd', raw)
                                for raw in self.soundscripts[snd][1]
                            ])
                            for snd in sounds
                        ])
                    ]))

        if cache_file is not None:
            # Write back out our new cache with updated data.
            with open(cache_file, 'w') as f:
                for line in new_cache_data.export():
                    f.write(line)