Skip to content

WoozyMasta/pac1

Repository files navigation

pac1

Go package for reading, extracting, and packing Arma Reforger PAC1 archives (.pak).

Installation

go get github.com/woozymasta/pac1

Current status

Implemented:

  • parse FORM/PAC1 container and top-level chunks (HEAD, DATA, FILE);
  • recursive FILE tree parsing to flat file entries;
  • read entry payloads (raw and zlib);
  • extraction to directory with worker pool;
  • packing .pak from stream-based inputs;
  • transactional editor workflow (OpenEditor + staged ops + Commit);
  • compression policy by pathrules.

API quick start

r, err := pac1.Open("data.pak")
if err != nil {
  return err
}
defer r.Close()

first, ok := r.EntryAt(0)
if !ok {
  return nil
}

data, err := r.ReadEntry(first.Path)
if err != nil {
  return err
}
_ = data

Zero-copy metadata iteration:

for i := range r.EntryCount() {
  entry, ok := r.EntryAt(i)
  if !ok {
    break
  }
  _ = entry
}

Extract selected entries:

err = r.Extract(ctx, "out", pac1.ExtractOptions{
  MaxWorkers: 4,
})

Pack from inputs:

res, err := pac1.PackFile(ctx, "out.pak", inputs, pac1.PackOptions{
  Compress: []pathrules.Rule{
    {Action: pathrules.ActionInclude, Pattern: "*.txt"},
  },
})
if err != nil {
  return err
}
_ = res

Edit existing archive:

editor, err := pac1.OpenEditor("addon.pak", pac1.EditOptions{BackupKeep: 1})
if err != nil {
  return err
}

if err := editor.Replace(pac1.Input{
  Path: "scripts/main.c",
  Open: func() (io.ReadCloser, error) { return os.Open("scripts/main.c") },
}); err != nil {
  return err
}

if err := editor.DeleteDir("obsolete"); err != nil {
  return err
}

_, err = editor.Commit(ctx)
if err != nil {
  return err
}

About

Go toolkit for Arma Reforger PAC1 (.pak): read, extract, pack, and edit archives

Topics

Resources

License

Stars

Watchers

Forks

Contributors