srctools.vpk

Classes for reading and writing Valve’s VPK format, version 1.

srctools.vpk.VPK_SIG: Final = 1437209140

The first byte of VPK files.

srctools.vpk.DIR_ARCH_INDEX: Final = 32767

The file index used for the _dir file.

class srctools.vpk.OpenModes(
value,
names=None,
*,
module=None,
qualname=None,
type=None,
start=1,
boundary=None,
)

Bases: Enum

Modes for opening VPK files.

READ = 'r'
WRITE = 'w'
APPEND = 'a'
writable

Check if this mode allows modifying the VPK.

srctools.vpk.script_write(args: List[str]) None

Create a VPK archive.

srctools.vpk.get_arch_filename(
prefix: str = 'pak01',
index: int | None = None,
) str

Generate the name for a VPK file.

Prefix is the name of the file, usually ‘pak01’. index is the index of the data file, or None for the directory.

class srctools.vpk.FileInfo(
vpk: VPK,
dir: str,
filename: str,
ext: str,
crc: int,
arch_index: int | None,
offset: int,
arch_len: int,
start_data: bytes,
)

Represents a file stored inside a VPK.

Do not call the constructor, it is only meant for VPK’s use.

property filename: str

The full filename for this file.

property name: str

The full filename for this file.

property size: int

The total size of this file.

read() bytes

Return the contents for this file.

verify() bool

Check this file matches the checksum.

write(
data: bytes,
arch_index: int | None = None,
) None

Replace this file with the given byte data.

arch_index is the pak_01_000 file to put data into (or None for _dir). If this file already exists in the VPK, the old data is not removed. For this reason VPK writes should be done once per file if possible.

class srctools.vpk.VPK(
dir_file: str | PathLike[str],
*,
mode: OpenModes | str = 'r',
dir_data_limit: int | None = 1024,
version: int = 1,
)

Represents a VPK file set in a directory.

folder: str

The directory the VPK is located in, used to find the numeric files.

file_prefix: str

The VPK filename, without _dir.vpk.

mode: OpenModes

How the file was opened.

  • Read mode, the file will not be modified and it must already exist.

  • Write mode will create the directory if needed.

  • Append mode will also create the directory, but not wipe the file.

dir_limit: int | None

The maximum amount of data for files saved to the dir file.

  • None: No limit.

  • 0: Save all to a data file.

footer_data: bytes

The block of data after the header, which contains the file data for files stored in the _dir file, not numeric files.

version: int

The VPK version, 1 or 2.

property path: str | PathLike[str]

The filename of the directory VPK file.

This can be assigned to set folder and file_prefix.

load_dirfile() None

Read in the directory file to get all filenames. This erases all changes in the file.

write_dirfile() None

Write the directory file with the changes. This must be performed after writing to the VPK.

filenames(
ext: str = '',
folder: str = '',
) Iterator[str]

Yield filenames from this VPK.

If an extension or folder is specified, only files with this extension or in this folder are returned.

folders(
*,
ext: str | None = None,
) Iterator[str]

Yield the names of folders present in this VPK.

If an extension is specified, only folders containing files with that extension are returned.

fileinfos(
*,
ext: str | None = None,
folder: str = '',
) Iterator[FileInfo]

Yield file info objects from this VPK.

If an extension or folder is specified, only files with this extension or in this folder are returned.

extract_all(dest_dir: str) None

Extract the contents of this VPK to a directory.

new_file(
filename: str | Tuple[str, str] | Tuple[str, str, str],
root: str = '',
) FileInfo

Create the given file, making it empty by default.

If root is set, files are treated as relative to there, otherwise the filename must be relative.

FileExistsError will be raised if the file is already present.

add_file(
filename: str | Tuple[str, str] | Tuple[str, str, str],
data: bytes,
root: str = '',
arch_index: int | None = 0,
) None

Add the given data to the VPK.

If root is set, files are treated as relative to there, otherwise the filename must be relative. arch_index is the pak01_xxx file to copy this to, if the length is larger than self.dir_limit. If None it’s written to the _dir file.

FileExistsError will be raised if the file is already present.

add_folder(folder: str, prefix: str = '') None

Write all files in a folder to the VPK.

If prefix is set, the folders will be written to that subfolder.

verify_all() bool

Check all files have a correct checksum.