Example #1
0
def find_steam_info(game_dir):
    """Determine the steam ID and game name of this folder, if it has one.

    This only works on Source games!
    """
    game_id = None
    name = None
    found_name = False
    found_id = False
    for folder in os.listdir(game_dir):
        info_path = os.path.join(game_dir, folder, 'gameinfo.txt')
        if os.path.isfile(info_path):
            with open(info_path) as file:
                for line in file:
                    clean_line = srctools.clean_line(line).replace('\t', ' ')
                    if not found_id and 'steamappid' in clean_line.casefold():
                        raw_id = clean_line.casefold().replace(
                            'steamappid', '').strip()
                        if raw_id.isdigit():
                            game_id = raw_id
                    elif not found_name and 'game ' in clean_line.casefold():
                        found_name = True
                        ind = clean_line.casefold().rfind('game') + 4
                        name = clean_line[ind:].strip().strip('"')
                    if found_name and found_id:
                        break
        if found_name and found_id:
            break
    return game_id, name
Example #2
0
def find_steam_info(game_dir):
    """Determine the steam ID and game name of this folder, if it has one.

    This only works on Source games!
    """
    game_id = None
    name = None
    found_name = False
    found_id = False
    for folder in os.listdir(game_dir):
        info_path = os.path.join(game_dir, folder, "gameinfo.txt")
        if os.path.isfile(info_path):
            with open(info_path) as file:
                for line in file:
                    clean_line = srctools.clean_line(line).replace("\t", " ")
                    if not found_id and "steamappid" in clean_line.casefold():
                        raw_id = clean_line.casefold().replace("steamappid", "").strip()
                        if raw_id.isdigit():
                            game_id = raw_id
                    elif not found_name and "game " in clean_line.casefold():
                        found_name = True
                        ind = clean_line.casefold().rfind("game") + 4
                        name = clean_line[ind:].strip().strip('"')
                    if found_name and found_id:
                        break
        if found_name and found_id:
            break
    return game_id, name
Example #3
0
    def edit_gameinfo(self, add_line=False) -> None:
        """Modify all gameinfo.txt files to add or remove our line.

        Add_line determines if we are adding or removing it.
        """

        for folder in self.dlc_priority():
            info_path = os.path.join(self.root, folder, 'gameinfo.txt')
            if os.path.isfile(info_path):
                with open(info_path, encoding='utf8') as file:
                    data = list(file)

                for line_num, line in reversed(list(enumerate(data))):
                    clean_line = srctools.clean_line(line)
                    if add_line:
                        if clean_line == GAMEINFO_LINE:
                            break  # Already added!
                        elif '|gameinfo_path|' in clean_line:
                            LOGGER.debug(
                                "Adding gameinfo hook to {}",
                                info_path,
                            )
                            # Match the line's indentation
                            data.insert(
                                line_num + 1,
                                utils.get_indent(line) + GAMEINFO_LINE + '\n',
                            )
                            break
                    else:
                        if clean_line == GAMEINFO_LINE:
                            LOGGER.debug("Removing gameinfo hook from {}",
                                         info_path)
                            data.pop(line_num)
                            break
                else:
                    if add_line:
                        LOGGER.warning(
                            'Failed editing "{}" to add our special folder!',
                            info_path,
                        )
                    continue

                with srctools.AtomicWriter(info_path) as file:
                    for line in data:
                        file.write(line)
        if not add_line:
            # Restore the original files!

            for name, file, ext in FILES_TO_BACKUP:
                item_path = self.abs_path(file + ext)
                backup_path = self.abs_path(file + '_original' + ext)
                old_version = self.abs_path(file + '_styles' + ext)
                if os.path.isfile(old_version):
                    LOGGER.info('Restoring Stylechanger version of "{}"!',
                                name)
                    shutil.copy(old_version, item_path)
                elif os.path.isfile(backup_path):
                    LOGGER.info('Restoring original "{}"!', name)
                    shutil.move(backup_path, item_path)
            self.clear_cache()
Example #4
0
    def edit_gameinfo(self, add_line=False):
        """Modify all gameinfo.txt files to add or remove our line.

        Add_line determines if we are adding or removing it.
        """

        for folder in self.dlc_priority():
            info_path = os.path.join(self.root, folder, "gameinfo.txt")
            if os.path.isfile(info_path):
                with open(info_path) as file:
                    data = list(file)

                for line_num, line in reversed(list(enumerate(data))):
                    clean_line = srctools.clean_line(line)
                    if add_line:
                        if clean_line == GAMEINFO_LINE:
                            break  # Already added!
                        elif "|gameinfo_path|" in clean_line:
                            LOGGER.debug("Adding gameinfo hook to {}", info_path)
                            # Match the line's indentation
                            data.insert(line_num + 1, utils.get_indent(line) + GAMEINFO_LINE + "\n")
                            break
                    else:
                        if clean_line == GAMEINFO_LINE:
                            LOGGER.debug("Removing gameinfo hook from {}", info_path)
                            data.pop(line_num)
                            break
                else:
                    if add_line:
                        LOGGER.warning('Failed editing "{}" to add our special folder!', info_path)
                    continue

                with srctools.AtomicWriter(info_path) as file:
                    for line in data:
                        file.write(line)
        if not add_line:
            # Restore the original files!
            for name, file, ext in FILES_TO_BACKUP:
                item_path = self.abs_path(file + ext)
                backup_path = self.abs_path(file + "_original" + ext)
                old_version = self.abs_path(file + "_styles" + ext)
                if os.path.isfile(old_version):
                    LOGGER.info('Restoring Stylechanger version of "{}"!', name)
                    shutil.copy(old_version, item_path)
                elif os.path.isfile(backup_path):
                    LOGGER.info('Restoring original "{}"!', name)
                    shutil.move(backup_path, item_path)
            self.clear_cache()
Example #5
0
def parse_legacy(posfile, propfile, path):
    """Parse the original BEE2.2 palette format."""
    props = Property.parse(propfile, path + ':properties.txt')
    name = props['name', 'Unnamed']
    pos = []
    for dirty_line in posfile:
        line = srctools.clean_line(dirty_line)
        if line:
            # Lines follow the form
            # "ITEM_BUTTON_FLOOR", 2
            # for subtype 3 of the button
            if line.startswith('"'):
                val = line.split('",')
                if len(val) == 2:
                    pos.append((
                        val[0][1:],  # Item ID
                        int(val[1].strip()),  # Item subtype
                    ))
                else:
                    LOGGER.warning('Malformed row "{}"!', line)
                    return None
    return Palette(name, pos)
Example #6
0
    def parse(cls, data: ParseData) -> 'PackList':
        """Read pack lists from packages."""
        filesystem = data.fsys
        conf = data.info.find_key('Config', '')

        if 'AddIfMat' in data.info:
            LOGGER.warning(
                '{}:{}: AddIfMat is no '
                'longer used.',
                data.pak_id,
                data.id,
            )

        files = []

        if conf.has_children():
            # Allow having a child block to define packlists inline
            files = [prop.value for prop in conf]
        elif conf.value:
            path = 'pack/' + conf.value + '.cfg'
            with filesystem, filesystem.open_str(path) as f:
                # Each line is a file to pack.
                # Skip blank lines, strip whitespace, and
                # allow // comments.
                for line in f:
                    line = srctools.clean_line(line)
                    if line:
                        files.append(line)

        # Deprecated old option.
        for prop in data.info.find_all('AddIfMat'):
            files.append('materials/' + prop.value + '.vmt')

        if not files:
            raise ValueError('"{}" has no files to pack!'.format(data.id))

        if CHECK_PACKFILE_CORRECTNESS:
            # Use normpath so sep differences are ignored, plus case.
            resources = {
                os.path.normpath(file.path).casefold()
                for file in filesystem.walk_folder('resources/')
            }
            for file in files:
                if file.startswith(('-#', 'precache_sound:')):
                    # Used to disable stock soundscripts, and precache sounds
                    # Not to pack - ignore.
                    continue

                file = file.lstrip(
                    '#')  # This means to put in soundscript too...

                #  Check to make sure the files exist...
                file = os.path.join('resources',
                                    os.path.normpath(file)).casefold()
                if file not in resources:
                    LOGGER.warning(
                        'Warning: "{file}" not in zip! ({pak_id})',
                        file=file,
                        pak_id=data.pak_id,
                    )

        return cls(data.id, files)