From 951bedbb131d2303bddfcb0dee9c7aaf4bbb1047 Mon Sep 17 00:00:00 2001 From: Tnze Date: Sun, 28 Feb 2021 15:14:52 +0800 Subject: [PATCH] Fix tests, changes pk.NBT api --- bot/basic/info.go | 4 +-- chat/chatMsg_test.go | 14 ++++++--- net/packet/packet_test.go | 66 ++++++++++++++++++++++++++++----------- net/packet/types.go | 29 ++++++++++------- net/packet/util.go | 3 +- 5 files changed, 76 insertions(+), 40 deletions(-) diff --git a/bot/basic/info.go b/bot/basic/info.go index 526de3f..a61fd80 100644 --- a/bot/basic/info.go +++ b/bot/basic/info.go @@ -47,8 +47,8 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error { (*pk.Byte)(&p.PrevGamemode), &WorldCount, pk.Ary{Len: &WorldCount, Ary: &WorldNames}, - &pk.NBT{V: new(interface{})}, - &pk.NBT{V: new(interface{})}, + pk.NBT(new(interface{})), + pk.NBT(new(interface{})), (*pk.Identifier)(&p.WorldName), (*pk.Long)(&p.HashedSeed), (*pk.VarInt)(&p.MaxPlayers), diff --git a/chat/chatMsg_test.go b/chat/chatMsg_test.go index b419a57..356fa62 100644 --- a/chat/chatMsg_test.go +++ b/chat/chatMsg_test.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "github.com/Tnze/go-mc/chat" + en_us "github.com/Tnze/go-mc/data/lang/en-us" "testing" pk "github.com/Tnze/go-mc/net/packet" @@ -71,8 +72,8 @@ var clearTexts = []string{ " ", } -func TestChatMsgFormatString(t *testing.T) { - +func TestMessage_String(t *testing.T) { + chat.SetLanguage(en_us.Map) for i, v := range jsons { var cm chat.Message err := cm.UnmarshalJSON([]byte(v)) @@ -85,7 +86,8 @@ func TestChatMsgFormatString(t *testing.T) { } } -func TestChatMsgClearString(t *testing.T) { +func TestMessage_ClearString(t *testing.T) { + chat.SetLanguage(en_us.Map) for i, v := range jsons { var cm chat.Message err := cm.UnmarshalJSON([]byte(v)) @@ -100,11 +102,12 @@ func TestChatMsgClearString(t *testing.T) { } } -func TestMessage_Encode(t *testing.T) { +func TestMessage_WriteTo(t *testing.T) { + chat.SetLanguage(en_us.Map) var codeMsg bytes.Buffer _, _ = chat.Message{Translate: "multiplayer.disconnect.server_full"}.WriteTo(&codeMsg) - var msg pk.Chat + var msg pk.String // Decode as a String if _, err := msg.ReadFrom(&codeMsg); err != nil { t.Errorf("decode message fail: %v", err) } @@ -129,6 +132,7 @@ func ExampleMessage_Append() { func ExampleTranslateMsg() { fmt.Println(chat.TranslateMsg("translation.test.none")) fmt.Println(chat.TranslateMsg( + // translation.test.complex == "Prefix, %s%[2]s again %s and %[1]s lastly %s and also %[1]s again!" "translation.test.complex", chat.Text("1111"), chat.Text("2222"), diff --git a/net/packet/packet_test.go b/net/packet/packet_test.go index 87b184f..f38736f 100644 --- a/net/packet/packet_test.go +++ b/net/packet/packet_test.go @@ -3,6 +3,7 @@ package packet_test import ( "bytes" _ "embed" + "fmt" "testing" pk "github.com/Tnze/go-mc/net/packet" @@ -22,7 +23,7 @@ var PackedVarInts = [][]byte{ {0x80, 0x80, 0x80, 0x80, 0x08}, } -func TestPackVarInt(t *testing.T) { +func TestVarInt_WriteTo(t *testing.T) { var buf bytes.Buffer for i, v := range VarInts { buf.Reset() @@ -36,7 +37,7 @@ func TestPackVarInt(t *testing.T) { } } } -func TestUnpackVarInt(t *testing.T) { +func TestVarInt_ReadFrom(t *testing.T) { for i, v := range PackedVarInts { var vi pk.VarInt if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil { @@ -48,7 +49,7 @@ func TestUnpackVarInt(t *testing.T) { } } -func TestUnpackVarInt_TooLongData(t *testing.T) { +func TestVarInt_ReadFrom_tooLongData(t *testing.T) { var vi pk.VarInt var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01} if _, err := vi.ReadFrom(bytes.NewReader(data)); err != nil { @@ -74,15 +75,19 @@ var PackedVarLongs = [][]byte{ {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}, } -func TestPackVarLong(t *testing.T) { +func TestVarLong_WriteTo(t *testing.T) { + var buf bytes.Buffer for i, v := range VarLongs { - p := v.Encode() - if !bytes.Equal(p, PackedVarLongs[i]) { - t.Errorf("pack long %d should be \"% x\", get \"% x\"", v, PackedVarLongs[i], p) + buf.Reset() + if _, err := v.WriteTo(&buf); err != nil { + t.Error(err) + } + if !bytes.Equal(buf.Bytes(), PackedVarLongs[i]) { + t.Errorf("pack long %d should be \"% x\", get \"% x\"", v, PackedVarLongs[i], buf.Bytes()) } } } -func TestUnpackVarLong(t *testing.T) { +func TestVarLong_ReadFrom(t *testing.T) { for i, v := range PackedVarLongs { var vi pk.VarLong if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil { @@ -94,18 +99,39 @@ func TestUnpackVarLong(t *testing.T) { } } -//go:embed joingame_test.bin -var joingame []byte +func TestAry_ReadFrom(t *testing.T) { + var num pk.Int = 2 + var ary []pk.String + var bin = []byte{ + 4, 'T', 'n', 'z', 'e', + 0, + } + var data = pk.Ary{Len: &num, Ary: &ary} + if _, err := data.ReadFrom(bytes.NewReader(bin)); err != nil { + t.Fatal(err) + } + if len(ary) != int(num) { + t.Fatalf("length not match: %d != %d", len(ary), num) + } + for i, v := range []string{"Tnze", ""} { + if string(ary[i]) != v { + t.Errorf("want %q, get %q", v, ary[i]) + } + } +} -func TestJoinGamePacket(t *testing.T) { - p := pk.Packet{ID: 0x24, Data: joingame} +//go:embed joingame_test.bin +var testJoinGameData []byte + +func ExamplePacket_Scan_joinGame() { + p := pk.Packet{ID: 0x24, Data: testJoinGameData} var ( EID pk.Int Hardcore pk.Boolean Gamemode pk.UnsignedByte PreGamemode pk.Byte WorldCount pk.VarInt - WorldNames = pk.Ary{Len: &WorldCount, Ary: &[]pk.String{}} + WorldNames = make([]pk.Identifier, 0) // This cannot replace with "var WorldNames []pk.Identifier" because "nil" has no type information DimensionCodec struct { DimensionType interface{} `nbt:"minecraft:dimension_type"` WorldgenBiome interface{} `nbt:"minecraft:worldgen/biome"` @@ -123,16 +149,18 @@ func TestJoinGamePacket(t *testing.T) { &Gamemode, &PreGamemode, &WorldCount, - WorldNames, - &pk.NBT{V: &DimensionCodec}, - &pk.NBT{V: &Dimension}, + pk.Ary{ + Len: &WorldCount, + Ary: &WorldNames, + }, + pk.NBT(&DimensionCodec), + pk.NBT(&Dimension), &WorldName, &HashedSeed, &MaxPlayers, &ViewDistance, &RDI, &ERS, &IsDebug, &IsFlat, ) - if err != nil { - t.Error(err) - } + fmt.Print(err) + // Output: } diff --git a/net/packet/types.go b/net/packet/types.go index 41f0ee3..0cda495 100644 --- a/net/packet/types.go +++ b/net/packet/types.go @@ -46,7 +46,9 @@ type ( String string //Chat is encoded as a String with max length of 32767. + // Deprecated: Use chat.Message Chat = String + //Identifier is encoded as a String with max length of 32767. Identifier = String @@ -66,12 +68,6 @@ type ( //UUID encoded as an unsigned 128-bit integer UUID uuid.UUID - //NBT encode a value as Named Binary Tag - //Tips: define your own struct and implement pk.Field for better performance - NBT struct { - V interface{} - } - //ByteArray is []byte with prefix VarInt as length ByteArray []byte ) @@ -299,7 +295,8 @@ func (v *VarInt) ReadFrom(r io.Reader) (n int64, err error) { } //Encode a VarLong -func (v VarLong) Encode() (vi []byte) { +func (v VarLong) WriteTo(w io.Writer) (n int64, err error) { + var vi = make([]byte, 0, MaxVarLongLen) num := uint64(v) for { b := num & 0x7F @@ -312,7 +309,8 @@ func (v VarLong) Encode() (vi []byte) { break } } - return + nn, err := w.Write(vi) + return int64(nn), err } //Decode a VarLong @@ -427,8 +425,15 @@ func (d *Double) ReadFrom(r io.Reader) (n int64, err error) { return } -// Encode a NBT -func (n *NBT) WriteTo(w io.Writer) (int64, error) { +//NBT encode a value as Named Binary Tag +func NBT(v interface{}) Field { + return nbtField{V: v} +} + +type nbtField struct{ V interface{} } + +// Encode a nbtField +func (n nbtField) WriteTo(w io.Writer) (int64, error) { var buf bytes.Buffer if err := nbt.NewEncoder(&buf).Encode(n.V); err != nil { panic(err) @@ -436,8 +441,8 @@ func (n *NBT) WriteTo(w io.Writer) (int64, error) { return buf.WriteTo(w) } -// Decode a NBT -func (n *NBT) ReadFrom(r io.Reader) (int64, error) { +// Decode a nbtField +func (n nbtField) ReadFrom(r io.Reader) (int64, error) { // LimitReader is used to count reader length lr := &io.LimitedReader{R: r, N: math.MaxInt64} err := nbt.NewDecoder(lr).Decode(n.V) diff --git a/net/packet/util.go b/net/packet/util.go index 369fafb..43795ca 100644 --- a/net/packet/util.go +++ b/net/packet/util.go @@ -28,8 +28,7 @@ func (a Ary) ReadFrom(r io.Reader) (n int64, err error) { length := int(reflect.ValueOf(a.Len).Elem().Int()) array := reflect.ValueOf(a.Ary).Elem() if array.Cap() < length { - array = reflect.MakeSlice(array.Type(), length, length) - a.Ary = array.Interface() + array.Set(reflect.MakeSlice(array.Type(), length, length)) } for i := 0; i < length; i++ { elem := array.Index(i)