@@ -11,20 +11,18 @@ static inline uint16_t readU16(const unsigned char *data)
11
11
return data[0 ] << 8 | data[1 ];
12
12
}
13
13
14
- static int readBlockContent (const unsigned char *mapData, u8 version , unsigned int datapos)
14
+ static int readBlockContent (const unsigned char *mapData, u8 contentWidth , unsigned int datapos)
15
15
{
16
- if (version >= 24 ) {
16
+ if (contentWidth == 2 ) {
17
17
size_t index = datapos << 1 ;
18
18
return (mapData[index ] << 8 ) | mapData[index + 1 ];
19
- } else if (version >= 20 ) {
20
- if (mapData[datapos] <= 0x80 )
21
- return mapData[datapos];
19
+ } else {
20
+ u8 param = mapData[datapos];
21
+ if (param <= 0x7f )
22
+ return param;
22
23
else
23
- return (int (mapData[datapos] ) << 4 ) | (int (mapData[datapos + 0x2000 ]) >> 4 );
24
+ return (int (param ) << 4 ) | (int (mapData[datapos + 0x2000 ]) >> 4 );
24
25
}
25
- std::ostringstream oss;
26
- oss << " Unsupported map version " << version;
27
- throw std::runtime_error (oss.str ());
28
26
}
29
27
30
28
BlockDecoder::BlockDecoder ()
@@ -39,6 +37,7 @@ void BlockDecoder::reset()
39
37
m_nameMap.clear ();
40
38
41
39
m_version = 0 ;
40
+ m_contentWidth = 0 ;
42
41
m_mapData = ustring ();
43
42
}
44
43
@@ -50,25 +49,37 @@ void BlockDecoder::decode(const ustring &datastr)
50
49
51
50
uint8_t version = data[0 ];
52
51
// uint8_t flags = data[1];
52
+ if (version < 22 ) {
53
+ std::ostringstream oss;
54
+ oss << " Unsupported map version " << (int )version;
55
+ throw std::runtime_error (oss.str ());
56
+ }
53
57
m_version = version;
54
58
55
59
size_t dataOffset = 0 ;
56
60
if (version >= 27 )
57
- dataOffset = 6 ;
58
- else if (version >= 22 )
59
61
dataOffset = 4 ;
60
62
else
61
63
dataOffset = 2 ;
62
64
65
+ uint8_t contentWidth = data[dataOffset];
66
+ dataOffset++;
67
+ uint8_t paramsWidth = data[dataOffset];
68
+ dataOffset++;
69
+ if (contentWidth != 1 && contentWidth != 2 )
70
+ throw std::runtime_error (" unsupported map version (contentWidth)" );
71
+ if (paramsWidth != 2 )
72
+ throw std::runtime_error (" unsupported map version (paramsWidth)" );
73
+ m_contentWidth = contentWidth;
74
+
75
+
63
76
ZlibDecompressor decompressor (data, length);
64
77
decompressor.setSeekPos (dataOffset);
65
78
m_mapData = decompressor.decompress ();
66
79
decompressor.decompress (); // unused metadata
67
80
dataOffset = decompressor.seekPos ();
68
81
69
82
// Skip unused data
70
- if (version <= 21 )
71
- dataOffset += 2 ;
72
83
if (version == 23 )
73
84
dataOffset += 1 ;
74
85
if (version == 24 ) {
@@ -92,7 +103,7 @@ void BlockDecoder::decode(const ustring &datastr)
92
103
dataOffset += 4 ; // Skip timestamp
93
104
94
105
// Read mapping
95
- if (version >= 22 ) {
106
+ {
96
107
dataOffset++; // mapping version
97
108
uint16_t numMappings = readU16 (data + dataOffset);
98
109
dataOffset += 2 ;
@@ -130,7 +141,7 @@ bool BlockDecoder::isEmpty() const
130
141
std::string BlockDecoder::getNode (u8 x, u8 y, u8 z) const
131
142
{
132
143
unsigned int position = x + (y << 4 ) + (z << 8 );
133
- int content = readBlockContent (m_mapData.c_str (), m_version , position);
144
+ int content = readBlockContent (m_mapData.c_str (), m_contentWidth , position);
134
145
if (content == m_blockAirId || content == m_blockIgnoreId)
135
146
return " " ;
136
147
NameMap::const_iterator it = m_nameMap.find (content);
0 commit comments