Added strict error reporting to chunk loading.
This should help with #1307.
This commit is contained in:
parent
82f2037146
commit
92a60bf4d5
@ -69,6 +69,18 @@ Since only the header is actually in the memory, this number can be high, but st
|
||||
/// The maximum size of an inflated chunk; raw chunk data is 192 KiB, allow 64 KiB more of entities
|
||||
#define CHUNK_INFLATE_MAX 256 KiB
|
||||
|
||||
#define LOAD_FAILED(CHX, CHZ) \
|
||||
{ \
|
||||
const int RegionX = FAST_FLOOR_DIV(CHX, 32); \
|
||||
const int RegionZ = FAST_FLOOR_DIV(CHZ, 32); \
|
||||
LOGERROR("%s (%d): Loading chunk [%d, %d] from file r.%d.%d.mca failed. " \
|
||||
"The server will now abort in order to avoid further data loss. " \
|
||||
"Please add the reported file and this message to the issue report.", \
|
||||
__FUNCTION__, __LINE__, CHX, CHZ, RegionX, RegionZ \
|
||||
); \
|
||||
*((int *)0) = 0; /* Crash intentionally */ \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -263,6 +275,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString &
|
||||
inflateEnd(&strm);
|
||||
if (res != Z_STREAM_END)
|
||||
{
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -271,6 +284,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString &
|
||||
if (!NBT.IsValid())
|
||||
{
|
||||
// NBT Parsing failed
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -317,11 +331,13 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT
|
||||
int Level = a_NBT.FindChildByName(0, "Level");
|
||||
if (Level < 0)
|
||||
{
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
int Sections = a_NBT.FindChildByName(Level, "Sections");
|
||||
if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound))
|
||||
{
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child))
|
||||
@ -2811,30 +2827,42 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a
|
||||
}
|
||||
unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]);
|
||||
unsigned ChunkOffset = ChunkLocation >> 8;
|
||||
if (ChunkOffset <= 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_File.Seek((int)ChunkOffset * 4096);
|
||||
|
||||
int ChunkSize = 0;
|
||||
if (m_File.Read(&ChunkSize, 4) != 4)
|
||||
{
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
ChunkSize = ntohl((u_long)ChunkSize);
|
||||
char CompressionType = 0;
|
||||
if (m_File.Read(&CompressionType, 1) != 1)
|
||||
{
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
if (CompressionType != 2)
|
||||
{
|
||||
// Chunk is in an unknown compression
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
ChunkSize--;
|
||||
|
||||
// HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
|
||||
a_Data.assign(ChunkSize, '\0');
|
||||
return (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize);
|
||||
if (m_File.Read((void *)a_Data.data(), ChunkSize) == ChunkSize)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
LOAD_FAILED(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user