anvil

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2023 License: MIT Imports: 16 Imported by: 0

README

anvil

Go Go Report Card codecov Go Reference

anvil is a simple library for reading and writing minecraft anvil files.

Installation

go get github.com/FireworkMC/anvil

Usage

Reading and writing data from a directory containing anvil files
a, err := anvil.Open("/path/to/anvil/dir")
if err != nil{
    // handle error
}

var buffer bytes.Buffer
_, err = a.ReadTo(chunkX, chunkZ, &buffer)

// do stuff with the buffer


err = a.Write(chunkX, chunkZ, buffer.Bytes())

err = a.Close()

The anvil.Anvil returned by Open contains a cache of opened anvil files. It is recommended to use Open instead of OpenFile since opening anvil files is an expensive operation.

Reading and writing data from a single anvil file
f, err := anvil.OpenFile("/path/to/anvil/file")
if err != nil{
    // handle error
}

var buffer bytes.Buffer
// relative coordinates of the chunk data must be used
// If the chunk exists at chunkX, chunkZ: chunkX % 32, chunkZ % 32 should be used. 
_, err = f.ReadTo(chunkX%32, chunkZ%32, &buffer)


// do stuff with buffer

_, err = f.Write(chunkX%32, chunkZ%32, buffer.Bytes())

Documentation

Index

Constants

View Source
const (
	// ErrExternal returned if the is in an external file.
	// This error is only returned if the entry anvil file was opened as a single file.
	ErrExternal = errors.Const("anvil: entry is in separate file")
	// ErrNotExist returned if the entry does not exist.
	ErrNotExist = errors.Const("anvil: entry does not exist")
	// ErrSize returned if the size of the anvil file is not a multiple of [SectionSize].
	ErrSize = errors.Const("anvil: invalid file size")
	// ErrCorrupted the given file contains invalid/corrupted data
	ErrCorrupted = errors.Const("anvil: corrupted file")
	// ErrClosed the given file has already been closed
	ErrClosed = errors.Const("anvil: file closed")
	// ErrReadOnly the file was opened in readonly mode.
	ErrReadOnly = errors.Const("anvil: file is opened in read-only mode")
)
View Source
const (

	// Entries the number of Entries in a anvil file
	Entries = 32 * 32
	// SectionSize the size of a section
	SectionSize = 1 << sectionShift
	// MaxFileSections the maximum number of sections a file can contain
	MaxFileSections = 255 * Entries
)
View Source
const DefaultCompression = CompressionZlib

DefaultCompression the default compression method to be used

Variables

This section is empty.

Functions

This section is empty.

Types

type Anvil

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

Anvil a anvil file cache.

func Open

func Open(path string, opt ...Settings) (c *Anvil, err error)

Open opens the given directory.

func OpenFs

func OpenFs(fs afero.Fs, opt ...Settings) (c *Anvil, err error)

OpenFs opens the given directory.

func (*Anvil) File

func (a *Anvil) File(rgX, rgZ int32) (f File, err error)

File opens the anvil file at rgX, rgZ. Callers must close the returned file for it to be removed from the cache.

func (*Anvil) Info added in v0.0.4

func (a *Anvil) Info(entryX, entryZ int32) (entry Entry, exists bool, err error)

Info gets information stored in the anvil header for the given entry.

func (*Anvil) Read

func (a *Anvil) Read(entryX, entryZ int32) (buf []byte, err error)

Read reads the content of the entry at the given coordinates to a a byte slice and returns it.

func (*Anvil) ReadFn added in v0.1.0

func (a *Anvil) ReadFn(entryX, entryZ int32, readFn func(io.Reader) error) (err error)

ReadFn reads the entry at x,z to using the given readFn. `readFn` must not retain the io.Reader passed to it. `readFn` must not return before reading has completed.

func (*Anvil) ReadTo added in v0.1.0

func (a *Anvil) ReadTo(entryX, entryZ int32, reader io.ReaderFrom) (n int64, err error)

ReadTo reads the entry at x,z to the given io.ReaderFrom. `reader` must not retain the io.Reader passed to it. `reader` must not return before reading has completed.

func (*Anvil) Write

func (a *Anvil) Write(entryX, entryZ int32, p []byte) (err error)

Write writes the chunk data for the given location

type CompressMethod

type CompressMethod byte

CompressMethod the compression method used for compressing section data

const (
	CompressionGzip CompressMethod = 1 + iota
	CompressionZlib
	CompressionNone
)

supported methods

func (CompressMethod) String

func (c CompressMethod) String() string

type Entry

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

Entry an entry in the anvil file

func (*Entry) CompressedSize

func (e *Entry) CompressedSize() int64

CompressedSize the number of sections used by this entry (in sections). To get the size in bytes, multiply this value by SectionSize. If this is zero the data does not exist in this file. If the entry is stored in an external file, this will return 1.

func (*Entry) Exists

func (e *Entry) Exists() bool

Exists returns if the entry is stored in this file.

func (*Entry) Modified

func (e *Entry) Modified() time.Time

Modified returns when the entry was last modified.

func (*Entry) Offset

func (e *Entry) Offset() int64

Offset is the offset of the entry in the anvil file (in sections). The maximum offset is (2<<24)-1 sections. To get the size in bytes, multiply this value by SectionSize. If this is zero the data does not exist in this file.

type File

type File interface {
	// Read reads the content of the entry at the given coordinates to a
	// a byte slice and returns it.
	Read(x, z uint8) (buf []byte, err error)

	// ReadTo reads the entry at x,z to the given [io.ReaderFrom].
	// `reader` must not retain the [io.Reader] passed to it.
	// `reader` must not return before reading has completed.
	ReadTo(x, z uint8, reader io.ReaderFrom) (n int64, err error)

	// ReadWith reads the entry at x,z to using the given readFn.
	// `readFn` must not retain the [io.Reader] passed to it.
	// `readFn` must not return before reading has completed.
	ReadWith(x, z uint8, readFn func(io.Reader) error) (err error)

	// Write updates the data for the entry at x,z to the given buffer.
	// The given buffer is compressed and written to the anvil file.
	// The compression method used can be changed using the [CompressMethod] method.
	// If the data is larger than 1MB after compression, the data is stored externally.
	// Calling this function with an empty buffer is the equivalent of calling [File.Remove](x,z).
	Write(x, z uint8, b []byte) (err error)

	// Remove removes the given entry from the file.
	Remove(x, z uint8) (err error)

	// CompressionMethod sets the compression method to be used by the writer.
	CompressionMethod(m CompressMethod) (err error)

	// Info gets information stored in the anvil header for the given entry.
	Info(x, z uint8) (entry Entry, exists bool)

	// Close closes the anvil file.
	Close() (err error)
}

File is a single anvil file. All functions can be called concurrently from multiple goroutines.

func OpenFile

func OpenFile(path string, opt ...Settings) (f File, err error)

OpenFile opens the given anvil file. If readonly is set any attempts to modify the file will return an error. If any data is stored in external files, any attempt to read it will return ErrExternal. If an attempt is made to write a data that is over 1MB after compression, ErrExternal will be returned. To allow reading and writing to external files use Open instead.

func ReadAnvil added in v0.0.2

func ReadAnvil(rgx, rgz int32, r io.ReaderAt, fileSize int64, fs afero.Fs, opt ...Settings) (a File, err error)

ReadAnvil reads an anvil file from the given ReadAtCloser. This has the same limitations as OpenFile if `fs` is nil. If fileSize is 0, no attempt is made to read any headers.

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

Header the header of the anvil file.

func LoadHeader

func LoadHeader(size, timestamps *[Entries]uint32, fileSections uint) (h *Header, err error)

LoadHeader reads the header from the given arrays. `size` should contains the size and position of entries, with the least significant byte being the number of sections used by the entry and the rest containing the offset where the entry starts. `timestamps` should be an array of timestamps when the entries were last modified as the number of seconds since January 1, 1970 UTC. This function expects `size`, `timestamps` to be in the hosts byte order. `fileSections` is the max amount of sections that can be used by the entries. If `fileSections` is 0, `maxFileSections` is used instead.

func ReadHeader

func ReadHeader(r io.ReaderAt, maxSection uint) (h *Header, err error)

ReadHeader reads a header from the given reader. The given reader must read at least 2*4096 bytes. If `maxSections` != 0, this returns an error if the header references more than `maxSections` sections.

func (*Header) FindSpace

func (h *Header) FindSpace(size uint) (offset uint, found bool)

FindSpace finds the next free space large enough to store `size` sections

func (*Header) Free

func (h *Header) Free()

Free frees the header and puts it into the pool. Callers must not use the header after calling this.

func (*Header) Get

func (h *Header) Get(x, z uint8) *Entry

Get gets the entry at the given x,z coords. If the given x,z values are not between 0 and 31 (inclusive) this panics.

func (*Header) Remove

func (h *Header) Remove(x, z uint8) error

Remove removes the given entry from the header and marks the space used by the given entry in the `used` bitset as unused.

func (*Header) Set

func (h *Header) Set(x, z uint8, c Entry) error

Set updates the entry at x,z and the given marks the space used by the given entry in the `used` bitset as used.

func (*Header) Write

func (h *Header) Write(size, timestamps *[Entries]uint32)

Write writes the header to the given arrays.

type Settings added in v0.0.2

type Settings struct {
	// Readonly if the file should be opened in readonly mode.
	// If this is set, all write operation will return [ErrReadOnly].
	// Default: false
	ReadOnly bool
	// Sync if the file should be opened for synchronous I/O.
	// Default: false
	Sync bool

	// The cache size for [Anvil].
	// If this value is -1 the cache will be disabled.
	// Default: 20
	CacheSize int

	// The formatting string to be used to generate the file name for an anvil file
	AnvilFmt string
	// The formatting string to be used to generate the file name for a chunk that is stored
	// separately from and anvil file.
	ChunkFmt string
	// contains filtered or unexported fields
}

Settings settings

Jump to

Keyboard shortcuts

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