nbt

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2024 License: MIT, MIT Imports: 12 Imported by: 0

Documentation

Overview

Package nbt implements the NBT formats used by Minecraft Bedrock Edition and Minecraft Java Edition. These formats are a little endian format, a big endian format and a little endian format using varints (typically used over network in Bedrock Edition).

The package exposes serialisation and deserialisation roughly the same way as the JSON standard library does, using nbt.Marshal() and nbt.Unmarshal when working with byte slices, and nbt.NewEncoder() and nbt.NewDecoder() when working with readers or writers.

The package encodes and decodes the following Go types with the following NBT tags.

byte/uint8: TAG_Byte
bool: TAG_Byte
int16: TAG_Short
int32: TAG_Int
int64: TAG_Long
float32: TAG_Float
float64: TAG_Double
[...]byte: TAG_ByteArray
[...]int32: TAG_IntArray
[...]int64: TAG_LongArray
string: TAG_String
[]<type>: TAG_List
struct{...}: TAG_Compound
map[string]<type/any>: TAG_Compound

Structures decoded or encoded may have struct field tags in a comparable way to the JSON standard library. The 'nbt' struct tag may be filled out the following ways:

'-': Ignores the field completely when encoding and decoding.
',omitempty': Doesn't encode the field if its value is the same as the default value.
'name(,omitempty)': Encodes/decodes the field with a different name than its usual name.

If no 'nbt' struct tag is present for a field, the name of the field will be used to encode/decode the struct. Note that this package, unlike the JSON standard library package, is case sensitive when decoding.

Index

Constants

This section is empty.

Variables

View Source
var (
	// NetworkLittleEndian is the variable sized integer implementation of NBT. It is otherwise the same as the
	// normal little endian NBT. The NetworkLittleEndian format limits the total bytes of NBT that may be read. If
	// the limit is hit, the reading operation will fail immediately. NetworkLittleEndian is generally used for NBT
	// sent over network in the Bedrock Edition protocol.
	NetworkLittleEndian networkLittleEndian

	// LittleEndian is the fixed size little endian implementation of NBT. It is the format typically used for
	// writing Minecraft (Bedrock Edition) world saves.
	LittleEndian littleEndian

	// BigEndian is the fixed size big endian implementation of NBT. It is the original implementation, and is
	// used only on Minecraft Java Edition.
	BigEndian bigEndian
)

Functions

func Dump

func Dump(data []byte, encoding Encoding) (string, error)

Dump returns a human readable decoded version of a serialised slice of NBT encoded using the encoding that is passed. Types are printed using the names present in the doc.go file and nested tags are indented using a single tab. Due to the nature of NBT, TAG_Compounds will not be printed in the same order. A different result is to be expected every time Dump is called, due to the random ordering.

If the serialised NBT data passed is not parsable using the encoding that was passed, an error is returned and the resulting string will always be empty.

func Marshal

func Marshal(v any) ([]byte, error)

Marshal encodes an object to its NBT representation and returns it as a byte slice. It uses the NetworkLittleEndian NBT encoding. To use a specific encoding, use MarshalEncoding.

The Go value passed must be one of the values below, and structs, maps and slices may only have types that are found in the list below.

The following Go types are converted to tags as such:

byte/uint8: TAG_Byte
bool: TAG_Byte
int16: TAG_Short
int32: TAG_Int
int64: TAG_Long
float32: TAG_Float
float64: TAG_Double
[...]byte: TAG_ByteArray
[...]int32: TAG_IntArray
[...]int64: TAG_LongArray
string: TAG_String
[]<type>: TAG_List
struct{...}: TAG_Compound
map[string]<type/any>: TAG_Compound

Marshal accepts struct fields with the 'nbt' struct tag. The 'nbt' struct tag allows setting the name of a field that some tag should be decoded in. Setting the struct tag to '-' means that field will never be filled by the decoding of the data passed. Suffixing the 'nbt' struct tag with ',omitempty' will prevent the field from being encoded if it is equal to its default value.

func MarshalEncoding

func MarshalEncoding(v any, encoding Encoding) ([]byte, error)

MarshalEncoding encodes an object to its NBT representation and returns it as a byte slice. Its functionality is identical to that of Marshal, except it accepts any NBT encoding.

func Unmarshal

func Unmarshal(data []byte, v any) error

Unmarshal decodes a slice of NBT data into a pointer to a Go values passed. Marshal will use the NetworkLittleEndian encoding by default. To use a specific encoding, use UnmarshalEncoding.

The Go value passed must be a pointer to a value. Anything else will return an error before decoding. The following NBT tags are decoded in the Go value passed as such:

TAG_Byte: byte/uint8(/any) or bool
TAG_Short: int16(/any)
TAG_Int: int32(/any)
TAG_Long: int64(/any)
TAG_Float: float32(/any)
TAG_Double: float64(/any)
TAG_ByteArray: [...]byte(/any) (The value must be a byte array, not a slice)
TAG_String: string(/any)
TAG_List: []any(/any) (The value type of the slice may vary. Depending on the type of
          values in the List tag, it might be of the type of any of the other tags, such as []int64.

TAG_Compound: struct{...}/map[string]any(/any) TAG_IntArray: [...]int32(/any) (The value must be an int32 array, not a slice) TAG_LongArray: [...]int64(/any) (The value must be an int64 array, not a slice)

Unmarshal returns an error if the data is decoded into a struct and the struct does not have all fields that the matching TAG_Compound in the NBT has, in order to prevent the loss of data. For varying data, the data should be decoded into a map. Nil maps and slices are initialised and filled out automatically by Unmarshal.

Unmarshal accepts struct fields with the 'nbt' struct tag. The 'nbt' struct tag allows setting the name of a field that some tag should be decoded in. Setting the struct tag to '-' means that field will never be filled by the decoding of the data passed.

func UnmarshalEncoding

func UnmarshalEncoding(data []byte, v any, encoding Encoding) error

UnmarshalEncoding decodes a slice of NBT data into a pointer to a Go values passed using the NBT encoding passed. Its functionality is identical to that of Unmarshal, except that it allows a specific encoding.

Types

type BufferOverrunError

type BufferOverrunError struct {
	Op string
}

BufferOverrunError is returned when the data buffer passed in when reading is overrun, meaning one of the reading operations extended beyond the end of the slice.

func (BufferOverrunError) Error

func (err BufferOverrunError) Error() string

Error ...

type Decoder

type Decoder struct {
	// Encoding is the variant to use for decoding the NBT passed. By default, the variant is set to
	// NetworkLittleEndian, which is the variant used for network NBT.
	Encoding Encoding
	// AllowZero, when set to true, prevents an error from being returned if the
	// first byte read from an io.Reader is 0x00 (TAG_End). This kind of data is
	// technically invalid, but some implementations do this to represent an
	// empty NBT tree.
	AllowZero bool
	// contains filtered or unexported fields
}

Decoder reads NBT objects from an NBT input stream.

func NewDecoder

func NewDecoder(r io.Reader) *Decoder

NewDecoder returns a new Decoder for the input stream reader passed.

func NewDecoderWithEncoding

func NewDecoderWithEncoding(r io.Reader, encoding Encoding) *Decoder

NewDecoderWithEncoding returns a new Decoder for the input stream reader passed with a specific encoding.

func (*Decoder) Decode

func (d *Decoder) Decode(v any) error

Decode reads the next NBT object from the input stream and stores it into the pointer to an object passed. See the Unmarshal docs for the conversion between NBT tags to Go types.

type Encoder

type Encoder struct {
	// Encoding is the variant to use for encoding the objects passed. By default, the variant is set to
	// NetworkLittleEndian, which is the variant used for network NBT.
	Encoding Encoding
	// contains filtered or unexported fields
}

Encoder writes NBT objects to an NBT output stream.

func NewEncoder

func NewEncoder(w io.Writer) *Encoder

NewEncoder returns a new encoder for the output stream writer passed.

func NewEncoderWithEncoding

func NewEncoderWithEncoding(w io.Writer, encoding Encoding) *Encoder

NewEncoderWithEncoding returns a new encoder for the output stream writer passed using a specific encoding. It is identical to calling NewEncoder and setting the Encoding field manually.

func (*Encoder) Encode

func (e *Encoder) Encode(v any) error

Encode encodes an object to NBT and writes it to the NBT output stream of the encoder. See the Marshal docs for the conversion from Go types to NBT tags and special struct tags.

type Encoding

type Encoding interface {
	Int16(r *offsetReader) (int16, error)
	Int32(r *offsetReader) (int32, error)
	Int64(r *offsetReader) (int64, error)
	Float32(r *offsetReader) (float32, error)
	Float64(r *offsetReader) (float64, error)
	String(r *offsetReader) (string, error)
	Int32Slice(r *offsetReader) ([]int32, error)
	Int64Slice(r *offsetReader) ([]int64, error)

	WriteInt16(w *offsetWriter, x int16) error
	WriteInt32(w *offsetWriter, x int32) error
	WriteInt64(w *offsetWriter, x int64) error
	WriteFloat32(w *offsetWriter, x float32) error
	WriteFloat64(w *offsetWriter, x float64) error
	WriteString(w *offsetWriter, x string) error
}

Encoding is an encoding variant of NBT. In general, there are three different encodings of NBT, which are all the same except for the way basic types are written.

type FailedWriteError

type FailedWriteError struct {
	Off int64
	Op  string
	Err error
}

FailedWriteError is returned if a Write operation failed on an offsetWriter, meaning some of the data could not be written to the io.Writer.

func (FailedWriteError) Error

func (err FailedWriteError) Error() string

Error ...

type IncompatibleTypeError

type IncompatibleTypeError struct {
	ValueName string
	Type      reflect.Type
}

IncompatibleTypeError is returned if a value is attempted to be written to an io.Writer, but its type can- not be translated to an NBT tag.

func (IncompatibleTypeError) Error

func (err IncompatibleTypeError) Error() string

Error ...

type InvalidArraySizeError

type InvalidArraySizeError struct {
	Off       int64
	Op        string
	GoLength  int
	NBTLength int
}

InvalidArraySizeError is returned when an array read from the NBT (that includes byte arrays, int32 arrays and int64 arrays) does not have the same size as the Go representation.

func (InvalidArraySizeError) Error

func (err InvalidArraySizeError) Error() string

Error ...

type InvalidStringError

type InvalidStringError struct {
	Off int64
	Err error
	N   uint
}

InvalidStringError is returned if a string read is not valid, meaning it does not exist exclusively out of utf8 characters, or if it is longer than the length prefix can carry.

func (InvalidStringError) Error

func (err InvalidStringError) Error() string

Error ...

type InvalidTypeError

type InvalidTypeError struct {
	Off       int64
	Field     string
	TagType   tagType
	FieldType reflect.Type
}

InvalidTypeError is returned when the type of a tag read is not equal to the struct field with the name of that tag.

func (InvalidTypeError) Error

func (err InvalidTypeError) Error() string

Error ...

type InvalidVarintError

type InvalidVarintError struct {
	Off int64
	N   int
}

InvalidVarintError is returned if a varint(32/64) is encountered that does not end after 5 or 10 bytes respectively.

func (InvalidVarintError) Error

func (err InvalidVarintError) Error() string

Error ...

type MaximumBytesReadError

type MaximumBytesReadError struct {
}

MaximumBytesReadError is returned if the maximum amount of bytes has been read for NetworkLittleEndian format. It is returned if the offset hits maximumNetworkOffset.

func (MaximumBytesReadError) Error

func (err MaximumBytesReadError) Error() string

Error ...

type MaximumDepthReachedError

type MaximumDepthReachedError struct {
}

MaximumDepthReachedError is returned if the maximum depth of 512 compound/list tags has been reached while reading or writing NBT.

func (MaximumDepthReachedError) Error

func (err MaximumDepthReachedError) Error() string

Error ...

type NonPointerTypeError

type NonPointerTypeError struct {
	ActualType reflect.Type
}

NonPointerTypeError is returned when the type of value passed in Decoder.Decode or Unmarshal is not a pointer.

func (NonPointerTypeError) Error

func (err NonPointerTypeError) Error() string

Error ...

type UnexpectedNamedTagError

type UnexpectedNamedTagError struct {
	Off     int64
	TagName string
	TagType tagType
}

UnexpectedNamedTagError is returned when a named tag is read from a compound which is not present in the struct it is decoded into.

func (UnexpectedNamedTagError) Error

func (err UnexpectedNamedTagError) Error() string

Error ...

type UnexpectedTagError

type UnexpectedTagError struct {
	Off     int64
	TagType tagType
}

UnexpectedTagError is returned when a tag type encountered was not expected, and thus valid in its context.

func (UnexpectedTagError) Error

func (err UnexpectedTagError) Error() string

Error ...

type UnknownTagError

type UnknownTagError struct {
	Off     int64
	Op      string
	TagType tagType
}

UnknownTagError is returned when the type of tag read is not known, meaning it is not found in the tag.go file.

func (UnknownTagError) Error

func (err UnknownTagError) Error() string

Error ...

Jump to

Keyboard shortcuts

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