vpk

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 14 Imported by: 0

README

go-vpk

Go library for reading, editing, and writing Valve VPK archives.

This project was built with OpenAI Codex.

The package centers on *vpk.VPK: open an archive, use it as an fs.FS, modify entries, then either save back to the original path or create a new VPK.

Install

go get github.com/aoisensi/go-vpk

Read

pkg, err := vpk.Open("pak01.vpk")
if err != nil {
	return err
}
defer pkg.Close()

data, err := fs.ReadFile(pkg, "scripts/items/items_game.txt")

Open accepts either pak01.vpk or pak01_dir.vpk. Sub archives such as pak01_000.vpk are opened lazily when file data is read.

CRC32 verification is optional and happens when file data is read.

pkg.SetVerifyCRC(true)

Read From io.ReaderAt

pkg, err := vpk.NewReader(readerAt, size).Read()
if err != nil {
	return err
}

NewReader(...).Read() parses the directory tree and returns a *VPK. Because this path does not know the original filename, pkg.Save() returns vpk.ErrNoSavePath unless the package was opened with vpk.Open.

Use As fs.FS

entries, err := fs.ReadDir(pkg, "materials")
file, err := pkg.Open("materials/example.vmt")
info, err := fs.Stat(pkg, "scripts/items/items_game.txt")

VPK implements:

  • fs.FS
  • fs.ReadFileFS
  • fs.ReadDirFS
  • fs.StatFS

Create

pkg := vpk.New()

err := pkg.Add("scripts/example.txt", strings.NewReader("hello"))
if err != nil {
	return err
}

err = vpk.Create("pak01_dir.vpk", pkg)

To write a VPK v2 directory archive:

err := vpk.Create("pak01_dir.vpk", pkg, vpk.WithVersion(vpk.Version2))

You can also add every file from an fs.FS.

pkg := vpk.New()
err := pkg.AddFS(os.DirFS("assets"), ".")

Edit And Save

pkg, err := vpk.Open("pak01_dir.vpk")
if err != nil {
	return err
}
defer pkg.Close()

pkg.Delete("scripts/old.txt")
pkg.Put("scripts/new.txt", strings.NewReader("updated"))

err = pkg.Save()

Save overwrites the path used by Open. To write to a different path, use Create.

err := vpk.Create("pak01_copy_dir.vpk", pkg)

Current Scope

  • Reads VPK v1 and v2 directory archives.
  • Lazily opens numbered sub archives when file data is needed.
  • Writes a single _dir.vpk archive containing all file data.
  • Writes v1 by default, or v2 with WithVersion(Version2).
  • Supports basic in-memory editing with Add, Put, Delete, Rename, and Clear.

License

MIT

Documentation

Overview

Package vpk reads, edits, and writes Valve VPK archives.

A VPK value is also an fs.FS, so callers can use the standard io/fs helpers to read files, stat entries, and list directories.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrClosed is returned when an operation uses a closed VPK or Writer.
	ErrClosed = errors.New("vpk: closed")
	// ErrExist is returned when adding an entry that already exists.
	ErrExist = errors.New("vpk: file already exists")
	// ErrNoSavePath is returned when Save is called for a VPK without an
	// original filesystem path.
	ErrNoSavePath = errors.New("vpk: no save path")
	// ErrNotExist is returned when an entry does not exist.
	ErrNotExist = errors.New("vpk: file does not exist")
)

Functions

func Create added in v1.0.0

func Create(path string, v *VPK, opts ...CreateOption) error

Create writes v to path as a new VPK directory archive.

Types

type ArchiveResolver added in v1.0.0

type ArchiveResolver interface {
	OpenArchive(index uint16) (io.ReaderAt, io.Closer, int64, error)
}

ArchiveResolver opens numbered sub archives referenced by directory entries.

type ChecksumError added in v1.0.0

type ChecksumError struct {
	Name     string
	Expected uint32
	Actual   uint32
}

ChecksumError is returned when CRC verification fails while reading a file.

func (ChecksumError) Error added in v1.0.0

func (e ChecksumError) Error() string

type CreateOption added in v1.0.0

type CreateOption func(*createOptions)

CreateOption configures archive creation.

func WithVersion added in v1.0.0

func WithVersion(version Version) CreateOption

WithVersion sets the VPK version used when writing.

Supported versions are Version1 and Version2.

type Entry added in v1.0.0

type Entry struct {
	Name         string
	CRC32        uint32
	PreloadBytes []byte
	ArchiveIndex uint16
	Offset       uint32
	Size         uint32
}

Entry describes a file entry in a VPK directory tree.

type EntryOption added in v1.0.0

type EntryOption func(*entryOptions)

EntryOption configures an entry added to a VPK.

type File added in v1.0.0

type File struct {
	Name string
	Body io.Reader
}

File is a named reader that can be used by helper code building a VPK.

type Header struct {
	Signature             uint32
	Version               uint32
	TreeSize              uint32
	FileDataSectionSize   uint32
	ArchiveMD5SectionSize uint32
	OtherMD5SectionSize   uint32
	SignatureSectionSize  uint32
}

Header is the fixed VPK header parsed from a directory archive.

type Option added in v1.0.0

type Option func(*options)

Option configures Open and OpenFS.

func WithArchiveResolver added in v1.0.0

func WithArchiveResolver(resolver ArchiveResolver) Option

WithArchiveResolver sets the resolver used to lazily open numbered sub archives while reading file contents.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader reads a VPK directory archive from an io.ReaderAt.

func NewReader

func NewReader(r io.ReaderAt, size int64, opts ...ReaderOption) *Reader

NewReader returns a Reader for a VPK directory archive.

func (*Reader) Read added in v1.0.0

func (r *Reader) Read() (*VPK, error)

Read parses the directory tree and returns an editable VPK.

type ReaderOption added in v1.0.0

type ReaderOption func(*readerOptions)

ReaderOption configures Reader.

func WithReaderArchiveResolver added in v1.0.0

func WithReaderArchiveResolver(resolver ArchiveResolver) ReaderOption

WithReaderArchiveResolver sets the resolver used by the VPK returned from Reader.Read.

type VPK added in v1.0.0

type VPK struct {
	// contains filtered or unexported fields
}

VPK is an editable VPK archive and implements fs.FS.

func New added in v1.0.0

func New() *VPK

New returns an empty editable VPK.

func Open added in v1.0.0

func Open(path string, opts ...Option) (*VPK, error)

Open opens a VPK from a filesystem path.

The path may point to either "name.vpk" or "name_dir.vpk". Numbered sub archives are opened lazily when their file data is read.

func OpenFS added in v1.0.0

func OpenFS(fsys fs.FS, name string, opts ...Option) (*VPK, error)

OpenFS opens a VPK directory archive from fsys.

The opened file and any lazily opened sub archives must implement io.ReaderAt.

func (*VPK) Add added in v1.0.0

func (v *VPK) Add(name string, r io.Reader, opts ...EntryOption) error

Add adds a new file entry. It returns ErrExist if name already exists.

func (*VPK) AddFS added in v1.0.0

func (v *VPK) AddFS(fsys fs.FS, root string, opts ...EntryOption) error

AddFS adds regular files below root from fsys.

When root is ".", file names are stored relative to the filesystem root.

func (*VPK) Clear added in v1.0.0

func (v *VPK) Clear() error

Clear removes all entries from the VPK.

func (*VPK) Close added in v1.0.0

func (v *VPK) Close() error

Close releases any open directory or sub archive handles.

func (*VPK) Delete added in v1.0.0

func (v *VPK) Delete(name string) error

Delete removes a file entry.

func (*VPK) Entries added in v1.0.0

func (v *VPK) Entries() []Entry

Entries returns the VPK file entries sorted by name.

func (*VPK) Open added in v1.0.0

func (v *VPK) Open(name string) (fs.File, error)

Open opens a file or directory from the VPK.

func (*VPK) Put added in v1.0.0

func (v *VPK) Put(name string, r io.Reader, opts ...EntryOption) error

Put adds or replaces a file entry.

func (*VPK) ReadDir added in v1.0.0

func (v *VPK) ReadDir(name string) ([]fs.DirEntry, error)

ReadDir reads a directory from the VPK.

func (*VPK) ReadFile added in v1.0.0

func (v *VPK) ReadFile(name string) ([]byte, error)

ReadFile reads a file from the VPK.

func (*VPK) Rename added in v1.0.0

func (v *VPK) Rename(oldName, newName string) error

Rename changes a file entry name.

func (*VPK) Save added in v1.0.0

func (v *VPK) Save() error

Save overwrites the original path used by Open.

It returns ErrNoSavePath for VPK values created with New, OpenFS, or NewReader(...).Read().

func (*VPK) SetVerifyCRC added in v1.0.0

func (v *VPK) SetVerifyCRC(enabled bool)

SetVerifyCRC controls whether file reads verify Entry.CRC32.

func (*VPK) Stat added in v1.0.0

func (v *VPK) Stat(name string) (fs.FileInfo, error)

Stat returns file or directory information for name.

func (*VPK) VerifyCRC added in v1.0.0

func (v *VPK) VerifyCRC() bool

VerifyCRC reports whether file reads verify Entry.CRC32.

type Version added in v1.0.0

type Version uint32

Version is a VPK directory archive format version.

const (
	// Version1 is the original VPK directory format.
	Version1 Version = Version(version1)
	// Version2 is the extended VPK directory format with section sizes.
	Version2 Version = Version(version2)
)

type Writer added in v1.0.0

type Writer struct {
	// contains filtered or unexported fields
}

Writer writes VPK archives to an io.Writer.

func NewWriter added in v1.0.0

func NewWriter(w io.Writer, opts ...CreateOption) *Writer

NewWriter returns a writer that serializes VPK values to w.

func (*Writer) Close added in v1.0.0

func (w *Writer) Close() error

Close closes the underlying writer when it implements io.Closer.

func (*Writer) Write added in v1.0.0

func (w *Writer) Write(v *VPK) error

Write serializes v to the underlying writer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL