arc0

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 15, 2025 License: MIT Imports: 0 Imported by: 0

README

ARC0

The arc0 library contains tools to decode information on files within ARC-archives, which have been used in Grim Dawn game as archives of resources. It is named after the magic number used in the format of the files.

Usage

The central routine to use is decode.Archive function, which extracts an instance of arc0.Archive from any valid instance of io.ReadSeeker (including os.File, of course):

import (
	"fmt"
	"os"

	"codeberg.org/alex-ichukov/arc0/decode"
)

func main() {
	file, err := os.Open("path/to/arc/file")
	if err != nil {
		// Process the error
	}
	defer file.Close()

	a, err := decode.Archive(file)
	if err != nil {
		// Process the error
	}

	// List the files within the archive
	for _, f := range a.Files() {
		fmt.Println(f.Name())
	}
}

The library has an example of an application, which lists the files with some additional information in the same manner as above.

Some more elaborate usage could involve extraction of the files. For any given ARC-archive, files within are split into chunks, which are independently compressed with LZ4. The library doesn't care about the format and the algorithm, but the chunks could be recovered with help of other libraries, for example, in the following way:

import (
	"io"
	"os"
	"slices"

	"codeberg.org/alex-ichukov/arc0"
	"codeberg.org/alex-ichukov/arc0/decode"
	"codeberg.org/alex-ichukov/lz4"
)

func main() {
	file, err := os.Open("/path/to/Levels.arc")
	if err != nil {
		// Process the error
	}
	defer file.Close()

	a, err := decode.Archive(file)
	if err != nil {
		// Process the error
	}

	// Search for the world map resource
	for _, f := range a.Files() {
		if f.Name() == "world001.map" {
			extractMap("/path/to/extract/world001.map", file, f)
		}
	}
}

func extractMap(path string, r io.ReadSeeker, m arc0.File) {
	file, err := os.Create(path)
	if err != nil {
		// Process the error
	}
	defer file.Close()

	dst, src := []byte(nil), []byte(nil)
	for _, c := m.Chunks() {
		_, err := r.Seek(int64(c.Offset()), io.SeekStart)
		if err != nil {
			// Process the error
		}
		src = slices.Grow(dst, int(c.CompressedSize()))[:c.CompressedSize()]
		_, err = io.ReadFull(r, src)
		if err != nil {
			// Process the error
		}
		// Some chunks are saved as is in the archive
		if c.CompressedSize() < c.DecompressedSize() {
			dst = slices.Grow(dst, int(c.DecompressedSize()))[:c.DecompressedSize()]
			err = LZ4.Decompress(dst, src)
			if err != nil {
				// Process the error
			}
			_, err = file.Write(dst)
			if err != nil {
				// Process the error
			}
		} else {
			_, err = file.Write(src)
			if err != nil {
				// Process the error
			}
		}
	}
}

License

The library is licensed under MIT license.

Documentation

Index

Constants

View Source
const Magic = uint32('A') | uint32('R')<<8 | uint32('C')<<16 | uint32(0)<<24

Magic is used in ARC-files as a "magic" number in the start of the files

View Source
const Version = "v1.0.0"

Version of the library

Variables

This section is empty.

Functions

This section is empty.

Types

type Archive

type Archive interface {
	// Files should return a slice of files of the archive
	Files() []File
}

Archive is type of collection of files of ARC-archives

type Chunk

type Chunk interface {
	// Offset should return offset of the chunk within the archive, that is
	// the position of its first byte
	Offset() uint32

	// CompressedSize should return how many bytes the chunk occupies
	// within the archive
	CompressedSize() uint32

	// DecompressedSize should return original size of the chunk in bytes
	DecompressedSize() uint32
}

Chunk is type of file chunks within ARC-files

type File

type File interface {
	// Name should return name of the file
	Name() string

	// Chunks should return a slice of all chunks, which the file was split
	// into, going in the order of the split
	Chunks() []Chunk
}

File is type of files within ARC-archives

Directories

Path Synopsis
Package archive provides an implementation of arc0.Archive interface and a factory function to construct an instance of it
Package archive provides an implementation of arc0.Archive interface and a factory function to construct an instance of it
Package chunk provides an implementation of arc0.Chunk interface and a factory function to construct an instance of it
Package chunk provides an implementation of arc0.Chunk interface and a factory function to construct an instance of it
Package decode provides tools to extract information from files of ARC-archives
Package decode provides tools to extract information from files of ARC-archives
archivev3
Package archivev3 provides function Pop as a mean of obtaining information on files of ARC-archives of version 3
Package archivev3 provides function Pop as a mean of obtaining information on files of ARC-archives of version 3
examples
arclist command
Package file provides an implementation of arc0.File interface and a factory function to construct an instance of it
Package file provides an implementation of arc0.File interface and a factory function to construct an instance of it

Jump to

Keyboard shortcuts

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