Add support for dimension ranges and network hashes
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/akmalfairuz/legacy-version/mapping"
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
)
|
||||
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
// returned is nil and the error non-nil.
|
||||
// The sub chunk count passed must be that found in the LevelChunk packet.
|
||||
// noinspection GoUnusedExportedFunction
|
||||
func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r cube.Range, pse Encoding, pe PaletteEncoding) (*Chunk, error) {
|
||||
func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r cube.Range, pse Encoding, pe PaletteEncoding, block mapping.Block, useBlockHashes bool) (*Chunk, error) {
|
||||
var (
|
||||
c = New(air, r)
|
||||
err error
|
||||
@@ -21,7 +22,7 @@ func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r c
|
||||
if oldFormat {
|
||||
index += 4
|
||||
}
|
||||
c.sub[index], err = DecodeSubChunk(air, r, buf, &index, NetworkEncoding, pse, pe)
|
||||
c.sub[index], err = DecodeSubChunk(air, r, buf, &index, NetworkEncoding, pse, pe, block, useBlockHashes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -45,7 +46,7 @@ func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r c
|
||||
} else {
|
||||
var last *PalettedStorage
|
||||
for i := 0; i < len(c.sub); i++ {
|
||||
b, err := decodePalettedStorage(buf, NetworkEncoding, pse, BiomePaletteEncoding)
|
||||
b, err := decodePalettedStorage(buf, NetworkEncoding, pse, BiomePaletteEncoding, block, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -68,7 +69,7 @@ func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r c
|
||||
|
||||
// DecodeSubChunk decodes a SubChunk from a bytes.Buffer. The Encoding passed defines how the block storages of the
|
||||
// SubChunk are decoded.
|
||||
func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e Encoding, pse Encoding, pe PaletteEncoding) (*SubChunk, error) {
|
||||
func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e Encoding, pse Encoding, pe PaletteEncoding, block mapping.Block, useBlockHashes bool) (*SubChunk, error) {
|
||||
ver, err := buf.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading version: %w", err)
|
||||
@@ -79,7 +80,7 @@ func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e
|
||||
return nil, fmt.Errorf("unknown sub chunk version %v: can't decode", ver)
|
||||
case 1:
|
||||
// Version 1 only has one layer for each sub chunk, but uses the format with palettes.
|
||||
storage, err := decodePalettedStorage(buf, e, pse, pe)
|
||||
storage, err := decodePalettedStorage(buf, e, pse, pe, block, useBlockHashes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -102,7 +103,7 @@ func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e
|
||||
sub.storages = make([]*PalettedStorage, storageCount)
|
||||
|
||||
for i := byte(0); i < storageCount; i++ {
|
||||
sub.storages[i], err = decodePalettedStorage(buf, e, pse, pe)
|
||||
sub.storages[i], err = decodePalettedStorage(buf, e, pse, pe, block, useBlockHashes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -113,7 +114,7 @@ func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e
|
||||
|
||||
// decodePalettedStorage decodes a PalettedStorage from a bytes.Buffer. The Encoding passed is used to read either a
|
||||
// network or disk block storage.
|
||||
func decodePalettedStorage(buf *bytes.Buffer, e Encoding, pse Encoding, pe PaletteEncoding) (*PalettedStorage, error) {
|
||||
func decodePalettedStorage(buf *bytes.Buffer, e Encoding, pse Encoding, pe PaletteEncoding, block mapping.Block, useBlockHashes bool) (*PalettedStorage, error) {
|
||||
blockSize, err := buf.ReadByte()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading block size: %w", err)
|
||||
@@ -142,5 +143,15 @@ func decodePalettedStorage(buf *bytes.Buffer, e Encoding, pse Encoding, pe Palet
|
||||
uint32s[i] = uint32(data[i*4]) | uint32(data[i*4+1])<<8 | uint32(data[i*4+2])<<16 | uint32(data[i*4+3])<<24
|
||||
}
|
||||
p, err := e.DecodePalette(buf, paletteSize(blockSize), pe)
|
||||
return newPalettedStorage(uint32s, p), err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if useBlockHashes {
|
||||
for i, hash := range p.values {
|
||||
if rid, ok := block.HashToRuntimeID(hash); ok {
|
||||
p.values[i] = rid
|
||||
}
|
||||
}
|
||||
}
|
||||
return newPalettedStorage(uint32s, p), nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"sync"
|
||||
|
||||
"github.com/akmalfairuz/legacy-version/mapping"
|
||||
"github.com/df-mc/dragonfly/server/block/cube"
|
||||
)
|
||||
|
||||
@@ -14,10 +15,10 @@ var pool = sync.Pool{
|
||||
},
|
||||
}
|
||||
|
||||
func NetworkEncode(air uint32, c *Chunk, oldFormat bool, pe PaletteEncoding) ([]byte, error) {
|
||||
func NetworkEncode(air uint32, c *Chunk, oldFormat bool, pe PaletteEncoding, block mapping.Block, useBlockHashes bool) ([]byte, error) {
|
||||
buf := pool.Get().(*bytes.Buffer)
|
||||
for i := 0; i < len(c.sub); i++ {
|
||||
_, _ = buf.Write(EncodeSubChunk(c.sub[i], NetworkEncoding, pe, SubChunkVersion8, c.r, i))
|
||||
_, _ = buf.Write(EncodeSubChunk(c.sub[i], NetworkEncoding, pe, SubChunkVersion8, c.r, i, block, useBlockHashes))
|
||||
}
|
||||
if oldFormat {
|
||||
biomes := make([]byte, 256)
|
||||
@@ -30,7 +31,7 @@ func NetworkEncode(air uint32, c *Chunk, oldFormat bool, pe PaletteEncoding) ([]
|
||||
}
|
||||
_, _ = buf.Write(biomes)
|
||||
} else {
|
||||
_, _ = buf.Write(EncodeBiomes(c, NetworkEncoding))
|
||||
_, _ = buf.Write(EncodeBiomes(c, NetworkEncoding, block, useBlockHashes))
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
@@ -38,7 +39,7 @@ func NetworkEncode(air uint32, c *Chunk, oldFormat bool, pe PaletteEncoding) ([]
|
||||
|
||||
// EncodeSubChunk encodes a sub-chunk from a chunk into bytes. An Encoding may be passed to encode either for network or
|
||||
// disk purposed, the most notable difference being that the network encoding generally uses varints and no NBT.
|
||||
func EncodeSubChunk(s *SubChunk, e Encoding, pe PaletteEncoding, subChunkVer subChunkVersion, r cube.Range, ind int) []byte {
|
||||
func EncodeSubChunk(s *SubChunk, e Encoding, pe PaletteEncoding, subChunkVer subChunkVersion, r cube.Range, ind int, block mapping.Block, useBlockHashes bool) []byte {
|
||||
buf := pool.Get().(*bytes.Buffer)
|
||||
defer func() {
|
||||
buf.Reset()
|
||||
@@ -47,7 +48,7 @@ func EncodeSubChunk(s *SubChunk, e Encoding, pe PaletteEncoding, subChunkVer sub
|
||||
|
||||
subChunkVer.EncodeHeader(buf, s, r, ind)
|
||||
for _, storage := range s.storages {
|
||||
encodePalettedStorage(buf, storage, nil, e, pe)
|
||||
encodePalettedStorage(buf, storage, nil, e, pe, block, useBlockHashes)
|
||||
}
|
||||
sub := make([]byte, buf.Len())
|
||||
_, _ = buf.Read(sub)
|
||||
@@ -56,7 +57,7 @@ func EncodeSubChunk(s *SubChunk, e Encoding, pe PaletteEncoding, subChunkVer sub
|
||||
|
||||
// EncodeBiomes encodes the biomes of a chunk into bytes. An Encoding may be passed to encode either for network or
|
||||
// disk purposed, the most notable difference being that the network encoding generally uses varints and no NBT.
|
||||
func EncodeBiomes(c *Chunk, e Encoding) []byte {
|
||||
func EncodeBiomes(c *Chunk, e Encoding, block mapping.Block, useBlockHashes bool) []byte {
|
||||
buf := pool.Get().(*bytes.Buffer)
|
||||
defer func() {
|
||||
buf.Reset()
|
||||
@@ -65,7 +66,7 @@ func EncodeBiomes(c *Chunk, e Encoding) []byte {
|
||||
|
||||
var previous *PalettedStorage
|
||||
for _, b := range c.biomes {
|
||||
encodePalettedStorage(buf, b, previous, e, BiomePaletteEncoding)
|
||||
encodePalettedStorage(buf, b, previous, e, BiomePaletteEncoding, block, useBlockHashes)
|
||||
previous = b
|
||||
}
|
||||
biomes := make([]byte, buf.Len())
|
||||
@@ -75,7 +76,7 @@ func EncodeBiomes(c *Chunk, e Encoding) []byte {
|
||||
|
||||
// encodePalettedStorage encodes a PalettedStorage into a bytes.Buffer. The Encoding passed is used to write the Palette
|
||||
// of the PalettedStorage.
|
||||
func encodePalettedStorage(buf *bytes.Buffer, storage, previous *PalettedStorage, e Encoding, pe PaletteEncoding) {
|
||||
func encodePalettedStorage(buf *bytes.Buffer, storage, previous *PalettedStorage, e Encoding, pe PaletteEncoding, block mapping.Block, useBlockHashes bool) {
|
||||
if storage.Equal(previous) {
|
||||
_, _ = buf.Write([]byte{0x7f<<1 | e.Network()})
|
||||
return
|
||||
@@ -89,5 +90,13 @@ func encodePalettedStorage(buf *bytes.Buffer, storage, previous *PalettedStorage
|
||||
}
|
||||
_, _ = buf.Write(b)
|
||||
|
||||
e.EncodePalette(buf, storage.palette, pe)
|
||||
palette := storage.palette
|
||||
if useBlockHashes {
|
||||
for i, rid := range palette.values {
|
||||
if hash, ok := block.RuntimeIDToHash(rid); ok {
|
||||
palette.values[i] = hash
|
||||
}
|
||||
}
|
||||
}
|
||||
e.EncodePalette(buf, palette, pe)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user