Merge remote-tracking branch 'origin/master'

This commit is contained in:
Tnze
2020-04-12 14:59:46 +08:00
9 changed files with 154 additions and 17 deletions

View File

@ -2,6 +2,7 @@ package bot
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -36,12 +37,12 @@ func (c *Client) HandleGame() error {
//Read packets //Read packets
p, err := c.conn.ReadPacket() p, err := c.conn.ReadPacket()
if err != nil { if err != nil {
return fmt.Errorf("bot: read packet fail: %v", err) return fmt.Errorf("bot: read packet fail: %w", err)
} }
//handle packets //handle packets
disconnect, err := c.handlePacket(p) disconnect, err := c.handlePacket(p)
if err != nil { if err != nil {
return fmt.Errorf("handle packet 0x%X error: %v", p.ID, err) return fmt.Errorf("handle packet 0x%X error: %w", p.ID, err)
} }
if disconnect { if disconnect {
return nil return nil
@ -201,7 +202,7 @@ func handleSetSlotPacket(c *Client, p pk.Packet) error {
slotI pk.Short slotI pk.Short
slot entity.Slot slot entity.Slot
) )
if err := p.Scan(&windowID, &slotI, &slot); err != nil && err != nbt.ErrEND { if err := p.Scan(&windowID, &slotI, &slot); err != nil && !errors.Is(err, nbt.ErrEND) {
return err return err
} }
@ -451,7 +452,7 @@ func handleChunkDataPacket(c *Client, p pk.Packet) error {
} }
chunk, err := world.DecodeChunkColumn(int32(PrimaryBitMask), Data) chunk, err := world.DecodeChunkColumn(int32(PrimaryBitMask), Data)
if err != nil { if err != nil {
return fmt.Errorf("decode chunk column fail: %v", err) return fmt.Errorf("decode chunk column fail: %w", err)
} }
c.Wd.LoadChunk(int(X), int(Z), chunk) c.Wd.LoadChunk(int(X), int(Z), chunk)
@ -588,7 +589,7 @@ func handleWindowItemsPacket(c *Client, p pk.Packet) (err error) {
} }
for i := 0; i < int(count); i++ { for i := 0; i < int(count); i++ {
var slot entity.Slot var slot entity.Slot
if err := slot.Decode(r); err != nil && err != nbt.ErrEND { if err := slot.Decode(r); err != nil && !errors.Is(err, nbt.ErrEND) {
return err return err
} }
slots = append(slots, slot) slots = append(slots, slot)

View File

@ -82,8 +82,8 @@ func fillSection(s *Section, bpb uint, DataArray []int64, palette []uint) {
data := uint(DataArray[offset/64]) data := uint(DataArray[offset/64])
data >>= offset % 64 data >>= offset % 64
if offset%64 > 64-bpb { if offset%64 > 64-bpb {
l := bpb + offset%64 - 64 l := 64 - offset % 64
data &= uint(DataArray[offset/64+1] << l) data |= uint(DataArray[offset/64+1] << l)
} }
data &= mask data &= mask

View File

@ -23,7 +23,7 @@ func main() {
args := flag.Args() args := flag.Args()
var o string var o string
o = "."// output dir o = "." // output dir
if len(args) < 2 { if len(args) < 2 {
usage() usage()
} }
@ -44,7 +44,7 @@ func main() {
} }
func usage() { func usage() {
_, _ = fmt.Fprintf(os.Stderr, "usage: %s [-x] [-r] r.<X>.<Z>.mc{a,c}\n", flag.Arg(0)) _, _ = fmt.Fprintf(os.Stderr, "usage: %s [-x] [-r] r.<X>.<Z>.mc{a,c}\n", os.Args[0])
os.Exit(1) os.Exit(1)
} }

View File

@ -1,5 +1,10 @@
# mcping # mcping
适用于Minecraft: Java Edition的ping工具
Ping tool for Minecraft: Java Edition.
Just for example. Not recommended for daily use. Use [github.com/go-mc/mcping](github.com/go-mc/mcping) instead, which including SRV parse.
适用于Minecraft: Java Edition的ping工具。
只起示例作用,日常使用建议使用完整版[github.com/go-mc/mcping](github.com/go-mc/mcping)包含SRV解析等功能。
Install with go tools: Install with go tools:
```go get -u github.com/Tnze/go-mc/cmd/mcping``` ```go get -u github.com/Tnze/go-mc/cmd/mcping```

2
go.mod
View File

@ -1,5 +1,5 @@
module github.com/Tnze/go-mc module github.com/Tnze/go-mc
go 1.12 go 1.13
require github.com/google/uuid v1.1.1 require github.com/google/uuid v1.1.1

View File

@ -1 +0,0 @@
package nbt

View File

@ -106,6 +106,81 @@ func (e *Encoder) marshal(val reflect.Value, tagName string) error {
} }
} }
case reflect.Int16:
if err := e.writeTag(TagList, tagName); err != nil {
return err
}
if _, err := e.w.Write([]byte{TagShort}); err != nil {
return err
}
n := val.Len()
if err := e.writeInt32(int32(n)); err != nil {
return err
}
for i := 0; i < n; i++ {
if err := e.writeInt16(int16(val.Index(i).Int())); err != nil {
return err
}
}
case reflect.Float32:
if err := e.writeTag(TagList, tagName); err != nil {
return err
}
if _, err := e.w.Write([]byte{TagFloat}); err != nil {
return err
}
n := val.Len()
if err := e.writeInt32(int32(n)); err != nil {
return err
}
for i := 0; i < n; i++ {
if err := e.writeInt32(int32(math.Float32bits(float32(val.Index(i).Float())))); err != nil {
return err
}
}
case reflect.Float64:
if err := e.writeTag(TagList, tagName); err != nil {
return err
}
if _, err := e.w.Write([]byte{TagFloat}); err != nil {
return err
}
n := val.Len()
if err := e.writeInt32(int32(n)); err != nil {
return err
}
for i := 0; i < n; i++ {
if err := e.writeInt64(int64(math.Float64bits(val.Index(i).Float()))); err != nil {
return err
}
}
case reflect.String:
if err := e.writeTag(TagList, tagName); err != nil {
return err
}
if _, err := e.w.Write([]byte{TagString}); err != nil {
return err
}
n := val.Len()
// Write length of strings
if err := e.writeInt32(int32(n)); err != nil {
return err
}
for i := 0; i < n; i++ {
// Write length of this string
s := val.Index(i).String()
if err := e.writeInt16(int16(len(s))); err != nil {
return err
}
// Write string
if _, err := e.w.Write([]byte(s)); err != nil {
return err
}
}
default: default:
return errors.New("unknown type " + val.Type().String() + " slice") return errors.New("unknown type " + val.Type().String() + " slice")
} }

57
nbt/marshal_test.go Normal file
View File

@ -0,0 +1,57 @@
package nbt
import (
"bytes"
"math"
"testing"
)
func TestMarshal_IntArray(t *testing.T) {
// Test marshal pure Int array
v := []int32{0, -10, 3}
out := []byte{TagIntArray, 0x00, 0x00, 0, 0, 0, 3,
0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xf6,
0x00, 0x00, 0x00, 0x03,
}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
}
// Test marshal in a struct
v2 := struct {
Ary []int32 `nbt:"ary"`
}{[]int32{0, -10, 3}}
out = []byte{TagCompound, 0x00, 0x00,
TagIntArray, 0x00, 0x03, 'a', 'r', 'y', 0, 0, 0, 3,
0x00, 0x00, 0x00, 0x00, // 0
0xff, 0xff, 0xff, 0xf6, // -10
0x00, 0x00, 0x00, 0x03, // 3
TagEnd,
}
buf.Reset()
if err := Marshal(&buf, v2); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
}
}
func TestMarshal_FloatArray(t *testing.T) {
// Test marshal pure Int array
v := []float32{0.3, -100, float32(math.NaN())}
out := []byte{TagList, 0x00, 0x00, TagFloat, 0, 0, 0, 3,
0x3e, 0x99, 0x99, 0x9a, // 0.3
0xc2, 0xc8, 0x00, 0x00, // -100
0x7f, 0xc0, 0x00, 0x00, // NaN
}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
}
}

View File

@ -23,7 +23,7 @@ func (d *Decoder) Decode(v interface{}) error {
//start read NBT //start read NBT
tagType, tagName, err := d.readTag() tagType, tagName, err := d.readTag()
if err != nil { if err != nil {
return fmt.Errorf("nbt: %v", err) return fmt.Errorf("nbt: %w", err)
} }
if c := d.checkCompressed(tagType); c != "" { if c := d.checkCompressed(tagType); c != "" {
@ -32,7 +32,7 @@ func (d *Decoder) Decode(v interface{}) error {
err = d.unmarshal(val.Elem(), tagType, tagName) err = d.unmarshal(val.Elem(), tagType, tagName)
if err != nil { if err != nil {
return fmt.Errorf("nbt: %v", err) return fmt.Errorf("nbt: fail to decode tag %q: %w", tagName, err)
} }
return nil return nil
} }
@ -304,7 +304,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
if field != -1 { if field != -1 {
err = d.unmarshal(val.Field(field), tt, tn) err = d.unmarshal(val.Field(field), tt, tn)
if err != nil { if err != nil {
return err return fmt.Errorf("fail to decode tag %q: %w", tn, err)
} }
} else { } else {
if err := d.rawRead(tt); err != nil { if err := d.rawRead(tt); err != nil {
@ -329,7 +329,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
} }
v := reflect.New(val.Type().Elem()) v := reflect.New(val.Type().Elem())
if err = d.unmarshal(v.Elem(), tt, tn); err != nil { if err = d.unmarshal(v.Elem(), tt, tn); err != nil {
return err return fmt.Errorf("fail to decode tag %q: %w", tn, err)
} }
val.SetMapIndex(reflect.ValueOf(tn), v.Elem()) val.SetMapIndex(reflect.ValueOf(tn), v.Elem())
} }
@ -345,7 +345,7 @@ func (d *Decoder) unmarshal(val reflect.Value, tagType byte, tagName string) err
} }
var value interface{} var value interface{}
if err = d.unmarshal(reflect.ValueOf(&value).Elem(), tt, tn); err != nil { if err = d.unmarshal(reflect.ValueOf(&value).Elem(), tt, tn); err != nil {
return err return fmt.Errorf("fail to decode tag %q: %w", tn, err)
} }
buf[tn] = value buf[tn] = value
} }