md parser and tests
This commit is contained in:
parent
904cb3496d
commit
d9db2c1d67
@ -1,24 +1,31 @@
|
||||
package mapblockparser
|
||||
|
||||
|
||||
type MapBlock struct {
|
||||
Version byte
|
||||
Version byte
|
||||
Underground bool
|
||||
Mapdata []byte
|
||||
Metadata Metadata
|
||||
Mapdata []byte
|
||||
Metadata Metadata
|
||||
}
|
||||
|
||||
func NewMapblock() MapBlock {
|
||||
mb := MapBlock{}
|
||||
mb.Metadata = NewMetadata()
|
||||
return mb
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
Inventories map[int]map[string]*Inventory
|
||||
Pairs map[int]map[string]string
|
||||
Pairs map[int]map[string]string
|
||||
}
|
||||
|
||||
func NewMetadata() Metadata {
|
||||
md := Metadata{}
|
||||
md.Inventories = make(map[int]map[string]*Inventory)
|
||||
md.Pairs = make(map[int]map[string]string)
|
||||
return md
|
||||
}
|
||||
|
||||
func (md *Metadata) GetPairsMap(pos int) map[string]string {
|
||||
if md.Pairs == nil {
|
||||
md.Pairs = make(map[int]map[string]string)
|
||||
}
|
||||
|
||||
pairsMap := md.Pairs[pos]
|
||||
if pairsMap == nil {
|
||||
pairsMap = make(map[string]string)
|
||||
@ -50,12 +57,12 @@ func (md *Metadata) GetInventory(pos int, name string) *Inventory {
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Name string
|
||||
Name string
|
||||
Count int
|
||||
Wear int
|
||||
Wear int
|
||||
}
|
||||
|
||||
type Inventory struct {
|
||||
Size int
|
||||
Size int
|
||||
Items []Item
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
package mapblockparser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"compress/zlib"
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
//TODO: mapdata struct with accessors
|
||||
|
||||
|
||||
func parseMapdata(mapblock *MapBlock, data []byte) (int, error) {
|
||||
log.WithFields(log.Fields{
|
||||
"data-length": len(data),
|
||||
|
@ -1,34 +1,34 @@
|
||||
package mapblockparser
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"compress/zlib"
|
||||
"errors"
|
||||
"strconv"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
INVENTORY_TERMINATOR = "EndInventory"
|
||||
INVENTORY_END = "EndInventoryList"
|
||||
INVENTORY_START = "List"
|
||||
INVENTORY_END = "EndInventoryList"
|
||||
INVENTORY_START = "List"
|
||||
)
|
||||
|
||||
func readU16(data []byte, offset int) int {
|
||||
return (int(data[offset]) << 8) | int(data[offset + 1])
|
||||
return (int(data[offset]) << 8) | int(data[offset+1])
|
||||
}
|
||||
|
||||
func readU32(data []byte, offset int) int {
|
||||
return int(data[offset]) << 24 |
|
||||
int(data[offset+1]) << 16 |
|
||||
int(data[offset+2]) << 8 |
|
||||
return int(data[offset])<<24 |
|
||||
int(data[offset+1])<<16 |
|
||||
int(data[offset+2])<<8 |
|
||||
int(data[offset+3])
|
||||
}
|
||||
|
||||
|
||||
func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
|
||||
log.WithFields(log.Fields{
|
||||
"data-length": len(data),
|
||||
@ -62,76 +62,98 @@ func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
|
||||
return 0, errors.New("Wrong metadata version: " + strconv.Itoa(int(version)))
|
||||
}
|
||||
|
||||
offset++;
|
||||
offset++
|
||||
count := readU16(metadata, offset)
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"count": count,
|
||||
"count": count,
|
||||
"version": version,
|
||||
}).Debug("Parsed metadata-header")
|
||||
|
||||
offset+=2
|
||||
|
||||
log.Println("Metadata", buf.String())//XXX
|
||||
offset += 2
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
position := readU16(metadata, offset);
|
||||
position := readU16(metadata, offset)
|
||||
pairsMap := mapblock.Metadata.GetPairsMap(position)
|
||||
|
||||
offset+=2
|
||||
offset += 2
|
||||
valuecount := readU32(metadata, offset)
|
||||
|
||||
offset+=4
|
||||
offset += 4
|
||||
for j := 0; j < valuecount; j++ {
|
||||
keyLength := readU16(metadata, offset);
|
||||
offset+=2;
|
||||
keyLength := readU16(metadata, offset)
|
||||
offset += 2
|
||||
|
||||
key := string(metadata[offset:keyLength+offset])
|
||||
offset+=keyLength
|
||||
key := string(metadata[offset : keyLength+offset])
|
||||
offset += keyLength
|
||||
|
||||
valueLength := readU32(metadata, offset)
|
||||
offset+=4
|
||||
offset += 4
|
||||
|
||||
value := string(metadata[offset:valueLength+offset])
|
||||
offset+=valueLength
|
||||
value := string(metadata[offset : valueLength+offset])
|
||||
offset += valueLength
|
||||
|
||||
pairsMap[key] = value
|
||||
|
||||
offset++
|
||||
}
|
||||
|
||||
var currentInventoryName *string = nil
|
||||
var currentInventory *Inventory = nil
|
||||
|
||||
var currentInventoryName *string
|
||||
var currentInventory *Inventory
|
||||
|
||||
scanner := bufio.NewScanner(bytes.NewReader(metadata[offset:]))
|
||||
for scanner.Scan() {
|
||||
txt := scanner.Text()
|
||||
offset += len(txt) + 1;
|
||||
|
||||
log.Println("inv", txt)//XXX
|
||||
|
||||
if txt == INVENTORY_END {
|
||||
currentInventoryName = nil
|
||||
currentInventory = nil
|
||||
}
|
||||
|
||||
if txt == INVENTORY_TERMINATOR {
|
||||
break
|
||||
}
|
||||
offset += len(txt) + 1
|
||||
|
||||
if strings.HasPrefix(txt, INVENTORY_START) {
|
||||
pairs := strings.Split(txt, " ")
|
||||
currentInventoryName = &pairs[1]
|
||||
currentInventory = mapblock.Metadata.GetInventory(position, *currentInventoryName)
|
||||
currentInventory.Size = 0
|
||||
|
||||
} else if txt == INVENTORY_END {
|
||||
currentInventoryName = nil
|
||||
currentInventory = nil
|
||||
} else if currentInventory != nil {
|
||||
//content
|
||||
if strings.HasPrefix(txt, "Item") {
|
||||
item := Item{}
|
||||
parts := strings.Split(txt, " ")
|
||||
|
||||
if len(parts) >= 2 {
|
||||
item.Name = parts[1]
|
||||
}
|
||||
|
||||
if len(parts) >= 3 {
|
||||
val, err := strconv.ParseInt(parts[2], 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
item.Count = int(val)
|
||||
}
|
||||
|
||||
if len(parts) >= 4 {
|
||||
val, err := strconv.ParseInt(parts[3], 10, 32)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
item.Count = int(val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if txt == INVENTORY_TERMINATOR {
|
||||
break
|
||||
|
||||
} else {
|
||||
return 0, errors.New("Malformed inventory: " + txt)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
||||
|
||||
}
|
||||
|
||||
return cr.Count, nil
|
||||
}
|
||||
|
||||
|
@ -3,13 +3,12 @@ package mapblockparser
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func Parse(data []byte) (*MapBlock, error) {
|
||||
mapblock := MapBlock{}
|
||||
mapblock := NewMapblock()
|
||||
if len(data) == 0 {
|
||||
return nil, errors.New("no data")
|
||||
}
|
||||
@ -56,4 +55,3 @@ func Parse(data []byte) (*MapBlock, error) {
|
||||
|
||||
return &mapblock, nil
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package mapblockparser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func TestReadU16(t *testing.T){
|
||||
func TestReadU16(t *testing.T) {
|
||||
v := readU16([]byte{0x00, 0x00}, 0)
|
||||
if v != 0 {
|
||||
t.Error(v)
|
||||
@ -25,14 +25,14 @@ func TestReadU16(t *testing.T){
|
||||
}
|
||||
|
||||
}
|
||||
func TestReadU32(t *testing.T){
|
||||
func TestReadU32(t *testing.T) {
|
||||
v := readU32([]byte{0x00, 0x00, 0x00, 0x00}, 0)
|
||||
if v != 0 {
|
||||
t.Error(v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T){
|
||||
func TestParse(t *testing.T) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
data, err := ioutil.ReadFile("testdata/0.0.0")
|
||||
@ -41,7 +41,6 @@ func TestParse(t *testing.T){
|
||||
}
|
||||
|
||||
mapblock, err := Parse(data)
|
||||
fmt.Println("mapblock.Metadata", mapblock.Metadata)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@ -65,17 +64,30 @@ func TestParse(t *testing.T){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestParse2(t *testing.T){
|
||||
func TestParse2(t *testing.T) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
data, err := ioutil.ReadFile("testdata/0.9.0")
|
||||
data, err := ioutil.ReadFile("testdata/11.0.2")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = Parse(data)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParse3(t *testing.T) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
data, err := ioutil.ReadFile("testdata/0.1.0")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = Parse(data)
|
||||
//fmt.Println("mapblock.Metadata", mapblock.Metadata)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
BIN
mapblockparser/testdata/11.0.2
vendored
Normal file
BIN
mapblockparser/testdata/11.0.2
vendored
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user