infer compress type before decode NBT fail
This commit is contained in:
@ -26,7 +26,7 @@ const (
|
||||
|
||||
type Decoder struct {
|
||||
r interface {
|
||||
io.ByteReader
|
||||
io.ByteScanner
|
||||
io.Reader
|
||||
}
|
||||
}
|
||||
@ -34,7 +34,7 @@ type Decoder struct {
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
d := new(Decoder)
|
||||
if br, ok := r.(interface {
|
||||
io.ByteReader
|
||||
io.ByteScanner
|
||||
io.Reader
|
||||
}); ok {
|
||||
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 {
|
||||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -25,6 +36,29 @@ func (d *Decoder) Decode(v interface{}) error {
|
||||
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
|
||||
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