infer compress type before decode NBT fail
This commit is contained in:
@ -26,7 +26,7 @@ const (
|
|||||||
|
|
||||||
type Decoder struct {
|
type Decoder struct {
|
||||||
r interface {
|
r interface {
|
||||||
io.ByteReader
|
io.ByteScanner
|
||||||
io.Reader
|
io.Reader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ type Decoder struct {
|
|||||||
func NewDecoder(r io.Reader) *Decoder {
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
d := new(Decoder)
|
d := new(Decoder)
|
||||||
if br, ok := r.(interface {
|
if br, ok := r.(interface {
|
||||||
io.ByteReader
|
io.ByteScanner
|
||||||
io.Reader
|
io.Reader
|
||||||
}); ok {
|
}); ok {
|
||||||
d.r = br
|
d.r = br
|
||||||
|
34
nbt/read.go
34
nbt/read.go
@ -18,6 +18,17 @@ func (d *Decoder) Decode(v interface{}) error {
|
|||||||
if val.Kind() != reflect.Ptr {
|
if val.Kind() != reflect.Ptr {
|
||||||
return errors.New("non-pointer passed to Unmarshal")
|
return errors.New("non-pointer passed to Unmarshal")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the head
|
||||||
|
compress, err := d.checkCompressed()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("check compressed fail: %v", err)
|
||||||
|
}
|
||||||
|
if compress != "" {
|
||||||
|
return fmt.Errorf("data may compressed with %s", compress)
|
||||||
|
}
|
||||||
|
|
||||||
|
//start read NBT
|
||||||
tagType, tagName, err := d.readTag()
|
tagType, tagName, err := d.readTag()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -25,6 +36,29 @@ func (d *Decoder) Decode(v interface{}) error {
|
|||||||
return d.unmarshal(val.Elem(), tagType, tagName)
|
return d.unmarshal(val.Elem(), tagType, tagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check the first byte and return if it use compress
|
||||||
|
func (d *Decoder) checkCompressed() (compress string, err error) {
|
||||||
|
var head byte
|
||||||
|
head, err = d.r.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if head <= 12 { //NBT
|
||||||
|
compress = ""
|
||||||
|
} else if head == 0x1f { //gzip
|
||||||
|
compress = "gzip"
|
||||||
|
} else if head == 0x78 { //zlib
|
||||||
|
compress = "zlib"
|
||||||
|
} else {
|
||||||
|
compress = "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.r.UnreadByte()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ErrEND error will be returned when reading a NBT with only Tag_End
|
// ErrEND error will be returned when reading a NBT with only Tag_End
|
||||||
var ErrEND = errors.New("unexpected TAG_End")
|
var ErrEND = errors.New("unexpected TAG_End")
|
||||||
|
|
||||||
|
4
save/level.go
Normal file
4
save/level.go
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package save
|
||||||
|
|
||||||
|
type Level struct {
|
||||||
|
}
|
16
save/playerdata.go
Normal file
16
save/playerdata.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package save
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Tnze/go-mc/nbt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerData struct {
|
||||||
|
Pos [3]float64
|
||||||
|
Motion [3]float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadPlayerData(r io.Reader) (data PlayerData, err error) {
|
||||||
|
err = nbt.NewDecoder(r).Decode(&data)
|
||||||
|
return
|
||||||
|
}
|
33
save/playerdata_test.go
Normal file
33
save/playerdata_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package save
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPlayerData(t *testing.T) {
|
||||||
|
f, err := os.Open("testdata/playerdata/58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := gzip.NewReader(f)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ReadPlayerData(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
want := PlayerData{
|
||||||
|
Pos: [3]float64{-41.5, 65, -89.5},
|
||||||
|
Motion: [3]float64{0, -0.0784000015258789, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
if data != want {
|
||||||
|
t.Errorf("player data parse error: get %v, want %v", data, want)
|
||||||
|
}
|
||||||
|
}
|
1
save/save.go
Normal file
1
save/save.go
Normal file
@ -0,0 +1 @@
|
|||||||
|
package save
|
BIN
save/testdata/DIM-1/data/raids_nether.dat
vendored
Normal file
BIN
save/testdata/DIM-1/data/raids_nether.dat
vendored
Normal file
Binary file not shown.
BIN
save/testdata/DIM1/data/raids_end.dat
vendored
Normal file
BIN
save/testdata/DIM1/data/raids_end.dat
vendored
Normal file
Binary file not shown.
9
save/testdata/advancements/58f6356e-b30c-4811-8bfc-d72a9ee99e73.json
vendored
Normal file
9
save/testdata/advancements/58f6356e-b30c-4811-8bfc-d72a9ee99e73.json
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"minecraft:adventure/adventuring_time": {
|
||||||
|
"criteria": {
|
||||||
|
"minecraft:plains": "2019-07-31 15:56:59 +0800"
|
||||||
|
},
|
||||||
|
"done": false
|
||||||
|
},
|
||||||
|
"DataVersion": 1976
|
||||||
|
}
|
BIN
save/testdata/data/raids.dat
vendored
Normal file
BIN
save/testdata/data/raids.dat
vendored
Normal file
Binary file not shown.
BIN
save/testdata/level.dat
vendored
Normal file
BIN
save/testdata/level.dat
vendored
Normal file
Binary file not shown.
BIN
save/testdata/level.dat_old
vendored
Normal file
BIN
save/testdata/level.dat_old
vendored
Normal file
Binary file not shown.
BIN
save/testdata/playerdata/58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat
vendored
Normal file
BIN
save/testdata/playerdata/58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat
vendored
Normal file
Binary file not shown.
BIN
save/testdata/region/r.-1.-1.mca
vendored
Normal file
BIN
save/testdata/region/r.-1.-1.mca
vendored
Normal file
Binary file not shown.
BIN
save/testdata/region/r.-1.0.mca
vendored
Normal file
BIN
save/testdata/region/r.-1.0.mca
vendored
Normal file
Binary file not shown.
BIN
save/testdata/region/r.0.-1.mca
vendored
Normal file
BIN
save/testdata/region/r.0.-1.mca
vendored
Normal file
Binary file not shown.
BIN
save/testdata/region/r.0.0.mca
vendored
Normal file
BIN
save/testdata/region/r.0.0.mca
vendored
Normal file
Binary file not shown.
BIN
save/testdata/session.lock
vendored
Normal file
BIN
save/testdata/session.lock
vendored
Normal file
Binary file not shown.
1
save/testdata/stats/58f6356e-b30c-4811-8bfc-d72a9ee99e73.json
vendored
Normal file
1
save/testdata/stats/58f6356e-b30c-4811-8bfc-d72a9ee99e73.json
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"stats":{"minecraft:custom":{"minecraft:time_since_rest":6,"minecraft:play_one_minute":6,"minecraft:leave_game":1,"minecraft:time_since_death":6}},"DataVersion":1976}
|
Reference in New Issue
Block a user