]> git.lizzy.rs Git - mtmap.git/commitdiff
Add deserialization
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 16 Jul 2022 15:12:47 +0000 (17:12 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 16 Jul 2022 15:12:47 +0000 (17:12 +0200)
deserialize.go [new file with mode: 0644]
go.mod [new file with mode: 0644]
go.sum [new file with mode: 0644]

diff --git a/deserialize.go b/deserialize.go
new file mode 100644 (file)
index 0000000..a6bc965
--- /dev/null
@@ -0,0 +1,283 @@
+package mtmap
+
+import (
+       "bytes"
+       "compress/zlib"
+       "encoding/binary"
+       "errors"
+       "github.com/anon55555/mt"
+       "io"
+)
+
+type MapBlk struct {
+       mt.MapBlk
+       Flags            MapBlkFlags
+       LightingComplete uint16
+       StaticObjs       []StaticObj
+       Timestamp        uint32
+}
+
+type MapBlkFlags uint8
+
+const (
+       IsUnderground MapBlkFlags = 1 << iota
+       DayNightDiffers
+       NotGenerated = 1 << 4
+)
+
+var SerializeVer uint8 = 28
+
+var (
+       ErrInvalidSerializeVer = errors.New("invalid serialize version")
+       ErrInvalidContentWidth = errors.New("invalid content width")
+       ErrInvalidParamsWidth  = errors.New("invalid params width")
+       ErrInvalidNodeMetaVer  = errors.New("invalid node meta version")
+       ErrInvalidNameIdMapVer = errors.New("invalid name id mapping version")
+       ErrInvalidNode         = errors.New("invalid node")
+)
+
+type StaticObj struct {
+       Type uint8
+       Pos  [3]float32
+       Data string
+}
+
+func Deserialize(data []byte, idNameMap map[string]mt.Content) (blk *MapBlk, err error) {
+       r := bytes.NewReader(data)
+       blk = &MapBlk{}
+
+       var ver uint8
+       if err := binary.Read(r, binary.BigEndian, &ver); err != nil {
+               return nil, err
+       }
+
+       if ver != SerializeVer {
+               return nil, ErrInvalidSerializeVer
+       }
+
+       if err := binary.Read(r, binary.BigEndian, &blk.Flags); err != nil {
+               return nil, err
+       }
+
+       if err := binary.Read(r, binary.BigEndian, &blk.LightingComplete); err != nil {
+               return nil, err
+       }
+
+       var contentWidth uint8
+       if err := binary.Read(r, binary.BigEndian, &contentWidth); err != nil {
+               return nil, err
+       }
+
+       if contentWidth != 2 {
+               return nil, ErrInvalidContentWidth
+       }
+
+       var paramsWidth uint8
+       if err := binary.Read(r, binary.BigEndian, &paramsWidth); err != nil {
+               return nil, err
+       }
+
+       if paramsWidth != 2 {
+               return nil, ErrInvalidParamsWidth
+       }
+
+       {
+               r, err := zlib.NewReader(r)
+               if err != nil {
+                       return nil, err
+               }
+
+               if err := binary.Read(r, binary.BigEndian, &blk.Param0); err != nil {
+                       return nil, err
+               }
+
+               if _, err := io.Copy(io.Discard, r); err != nil {
+                       return nil, err
+               }
+
+               if err := r.Close(); err != nil {
+                       return nil, err
+               }
+       }
+
+       blk.NodeMetas = make(map[uint16]*mt.NodeMeta)
+       {
+               r, err := zlib.NewReader(r)
+               if err != nil {
+                       return nil, err
+               }
+
+               var version uint8
+               if err := binary.Read(r, binary.BigEndian, &version); err != nil {
+                       return nil, err
+               }
+
+               if version != 2 {
+                       return nil, ErrInvalidNodeMetaVer
+               }
+
+               var count uint16
+               if err := binary.Read(r, binary.BigEndian, &count); err != nil {
+                       return nil, err
+               }
+
+               for i := uint16(0); i < count; i++ {
+                       var pos uint16
+                       if err := binary.Read(r, binary.BigEndian, &pos); err != nil {
+                               return nil, err
+                       }
+
+                       var num uint32
+                       if err := binary.Read(r, binary.BigEndian, &num); err != nil {
+                               return nil, err
+                       }
+
+                       var data = &mt.NodeMeta{}
+                       data.Fields = make([]mt.NodeMetaField, 0)
+                       for j := uint32(0); j < num; j++ {
+                               var field mt.NodeMetaField
+
+                               var lenName uint16
+                               if err := binary.Read(r, binary.BigEndian, &lenName); err != nil {
+                                       return nil, err
+                               }
+
+                               var name = make([]byte, lenName)
+                               if err := binary.Read(r, binary.BigEndian, &name); err != nil {
+                                       return nil, err
+                               }
+                               field.Name = string(name)
+
+                               var lenValue uint32
+                               if err := binary.Read(r, binary.BigEndian, &lenValue); err != nil {
+                                       return nil, err
+                               }
+
+                               var value = make([]byte, lenValue)
+                               if err := binary.Read(r, binary.BigEndian, &value); err != nil {
+                                       return nil, err
+                               }
+                               field.Value = string(value)
+
+                               if err := binary.Read(r, binary.BigEndian, &field.Private); err != nil {
+                                       return nil, err
+                               }
+
+                               data.Fields = append(data.Fields, field)
+                       }
+
+                       if err := data.Inv.Deserialize(r); err != nil {
+                               return nil, err
+                       }
+
+                       blk.NodeMetas[pos] = data
+               }
+
+               if _, err := io.Copy(io.Discard, r); err != nil {
+                       return nil, err
+               }
+
+               if err := r.Close(); err != nil {
+                       return nil, err
+               }
+       }
+
+       var staticObjVer uint8
+       if err := binary.Read(r, binary.BigEndian, &staticObjVer); err != nil {
+               return nil, err
+       }
+
+       var staticObjCount uint16
+       if err := binary.Read(r, binary.BigEndian, &staticObjCount); err != nil {
+               return nil, err
+       }
+
+       blk.StaticObjs = make([]StaticObj, 0)
+       for i := uint16(0); i < staticObjCount; i++ {
+               var obj StaticObj
+
+               if err := binary.Read(r, binary.BigEndian, &obj.Type); err != nil {
+                       return nil, err
+               }
+
+               var pos [3]int32
+               if err := binary.Read(r, binary.BigEndian, &pos); err != nil {
+                       return nil, err
+               }
+
+               obj.Pos = [3]float32{
+                       float32(pos[0]) / 1000.0,
+                       float32(pos[1]) / 1000.0,
+                       float32(pos[2]) / 1000.0,
+               }
+
+               var dataLen uint16
+               if err := binary.Read(r, binary.BigEndian, &dataLen); err != nil {
+                       return nil, err
+               }
+
+               var data = make([]byte, dataLen)
+               if err := binary.Read(r, binary.BigEndian, &data); err != nil {
+                       return nil, err
+               }
+
+               obj.Data = string(data)
+
+               blk.StaticObjs = append(blk.StaticObjs, obj)
+       }
+
+       if err := binary.Read(r, binary.BigEndian, &blk.Timestamp); err != nil {
+               return nil, err
+       }
+
+       var nameIdMapVer uint8
+       if err := binary.Read(r, binary.BigEndian, &nameIdMapVer); err != nil {
+               return nil, err
+       }
+
+       if nameIdMapVer != 0 {
+               return nil, ErrInvalidNameIdMapVer
+       }
+
+       var nameIdMapCount uint16
+       if err := binary.Read(r, binary.BigEndian, &nameIdMapCount); err != nil {
+               return nil, err
+       }
+
+       nameIdMap := make(map[mt.Content]string)
+
+       for i := uint16(0); i < nameIdMapCount; i++ {
+               var id uint16
+               if err := binary.Read(r, binary.BigEndian, &id); err != nil {
+                       return nil, err
+               }
+
+               var nameLen mt.Content
+               if err := binary.Read(r, binary.BigEndian, &nameLen); err != nil {
+                       return nil, err
+               }
+
+               var name = make([]byte, nameLen)
+               if err := binary.Read(r, binary.BigEndian, &name); err != nil {
+                       return nil, err
+               }
+
+               nameIdMap[mt.Content(id)] = string(name)
+       }
+
+       for i := 0; i < 4096; i++ {
+               name, ok := nameIdMap[blk.Param0[i]]
+               if !ok {
+                       return nil, ErrInvalidNode
+               }
+
+               id, ok := idNameMap[name]
+               if !ok {
+                       return nil, ErrInvalidNode
+               }
+
+               blk.Param0[i] = id
+       }
+
+       return
+}
diff --git a/go.mod b/go.mod
new file mode 100644 (file)
index 0000000..2d76405
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/EliasFleckenstein03/mtmap
+
+go 1.18
+
+require github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f // indirect
diff --git a/go.sum b/go.sum
new file mode 100644 (file)
index 0000000..a9fbb58
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,2 @@
+github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f h1:tZU8VPYLyRrG3Lj9zBZvTVF5tUGciC/2aUIgTcU4WaM=
+github.com/anon55555/mt v0.0.0-20210919124550-bcc58cb3048f/go.mod h1:jH4ER+ahjl7H6TczzK+q4V9sXY++U2Geh6/vt3r4Xvs=