]> git.lizzy.rs Git - mtmap.git/blob - deserialize.go
a6bc96563d4c65889e84212049d7fe75461bdcd5
[mtmap.git] / deserialize.go
1 package mtmap
2
3 import (
4         "bytes"
5         "compress/zlib"
6         "encoding/binary"
7         "errors"
8         "github.com/anon55555/mt"
9         "io"
10 )
11
12 type MapBlk struct {
13         mt.MapBlk
14         Flags            MapBlkFlags
15         LightingComplete uint16
16         StaticObjs       []StaticObj
17         Timestamp        uint32
18 }
19
20 type MapBlkFlags uint8
21
22 const (
23         IsUnderground MapBlkFlags = 1 << iota
24         DayNightDiffers
25         NotGenerated = 1 << 4
26 )
27
28 var SerializeVer uint8 = 28
29
30 var (
31         ErrInvalidSerializeVer = errors.New("invalid serialize version")
32         ErrInvalidContentWidth = errors.New("invalid content width")
33         ErrInvalidParamsWidth  = errors.New("invalid params width")
34         ErrInvalidNodeMetaVer  = errors.New("invalid node meta version")
35         ErrInvalidNameIdMapVer = errors.New("invalid name id mapping version")
36         ErrInvalidNode         = errors.New("invalid node")
37 )
38
39 type StaticObj struct {
40         Type uint8
41         Pos  [3]float32
42         Data string
43 }
44
45 func Deserialize(data []byte, idNameMap map[string]mt.Content) (blk *MapBlk, err error) {
46         r := bytes.NewReader(data)
47         blk = &MapBlk{}
48
49         var ver uint8
50         if err := binary.Read(r, binary.BigEndian, &ver); err != nil {
51                 return nil, err
52         }
53
54         if ver != SerializeVer {
55                 return nil, ErrInvalidSerializeVer
56         }
57
58         if err := binary.Read(r, binary.BigEndian, &blk.Flags); err != nil {
59                 return nil, err
60         }
61
62         if err := binary.Read(r, binary.BigEndian, &blk.LightingComplete); err != nil {
63                 return nil, err
64         }
65
66         var contentWidth uint8
67         if err := binary.Read(r, binary.BigEndian, &contentWidth); err != nil {
68                 return nil, err
69         }
70
71         if contentWidth != 2 {
72                 return nil, ErrInvalidContentWidth
73         }
74
75         var paramsWidth uint8
76         if err := binary.Read(r, binary.BigEndian, &paramsWidth); err != nil {
77                 return nil, err
78         }
79
80         if paramsWidth != 2 {
81                 return nil, ErrInvalidParamsWidth
82         }
83
84         {
85                 r, err := zlib.NewReader(r)
86                 if err != nil {
87                         return nil, err
88                 }
89
90                 if err := binary.Read(r, binary.BigEndian, &blk.Param0); err != nil {
91                         return nil, err
92                 }
93
94                 if _, err := io.Copy(io.Discard, r); err != nil {
95                         return nil, err
96                 }
97
98                 if err := r.Close(); err != nil {
99                         return nil, err
100                 }
101         }
102
103         blk.NodeMetas = make(map[uint16]*mt.NodeMeta)
104         {
105                 r, err := zlib.NewReader(r)
106                 if err != nil {
107                         return nil, err
108                 }
109
110                 var version uint8
111                 if err := binary.Read(r, binary.BigEndian, &version); err != nil {
112                         return nil, err
113                 }
114
115                 if version != 2 {
116                         return nil, ErrInvalidNodeMetaVer
117                 }
118
119                 var count uint16
120                 if err := binary.Read(r, binary.BigEndian, &count); err != nil {
121                         return nil, err
122                 }
123
124                 for i := uint16(0); i < count; i++ {
125                         var pos uint16
126                         if err := binary.Read(r, binary.BigEndian, &pos); err != nil {
127                                 return nil, err
128                         }
129
130                         var num uint32
131                         if err := binary.Read(r, binary.BigEndian, &num); err != nil {
132                                 return nil, err
133                         }
134
135                         var data = &mt.NodeMeta{}
136                         data.Fields = make([]mt.NodeMetaField, 0)
137                         for j := uint32(0); j < num; j++ {
138                                 var field mt.NodeMetaField
139
140                                 var lenName uint16
141                                 if err := binary.Read(r, binary.BigEndian, &lenName); err != nil {
142                                         return nil, err
143                                 }
144
145                                 var name = make([]byte, lenName)
146                                 if err := binary.Read(r, binary.BigEndian, &name); err != nil {
147                                         return nil, err
148                                 }
149                                 field.Name = string(name)
150
151                                 var lenValue uint32
152                                 if err := binary.Read(r, binary.BigEndian, &lenValue); err != nil {
153                                         return nil, err
154                                 }
155
156                                 var value = make([]byte, lenValue)
157                                 if err := binary.Read(r, binary.BigEndian, &value); err != nil {
158                                         return nil, err
159                                 }
160                                 field.Value = string(value)
161
162                                 if err := binary.Read(r, binary.BigEndian, &field.Private); err != nil {
163                                         return nil, err
164                                 }
165
166                                 data.Fields = append(data.Fields, field)
167                         }
168
169                         if err := data.Inv.Deserialize(r); err != nil {
170                                 return nil, err
171                         }
172
173                         blk.NodeMetas[pos] = data
174                 }
175
176                 if _, err := io.Copy(io.Discard, r); err != nil {
177                         return nil, err
178                 }
179
180                 if err := r.Close(); err != nil {
181                         return nil, err
182                 }
183         }
184
185         var staticObjVer uint8
186         if err := binary.Read(r, binary.BigEndian, &staticObjVer); err != nil {
187                 return nil, err
188         }
189
190         var staticObjCount uint16
191         if err := binary.Read(r, binary.BigEndian, &staticObjCount); err != nil {
192                 return nil, err
193         }
194
195         blk.StaticObjs = make([]StaticObj, 0)
196         for i := uint16(0); i < staticObjCount; i++ {
197                 var obj StaticObj
198
199                 if err := binary.Read(r, binary.BigEndian, &obj.Type); err != nil {
200                         return nil, err
201                 }
202
203                 var pos [3]int32
204                 if err := binary.Read(r, binary.BigEndian, &pos); err != nil {
205                         return nil, err
206                 }
207
208                 obj.Pos = [3]float32{
209                         float32(pos[0]) / 1000.0,
210                         float32(pos[1]) / 1000.0,
211                         float32(pos[2]) / 1000.0,
212                 }
213
214                 var dataLen uint16
215                 if err := binary.Read(r, binary.BigEndian, &dataLen); err != nil {
216                         return nil, err
217                 }
218
219                 var data = make([]byte, dataLen)
220                 if err := binary.Read(r, binary.BigEndian, &data); err != nil {
221                         return nil, err
222                 }
223
224                 obj.Data = string(data)
225
226                 blk.StaticObjs = append(blk.StaticObjs, obj)
227         }
228
229         if err := binary.Read(r, binary.BigEndian, &blk.Timestamp); err != nil {
230                 return nil, err
231         }
232
233         var nameIdMapVer uint8
234         if err := binary.Read(r, binary.BigEndian, &nameIdMapVer); err != nil {
235                 return nil, err
236         }
237
238         if nameIdMapVer != 0 {
239                 return nil, ErrInvalidNameIdMapVer
240         }
241
242         var nameIdMapCount uint16
243         if err := binary.Read(r, binary.BigEndian, &nameIdMapCount); err != nil {
244                 return nil, err
245         }
246
247         nameIdMap := make(map[mt.Content]string)
248
249         for i := uint16(0); i < nameIdMapCount; i++ {
250                 var id uint16
251                 if err := binary.Read(r, binary.BigEndian, &id); err != nil {
252                         return nil, err
253                 }
254
255                 var nameLen mt.Content
256                 if err := binary.Read(r, binary.BigEndian, &nameLen); err != nil {
257                         return nil, err
258                 }
259
260                 var name = make([]byte, nameLen)
261                 if err := binary.Read(r, binary.BigEndian, &name); err != nil {
262                         return nil, err
263                 }
264
265                 nameIdMap[mt.Content(id)] = string(name)
266         }
267
268         for i := 0; i < 4096; i++ {
269                 name, ok := nameIdMap[blk.Param0[i]]
270                 if !ok {
271                         return nil, ErrInvalidNode
272                 }
273
274                 id, ok := idNameMap[name]
275                 if !ok {
276                         return nil, ErrInvalidNode
277                 }
278
279                 blk.Param0[i] = id
280         }
281
282         return
283 }