Fix other code for compatible with new go-mc/net packet
This commit is contained in:
@ -294,22 +294,16 @@ func handleEntityStatusPacket(c *Client, p pk.Packet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleDestroyEntitiesPacket(c *Client, p pk.Packet) error {
|
func handleDestroyEntitiesPacket(c *Client, p pk.Packet) error {
|
||||||
var (
|
var count pk.VarInt
|
||||||
count pk.VarInt
|
var data = pk.Ary{
|
||||||
r = bytes.NewReader(p.Data)
|
Len: &count,
|
||||||
)
|
Ary: []pk.VarInt{},
|
||||||
if err := count.Decode(r); err != nil {
|
}
|
||||||
|
if err := p.Scan(&count, &data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
entities := make([]pk.VarInt, int(count))
|
return c.Wd.OnEntityDestroy(data.Ary.([]pk.VarInt))
|
||||||
for i := 0; i < int(count); i++ {
|
|
||||||
if err := entities[i].Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Wd.OnEntityDestroy(entities)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSoundEffect(c *Client, p pk.Packet) error {
|
func handleSoundEffect(c *Client, p pk.Packet) error {
|
||||||
@ -378,34 +372,24 @@ func handleMultiBlockChangePacket(c *Client, p pk.Packet) error {
|
|||||||
if !c.settings.ReceiveMap {
|
if !c.settings.ReceiveMap {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
r := bytes.NewReader(p.Data)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
loc pk.Long
|
loc pk.Long
|
||||||
dontTrustEdges pk.Boolean
|
dontTrustEdges pk.Boolean
|
||||||
sz pk.VarInt
|
sz pk.VarInt
|
||||||
|
packedBlocks = pk.Ary{
|
||||||
|
Len: &sz,
|
||||||
|
Ary: []pk.VarLong{},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
err := p.Scan(&loc, &dontTrustEdges, &sz, &packedBlocks)
|
||||||
if err := loc.Decode(r); err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("packed location: %v", err)
|
return err
|
||||||
}
|
|
||||||
if err := dontTrustEdges.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("unknown 1: %v", err)
|
|
||||||
}
|
|
||||||
if err := sz.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("array size: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packedBlocks := make([]pk.VarLong, int(sz))
|
x := int((loc >> 42) & ((1 << 22) - 1))
|
||||||
for i := 0; i < int(sz); i++ {
|
y := int((loc >> 20) & ((1 << 22) - 1))
|
||||||
if err := packedBlocks[i].Decode(r); err != nil {
|
z := int(loc & ((1 << 20) - 1))
|
||||||
return fmt.Errorf("block[%d]: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x, z, y := int((loc>>42)&((1<<22)-1)),
|
|
||||||
int((loc>>20)&((1<<22)-1)),
|
|
||||||
int(loc&((1<<20)-1))
|
|
||||||
|
|
||||||
// Apply transform into negative (these numbers are signed)
|
// Apply transform into negative (these numbers are signed)
|
||||||
if x >= 1<<21 {
|
if x >= 1<<21 {
|
||||||
@ -415,7 +399,7 @@ func handleMultiBlockChangePacket(c *Client, p pk.Packet) error {
|
|||||||
z -= 1 << 22
|
z -= 1 << 22
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Wd.MultiBlockUpdate(world.ChunkLoc{X: x, Z: z}, y, packedBlocks)
|
c.Wd.MultiBlockUpdate(world.ChunkLoc{X: x, Z: z}, y, packedBlocks.Ary.([]pk.VarLong))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,14 +504,14 @@ func handlePluginPacket(c *Client, p pk.Packet) error {
|
|||||||
switch msg.Channel {
|
switch msg.Channel {
|
||||||
case "minecraft:brand":
|
case "minecraft:brand":
|
||||||
var brandRaw pk.String
|
var brandRaw pk.String
|
||||||
if err := brandRaw.Decode(bytes.NewReader(msg.Data)); err != nil {
|
if _, err := brandRaw.ReadFrom(bytes.NewReader(msg.Data)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.ServInfo.Brand = string(brandRaw)
|
c.ServInfo.Brand = string(brandRaw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Events.PluginMessage != nil {
|
if c.Events.PluginMessage != nil {
|
||||||
return c.Events.PluginMessage(string(msg.Channel), []byte(msg.Data))
|
return c.Events.PluginMessage(string(msg.Channel), msg.Data)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -622,7 +606,7 @@ func handleChunkDataPacket(c *Client, p pk.Packet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pkt ptypes.ChunkData
|
var pkt ptypes.ChunkData
|
||||||
if err := pkt.Decode(p); err != nil {
|
if _, err := pkt.ReadFrom(bytes.NewReader(p.Data)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,7 +625,7 @@ func handleChunkDataPacket(c *Client, p pk.Packet) error {
|
|||||||
|
|
||||||
func handleTileEntityDataPacket(c *Client, p pk.Packet) error {
|
func handleTileEntityDataPacket(c *Client, p pk.Packet) error {
|
||||||
var pkt ptypes.TileEntityData
|
var pkt ptypes.TileEntityData
|
||||||
if err := pkt.Decode(p); err != nil {
|
if _, err := pkt.ReadFrom(bytes.NewReader(p.Data)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.Wd.TileEntityUpdate(pkt)
|
return c.Wd.TileEntityUpdate(pkt)
|
||||||
@ -712,7 +696,7 @@ func handleKeepAlivePacket(c *Client, p pk.Packet) error {
|
|||||||
|
|
||||||
func handleWindowItemsPacket(c *Client, p pk.Packet) error {
|
func handleWindowItemsPacket(c *Client, p pk.Packet) error {
|
||||||
var pkt ptypes.WindowItems
|
var pkt ptypes.WindowItems
|
||||||
if err := pkt.Decode(p); err != nil {
|
if _, err := pkt.ReadFrom(bytes.NewReader(p.Data)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
bot/login.go
49
bot/login.go
@ -62,34 +62,12 @@ type encryptionRequest struct {
|
|||||||
VerifyToken []byte
|
VerifyToken []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *encryptionRequest) Decode(r pk.DecodeReader) error {
|
func (e *encryptionRequest) ReadFrom(r io.Reader) (int64, error) {
|
||||||
var serverID pk.String
|
return pk.Tuple{
|
||||||
if err := serverID.Decode(r); err != nil {
|
(*pk.String)(&e.ServerID),
|
||||||
return err
|
(*pk.ByteArray)(&e.PublicKey),
|
||||||
}
|
(*pk.ByteArray)(&e.VerifyToken),
|
||||||
|
}.ReadFrom(r)
|
||||||
var publicKeyLength, verifyTokenLength pk.VarInt
|
|
||||||
|
|
||||||
if err := publicKeyLength.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
publicKey, err := pk.ReadNBytes(r, int(publicKeyLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := verifyTokenLength.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
verifyToken, err := pk.ReadNBytes(r, int(verifyTokenLength))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
e.ServerID = string(serverID)
|
|
||||||
e.PublicKey = publicKey
|
|
||||||
e.VerifyToken = verifyToken
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// authDigest computes a special SHA-1 digest required for Minecraft web
|
// authDigest computes a special SHA-1 digest required for Minecraft web
|
||||||
@ -216,14 +194,9 @@ func genEncryptionKeyResponse(shareSecret, publicKey, verifyToken []byte) (erp p
|
|||||||
err = fmt.Errorf("encryption verfy tokenfail: %v", err)
|
err = fmt.Errorf("encryption verfy tokenfail: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var data []byte
|
return pk.Marshal(
|
||||||
data = append(data, pk.VarInt(int32(len(cryptPK))).Encode()...)
|
0x01,
|
||||||
data = append(data, cryptPK...)
|
pk.ByteArray(cryptPK),
|
||||||
data = append(data, pk.VarInt(int32(len(verifyT))).Encode()...)
|
pk.ByteArray(verifyT),
|
||||||
data = append(data, verifyT...)
|
), nil
|
||||||
erp = pk.Packet{
|
|
||||||
ID: 0x01,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package world
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/data/block"
|
"github.com/Tnze/go-mc/data/block"
|
||||||
@ -41,13 +42,13 @@ func perBits(bpb byte) uint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSection(data pk.DecodeReader) (s Section, err error) {
|
func readSection(data io.Reader) (s Section, err error) {
|
||||||
var nonAirBlockCount pk.Short
|
var nonAirBlockCount pk.Short
|
||||||
if err := nonAirBlockCount.Decode(data); err != nil {
|
if _, err := nonAirBlockCount.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("block count: %w", err)
|
return nil, fmt.Errorf("block count: %w", err)
|
||||||
}
|
}
|
||||||
var bpb pk.UnsignedByte
|
var bpb pk.UnsignedByte
|
||||||
if err := bpb.Decode(data); err != nil {
|
if _, err := bpb.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("bits per block: %w", err)
|
return nil, fmt.Errorf("bits per block: %w", err)
|
||||||
}
|
}
|
||||||
// If bpb values greater than or equal to 9, use directSection.
|
// If bpb values greater than or equal to 9, use directSection.
|
||||||
@ -57,14 +58,14 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
if bpb <= maxPaletteBits {
|
if bpb <= maxPaletteBits {
|
||||||
// read palettes
|
// read palettes
|
||||||
var length pk.VarInt
|
var length pk.VarInt
|
||||||
if err := length.Decode(data); err != nil {
|
if _, err := length.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("palette length: %w", err)
|
return nil, fmt.Errorf("palette length: %w", err)
|
||||||
}
|
}
|
||||||
palettes = make([]BlockStatus, length)
|
palettes = make([]BlockStatus, length)
|
||||||
palettesIndex = make(map[BlockStatus]int, length)
|
palettesIndex = make(map[BlockStatus]int, length)
|
||||||
for i := 0; i < int(length); i++ {
|
for i := 0; i < int(length); i++ {
|
||||||
var v pk.VarInt
|
var v pk.VarInt
|
||||||
if err := v.Decode(data); err != nil {
|
if _, err := v.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("read palettes[%d] error: %w", i, err)
|
return nil, fmt.Errorf("read palettes[%d] error: %w", i, err)
|
||||||
}
|
}
|
||||||
palettes[i] = BlockStatus(v)
|
palettes[i] = BlockStatus(v)
|
||||||
@ -74,7 +75,7 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
|
|
||||||
// read data array
|
// read data array
|
||||||
var dataLen pk.VarInt
|
var dataLen pk.VarInt
|
||||||
if err := dataLen.Decode(data); err != nil {
|
if _, err := dataLen.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("read data array length error: %w", err)
|
return nil, fmt.Errorf("read data array length error: %w", err)
|
||||||
}
|
}
|
||||||
if int(dataLen) < 16*16*16*int(bpb)/64 {
|
if int(dataLen) < 16*16*16*int(bpb)/64 {
|
||||||
@ -83,7 +84,7 @@ func readSection(data pk.DecodeReader) (s Section, err error) {
|
|||||||
dataArray := make([]uint64, dataLen)
|
dataArray := make([]uint64, dataLen)
|
||||||
for i := 0; i < int(dataLen); i++ {
|
for i := 0; i < int(dataLen); i++ {
|
||||||
var v pk.Long
|
var v pk.Long
|
||||||
if err := v.Decode(data); err != nil {
|
if _, err := v.ReadFrom(data); err != nil {
|
||||||
return nil, fmt.Errorf("read dataArray[%d] error: %w", i, err)
|
return nil, fmt.Errorf("read dataArray[%d] error: %w", i, err)
|
||||||
}
|
}
|
||||||
dataArray[i] = uint64(v)
|
dataArray[i] = uint64(v)
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package entity
|
package entity
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"io"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/data/entity"
|
"github.com/Tnze/go-mc/data/entity"
|
||||||
item "github.com/Tnze/go-mc/data/item"
|
item "github.com/Tnze/go-mc/data/item"
|
||||||
"github.com/Tnze/go-mc/nbt"
|
|
||||||
pk "github.com/Tnze/go-mc/net/packet"
|
pk "github.com/Tnze/go-mc/net/packet"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
@ -49,53 +48,48 @@ type Slot struct {
|
|||||||
Present bool
|
Present bool
|
||||||
ItemID item.ID
|
ItemID item.ID
|
||||||
Count int8
|
Count int8
|
||||||
NBT interface{}
|
NBT pk.NBT
|
||||||
|
}
|
||||||
|
|
||||||
|
type SlotNBT struct {
|
||||||
|
data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode implement packet.FieldDecoder interface
|
//Decode implement packet.FieldDecoder interface
|
||||||
func (s *Slot) Decode(r pk.DecodeReader) error {
|
func (s *Slot) ReadFrom(r io.Reader) (int64, error) {
|
||||||
if err := (*pk.Boolean)(&s.Present).Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if s.Present {
|
|
||||||
var itemID pk.VarInt
|
var itemID pk.VarInt
|
||||||
if err := itemID.Decode(r); err != nil {
|
n, err := pk.Tuple{
|
||||||
return err
|
(*pk.Boolean)(&s.Present),
|
||||||
|
pk.Opt{
|
||||||
|
Has: (*pk.Boolean)(&s.Present),
|
||||||
|
Field: pk.Tuple{
|
||||||
|
&itemID,
|
||||||
|
(*pk.Byte)(&s.Count),
|
||||||
|
&s.NBT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
}
|
}
|
||||||
s.ItemID = item.ID(itemID)
|
s.ItemID = item.ID(itemID)
|
||||||
if err := (*pk.Byte)(&s.Count).Decode(r); err != nil {
|
return n, nil
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := nbt.NewDecoder(r).Decode(&s.NBT); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Slot) Encode() []byte {
|
func (s Slot) WriteTo(w io.Writer) (int64, error) {
|
||||||
if !s.Present {
|
return pk.Tuple{
|
||||||
return pk.Boolean(false).Encode()
|
pk.Boolean(s.Present),
|
||||||
}
|
pk.Opt{
|
||||||
|
Has: (*pk.Boolean)(&s.Present),
|
||||||
var b bytes.Buffer
|
Field: pk.Tuple{
|
||||||
b.Write(pk.Boolean(true).Encode())
|
pk.VarInt(s.ItemID),
|
||||||
b.Write(pk.VarInt(s.ItemID).Encode())
|
pk.Byte(s.Count),
|
||||||
b.Write(pk.Byte(s.Count).Encode())
|
s.NBT,
|
||||||
|
},
|
||||||
if s.NBT != nil {
|
},
|
||||||
if err := nbt.NewEncoder(&b).Encode(s.NBT); err != nil {
|
}.WriteTo(w)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if _, err := b.Write([]byte{nbt.TagEnd}); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.Bytes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Slot) String() string {
|
func (s Slot) String() string {
|
||||||
return item.ByID[item.ID(s.ItemID)].DisplayName
|
return item.ByID[s.ItemID].DisplayName
|
||||||
}
|
}
|
||||||
|
@ -51,22 +51,23 @@ func (m *Message) UnmarshalJSON(jsonMsg []byte) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Decode for a ChatMsg packet
|
//Decode for a ChatMsg packet
|
||||||
func (m *Message) Decode(r pk.DecodeReader) error {
|
func (m *Message) ReadFrom(r io.Reader) (int64, error) {
|
||||||
var Len pk.VarInt
|
var Len pk.VarInt
|
||||||
if err := Len.Decode(r); err != nil {
|
if n, err := Len.ReadFrom(r); err != nil {
|
||||||
return err
|
return n, err
|
||||||
}
|
}
|
||||||
|
lr := &io.LimitedReader{R: r, N: int64(Len)}
|
||||||
return json.NewDecoder(io.LimitReader(r, int64(Len))).Decode(m)
|
err := json.NewDecoder(lr).Decode(m)
|
||||||
|
return int64(Len) - lr.N, err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode for a ChatMsg packet
|
//Encode for a ChatMsg packet
|
||||||
func (m Message) Encode() []byte {
|
func (m Message) WriteTo(w io.Writer) (int64, error) {
|
||||||
code, err := json.Marshal(m)
|
code, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return pk.String(code).Encode()
|
return pk.String(code).WriteTo(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) Append(extraMsg ...Message) {
|
func (m *Message) Append(extraMsg ...Message) {
|
||||||
|
@ -101,10 +101,11 @@ func TestChatMsgClearString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMessage_Encode(t *testing.T) {
|
func TestMessage_Encode(t *testing.T) {
|
||||||
codeMsg := chat.Message{Translate: "multiplayer.disconnect.server_full"}.Encode()
|
var codeMsg bytes.Buffer
|
||||||
|
_, _ = chat.Message{Translate: "multiplayer.disconnect.server_full"}.WriteTo(&codeMsg)
|
||||||
|
|
||||||
var msg pk.Chat
|
var msg pk.Chat
|
||||||
if err := msg.Decode(bytes.NewReader(codeMsg)); err != nil {
|
if _, err := msg.ReadFrom(&codeMsg); err != nil {
|
||||||
t.Errorf("decode message fail: %v", err)
|
t.Errorf("decode message fail: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ func onPluginMessage(channel string, data []byte) error {
|
|||||||
switch channel {
|
switch channel {
|
||||||
case "minecraft:brand":
|
case "minecraft:brand":
|
||||||
var brand pk.String
|
var brand pk.String
|
||||||
if err := brand.Decode(bytes.NewReader(data)); err != nil {
|
if _, err := brand.ReadFrom(bytes.NewReader(data)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Println("Server brand is:", brand)
|
log.Println("Server brand is:", brand)
|
||||||
|
@ -85,8 +85,7 @@ func (c *Conn) ReadPacket(p *pk.Packet) error {
|
|||||||
|
|
||||||
//WritePacket write a Packet to Conn.
|
//WritePacket write a Packet to Conn.
|
||||||
func (c *Conn) WritePacket(p pk.Packet) error {
|
func (c *Conn) WritePacket(p pk.Packet) error {
|
||||||
_, err := c.Write(p.Pack(c.threshold))
|
return p.Pack(c, c.threshold)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCipher load the decode/encode stream to this Conn
|
// SetCipher load the decode/encode stream to this Conn
|
||||||
|
@ -8,7 +8,10 @@ type Builder struct {
|
|||||||
|
|
||||||
func (p *Builder) WriteField(fields ...FieldEncoder) {
|
func (p *Builder) WriteField(fields ...FieldEncoder) {
|
||||||
for _, f := range fields {
|
for _, f := range fields {
|
||||||
p.buf.Write(f.Encode())
|
_, err := f.WriteTo(&p.buf)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,20 +15,18 @@ type Packet struct {
|
|||||||
|
|
||||||
//Marshal generate Packet with the ID and Fields
|
//Marshal generate Packet with the ID and Fields
|
||||||
func Marshal(id int32, fields ...FieldEncoder) (pk Packet) {
|
func Marshal(id int32, fields ...FieldEncoder) (pk Packet) {
|
||||||
pk.ID = id
|
var pb Builder
|
||||||
|
|
||||||
for _, v := range fields {
|
for _, v := range fields {
|
||||||
pk.Data = append(pk.Data, v.Encode()...)
|
pb.WriteField(v)
|
||||||
}
|
}
|
||||||
|
return pb.Packet(id)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Scan decode the packet and fill data into fields
|
//Scan decode the packet and fill data into fields
|
||||||
func (p Packet) Scan(fields ...FieldDecoder) error {
|
func (p Packet) Scan(fields ...FieldDecoder) error {
|
||||||
r := bytes.NewReader(p.Data)
|
r := bytes.NewReader(p.Data)
|
||||||
for _, v := range fields {
|
for _, v := range fields {
|
||||||
err := v.Decode(r)
|
_, err := v.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -37,34 +35,48 @@ func (p Packet) Scan(fields ...FieldDecoder) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pack 打包一个数据包
|
// Pack 打包一个数据包
|
||||||
func (p *Packet) Pack(threshold int) (pack []byte) {
|
func (p *Packet) Pack(w io.Writer, threshold int) error {
|
||||||
d := append(VarInt(p.ID).Encode(), p.Data...)
|
var content bytes.Buffer
|
||||||
|
if _, err := VarInt(p.ID).WriteTo(&content); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if _, err := content.Write(p.Data); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
if threshold > 0 { //是否启用了压缩
|
if threshold > 0 { //是否启用了压缩
|
||||||
if len(d) > threshold { //是否需要压缩
|
Len := content.Len()
|
||||||
Len := len(d)
|
var VarLen bytes.Buffer
|
||||||
VarLen := VarInt(Len).Encode()
|
if _, err := VarInt(Len).WriteTo(&VarLen); err != nil {
|
||||||
d = compress(d)
|
panic(err)
|
||||||
|
}
|
||||||
pack = append(pack, VarInt(len(VarLen)+len(d)).Encode()...)
|
if _, err := VarInt(VarLen.Len() + Len).WriteTo(w); err != nil {
|
||||||
pack = append(pack, VarLen...)
|
return err
|
||||||
pack = append(pack, d...)
|
}
|
||||||
} else {
|
if Len > threshold { //是否需要压缩
|
||||||
pack = append(pack, VarInt(int32(len(d)+1)).Encode()...)
|
compress(&content)
|
||||||
pack = append(pack, 0x00)
|
}
|
||||||
pack = append(pack, d...)
|
if _, err := VarLen.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := content.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pack = append(pack, VarInt(int32(len(d))).Encode()...) //len
|
if _, err := VarInt(content.Len()).WriteTo(w); err != nil {
|
||||||
pack = append(pack, d...)
|
return err
|
||||||
|
}
|
||||||
|
if _, err := content.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnPack in-place decompression a packet
|
// UnPack in-place decompression a packet
|
||||||
func (p *Packet) UnPack(r DecodeReader, threshold int) error {
|
func (p *Packet) UnPack(r io.Reader, threshold int) error {
|
||||||
var length VarInt
|
var length VarInt
|
||||||
if err := length.Decode(r); err != nil {
|
if _, err := length.ReadFrom(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if length < 1 {
|
if length < 1 {
|
||||||
@ -84,7 +96,7 @@ func (p *Packet) UnPack(r DecodeReader, threshold int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var packetID VarInt
|
var packetID VarInt
|
||||||
if err := packetID.Decode(buf); err != nil {
|
if _, err := packetID.ReadFrom(buf); err != nil {
|
||||||
return fmt.Errorf("read packet id fail: %v", err)
|
return fmt.Errorf("read packet id fail: %v", err)
|
||||||
}
|
}
|
||||||
p.ID = int32(packetID)
|
p.ID = int32(packetID)
|
||||||
@ -97,7 +109,7 @@ func unCompress(data *bytes.Buffer) error {
|
|||||||
reader := bytes.NewReader(data.Bytes())
|
reader := bytes.NewReader(data.Bytes())
|
||||||
|
|
||||||
var sizeUncompressed VarInt
|
var sizeUncompressed VarInt
|
||||||
if err := sizeUncompressed.Decode(reader); err != nil {
|
if _, err := sizeUncompressed.ReadFrom(reader); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,14 +133,15 @@ func unCompress(data *bytes.Buffer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compress 压缩数据
|
// compress 压缩数据
|
||||||
func compress(data []byte) []byte {
|
func compress(data *bytes.Buffer) {
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
w := zlib.NewWriter(&b)
|
w := zlib.NewWriter(&b)
|
||||||
if _, err := w.Write(data); err != nil {
|
if _, err := data.WriteTo(w); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return b.Bytes()
|
*data = b
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,15 @@ var PackedVarInts = [][]byte{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPackVarInt(t *testing.T) {
|
func TestPackVarInt(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
for i, v := range VarInts {
|
for i, v := range VarInts {
|
||||||
p := v.Encode()
|
buf.Reset()
|
||||||
if !bytes.Equal(p, PackedVarInts[i]) {
|
if n, err := v.WriteTo(&buf); err != nil {
|
||||||
|
t.Fatalf("Write to bytes.Buffer should never fail: %v", err)
|
||||||
|
} else if n != int64(buf.Len()) {
|
||||||
|
t.Errorf("Number of byte returned by WriteTo should equal to buffer.Len()")
|
||||||
|
}
|
||||||
|
if p := buf.Bytes(); !bytes.Equal(p, PackedVarInts[i]) {
|
||||||
t.Errorf("pack int %d should be \"% x\", get \"% x\"", v, PackedVarInts[i], p)
|
t.Errorf("pack int %d should be \"% x\", get \"% x\"", v, PackedVarInts[i], p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +36,7 @@ func TestPackVarInt(t *testing.T) {
|
|||||||
func TestUnpackVarInt(t *testing.T) {
|
func TestUnpackVarInt(t *testing.T) {
|
||||||
for i, v := range PackedVarInts {
|
for i, v := range PackedVarInts {
|
||||||
var vi VarInt
|
var vi VarInt
|
||||||
if err := vi.Decode(bytes.NewReader(v)); err != nil {
|
if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil {
|
||||||
t.Errorf("unpack \"% x\" error: %v", v, err)
|
t.Errorf("unpack \"% x\" error: %v", v, err)
|
||||||
}
|
}
|
||||||
if vi != VarInts[i] {
|
if vi != VarInts[i] {
|
||||||
@ -42,7 +48,7 @@ func TestUnpackVarInt(t *testing.T) {
|
|||||||
func TestUnpackVarInt_TooLongData(t *testing.T) {
|
func TestUnpackVarInt_TooLongData(t *testing.T) {
|
||||||
var vi VarInt
|
var vi VarInt
|
||||||
var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
|
var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
|
||||||
if err := vi.Decode(bytes.NewReader(data)); err != nil {
|
if _, err := vi.ReadFrom(bytes.NewReader(data)); err != nil {
|
||||||
t.Logf("unpack \"% x\" error: %v", data, err)
|
t.Logf("unpack \"% x\" error: %v", data, err)
|
||||||
} else {
|
} else {
|
||||||
t.Errorf("unpack \"% x\" should be error, get %d", data, vi)
|
t.Errorf("unpack \"% x\" should be error, get %d", data, vi)
|
||||||
@ -76,7 +82,7 @@ func TestPackVarLong(t *testing.T) {
|
|||||||
func TestUnpackVarLong(t *testing.T) {
|
func TestUnpackVarLong(t *testing.T) {
|
||||||
for i, v := range PackedVarLongs {
|
for i, v := range PackedVarLongs {
|
||||||
var vi VarLong
|
var vi VarLong
|
||||||
if err := vi.Decode(bytes.NewReader(v)); err != nil {
|
if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil {
|
||||||
t.Errorf("unpack \"% x\" error: %v", v, err)
|
t.Errorf("unpack \"% x\" error: %v", v, err)
|
||||||
}
|
}
|
||||||
if vi != VarLongs[i] {
|
if vi != VarLongs[i] {
|
||||||
|
@ -18,20 +18,10 @@ type Field interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A FieldEncoder can be encode as minecraft protocol used.
|
// A FieldEncoder can be encode as minecraft protocol used.
|
||||||
type FieldEncoder interface {
|
type FieldEncoder io.WriterTo
|
||||||
Encode() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// A FieldDecoder can Decode from minecraft protocol
|
// A FieldDecoder can Decode from minecraft protocol
|
||||||
type FieldDecoder interface {
|
type FieldDecoder io.ReaderFrom
|
||||||
Decode(r DecodeReader) error
|
|
||||||
}
|
|
||||||
|
|
||||||
//DecodeReader is both io.Reader and io.ByteReader
|
|
||||||
type DecodeReader interface {
|
|
||||||
io.ByteReader
|
|
||||||
io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
//Boolean of True is encoded as 0x01, false as 0x00.
|
//Boolean of True is encoded as 0x01, false as 0x00.
|
||||||
@ -71,7 +61,7 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Angle is rotation angle in steps of 1/256 of a full turn
|
//Angle is rotation angle in steps of 1/256 of a full turn
|
||||||
Angle int8
|
Angle Byte
|
||||||
|
|
||||||
//UUID encoded as an unsigned 128-bit integer
|
//UUID encoded as an unsigned 128-bit integer
|
||||||
UUID uuid.UUID
|
UUID uuid.UUID
|
||||||
@ -86,174 +76,190 @@ type (
|
|||||||
ByteArray []byte
|
ByteArray []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
//ReadNBytes read N bytes from bytes.Reader
|
const MaxVarIntLen = 5
|
||||||
func ReadNBytes(r DecodeReader, n int) (bs []byte, err error) {
|
const MaxVarLongLen = 10
|
||||||
bs = make([]byte, n)
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
bs[i], err = r.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//Encode a Boolean
|
//Encode a Boolean
|
||||||
func (b Boolean) Encode() []byte {
|
func (b Boolean) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
var nn int
|
||||||
if b {
|
if b {
|
||||||
return []byte{0x01}
|
nn, err = w.Write([]byte{0x01})
|
||||||
}
|
}
|
||||||
return []byte{0x00}
|
nn, err = w.Write([]byte{0x00})
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a Boolean
|
//Decode a Boolean
|
||||||
func (b *Boolean) Decode(r DecodeReader) error {
|
func (b *Boolean) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
v, err := r.ReadByte()
|
v, err := readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
*b = Boolean(v != 0)
|
*b = v != 0
|
||||||
return nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a String
|
// Encode a String
|
||||||
func (s String) Encode() (p []byte) {
|
func (s String) WriteTo(w io.Writer) (int64, error) {
|
||||||
byteString := []byte(s)
|
byteStr := []byte(s)
|
||||||
p = append(p, VarInt(len(byteString)).Encode()...) //len
|
n1, err := VarInt(len(byteStr)).WriteTo(w)
|
||||||
p = append(p, byteString...) //data
|
if err != nil {
|
||||||
return
|
return n1, err
|
||||||
|
}
|
||||||
|
n2, err := w.Write(byteStr)
|
||||||
|
return n1 + int64(n2), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a String
|
//Decode a String
|
||||||
func (s *String) Decode(r DecodeReader) error {
|
func (s *String) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var l VarInt //String length
|
var l VarInt //String length
|
||||||
if err := l.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
bs, err := ReadNBytes(r, int(l))
|
nn, err := l.ReadFrom(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nn, err
|
||||||
}
|
}
|
||||||
|
n += nn
|
||||||
|
|
||||||
|
bs := make([]byte, l)
|
||||||
|
if _, err := io.ReadFull(r, bs); err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n += int64(l)
|
||||||
|
|
||||||
*s = String(bs)
|
*s = String(bs)
|
||||||
return nil
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readByte read one byte from io.Reader
|
||||||
|
func readByte(r io.Reader) (byte, error) {
|
||||||
|
if r, ok := r.(io.ByteReader); ok {
|
||||||
|
return r.ReadByte()
|
||||||
|
}
|
||||||
|
var v [1]byte
|
||||||
|
_, err := io.ReadFull(r, v[:])
|
||||||
|
return v[0], err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a Byte
|
//Encode a Byte
|
||||||
func (b Byte) Encode() []byte {
|
func (b Byte) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return []byte{byte(b)}
|
nn, err := w.Write([]byte{byte(b)})
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a Byte
|
//Decode a Byte
|
||||||
func (b *Byte) Decode(r DecodeReader) error {
|
func (b *Byte) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
v, err := r.ReadByte()
|
v, err := readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
*b = Byte(v)
|
*b = Byte(v)
|
||||||
return nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a UnsignedByte
|
//Encode a UnsignedByte
|
||||||
func (ub UnsignedByte) Encode() []byte {
|
func (u UnsignedByte) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return []byte{byte(ub)}
|
nn, err := w.Write([]byte{byte(u)})
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a UnsignedByte
|
//Decode a UnsignedByte
|
||||||
func (ub *UnsignedByte) Decode(r DecodeReader) error {
|
func (u *UnsignedByte) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
v, err := r.ReadByte()
|
v, err := readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
*ub = UnsignedByte(v)
|
*u = UnsignedByte(v)
|
||||||
return nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Signed Short
|
// Encode a Signed Short
|
||||||
func (s Short) Encode() []byte {
|
func (s Short) WriteTo(w io.Writer) (int64, error) {
|
||||||
n := uint16(s)
|
n := uint16(s)
|
||||||
return []byte{
|
nn, err := w.Write([]byte{byte(n >> 8), byte(n)})
|
||||||
byte(n >> 8),
|
return int64(nn), err
|
||||||
byte(n),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a Short
|
//Decode a Short
|
||||||
func (s *Short) Decode(r DecodeReader) error {
|
func (s *Short) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
bs, err := ReadNBytes(r, 2)
|
var bs [2]byte
|
||||||
if err != nil {
|
if nn, err := io.ReadFull(r, bs[:]); err != nil {
|
||||||
return err
|
return int64(nn), err
|
||||||
|
} else {
|
||||||
|
n += int64(nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
*s = Short(int16(bs[0])<<8 | int16(bs[1]))
|
*s = Short(int16(bs[0])<<8 | int16(bs[1]))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Unsigned Short
|
// Encode a Unsigned Short
|
||||||
func (us UnsignedShort) Encode() []byte {
|
func (us UnsignedShort) WriteTo(w io.Writer) (int64, error) {
|
||||||
n := uint16(us)
|
n := uint16(us)
|
||||||
return []byte{
|
nn, err := w.Write([]byte{byte(n >> 8), byte(n)})
|
||||||
byte(n >> 8),
|
return int64(nn), err
|
||||||
byte(n),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a UnsignedShort
|
//Decode a UnsignedShort
|
||||||
func (us *UnsignedShort) Decode(r DecodeReader) error {
|
func (us *UnsignedShort) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
bs, err := ReadNBytes(r, 2)
|
var bs [2]byte
|
||||||
if err != nil {
|
if nn, err := io.ReadFull(r, bs[:]); err != nil {
|
||||||
return err
|
return int64(nn), err
|
||||||
|
} else {
|
||||||
|
n += int64(nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
*us = UnsignedShort(int16(bs[0])<<8 | int16(bs[1]))
|
*us = UnsignedShort(int16(bs[0])<<8 | int16(bs[1]))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Int
|
// Encode a Int
|
||||||
func (i Int) Encode() []byte {
|
func (i Int) WriteTo(w io.Writer) (int64, error) {
|
||||||
n := uint32(i)
|
n := uint32(i)
|
||||||
return []byte{
|
nn, err := w.Write([]byte{byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)})
|
||||||
byte(n >> 24), byte(n >> 16),
|
return int64(nn), err
|
||||||
byte(n >> 8), byte(n),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a Int
|
//Decode a Int
|
||||||
func (i *Int) Decode(r DecodeReader) error {
|
func (i *Int) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
bs, err := ReadNBytes(r, 4)
|
var bs [4]byte
|
||||||
if err != nil {
|
if nn, err := io.ReadFull(r, bs[:]); err != nil {
|
||||||
return err
|
return int64(nn), err
|
||||||
|
} else {
|
||||||
|
n += int64(nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
*i = Int(int32(bs[0])<<24 | int32(bs[1])<<16 | int32(bs[2])<<8 | int32(bs[3]))
|
*i = Int(int32(bs[0])<<24 | int32(bs[1])<<16 | int32(bs[2])<<8 | int32(bs[3]))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Long
|
// Encode a Long
|
||||||
func (l Long) Encode() []byte {
|
func (l Long) WriteTo(w io.Writer) (int64, error) {
|
||||||
n := uint64(l)
|
n := uint64(l)
|
||||||
return []byte{
|
nn, err := w.Write([]byte{
|
||||||
byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32),
|
byte(n >> 56), byte(n >> 48), byte(n >> 40), byte(n >> 32),
|
||||||
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
|
byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
|
||||||
}
|
})
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a Long
|
//Decode a Long
|
||||||
func (l *Long) Decode(r DecodeReader) error {
|
func (l *Long) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
bs, err := ReadNBytes(r, 8)
|
var bs [8]byte
|
||||||
if err != nil {
|
if nn, err := io.ReadFull(r, bs[:]); err != nil {
|
||||||
return err
|
return int64(nn), err
|
||||||
|
} else {
|
||||||
|
n += int64(nn)
|
||||||
}
|
}
|
||||||
|
|
||||||
*l = Long(int64(bs[0])<<56 | int64(bs[1])<<48 | int64(bs[2])<<40 | int64(bs[3])<<32 |
|
*l = Long(int64(bs[0])<<56 | int64(bs[1])<<48 | int64(bs[2])<<40 | int64(bs[3])<<32 |
|
||||||
int64(bs[4])<<24 | int64(bs[5])<<16 | int64(bs[6])<<8 | int64(bs[7]))
|
int64(bs[4])<<24 | int64(bs[5])<<16 | int64(bs[6])<<8 | int64(bs[7]))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a VarInt
|
//Encode a VarInt
|
||||||
func (v VarInt) Encode() (vi []byte) {
|
func (v VarInt) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
var vi = make([]byte, 0, MaxVarIntLen)
|
||||||
num := uint32(v)
|
num := uint32(v)
|
||||||
for {
|
for {
|
||||||
b := num & 0x7F
|
b := num & 0x7F
|
||||||
@ -266,29 +272,28 @@ func (v VarInt) Encode() (vi []byte) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
nn, err := w.Write(vi)
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decode a VarInt
|
//Decode a VarInt
|
||||||
func (v *VarInt) Decode(r DecodeReader) error {
|
func (v *VarInt) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var n uint32
|
var V uint32
|
||||||
for i := 0; ; i++ { //读数据前的长度标记
|
for sec := byte(0x80); sec&0x80 != 0; n++ {
|
||||||
sec, err := r.ReadByte()
|
if n > MaxVarIntLen {
|
||||||
|
return n, errors.New("VarInt is too big")
|
||||||
|
}
|
||||||
|
|
||||||
|
sec, err = readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
n |= uint32(sec&0x7F) << uint32(7*i)
|
V |= uint32(sec&0x7F) << uint32(7*n)
|
||||||
|
|
||||||
if i >= 5 {
|
|
||||||
return errors.New("VarInt is too big")
|
|
||||||
} else if sec&0x80 == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*v = VarInt(n)
|
*v = VarInt(V)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a VarLong
|
//Encode a VarLong
|
||||||
@ -309,44 +314,44 @@ func (v VarLong) Encode() (vi []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Decode a VarLong
|
//Decode a VarLong
|
||||||
func (v *VarLong) Decode(r DecodeReader) error {
|
func (v *VarLong) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var n uint64
|
var V uint64
|
||||||
for i := 0; ; i++ { //读数据前的长度标记
|
for sec := byte(0x80); sec&0x80 != 0; n++ {
|
||||||
sec, err := r.ReadByte()
|
if n >= MaxVarLongLen {
|
||||||
|
return n, errors.New("VarLong is too big")
|
||||||
|
}
|
||||||
|
sec, err = readByte(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n |= uint64(sec&0x7F) << uint64(7*i)
|
V |= uint64(sec&0x7F) << uint64(7*n)
|
||||||
|
|
||||||
if i >= 10 {
|
|
||||||
return errors.New("VarLong is too big")
|
|
||||||
} else if sec&0x80 == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*v = VarLong(n)
|
*v = VarLong(V)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a Position
|
//Encode a Position
|
||||||
func (p Position) Encode() []byte {
|
func (p Position) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
b := make([]byte, 8)
|
var b [8]byte
|
||||||
position := uint64(p.X&0x3FFFFFF)<<38 | uint64((p.Z&0x3FFFFFF)<<12) | uint64(p.Y&0xFFF)
|
position := uint64(p.X&0x3FFFFFF)<<38 | uint64((p.Z&0x3FFFFFF)<<12) | uint64(p.Y&0xFFF)
|
||||||
for i := 7; i >= 0; i-- {
|
for i := 7; i >= 0; i-- {
|
||||||
b[i] = byte(position)
|
b[i] = byte(position)
|
||||||
position >>= 8
|
position >>= 8
|
||||||
}
|
}
|
||||||
return b
|
nn, err := w.Write(b[:])
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a Position
|
// Decode a Position
|
||||||
func (p *Position) Decode(r DecodeReader) error {
|
func (p *Position) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var v Long
|
var v Long
|
||||||
if err := v.Decode(r); err != nil {
|
nn, err := v.ReadFrom(r)
|
||||||
return err
|
if err != nil {
|
||||||
|
return nn, err
|
||||||
}
|
}
|
||||||
|
n += nn
|
||||||
|
|
||||||
x := int(v >> 38)
|
x := int(v >> 38)
|
||||||
y := int(v & 0xFFF)
|
y := int(v & 0xFFF)
|
||||||
@ -364,88 +369,111 @@ func (p *Position) Decode(r DecodeReader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.X, p.Y, p.Z = x, y, z
|
p.X, p.Y, p.Z = x, y, z
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decodes an Angle
|
// ToDeg convert Angle to Degree
|
||||||
func (b *Angle) Decode(r DecodeReader) error {
|
func (a Angle) ToDeg() float64 {
|
||||||
v, err := r.ReadByte()
|
return 360 * float64(a) / 256
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
// ToRad convert Angle to Radian
|
||||||
*b = Angle(v)
|
func (a Angle) ToRad() float64 {
|
||||||
return nil
|
return 2 * math.Pi * float64(a) / 256
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Angle) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
return Byte(a).WriteTo(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Angle) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
return (*Byte)(a).ReadFrom(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a Float
|
//Encode a Float
|
||||||
func (f Float) Encode() []byte {
|
func (f Float) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return Int(math.Float32bits(float32(f))).Encode()
|
return Int(math.Float32bits(float32(f))).WriteTo(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a Float
|
// Decode a Float
|
||||||
func (f *Float) Decode(r DecodeReader) error {
|
func (f *Float) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var v Int
|
var v Int
|
||||||
if err := v.Decode(r); err != nil {
|
|
||||||
return err
|
n, err = v.ReadFrom(r)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
*f = Float(math.Float32frombits(uint32(v)))
|
*f = Float(math.Float32frombits(uint32(v)))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encode a Double
|
//Encode a Double
|
||||||
func (d Double) Encode() []byte {
|
func (d Double) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return Long(math.Float64bits(float64(d))).Encode()
|
return Long(math.Float64bits(float64(d))).WriteTo(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a Double
|
// Decode a Double
|
||||||
func (d *Double) Decode(r DecodeReader) error {
|
func (d *Double) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var v Long
|
var v Long
|
||||||
if err := v.Decode(r); err != nil {
|
n, err = v.ReadFrom(r)
|
||||||
return err
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
*d = Double(math.Float64frombits(uint64(v)))
|
*d = Double(math.Float64frombits(uint64(v)))
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a NBT
|
// Encode a NBT
|
||||||
func (n NBT) Encode() []byte {
|
func (n *NBT) WriteTo(w io.Writer) (int64, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := nbt.NewEncoder(&buf).Encode(n.V); err != nil {
|
if err := nbt.NewEncoder(&buf).Encode(n.V); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.WriteTo(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a NBT
|
// Decode a NBT
|
||||||
func (n NBT) Decode(r DecodeReader) error {
|
func (n *NBT) ReadFrom(r io.Reader) (int64, error) {
|
||||||
return nbt.NewDecoder(r).Decode(n.V)
|
// LimitReader is used to count reader length
|
||||||
|
lr := &io.LimitedReader{R: r, N: math.MaxInt64}
|
||||||
|
err := nbt.NewDecoder(lr).Decode(n.V)
|
||||||
|
return math.MaxInt64 - lr.N, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a ByteArray
|
// Encode a ByteArray
|
||||||
func (b ByteArray) Encode() []byte {
|
func (b ByteArray) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return append(VarInt(len(b)).Encode(), b...)
|
n1, err := VarInt(len(b)).WriteTo(w)
|
||||||
|
if err != nil {
|
||||||
|
return n1, err
|
||||||
|
}
|
||||||
|
n2, err := w.Write(b)
|
||||||
|
return n1 + int64(n2), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a ByteArray
|
// Decode a ByteArray
|
||||||
func (b *ByteArray) Decode(r DecodeReader) error {
|
func (b *ByteArray) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var Len VarInt
|
var Len VarInt
|
||||||
if err := Len.Decode(r); err != nil {
|
n1, err := Len.ReadFrom(r)
|
||||||
return err
|
if err != nil {
|
||||||
|
return n1, err
|
||||||
}
|
}
|
||||||
*b = make([]byte, Len)
|
buf := bytes.NewBuffer(*b)
|
||||||
_, err := r.Read(*b)
|
buf.Reset()
|
||||||
return err
|
n2, err := io.CopyN(buf, r, int64(Len))
|
||||||
|
*b = buf.Bytes()
|
||||||
|
return n1 + n2, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a UUID
|
// Encode a UUID
|
||||||
func (u UUID) Encode() []byte {
|
func (u UUID) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
return u[:]
|
nn, err := w.Write(u[:])
|
||||||
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a UUID
|
// Decode a UUID
|
||||||
func (u *UUID) Decode(r DecodeReader) error {
|
func (u *UUID) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
_, err := io.ReadFull(r, (*u)[:])
|
nn, err := io.ReadFull(r, (*u)[:])
|
||||||
return err
|
return int64(nn), err
|
||||||
}
|
}
|
||||||
|
@ -1,51 +1,84 @@
|
|||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Ary struct {
|
type Ary struct {
|
||||||
Len Field
|
Len Field // One of VarInt, VarLong, Int or Long
|
||||||
Ary interface{}
|
Ary interface{} // FieldEncoder, FieldDecoder or both (Field)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Ary) Encode() (data []byte) {
|
func (a Ary) WriteTo(r io.Writer) (n int64, err error) {
|
||||||
length := int(reflect.ValueOf(a.Len).Int())
|
length := int(reflect.ValueOf(a.Len).Int())
|
||||||
array := reflect.ValueOf(a.Ary).Elem()
|
array := reflect.ValueOf(a.Ary).Elem()
|
||||||
for i := 0; i < length; i++ {
|
for i := 0; i < length; i++ {
|
||||||
elem := array.Index(i)
|
elem := array.Index(i)
|
||||||
data = append(data, elem.Interface().(FieldEncoder).Encode()...)
|
nn, err := elem.Interface().(FieldEncoder).WriteTo(r)
|
||||||
|
n += nn
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a Ary) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
|
length := int(reflect.ValueOf(a.Len).Int())
|
||||||
|
array := reflect.ValueOf(a.Ary).Elem()
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
elem := array.Index(i)
|
||||||
|
nn, err := elem.Interface().(FieldDecoder).ReadFrom(r)
|
||||||
|
n += nn
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Opt struct {
|
||||||
|
Has *Boolean
|
||||||
|
Field interface{} // FieldEncoder, FieldDecoder or both (Field)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Opt) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
if *o.Has {
|
||||||
|
return o.Field.(FieldEncoder).WriteTo(w)
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o Opt) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
if *o.Has {
|
||||||
|
return o.Field.(FieldDecoder).ReadFrom(r)
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tuple []interface{} // FieldEncoder, FieldDecoder or both (Field)
|
||||||
|
|
||||||
|
// WriteTo write Tuple to io.Writer, panic when any of filed don't implement FieldEncoder
|
||||||
|
func (t Tuple) WriteTo(w io.Writer) (n int64, err error) {
|
||||||
|
for _, v := range t {
|
||||||
|
nn, err := v.(FieldEncoder).WriteTo(w)
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
n += nn
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a Ary) Decode(r DecodeReader) error {
|
// ReadFrom read Tuple from io.Reader, panic when any of field don't implement FieldDecoder
|
||||||
length := int(reflect.ValueOf(a.Len).Int())
|
func (t Tuple) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
array := reflect.ValueOf(a.Ary).Elem()
|
for _, v := range t {
|
||||||
for i := 0; i < length; i++ {
|
nn, err := v.(FieldDecoder).ReadFrom(r)
|
||||||
elem := array.Index(i)
|
if err != nil {
|
||||||
if err := elem.Interface().(FieldDecoder).Decode(r); err != nil {
|
return n, err
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
n += nn
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
}
|
|
||||||
|
|
||||||
type Opt struct {
|
|
||||||
Has func() bool
|
|
||||||
Field interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Opt) Encode() []byte {
|
|
||||||
if o.Has() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return o.Field.(FieldEncoder).Encode()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Opt) Decode(r DecodeReader) error {
|
|
||||||
if o.Has() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return o.Field.(FieldDecoder).Decode(r)
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
package ptypes
|
package ptypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"io"
|
||||||
"fmt"
|
"math"
|
||||||
|
|
||||||
"github.com/Tnze/go-mc/bot/world/entity"
|
"github.com/Tnze/go-mc/bot/world/entity"
|
||||||
"github.com/Tnze/go-mc/nbt"
|
"github.com/Tnze/go-mc/nbt"
|
||||||
@ -17,96 +17,53 @@ type ChunkData struct {
|
|||||||
PrimaryBitMask pk.VarInt
|
PrimaryBitMask pk.VarInt
|
||||||
Heightmaps struct{}
|
Heightmaps struct{}
|
||||||
Biomes biomesData
|
Biomes biomesData
|
||||||
Data chunkData
|
Data pk.ByteArray
|
||||||
BlockEntities blockEntities
|
BlockEntities blockEntities
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ChunkData) Decode(pkt pk.Packet) error {
|
func (p *ChunkData) ReadFrom(r io.Reader) (int64, error) {
|
||||||
r := bytes.NewReader(pkt.Data)
|
return pk.Tuple{
|
||||||
if err := p.X.Decode(r); err != nil {
|
&p.X,
|
||||||
return fmt.Errorf("decode X: %v", err)
|
&p.Z,
|
||||||
}
|
&p.FullChunk,
|
||||||
if err := p.Z.Decode(r); err != nil {
|
&p.PrimaryBitMask,
|
||||||
return fmt.Errorf("decode Z: %v", err)
|
&pk.NBT{V: &p.Heightmaps},
|
||||||
}
|
pk.Opt{Has: &p.FullChunk, Field: &p.Biomes},
|
||||||
if err := p.FullChunk.Decode(r); err != nil {
|
&p.Data,
|
||||||
return fmt.Errorf("full chunk: %v", err)
|
&p.BlockEntities,
|
||||||
}
|
}.ReadFrom(r)
|
||||||
if err := p.PrimaryBitMask.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("bit mask: %v", err)
|
|
||||||
}
|
|
||||||
if err := (pk.NBT{V: &p.Heightmaps}).Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("heightmaps: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Biomes data is only present for full chunks.
|
|
||||||
if p.FullChunk {
|
|
||||||
if err := p.Biomes.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("heightmaps: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.Data.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("data: %v", err)
|
|
||||||
}
|
|
||||||
if err := p.BlockEntities.Decode(r); err != nil {
|
|
||||||
return fmt.Errorf("block entities: %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type biomesData struct {
|
type biomesData struct {
|
||||||
data []pk.VarInt
|
data []pk.VarInt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *biomesData) Decode(r pk.DecodeReader) error {
|
func (b *biomesData) ReadFrom(r io.Reader) (int64, error) {
|
||||||
var BiomesDataNums pk.VarInt // Number of Biomes Data
|
var n pk.VarInt // Number of Biomes Data
|
||||||
if err := BiomesDataNums.Decode(r); err != nil {
|
return pk.Tuple{
|
||||||
return err
|
&n, pk.Ary{Len: &n, Ary: []pk.VarInt{}},
|
||||||
}
|
}.ReadFrom(r)
|
||||||
b.data = make([]pk.VarInt, BiomesDataNums)
|
|
||||||
|
|
||||||
for i := 0; i < int(BiomesDataNums); i++ {
|
|
||||||
var d pk.VarInt
|
|
||||||
if err := d.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.data[i] = d
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type chunkData []byte
|
|
||||||
type blockEntities []entity.BlockEntity
|
type blockEntities []entity.BlockEntity
|
||||||
|
|
||||||
// Decode implement net.packet.FieldDecoder
|
// Decode implement net.packet.FieldDecoder
|
||||||
func (c *chunkData) Decode(r pk.DecodeReader) error {
|
func (b *blockEntities) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
var sz pk.VarInt
|
|
||||||
if err := sz.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*c = make([]byte, sz)
|
|
||||||
if _, err := r.Read(*c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode implement net.packet.FieldDecoder
|
|
||||||
func (b *blockEntities) Decode(r pk.DecodeReader) error {
|
|
||||||
var sz pk.VarInt // Number of BlockEntities
|
var sz pk.VarInt // Number of BlockEntities
|
||||||
if err := sz.Decode(r); err != nil {
|
if nn, err := sz.ReadFrom(r); err != nil {
|
||||||
return err
|
return nn, err
|
||||||
|
} else {
|
||||||
|
n += nn
|
||||||
}
|
}
|
||||||
*b = make(blockEntities, sz)
|
*b = make(blockEntities, sz)
|
||||||
decoder := nbt.NewDecoder(r)
|
lr := &io.LimitedReader{R: r, N: math.MaxInt64}
|
||||||
|
d := nbt.NewDecoder(lr)
|
||||||
for i := 0; i < int(sz); i++ {
|
for i := 0; i < int(sz); i++ {
|
||||||
if err := decoder.Decode(&(*b)[i]); err != nil {
|
if err := d.Decode(&(*b)[i]); err != nil {
|
||||||
return err
|
return math.MaxInt64 - lr.N, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return math.MaxInt64 - lr.N, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TileEntityData describes a change to a tile entity.
|
// TileEntityData describes a change to a tile entity.
|
||||||
@ -116,13 +73,10 @@ type TileEntityData struct {
|
|||||||
Data entity.BlockEntity
|
Data entity.BlockEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TileEntityData) Decode(pkt pk.Packet) error {
|
func (p *TileEntityData) ReadFrom(r io.Reader) (int64, error) {
|
||||||
r := bytes.NewReader(pkt.Data)
|
return pk.Tuple{
|
||||||
if err := p.Pos.Decode(r); err != nil {
|
&p.Pos,
|
||||||
return fmt.Errorf("position: %v", err)
|
&p.Action,
|
||||||
}
|
&pk.NBT{V: &p.Data},
|
||||||
if err := p.Action.Decode(r); err != nil {
|
}.ReadFrom(r)
|
||||||
return fmt.Errorf("action: %v", err)
|
|
||||||
}
|
|
||||||
return nbt.NewDecoder(r).Decode(&p.Data)
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
package ptypes
|
package ptypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
|
|
||||||
"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"
|
||||||
@ -35,24 +35,16 @@ type WindowItems struct {
|
|||||||
Slots []entity.Slot
|
Slots []entity.Slot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *WindowItems) Decode(pkt pk.Packet) error {
|
func (p *WindowItems) ReadFrom(r io.Reader) (int64, error) {
|
||||||
r := bytes.NewReader(pkt.Data)
|
|
||||||
if err := p.WindowID.Decode(r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var count pk.Short
|
var count pk.Short
|
||||||
if err := count.Decode(r); err != nil {
|
return pk.Tuple{
|
||||||
return err
|
&p.WindowID,
|
||||||
}
|
&count,
|
||||||
|
&pk.Ary{
|
||||||
p.Slots = make([]entity.Slot, int(count))
|
Len: &count,
|
||||||
for i := 0; i < int(count); i++ {
|
Ary: []entity.Slot{},
|
||||||
if err := p.Slots[i].Decode(r); err != nil && !errors.Is(err, nbt.ErrEND) {
|
},
|
||||||
return err
|
}.ReadFrom(r)
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenWindow is a clientbound packet which opens an inventory.
|
// OpenWindow is a clientbound packet which opens an inventory.
|
||||||
|
@ -59,17 +59,18 @@ func (p *UpdateHealth) Decode(pkt pk.Packet) error {
|
|||||||
// PluginData encodes the custom data encoded in a plugin message.
|
// PluginData encodes the custom data encoded in a plugin message.
|
||||||
type PluginData []byte
|
type PluginData []byte
|
||||||
|
|
||||||
func (p PluginData) Encode() []byte {
|
func (p PluginData) WriteTo(w io.Writer) (int64, error) {
|
||||||
return []byte(p)
|
n, err := w.Write(p)
|
||||||
|
return int64(n), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PluginData) Decode(r pk.DecodeReader) error {
|
func (p *PluginData) ReadFrom(r io.Reader) (int64, error) {
|
||||||
d, err := io.ReadAll(r)
|
d, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return int64(len(d)), err
|
||||||
}
|
}
|
||||||
*p = d
|
*p = d
|
||||||
return nil
|
return int64(len(d)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PluginMessage represents a packet with a customized payload.
|
// PluginMessage represents a packet with a customized payload.
|
||||||
|
Reference in New Issue
Block a user