Skip to content

Commit 2979dc5

Browse files
committedMay 6, 2020
Fix compatibility of MapBlock decoding
also properly drop support for version < 22, which hasn't worked in years
1 parent 92f6b05 commit 2979dc5

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed
 

Diff for: ‎BlockDecoder.cpp

+26-15
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,18 @@ static inline uint16_t readU16(const unsigned char *data)
1111
return data[0] << 8 | data[1];
1212
}
1313

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)
1515
{
16-
if (version >= 24) {
16+
if (contentWidth == 2) {
1717
size_t index = datapos << 1;
1818
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;
2223
else
23-
return (int(mapData[datapos]) << 4) | (int(mapData[datapos + 0x2000]) >> 4);
24+
return (int(param) << 4) | (int(mapData[datapos + 0x2000]) >> 4);
2425
}
25-
std::ostringstream oss;
26-
oss << "Unsupported map version " << version;
27-
throw std::runtime_error(oss.str());
2826
}
2927

3028
BlockDecoder::BlockDecoder()
@@ -39,6 +37,7 @@ void BlockDecoder::reset()
3937
m_nameMap.clear();
4038

4139
m_version = 0;
40+
m_contentWidth = 0;
4241
m_mapData = ustring();
4342
}
4443

@@ -50,25 +49,37 @@ void BlockDecoder::decode(const ustring &datastr)
5049

5150
uint8_t version = data[0];
5251
//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+
}
5357
m_version = version;
5458

5559
size_t dataOffset = 0;
5660
if (version >= 27)
57-
dataOffset = 6;
58-
else if (version >= 22)
5961
dataOffset = 4;
6062
else
6163
dataOffset = 2;
6264

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+
6376
ZlibDecompressor decompressor(data, length);
6477
decompressor.setSeekPos(dataOffset);
6578
m_mapData = decompressor.decompress();
6679
decompressor.decompress(); // unused metadata
6780
dataOffset = decompressor.seekPos();
6881

6982
// Skip unused data
70-
if (version <= 21)
71-
dataOffset += 2;
7283
if (version == 23)
7384
dataOffset += 1;
7485
if (version == 24) {
@@ -92,7 +103,7 @@ void BlockDecoder::decode(const ustring &datastr)
92103
dataOffset += 4; // Skip timestamp
93104

94105
// Read mapping
95-
if (version >= 22) {
106+
{
96107
dataOffset++; // mapping version
97108
uint16_t numMappings = readU16(data + dataOffset);
98109
dataOffset += 2;
@@ -130,7 +141,7 @@ bool BlockDecoder::isEmpty() const
130141
std::string BlockDecoder::getNode(u8 x, u8 y, u8 z) const
131142
{
132143
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);
134145
if (content == m_blockAirId || content == m_blockIgnoreId)
135146
return "";
136147
NameMap::const_iterator it = m_nameMap.find(content);

Diff for: ‎include/BlockDecoder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class BlockDecoder {
2020
int m_blockAirId;
2121
int m_blockIgnoreId;
2222

23-
u8 m_version;
23+
u8 m_version, m_contentWidth;
2424
ustring m_mapData;
2525
};
2626

0 commit comments

Comments
 (0)
Please sign in to comment.