diff --git a/net/packet/packet_test.go b/net/packet/packet_test.go index e3fd953..4324fa1 100644 --- a/net/packet/packet_test.go +++ b/net/packet/packet_test.go @@ -8,15 +8,15 @@ import ( var VarInts = []VarInt{0, 1, 2, 127, 128, 255, 2147483647, -1, -2147483648} var PackedVarInts = [][]byte{ - []byte{0x00}, - []byte{0x01}, - []byte{0x02}, - []byte{0x7f}, - []byte{0x80, 0x01}, - []byte{0xff, 0x01}, - []byte{0xff, 0xff, 0xff, 0xff, 0x07}, - []byte{0xff, 0xff, 0xff, 0xff, 0x0f}, - []byte{0x80, 0x80, 0x80, 0x80, 0x08}, + {0x00}, + {0x01}, + {0x02}, + {0x7f}, + {0x80, 0x01}, + {0xff, 0x01}, + {0xff, 0xff, 0xff, 0xff, 0x07}, + {0xff, 0xff, 0xff, 0xff, 0x0f}, + {0x80, 0x80, 0x80, 0x80, 0x08}, } func TestPackVarInt(t *testing.T) { @@ -39,24 +39,38 @@ func TestUnpackVarInt(t *testing.T) { } } -// func TestPositionPack(t *testing.T) { -// // This test is not good. +var VarLongs = []VarLong{0, 1, 2, 127, 128, 255, 2147483647, 9223372036854775807, -1, -2147483648, -9223372036854775808} -// for x := -33554432; x < 33554432; x += 55443 { -// for y := -2048; y < 2048; y += 48 { -// for z := -33554432; z < 33554432; z += 55443 { -// var ( -// pos1 Position -// pos2 = Position{x, y, z} -// ) -// if err := pos1.Decode(bytes.NewReader(pos2.Encode())); err != nil { -// t.Errorf("Position decode fail: %v", err) -// } +var PackedVarLongs = [][]byte{ + {0x00}, + {0x01}, + {0x02}, + {0x7f}, + {0x80, 0x01}, + {0xff, 0x01}, + {0xff, 0xff, 0xff, 0xff, 0x07}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}, + {0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01}, + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}, +} -// if pos1 != pos2 { -// t.Errorf("cannot pack %v", pos2) -// } -// } -// } -// } -// } +func TestPackVarLong(t *testing.T) { + 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) + } + } +} +func TestUnpackVarLong(t *testing.T) { + for i, v := range PackedVarLongs { + var vi VarLong + if err := vi.Decode(bytes.NewReader(v)); err != nil { + t.Errorf("unpack \"% x\" error: %v", v, err) + } + if vi != VarLongs[i] { + t.Errorf("unpack \"% x\" should be %d, get %d", v, VarLongs[i], vi) + } + } +} diff --git a/net/packet/types.go b/net/packet/types.go index 3fc2b65..c95dda4 100644 --- a/net/packet/types.go +++ b/net/packet/types.go @@ -1,6 +1,7 @@ package packet import ( + "errors" "github.com/google/uuid" "io" "math" @@ -268,7 +269,7 @@ func (v VarInt) Encode() (vi []byte) { //Decode a VarInt func (v *VarInt) Decode(r DecodeReader) error { var n uint32 - for i := 0; i < 5; i++ { //读数据前的长度标记 + for i := 0; ; i++ { //读数据前的长度标记 sec, err := r.ReadByte() if err != nil { return err @@ -278,6 +279,8 @@ func (v *VarInt) Decode(r DecodeReader) error { if sec&0x80 == 0 { break + } else if i > 5 { + return errors.New("VarInt is too big") } } @@ -285,6 +288,45 @@ func (v *VarInt) Decode(r DecodeReader) error { return nil } +//Encode a VarLong +func (v VarLong) Encode() (vi []byte) { + num := uint64(v) + for { + b := num & 0x7F + num >>= 7 + if num != 0 { + b |= 0x80 + } + vi = append(vi, byte(b)) + if num == 0 { + break + } + } + return +} + +//Decode a VarLong +func (v *VarLong) Decode(r DecodeReader) error { + var n uint64 + for i := 0; ; i++ { //读数据前的长度标记 + sec, err := r.ReadByte() + if err != nil { + return err + } + + n |= uint64(sec&0x7F) << uint64(7*i) + + if sec&0x80 == 0 { + break + } else if i > 10 { + return errors.New("VarInt is too big") + } + } + + *v = VarLong(n) + return nil +} + //Encode a Position func (p Position) Encode() []byte { b := make([]byte, 8)