mapserver/mapblockparser/metadata.go

137 lines
2.5 KiB
Go
Raw Normal View History

2019-01-06 23:00:24 +03:00
package mapblockparser
import (
"compress/zlib"
2019-01-07 18:06:03 +03:00
"bufio"
2019-01-06 23:00:24 +03:00
"bytes"
2019-01-07 18:06:03 +03:00
"strings"
2019-01-06 23:00:24 +03:00
"errors"
"strconv"
"io"
log "github.com/sirupsen/logrus"
)
2019-01-07 18:06:03 +03:00
const (
INVENTORY_TERMINATOR = "EndInventory"
INVENTORY_END = "EndInventoryList"
INVENTORY_START = "List"
)
2019-01-06 23:00:24 +03:00
func readU16(data []byte, offset int) int {
return (int(data[offset]) << 8) | int(data[offset + 1])
}
2019-01-07 18:06:03 +03:00
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])
2019-01-06 23:00:24 +03:00
}
2019-01-07 18:06:03 +03:00
2019-01-06 23:00:24 +03:00
func parseMetadata(mapblock *MapBlock, data []byte) (int, error) {
log.WithFields(log.Fields{
"data-length": len(data),
}).Debug("Parsing metadata")
r := bytes.NewReader(data)
cr := new(CountedReader)
cr.Reader = r
z, err := zlib.NewReader(cr)
if err != nil {
return 0, err
}
defer z.Close()
buf := new(bytes.Buffer)
io.Copy(buf, z)
metadata := buf.Bytes()
offset := 0
version := metadata[offset]
if version != 2 {
return 0, errors.New("Wrong metadata version: " + strconv.Itoa(int(version)))
}
offset++;
count := readU16(metadata, offset)
log.WithFields(log.Fields{
"count": count,
"version": version,
}).Debug("Parsed metadata-header")
offset+=2
log.Println("Metadata", buf.String())//XXX
for i := 0; i < count; i++ {
position := readU16(metadata, offset);
2019-01-07 18:06:03 +03:00
pairsMap := mapblock.Metadata.GetPairsMap(position)
2019-01-06 23:00:24 +03:00
offset+=2
2019-01-07 18:06:03 +03:00
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
}
}
2019-01-06 23:00:24 +03:00
//TODO
2019-01-07 18:06:03 +03:00
2019-01-06 23:00:24 +03:00
}
return cr.Count, nil
}