Skip to content

Commit

Permalink
minecraft/nbt: Support network big endian (#221)
Browse files Browse the repository at this point in the history
  • Loading branch information
TwistedAsylumMC authored Jan 5, 2024
1 parent c78fe56 commit 2615e5f
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
7 changes: 6 additions & 1 deletion minecraft/nbt/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,12 @@ func (d *Decoder) tag() (t tagType, tagName string, err error) {
if err != nil {
return 0, "", BufferOverrunError{Op: "ReadTag"}
}
if t = tagType(tagTypeByte); t != tagEnd {
t = tagType(tagTypeByte)
if _, ok := d.Encoding.(networkBigEndian); ok && t == tagStruct && d.depth == 0 {
// As of Minecraft Java 1.20.2, the name of the root compound tag is not written over the network.
return t, "", err
}
if t != tagEnd {
// Only read a tag name if the tag's type is not TAG_End.
tagName, err = d.Encoding.String(d.r)
}
Expand Down
4 changes: 4 additions & 0 deletions minecraft/nbt/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,5 +299,9 @@ func (e *Encoder) writeTag(t tagType, tagName string) error {
if err := e.w.WriteByte(byte(t)); err != nil {
return err
}
if _, ok := e.Encoding.(networkBigEndian); ok && t == tagStruct && e.depth == 1 {
// As of Minecraft Java 1.20.2, the name of the root compound tag is not written over the network.
return nil
}
return e.Encoding.WriteString(e.w, tagName)
}
8 changes: 8 additions & 0 deletions minecraft/nbt/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ var (
// writing Minecraft (Bedrock Edition) world saves.
LittleEndian littleEndian

// NetworkBigEndian is a version of BigEndian introduced in 1.20.2 where the name of the root compound tag is
// not written. Similarly to BigEndian, it is only used on Minecraft Java Edition and generally used for NBT
// sent over the network.
NetworkBigEndian networkBigEndian

// 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

_ Encoding = NetworkLittleEndian
_ Encoding = LittleEndian
_ Encoding = NetworkBigEndian
_ Encoding = BigEndian
)

Expand Down Expand Up @@ -210,3 +216,5 @@ func (e networkLittleEndian) Int64Slice(r *offsetReader) ([]int64, error) {
}
return m, nil
}

type networkBigEndian struct{ bigEndian }

0 comments on commit 2615e5f

Please sign in to comment.