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

View File

@ -3,10 +3,13 @@ package bot
import ( import (
"bytes" "bytes"
"errors" "errors"
"io"
"io/ioutil"
// "math" // "math"
// "time" // "time"
"fmt" "fmt"
"github.com/Tnze/go-mc/bot/world"
"github.com/Tnze/go-mc/bot/world/entity" "github.com/Tnze/go-mc/bot/world/entity"
"github.com/Tnze/go-mc/chat" "github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data" "github.com/Tnze/go-mc/data"
@ -82,7 +85,7 @@ func (c *Client) handlePacket(p pk.Packet) (disconnect bool, err error) {
case data.HeldItemChangeClientbound: case data.HeldItemChangeClientbound:
err = handleHeldItemPacket(c, p) err = handleHeldItemPacket(c, p)
case data.ChunkData: case data.ChunkData:
////err = handleChunkDataPacket(c, p) err = handleChunkDataPacket(c, p)
case data.PlayerPositionAndLookClientbound: case data.PlayerPositionAndLookClientbound:
err = handlePlayerPositionAndLookPacket(c, p) err = handlePlayerPositionAndLookPacket(c, p)
sendPlayerPositionAndLookPacket(c) // to confirm the position sendPlayerPositionAndLookPacket(c) // to confirm the position
@ -345,10 +348,30 @@ func handleJoinGamePacket(c *Client, p pk.Packet) error {
return nil 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 { func handlePluginPacket(c *Client, p pk.Packet) error {
var ( var (
Channel pk.Identifier Channel pk.Identifier
Data pk.PluginMessageData Data pluginMessageData
) )
if err := p.Scan(&Channel, &Data); err != nil { if err := p.Scan(&Channel, &Data); err != nil {
return err return err
@ -405,15 +428,15 @@ func handleHeldItemPacket(c *Client, p pk.Packet) error {
return nil return nil
} }
// func handleChunkDataPacket(g *Client, p pk.Packet) error { func handleChunkDataPacket(c *Client, p pk.Packet) error {
// if !g.settings.ReciveMap { if !c.settings.ReciveMap {
// return nil return nil
// } }
// c, x, y, err := unpackChunkDataPacket(p, g.Info.Dimension == 0) chunk, x, z, err := world.UnpackChunkDataPacket(p, c.Dimension == 0)
// g.wd.chunks[chunkLoc{x, y}] = c c.Wd.Chunks[world.ChunkLoc{x, z}] = chunk
// return err return err
// } }
// var isSpawn bool // var isSpawn bool

View File

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

View File

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

View File

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

0
go.sum
View File

View File

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