working inv/metadata parsing

This commit is contained in:
Thomas Rudin 2019-01-07 16:06:03 +01:00
parent db6e436b14
commit 9afcfed658
3 changed files with 127 additions and 4 deletions

View File

@ -10,8 +10,43 @@ type MapBlock struct {
type Metadata struct {
Inventories map[int]map[string]Inventory
Pairs map[int]map[string]string
Inventories map[int]map[string]*Inventory
Pairs map[int]map[string]*string
}
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)
md.Pairs[pos] = pairsMap
}
return pairsMap
}
func (md *Metadata) GetInventoryMap(pos int) map[string]*Inventory {
invMap := md.Inventories[pos]
if invMap == nil {
invMap = make(map[string]*Inventory)
md.Inventories[pos] = invMap
}
return invMap
}
func (md *Metadata) GetInventory(pos int, name string) *Inventory {
m := md.GetInventoryMap(pos)
inv := m[name]
if inv == nil {
inv = &Inventory{}
m[name] = inv
}
return inv
}
type Item struct {

View File

@ -2,21 +2,33 @@ package mapblockparser
import (
"compress/zlib"
"bufio"
"bytes"
"strings"
"errors"
"strconv"
"io"
log "github.com/sirupsen/logrus"
)
const (
INVENTORY_TERMINATOR = "EndInventory"
INVENTORY_END = "EndInventoryList"
INVENTORY_START = "List"
)
func readU16(data []byte, offset int) int {
return (int(data[offset]) << 8) | int(data[offset + 1])
}
func readU32(data []byte, offset int){
func readU32(data []byte, offset int) int {
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),
@ -60,11 +72,63 @@ func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
for i := 0; i < count; i++ {
position := readU16(metadata, offset);
log.Println("MD item", i, position)//XXX
pairsMap := mapblock.Metadata.GetPairsMap(position)
offset+=2
valuecount := readU32(metadata, offset)
offset+=4
for j := 0; j < valuecount; j++ {
keyLength := readU16(metadata, offset);
offset+=2;
key := string(metadata[offset:keyLength+offset])
offset+=keyLength
valueLength := readU32(metadata, offset)
offset+=4;
value := string(metadata[offset:keyLength+offset])
offset+=valueLength
pairsMap[key] = &value
offset++
log.Println("MD item", i, offset, position, valuecount, valueLength, keyLength, pairsMap)//XXX
}
var currentInventoryName *string = nil
var currentInventory *Inventory = nil
scanner := bufio.NewScanner(bytes.NewReader(metadata[offset:]))
for scanner.Scan() {
txt := scanner.Text()
offset += len(txt) + 1;
log.Println("inv", txt)
if txt == INVENTORY_END {
currentInventoryName = nil
currentInventory = nil
}
if txt == INVENTORY_TERMINATOR {
break
}
if strings.HasPrefix(txt, INVENTORY_START) {
pairs := strings.Split(txt, " ")
currentInventoryName = &pairs[1]
currentInventory = mapblock.Metadata.GetInventory(position, *currentInventoryName)
currentInventory.Size = 0
}
}
//TODO
}
return cr.Count, nil

View File

@ -7,6 +7,30 @@ import (
log "github.com/sirupsen/logrus"
)
func TestReadU16(t *testing.T){
v := readU16([]byte{0x00, 0x00}, 0)
if v != 0 {
t.Error(v)
}
v = readU16([]byte{0x00, 0x01}, 0)
if v != 1 {
t.Error(v)
}
v = readU16([]byte{0x01, 0x00}, 0)
if v != 256 {
t.Error(v)
}
}
func TestReadU32(t *testing.T){
v := readU32([]byte{0x00, 0x00, 0x00, 0x00}, 0)
if v != 0 {
t.Error(v)
}
}
func TestParse(t *testing.T){
log.SetLevel(log.DebugLevel)