Fix tests, changes pk.NBT api

This commit is contained in:
Tnze
2021-02-28 15:14:52 +08:00
parent b8a3f1a094
commit 951bedbb13
5 changed files with 76 additions and 40 deletions

View File

@ -47,8 +47,8 @@ func (p *Player) handleJoinGamePacket(packet pk.Packet) error {
(*pk.Byte)(&p.PrevGamemode), (*pk.Byte)(&p.PrevGamemode),
&WorldCount, &WorldCount,
pk.Ary{Len: &WorldCount, Ary: &WorldNames}, pk.Ary{Len: &WorldCount, Ary: &WorldNames},
&pk.NBT{V: new(interface{})}, pk.NBT(new(interface{})),
&pk.NBT{V: new(interface{})}, pk.NBT(new(interface{})),
(*pk.Identifier)(&p.WorldName), (*pk.Identifier)(&p.WorldName),
(*pk.Long)(&p.HashedSeed), (*pk.Long)(&p.HashedSeed),
(*pk.VarInt)(&p.MaxPlayers), (*pk.VarInt)(&p.MaxPlayers),

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/Tnze/go-mc/chat" "github.com/Tnze/go-mc/chat"
en_us "github.com/Tnze/go-mc/data/lang/en-us"
"testing" "testing"
pk "github.com/Tnze/go-mc/net/packet" 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 { for i, v := range jsons {
var cm chat.Message var cm chat.Message
err := cm.UnmarshalJSON([]byte(v)) 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 { for i, v := range jsons {
var cm chat.Message var cm chat.Message
err := cm.UnmarshalJSON([]byte(v)) 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 var codeMsg bytes.Buffer
_, _ = chat.Message{Translate: "multiplayer.disconnect.server_full"}.WriteTo(&codeMsg) _, _ = 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 { if _, err := msg.ReadFrom(&codeMsg); err != nil {
t.Errorf("decode message fail: %v", err) t.Errorf("decode message fail: %v", err)
} }
@ -129,6 +132,7 @@ func ExampleMessage_Append() {
func ExampleTranslateMsg() { func ExampleTranslateMsg() {
fmt.Println(chat.TranslateMsg("translation.test.none")) fmt.Println(chat.TranslateMsg("translation.test.none"))
fmt.Println(chat.TranslateMsg( 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", "translation.test.complex",
chat.Text("1111"), chat.Text("1111"),
chat.Text("2222"), chat.Text("2222"),

View File

@ -3,6 +3,7 @@ package packet_test
import ( import (
"bytes" "bytes"
_ "embed" _ "embed"
"fmt"
"testing" "testing"
pk "github.com/Tnze/go-mc/net/packet" pk "github.com/Tnze/go-mc/net/packet"
@ -22,7 +23,7 @@ var PackedVarInts = [][]byte{
{0x80, 0x80, 0x80, 0x80, 0x08}, {0x80, 0x80, 0x80, 0x80, 0x08},
} }
func TestPackVarInt(t *testing.T) { func TestVarInt_WriteTo(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
for i, v := range VarInts { for i, v := range VarInts {
buf.Reset() 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 { for i, v := range PackedVarInts {
var vi pk.VarInt var vi pk.VarInt
if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil { 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 vi pk.VarInt
var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01} var data = []byte{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
if _, err := vi.ReadFrom(bytes.NewReader(data)); err != nil { 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}, {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 { for i, v := range VarLongs {
p := v.Encode() buf.Reset()
if !bytes.Equal(p, PackedVarLongs[i]) { if _, err := v.WriteTo(&buf); err != nil {
t.Errorf("pack long %d should be \"% x\", get \"% x\"", v, PackedVarLongs[i], p) 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 { for i, v := range PackedVarLongs {
var vi pk.VarLong var vi pk.VarLong
if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil { if _, err := vi.ReadFrom(bytes.NewReader(v)); err != nil {
@ -94,18 +99,39 @@ func TestUnpackVarLong(t *testing.T) {
} }
} }
//go:embed joingame_test.bin func TestAry_ReadFrom(t *testing.T) {
var joingame []byte 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) { //go:embed joingame_test.bin
p := pk.Packet{ID: 0x24, Data: joingame} var testJoinGameData []byte
func ExamplePacket_Scan_joinGame() {
p := pk.Packet{ID: 0x24, Data: testJoinGameData}
var ( var (
EID pk.Int EID pk.Int
Hardcore pk.Boolean Hardcore pk.Boolean
Gamemode pk.UnsignedByte Gamemode pk.UnsignedByte
PreGamemode pk.Byte PreGamemode pk.Byte
WorldCount pk.VarInt 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 { DimensionCodec struct {
DimensionType interface{} `nbt:"minecraft:dimension_type"` DimensionType interface{} `nbt:"minecraft:dimension_type"`
WorldgenBiome interface{} `nbt:"minecraft:worldgen/biome"` WorldgenBiome interface{} `nbt:"minecraft:worldgen/biome"`
@ -123,16 +149,18 @@ func TestJoinGamePacket(t *testing.T) {
&Gamemode, &Gamemode,
&PreGamemode, &PreGamemode,
&WorldCount, &WorldCount,
WorldNames, pk.Ary{
&pk.NBT{V: &DimensionCodec}, Len: &WorldCount,
&pk.NBT{V: &Dimension}, Ary: &WorldNames,
},
pk.NBT(&DimensionCodec),
pk.NBT(&Dimension),
&WorldName, &WorldName,
&HashedSeed, &HashedSeed,
&MaxPlayers, &MaxPlayers,
&ViewDistance, &ViewDistance,
&RDI, &ERS, &IsDebug, &IsFlat, &RDI, &ERS, &IsDebug, &IsFlat,
) )
if err != nil { fmt.Print(err)
t.Error(err) // Output: <nil>
}
} }

View File

@ -46,7 +46,9 @@ type (
String string String string
//Chat is encoded as a String with max length of 32767. //Chat is encoded as a String with max length of 32767.
// Deprecated: Use chat.Message
Chat = String Chat = String
//Identifier is encoded as a String with max length of 32767. //Identifier is encoded as a String with max length of 32767.
Identifier = String Identifier = String
@ -66,12 +68,6 @@ type (
//UUID encoded as an unsigned 128-bit integer //UUID encoded as an unsigned 128-bit integer
UUID uuid.UUID 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 is []byte with prefix VarInt as length
ByteArray []byte ByteArray []byte
) )
@ -299,7 +295,8 @@ func (v *VarInt) ReadFrom(r io.Reader) (n int64, err error) {
} }
//Encode a VarLong //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) num := uint64(v)
for { for {
b := num & 0x7F b := num & 0x7F
@ -312,7 +309,8 @@ func (v VarLong) Encode() (vi []byte) {
break break
} }
} }
return nn, err := w.Write(vi)
return int64(nn), err
} }
//Decode a VarLong //Decode a VarLong
@ -427,8 +425,15 @@ func (d *Double) ReadFrom(r io.Reader) (n int64, err error) {
return return
} }
// Encode a NBT //NBT encode a value as Named Binary Tag
func (n *NBT) WriteTo(w io.Writer) (int64, error) { 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 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)
@ -436,8 +441,8 @@ func (n *NBT) WriteTo(w io.Writer) (int64, error) {
return buf.WriteTo(w) return buf.WriteTo(w)
} }
// Decode a NBT // Decode a nbtField
func (n *NBT) ReadFrom(r io.Reader) (int64, error) { func (n nbtField) ReadFrom(r io.Reader) (int64, error) {
// LimitReader is used to count reader length // LimitReader is used to count reader length
lr := &io.LimitedReader{R: r, N: math.MaxInt64} lr := &io.LimitedReader{R: r, N: math.MaxInt64}
err := nbt.NewDecoder(lr).Decode(n.V) err := nbt.NewDecoder(lr).Decode(n.V)

View File

@ -28,8 +28,7 @@ func (a Ary) ReadFrom(r io.Reader) (n int64, err error) {
length := int(reflect.ValueOf(a.Len).Elem().Int()) length := int(reflect.ValueOf(a.Len).Elem().Int())
array := reflect.ValueOf(a.Ary).Elem() array := reflect.ValueOf(a.Ary).Elem()
if array.Cap() < length { if array.Cap() < length {
array = reflect.MakeSlice(array.Type(), length, length) array.Set(reflect.MakeSlice(array.Type(), length, length))
a.Ary = array.Interface()
} }
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
elem := array.Index(i) elem := array.Index(i)