RegionIO/internal/nbt/nbt.go
Master290 a7bb9496ae Initial commit: RegionIO Minecraft server core (26.1.2/protocol 775)
Vanilla-faithful overworld generator (final_density + multi-noise biomes),
full connection lifecycle (status/login/configuration/play), chunk streaming,
creative block editing, and the protocol/nbt/registry infrastructure.
2026-06-24 00:32:51 +03:00

98 lines
2.8 KiB
Go

// Package nbt implements Minecraft's Named Binary Tag format, including the
// network variant used since 1.20.2 where the root tag carries no name.
//
// All numeric payloads are big-endian. Strings use Java's "modified UTF-8":
// an unsigned-short byte length followed by bytes where NUL and supplementary
// code points are escaped (see encode/decodeModifiedUTF8).
package nbt
// Tag type identifiers as defined by the NBT specification.
const (
TagEnd = 0x00
TagByte = 0x01
TagShort = 0x02
TagInt = 0x03
TagLong = 0x04
TagFloat = 0x05
TagDouble = 0x06
TagByteArray = 0x07
TagString = 0x08
TagList = 0x09
TagCompound = 0x0A
TagIntArray = 0x0B
TagLongArray = 0x0C
)
// Tag is any NBT value. ID returns its tag type identifier.
type Tag interface{ ID() byte }
// Primitive and array tag types map directly onto Go types.
type (
Byte int8
Short int16
Int int32
Long int64
Float float32
Double float64
ByteArray []byte
String string
IntArray []int32
LongArray []int64
)
func (Byte) ID() byte { return TagByte }
func (Short) ID() byte { return TagShort }
func (Int) ID() byte { return TagInt }
func (Long) ID() byte { return TagLong }
func (Float) ID() byte { return TagFloat }
func (Double) ID() byte { return TagDouble }
func (ByteArray) ID() byte { return TagByteArray }
func (String) ID() byte { return TagString }
func (IntArray) ID() byte { return TagIntArray }
func (LongArray) ID() byte { return TagLongArray }
// List is a homogeneous sequence of unnamed tags. ElemID must match the type
// of every element; for an empty list it is written as TagEnd, per Java.
type List struct {
ElemID byte
Elems []Tag
}
func (List) ID() byte { return TagList }
// Compound is an ordered set of named tags. Insertion order is preserved so
// that encoding is deterministic (the protocol does not require any order).
type Compound struct {
keys []string
m map[string]Tag
}
func (*Compound) ID() byte { return TagCompound }
// NewCompound returns an empty compound ready for Set.
func NewCompound() *Compound {
return &Compound{m: make(map[string]Tag)}
}
// Set inserts or replaces the tag for name, preserving first-insertion order,
// and returns the compound for chaining.
func (c *Compound) Set(name string, t Tag) *Compound {
if _, ok := c.m[name]; !ok {
c.keys = append(c.keys, name)
}
c.m[name] = t
return c
}
// Get returns the tag for name and whether it is present.
func (c *Compound) Get(name string) (Tag, bool) {
t, ok := c.m[name]
return t, ok
}
// Len returns the number of entries.
func (c *Compound) Len() int { return len(c.keys) }
// Keys returns the entry names in insertion order. The slice must not be
// mutated by callers.
func (c *Compound) Keys() []string { return c.keys }