PaletteContainer

This commit is contained in:
Tnze
2021-12-19 13:37:45 +08:00
parent 58f7fe336d
commit a4c4ffd6be
8 changed files with 250 additions and 2273 deletions

View File

@ -6,6 +6,7 @@ import (
pk "github.com/Tnze/go-mc/net/packet"
"github.com/Tnze/go-mc/save"
"io"
"math/bits"
"sync"
)
@ -20,33 +21,74 @@ type DimInfo struct {
HashedSeed uint64
}
type SimpleDim struct {
Columns map[struct{ X, Z int }]*struct {
sync.Mutex
type ChunkPos struct{ X, Z int }
type Chunk struct {
sync.Mutex
sections []Section
HeightMaps *save.BitStorage
}
type Section struct {
blockCount int16
States *save.PaletteContainer
Biomes *save.PaletteContainer
}
func (s *Section) WriteTo(w io.Writer) (int64, error) {
return pk.Tuple{
pk.Short(s.blockCount),
s.States,
s.Biomes,
}.WriteTo(w)
}
func (s *Section) ReadFrom(r io.Reader) (int64, error) {
return pk.Tuple{
pk.Short(s.blockCount),
s.States,
s.Biomes,
}.ReadFrom(r)
}
func EmptyChunk(secs int) *Chunk {
sections := make([]Section, secs)
for i := range sections {
sections[i] = Section{
blockCount: 0,
States: save.NewStatesPaletteContainer(nil, 16*16*16),
Biomes: save.NewBiomesPaletteContainer(nil, 4*4*4),
}
}
return &Chunk{
sections: sections,
HeightMaps: save.NewBitStorage(bits.Len(uint(secs)*16), 16*16, nil),
}
}
type chunkData struct {
HeightMaps save.BitStorage
BlockState save.BitStorage
Biomes save.BitStorage
}
func (c *chunkData) WriteTo(w io.Writer) (int64, error) {
func (c *Chunk) WriteTo(w io.Writer) (int64, error) {
data, err := c.Data()
if err != nil {
return 0, err
}
return pk.Tuple{
// Heightmaps
pk.NBT(struct {
MotionBlocking []uint64 `nbt:"MOTION_BLOCKING"`
}{c.HeightMaps.Raw()}),
pk.ByteArray(c.Data()), // TODO: Chunk Data
pk.VarInt(0), // TODO: Block Entity
pk.ByteArray(data),
pk.VarInt(0), // TODO: Block Entity
}.WriteTo(w)
}
func (c *chunkData) Data() []byte {
func (c *Chunk) Data() ([]byte, error) {
var buff bytes.Buffer
_, _ = pk.Short(0).WriteTo(&buff)
return buff.Bytes()
for _, section := range c.sections {
_, err := section.WriteTo(&buff)
if err != nil {
return nil, err
}
}
return buff.Bytes(), nil
}
type lightData struct {
@ -76,13 +118,36 @@ func (l *lightData) WriteTo(w io.Writer) (int64, error) {
}.WriteTo(w)
}
type SimpleDim struct {
numOfSection int
Columns map[ChunkPos]*Chunk
}
func NewSimpleDim(secs int) *SimpleDim {
return &SimpleDim{
numOfSection: secs,
Columns: make(map[ChunkPos]*Chunk),
}
}
func (s *SimpleDim) LoadChunk(pos ChunkPos, c *Chunk) {
s.Columns[pos] = c
}
func (s *SimpleDim) Info() DimInfo {
return DimInfo{
Name: "minecraft:overworld",
HashedSeed: 0,
}
}
func (s *SimpleDim) PlayerJoin(p *Player) {
for pos, column := range s.Columns {
column.Lock()
packet := pk.Marshal(
packetid.ClientboundLevelChunkWithLight,
pk.Int(pos.X), pk.Int(pos.Z),
&chunkData{},
column,
&lightData{
SkyLightMask: make(pk.BitSet, (16*16*16-1)>>6+1),
BlockLightMask: make(pk.BitSet, (16*16*16-1)>>6+1),
@ -97,6 +162,18 @@ func (s *SimpleDim) PlayerJoin(p *Player) {
return
}
}
err := p.WritePacket(Packet757(pk.Marshal(
packetid.ClientboundPlayerPosition,
pk.Double(0), pk.Double(0), pk.Double(0),
pk.Float(0), pk.Float(0),
pk.Byte(0),
pk.VarInt(0),
pk.Boolean(true),
)))
if err != nil {
return
}
}
func (s *SimpleDim) PlayerQuit(p *Player) {