unrealpak

package
v1.29.0 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrUnsupportedFormat = errors.New("unrealpak: unsupported pak feature")

ErrUnsupportedFormat indicates the pak uses a feature this package deliberately does not support (compression, encryption, exotic FString encodings) rather than a genuine parse failure. Callers should fail loudly on this, not silently degrade (repo precedent: #95).

Functions

This section is empty.

Types

type FileEntry

type FileEntry struct {
	Path string // Mount-relative path, e.g. "Icarus/Content/Data/AI-D_AIGrowth.json"
	Size int64  // Uncompressed size in bytes
}

FileEntry describes one file inside a pak, as returned by Reader.Files.

type Option

type Option func(*Writer)

Option configures a Writer at construction time (see Create). The set is deliberately tiny and additive: new options can be introduced without breaking existing Create(path) call sites, since opts is variadic.

func WithMountPoint

func WithMountPoint(mountPoint string) Option

WithMountPoint overrides the mount point Writer stamps into the primary index (see defaultMountPoint). This package stays game-agnostic — it has no built-in notion of any specific game's directory layout — so a caller that knows what its target game's mod loader expects (e.g. internal/source/icarus, #178) supplies it here rather than this package guessing or hard-coding one game's convention.

type Reader

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

Reader provides read access to an unencrypted UE4-range pak. Stored entries and Zlib-compressed entries are readable; any other compression method is a loud ErrUnsupportedFormat.

func Open

func Open(path string) (*Reader, error)

Open parses path's footer and index. It does not read file contents — call ReadFile for that (Task 3).

func (*Reader) Close

func (r *Reader) Close() error

Close releases the underlying file handle.

func (*Reader) Files

func (r *Reader) Files() []FileEntry

Files returns every file this pak's index describes.

func (*Reader) IndexHash

func (r *Reader) IndexHash() string

IndexHash returns the pak's footer-recorded primary-index SHA1 as a lowercase hex string — a cheap, stable fingerprint of the pak's content (Open already reads and verifies this region; IndexHash reads no further bytes and never hashes the pak's actual file payloads). Any content or layout change to the pak changes its primary index and therefore this hash, making it a reliable "has this pak changed" signal without the cost of hashing the whole (often multi-gigabyte) file.

func (*Reader) MountPoint

func (r *Reader) MountPoint() string

MountPoint returns this pak's primary-index MountPoint string — where the engine roots Files' mount-relative paths once the pak is mounted. Real paks vary this: Icarus's own data.pak declares an absolute cook-machine path, while mod paks conventionally declare a relative "../../../..." form (see Writer's WithMountPoint, #178).

func (*Reader) ReadFile

func (r *Reader) ReadFile(path string) ([]byte, error)

ReadFile returns the bytes of the entry at mount-relative path.

On-disk entry data is preceded by a full FPakEntry header — 53 bytes for a stored entry, plus a block table for a compressed one — and the index's offset points at that header, not the payload. The header is re-read and cross-checked rather than trusted: its method and sizes must agree with the index, and its Hash must match the on-disk payload's SHA1. Real paks satisfy all of this (verified across a whole install), so a disagreement means corruption or a layout this package misread.

type Writer

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

Writer produces a stored (uncompressed), unencrypted version-11 pak carrying the full three-part index: primary index, path-hash index and full directory index, then the 221-byte footer.

AddFile buffers content in memory and Close emits everything sorted by path, so identical inputs produce byte-identical output regardless of AddFile call order. Mod paks are small — Icarus's entire base data.pak is 2.4 MB — so buffering costs little, and deterministic output is worth more: it makes the round-trip test able to assert on bytes and keeps compiled paks stable across recompiles.

func Create

func Create(path string, opts ...Option) (*Writer, error)

Create opens path for writing. Call AddFile for each entry, then Close. With no options, the written pak uses defaultMountPoint, matching every existing caller's prior behavior exactly.

func (*Writer) AddFile

func (w *Writer) AddFile(mountPath string, data []byte) error

AddFile records one entry. Nothing reaches disk until Close.

func (*Writer) Close

func (w *Writer) Close() error

Close assembles the data section and all three index structures, writes them with the footer, and closes the file.

Jump to

Keyboard shortcuts

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