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.
This commit is contained in:
commit
a7bb9496ae
146 changed files with 217621 additions and 0 deletions
98
internal/nbt/nbt.go
Normal file
98
internal/nbt/nbt.go
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
// 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 }
|
||||
Loading…
Add table
Add a link
Reference in a new issue