recive Chunk data

This commit is contained in:
JunDao
2019-05-19 21:27:07 +08:00
parent 845b7949dd
commit bb7fffbce6
7 changed files with 187 additions and 159 deletions

View File

@ -1,6 +1,7 @@
package bot
import (
"github.com/Tnze/go-mc/bot/world"
"github.com/Tnze/go-mc/bot/world/entity"
"github.com/Tnze/go-mc/bot/world/entity/player"
"github.com/Tnze/go-mc/net"
@ -15,7 +16,7 @@ type Client struct {
PlayInfo
abilities PlayerAbilities
settings Settings
// wd world //the map data
Wd world.World //the map data
// Delegate allows you push a function to let HandleGame run.
// Do not send at the same goroutin!
@ -40,6 +41,9 @@ func NewClient() (c *Client) {
c.Name = "Steve"
c.Delegate = make(chan func() error)
c.Wd.Entities = make(map[int32]entity.Entity)
c.Wd.Chunks = make(map[world.ChunkLoc]*world.Chunk)
return
}

View File

@ -3,10 +3,13 @@ package bot
import (
"bytes"
"errors"
"io"
"io/ioutil"
// "math"
// "time"
"fmt"
"github.com/Tnze/go-mc/bot/world"
"github.com/Tnze/go-mc/bot/world/entity"
"github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data"
@ -82,7 +85,7 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
case data.HeldItemChangeClientbound:
err = handleHeldItemPacket(c, p)
case data.ChunkData:
////err = handleChunkDataPacket(c, p)
err = handleChunkDataPacket(c, p)
case data.PlayerPositionAndLookClientbound:
err = handlePlayerPositionAndLookPacket(c, p)
sendPlayerPositionAndLookPacket(c) // to confirm the position
@ -345,10 +348,30 @@ func handleJoinGamePacket(c *Client, p pk.Packet) error {
return nil
}
// The PluginMessageData only used in recive PluginMessage packet.
// When decode it, read to end.
type pluginMessageData []byte
//Encode a PluginMessageData
func (p *pluginMessageData) Encode(r io.Writer) error {
_, err := r.Write([]byte(*p))
return err
}
//Decode a PluginMessageData
func (p *pluginMessageData) Decode(r pk.DecodeReader) error {
data, err := ioutil.ReadAll(r)
if err != nil {
return err
}
*p = pluginMessageData(data)
return nil
}
func handlePluginPacket(c *Client, p pk.Packet) error {
var (
Channel pk.Identifier
Data pk.PluginMessageData
Data pluginMessageData
)
if err := p.Scan(&Channel, &Data); err != nil {
return err
@ -405,15 +428,15 @@ func handleHeldItemPacket(c *Client, p pk.Packet) error {
return nil
}
// func handleChunkDataPacket(g *Client, p pk.Packet) error {
// if !g.settings.ReciveMap {
// return nil
// }
func handleChunkDataPacket(c *Client, p pk.Packet) error {
if !c.settings.ReciveMap {
return nil
}
// c, x, y, err := unpackChunkDataPacket(p, g.Info.Dimension == 0)
// g.wd.chunks[chunkLoc{x, y}] = c
// return err
// }
chunk, x, z, err := world.UnpackChunkDataPacket(p, c.Dimension == 0)
c.Wd.Chunks[world.ChunkLoc{x, z}] = chunk
return err
}
// var isSpawn bool

View File

@ -1,127 +1,132 @@
package world
// import (
// "bytes"
// "fmt"
// pk "github.com/Tnze/gomcbot/network/packet"
// "io"
// )
import (
"github.com/Tnze/go-mc/nbt"
// "fmt"
pk "github.com/Tnze/go-mc/net/packet"
// "io"
)
// func unpackChunkDataPacket(p *pk.Packet, hasSkyLight bool) (c *Chunk, x, y int, err error) {
// reader := bytes.NewReader(p.Data)
// //区块坐标
// X, err := pk.UnpackInt32(reader)
// if err != nil {
// return nil, 0, 0, err
// }
// Y, err := pk.UnpackInt32(reader)
// if err != nil {
// return nil, 0, 0, err
// }
// // fmt.Println("Chunk: (", X, ", ", Y, ")") //Debug: Show Chunk loc
// fc, err := reader.ReadByte()
// if err != nil {
// return nil, 0, 0, err
// }
// FullChunk := fc != 0x00
func UnpackChunkDataPacket(p pk.Packet, hasSkyLight bool) (c *Chunk, x, z int, err error) {
var (
X, Z pk.Int
FullChunk pk.Boolean
PrimaryBitMask pk.VarInt
Heightmaps struct{}
Data chunkData
BlockEntities blockEntities
)
// //主掩码
// PrimaryBitMask, err := pk.UnpackVarInt(reader)
// if err != nil {
// return nil, 0, 0, err
// }
p.Scan(&X, &Z, &FullChunk, &PrimaryBitMask, pk.NBT{V: &Heightmaps}, &Data, &BlockEntities)
// //区块数据
// Size, err := pk.UnpackVarInt(reader)
// if err != nil {
// return nil, 0, 0, err
// }
// Data := make([]byte, Size)
// _, err = io.ReadAtLeast(reader, Data, int(Size))
// if err != nil {
// return nil, 0, 0, err
// }
//解析区块数据
cc, err := readChunkColumn(bool(FullChunk), int32(PrimaryBitMask), []byte(Data), hasSkyLight)
if err != nil {
panic(err)
}
return cc, int(X), int(Z), err
}
// //实体信息
// // NumberofBlockEntities, len := pk.UnpackVarInt(p.Data[index:])
// // index += len
type chunkData []byte
type blockEntities []blockEntitie
type blockEntitie struct {
}
// //解析区块数据
// cc, err := readChunkColumn(FullChunk, PrimaryBitMask, bytes.NewReader(Data), hasSkyLight)
// if err != nil {
// panic(err)
// }
// return cc, int(X), int(Y), err
// }
func (c *chunkData) Decode(r pk.DecodeReader) error {
var Size pk.VarInt
if err := Size.Decode(r); err != nil {
return err
}
*c = make([]byte, Size)
if _, err := r.Read(*c); err != nil {
return err
}
return nil
}
// func readChunkColumn(isFull bool, mask int32, data *bytes.Reader, hasSkyLight bool) (*Chunk, error) {
// var c Chunk
// for sectionY := 0; sectionY < 16; sectionY++ {
// if (mask & (1 << uint(sectionY))) != 0 { // Is the given bit set in the mask?
// BitsPerBlock, err := data.ReadByte()
// if err != nil {
// return nil, fmt.Errorf("read BitsPerBlock fail: %v", err)
// }
// //读调色板
// var palette []uint
// if BitsPerBlock < 9 {
// length, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read palette (id len) fail: %v", err)
// }
// palette = make([]uint, length)
func (b *blockEntities) Decode(r pk.DecodeReader) error {
var NumberofBlockEntities pk.VarInt
if err := NumberofBlockEntities.Decode(r); err != nil {
return err
}
*b = make(blockEntities, NumberofBlockEntities)
decoder := nbt.NewDecoder(r)
for i := 0; i < int(NumberofBlockEntities); i++ {
if err := decoder.Decode(&(*b)[i]); err != nil {
return err
}
}
return nil
}
// for id := uint(0); id < uint(length); id++ {
// stateID, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read palette (id) fail: %v", err)
// }
func readChunkColumn(isFull bool, mask int32, data []byte, hasSkyLight bool) (*Chunk, error) {
var c Chunk
// for sectionY := 0; sectionY < 16; sectionY++ {
// if (mask & (1 << uint(sectionY))) != 0 { // Is the given bit set in the mask?
// BitsPerBlock, err := data.ReadByte()
// if err != nil {
// return nil, fmt.Errorf("read BitsPerBlock fail: %v", err)
// }
// //读调色板
// var palette []uint
// if BitsPerBlock < 9 {
// length, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read palette (id len) fail: %v", err)
// }
// palette = make([]uint, length)
// palette[id] = uint(stateID)
// }
// }
// for id := uint(0); id < uint(length); id++ {
// stateID, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read palette (id) fail: %v", err)
// }
// //Section数据
// DataArrayLength, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read DataArrayLength fail: %v", err)
// }
// palette[id] = uint(stateID)
// }
// }
// DataArray := make([]int64, DataArrayLength)
// for i := 0; i < int(DataArrayLength); i++ {
// DataArray[i], err = pk.UnpackInt64(data)
// if err != nil {
// return nil, fmt.Errorf("read DataArray fail: %v", err)
// }
// }
// //用数据填充区块
// fillSection(&c.sections[sectionY], perBits(BitsPerBlock), DataArray, palette)
// //Section数据
// DataArrayLength, err := pk.UnpackVarInt(data)
// if err != nil {
// return nil, fmt.Errorf("read DataArrayLength fail: %v", err)
// }
// //throw BlockLight data
// _, err = pk.ReadNBytes(data, 2048)
// if err != nil {
// return nil, fmt.Errorf("read BlockLight fail: %v", err)
// }
// DataArray := make([]int64, DataArrayLength)
// for i := 0; i < int(DataArrayLength); i++ {
// DataArray[i], err = pk.UnpackInt64(data)
// if err != nil {
// return nil, fmt.Errorf("read DataArray fail: %v", err)
// }
// }
// //用数据填充区块
// fillSection(&c.sections[sectionY], perBits(BitsPerBlock), DataArray, palette)
// if hasSkyLight {
// //throw SkyLight data
// _, err = pk.ReadNBytes(data, 2048)
// if err != nil {
// return nil, fmt.Errorf("read SkyLight fail: %v", err)
// }
// }
// }
// }
// if isFull { //need recive Biomes datas
// _, err := pk.ReadNBytes(data, 256*4)
// if err != nil {
// return nil, fmt.Errorf("read Biomes fail: %v", err)
// }
// }
// //throw BlockLight data
// _, err = pk.ReadNBytes(data, 2048)
// if err != nil {
// return nil, fmt.Errorf("read BlockLight fail: %v", err)
// }
// // fmt.Println(c)
// return &c, nil
// }
// if hasSkyLight {
// //throw SkyLight data
// _, err = pk.ReadNBytes(data, 2048)
// if err != nil {
// return nil, fmt.Errorf("read SkyLight fail: %v", err)
// }
// }
// }
// }
// if isFull { //need recive Biomes datas
// _, err := pk.ReadNBytes(data, 256*4)
// if err != nil {
// return nil, fmt.Errorf("read Biomes fail: %v", err)
// }
// }
// fmt.Println(c)
return &c, nil
}
// const defaultBitsPerBlock = 14

View File

@ -1,29 +1,33 @@
package world
// //World record all of the things in the world where player at
// type world struct {
// Entities map[int32]Entity
// chunks map[chunkLoc]*Chunk
// }
import (
"github.com/Tnze/go-mc/bot/world/entity"
)
// //Chunk store a 256*16*16 clolumn blocks
// type Chunk struct {
// sections [16]Section
// }
//World record all of the things in the world where player at
type World struct {
Entities map[int32]entity.Entity
Chunks map[ChunkLoc]*Chunk
}
// //Section store a 16*16*16 cube blocks
// type Section struct {
// blocks [16][16][16]Block
// }
//Chunk store a 256*16*16 clolumn blocks
type Chunk struct {
sections [16]Section
}
// //Block is the base of world
// type Block struct {
// id uint
// }
//Section store a 16*16*16 cube blocks
type Section struct {
blocks [16][16][16]Block
}
// type chunkLoc struct {
// X, Y int
// }
//Block is the base of world
type Block struct {
id uint
}
type ChunkLoc struct {
X, Z int
}
// //Entity 表示一个实体
// type Entity interface {

View File

@ -16,6 +16,7 @@ var (
func main() {
c = bot.NewClient()
//Login
err := c.JoinServer("localhost", 25565)
if err != nil {

0
go.sum
View File

View File

@ -2,8 +2,9 @@ package packet
import (
"io"
"io/ioutil"
"math"
"github.com/Tnze/go-mc/nbt"
)
// A Field is both FieldEncoder and FieldDecoder
@ -70,6 +71,11 @@ type (
//UUID encoded as an unsigned 128-bit integer
UUID [16]byte
//NBT encode a value as Named Binary Tag
NBT struct {
V interface{}
}
)
//ReadNBytes read N bytes from bytes.Reader
@ -344,22 +350,7 @@ func (d *Double) Decode(r DecodeReader) error {
return nil
}
// The PluginMessageData only used in recive PluginMessage packet.
// When decode it, read to end.
type PluginMessageData []byte
//Encode a PluginMessageData
func (p *PluginMessageData) Encode(r io.Writer) error {
_, err := r.Write([]byte(*p))
return err
}
//Decode a PluginMessageData
func (p *PluginMessageData) Decode(r DecodeReader) error {
data, err := ioutil.ReadAll(r)
if err != nil {
return err
}
*p = PluginMessageData(data)
return nil
// Decode a NBT
func (n NBT) Decode(r DecodeReader) error {
return nbt.NewDecoder(r).Decode(&n.V)
}