summaryrefslogtreecommitdiffstats
path: root/src/WorldStorage
diff options
context:
space:
mode:
Diffstat (limited to 'src/WorldStorage')
-rw-r--r--src/WorldStorage/FastNBT.cpp88
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp4
-rw-r--r--src/WorldStorage/SchematicFileSerializer.cpp4
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp54
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.h2
5 files changed, 108 insertions, 44 deletions
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index ed8e8bb14..033a07601 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -10,6 +10,13 @@
+/** If a list being loaded has more than this number of items, it's considered corrupted. */
+static const int MAX_LIST_ITEMS = 10000;
+
+
+
+
+
// The number of NBT tags that are reserved when an NBT parsing is started.
// You can override this by using a cmdline define
#ifndef NBT_RESERVE_SIZE
@@ -102,7 +109,7 @@ bool cParsedNBT::ReadCompound(void)
ASSERT(m_Tags.size() > 0);
// Reads the latest tag as a compound
- int ParentIdx = (int)m_Tags.size() - 1;
+ size_t ParentIdx = m_Tags.size() - 1;
int PrevSibling = -1;
for (;;)
{
@@ -113,10 +120,10 @@ bool cParsedNBT::ReadCompound(void)
{
break;
}
- m_Tags.push_back(cFastNBTTag(TagType, ParentIdx, PrevSibling));
+ m_Tags.push_back(cFastNBTTag(TagType, static_cast<int>(ParentIdx), PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
+ m_Tags[static_cast<size_t>(PrevSibling)].m_NextSibling = (int)m_Tags.size() - 1;
}
else
{
@@ -142,26 +149,27 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType)
NEEDBYTES(4);
int Count = GetBEInt(m_Data + m_Pos);
m_Pos += 4;
- if (Count < 0)
+ if ((Count < 0) || (Count > MAX_LIST_ITEMS))
{
return false;
}
// Read items:
- int ParentIdx = (int)m_Tags.size() - 1;
+ ASSERT(m_Tags.size() > 0);
+ size_t ParentIdx = m_Tags.size() - 1;
int PrevSibling = -1;
for (int i = 0; i < Count; i++)
{
- m_Tags.push_back(cFastNBTTag(a_ChildrenType, ParentIdx, PrevSibling));
+ m_Tags.push_back(cFastNBTTag(a_ChildrenType, static_cast<int>(ParentIdx), PrevSibling));
if (PrevSibling >= 0)
{
- m_Tags[PrevSibling].m_NextSibling = (int)m_Tags.size() - 1;
+ m_Tags[static_cast<size_t>(PrevSibling)].m_NextSibling = static_cast<int>(m_Tags.size()) - 1;
}
else
{
- m_Tags[ParentIdx].m_FirstChild = (int)m_Tags.size() - 1;
+ m_Tags[ParentIdx].m_FirstChild = static_cast<int>(m_Tags.size()) - 1;
}
- PrevSibling = (int)m_Tags.size() - 1;
+ PrevSibling = static_cast<int>(m_Tags.size()) - 1;
RETURN_FALSE_IF_FALSE(ReadTag());
} // for (i)
m_Tags[ParentIdx].m_LastChild = PrevSibling;
@@ -210,16 +218,16 @@ bool cParsedNBT::ReadTag(void)
return false;
}
NEEDBYTES(len);
- Tag.m_DataLength = len;
+ Tag.m_DataLength = static_cast<size_t>(len);
Tag.m_DataStart = m_Pos;
- m_Pos += len;
+ m_Pos += static_cast<size_t>(len);
return true;
}
case TAG_List:
{
NEEDBYTES(1);
- eTagType ItemType = (eTagType)m_Data[m_Pos];
+ eTagType ItemType = static_cast<eTagType>(m_Data[m_Pos]);
m_Pos++;
RETURN_FALSE_IF_FALSE(ReadList(ItemType));
return true;
@@ -243,9 +251,9 @@ bool cParsedNBT::ReadTag(void)
}
len *= 4;
NEEDBYTES(len);
- Tag.m_DataLength = len;
+ Tag.m_DataLength = static_cast<size_t>(len);
Tag.m_DataStart = m_Pos;
- m_Pos += len;
+ m_Pos += static_cast<size_t>(len);
return true;
}
@@ -269,7 +277,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
{
return -1;
}
- if (m_Tags[a_Tag].m_Type != TAG_Compound)
+ if (m_Tags[static_cast<size_t>(a_Tag)].m_Type != TAG_Compound)
{
return -1;
}
@@ -278,11 +286,11 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen
{
a_NameLength = strlen(a_Name);
}
- for (int Child = m_Tags[a_Tag].m_FirstChild; Child != -1; Child = m_Tags[Child].m_NextSibling)
+ for (int Child = m_Tags[static_cast<size_t>(a_Tag)].m_FirstChild; Child != -1; Child = m_Tags[static_cast<size_t>(Child)].m_NextSibling)
{
if (
- (m_Tags[Child].m_NameLength == a_NameLength) &&
- (memcmp(m_Data + m_Tags[Child].m_NameStart, a_Name, a_NameLength) == 0)
+ (m_Tags[static_cast<size_t>(Child)].m_NameLength == a_NameLength) &&
+ (memcmp(m_Data + m_Tags[static_cast<size_t>(Child)].m_NameStart, a_Name, a_NameLength) == 0)
)
{
return Child;
@@ -406,7 +414,7 @@ void cFastNBTWriter::EndList(void)
ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List);
// Update the list count:
- SetBEInt((char *)(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);
+ SetBEInt(const_cast<char *>(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count);
--m_CurrentStack;
}
@@ -418,7 +426,7 @@ void cFastNBTWriter::EndList(void)
void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
{
TagCommon(a_Name, TAG_Byte);
- m_Result.push_back(a_Value);
+ m_Result.push_back(static_cast<char>(a_Value));
}
@@ -428,8 +436,8 @@ void cFastNBTWriter::AddByte(const AString & a_Name, unsigned char a_Value)
void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
{
TagCommon(a_Name, TAG_Short);
- Int16 Value = htons(a_Value);
- m_Result.append((const char *)&Value, 2);
+ UInt16 Value = htons(a_Value);
+ m_Result.append(reinterpret_cast<const char *>(&Value), 2);
}
@@ -439,8 +447,8 @@ void cFastNBTWriter::AddShort(const AString & a_Name, Int16 a_Value)
void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
{
TagCommon(a_Name, TAG_Int);
- Int32 Value = htonl(a_Value);
- m_Result.append((const char *)&Value, 4);
+ UInt32 Value = htonl(a_Value);
+ m_Result.append(reinterpret_cast<const char *>(&Value), 4);
}
@@ -450,8 +458,8 @@ void cFastNBTWriter::AddInt(const AString & a_Name, Int32 a_Value)
void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
{
TagCommon(a_Name, TAG_Long);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
+ UInt64 Value = HostToNetwork8(&a_Value);
+ m_Result.append(reinterpret_cast<const char *>(&Value), 8);
}
@@ -461,8 +469,8 @@ void cFastNBTWriter::AddLong(const AString & a_Name, Int64 a_Value)
void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
{
TagCommon(a_Name, TAG_Float);
- Int32 Value = HostToNetwork4(&a_Value);
- m_Result.append((const char *)&Value, 4);
+ UInt32 Value = HostToNetwork4(&a_Value);
+ m_Result.append(reinterpret_cast<const char *>(&Value), 4);
}
@@ -472,8 +480,8 @@ void cFastNBTWriter::AddFloat(const AString & a_Name, float a_Value)
void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
{
TagCommon(a_Name, TAG_Double);
- Int64 Value = HostToNetwork8(&a_Value);
- m_Result.append((const char *)&Value, 8);
+ UInt64 Value = HostToNetwork8(&a_Value);
+ m_Result.append(reinterpret_cast<const char *>(&Value), 8);
}
@@ -483,8 +491,8 @@ void cFastNBTWriter::AddDouble(const AString & a_Name, double a_Value)
void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
{
TagCommon(a_Name, TAG_String);
- Int16 len = htons((short)(a_Value.size()));
- m_Result.append((const char *)&len, 2);
+ UInt16 len = htons(static_cast<short>(a_Value.size()));
+ m_Result.append(reinterpret_cast<const char *>(&len), 2);
m_Result.append(a_Value.c_str(), a_Value.size());
}
@@ -495,8 +503,8 @@ void cFastNBTWriter::AddString(const AString & a_Name, const AString & a_Value)
void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_ByteArray);
- u_long len = htonl((u_long)a_NumElements);
- m_Result.append((const char *)&len, 4);
+ u_long len = htonl(static_cast<u_long>(a_NumElements));
+ m_Result.append(reinterpret_cast<const char *>(&len), 4);
m_Result.append(a_Value, a_NumElements);
}
@@ -507,18 +515,18 @@ void cFastNBTWriter::AddByteArray(const AString & a_Name, const char * a_Value,
void cFastNBTWriter::AddIntArray(const AString & a_Name, const int * a_Value, size_t a_NumElements)
{
TagCommon(a_Name, TAG_IntArray);
- u_long len = htonl((u_long)a_NumElements);
+ u_long len = htonl(static_cast<u_long>(a_NumElements));
size_t cap = m_Result.capacity();
size_t size = m_Result.length();
if ((cap - size) < (4 + a_NumElements * 4))
{
m_Result.reserve(size + 4 + (a_NumElements * 4));
}
- m_Result.append((const char *)&len, 4);
+ m_Result.append(reinterpret_cast<const char *>(&len), 4);
for (size_t i = 0; i < a_NumElements; i++)
{
- int Element = htonl(a_Value[i]);
- m_Result.append((const char *)&Element, 4);
+ UInt32 Element = htonl(a_Value[i]);
+ m_Result.append(reinterpret_cast<const char *>(&Element), 4);
}
}
@@ -538,8 +546,8 @@ void cFastNBTWriter::Finish(void)
void cFastNBTWriter::WriteString(const char * a_Data, UInt16 a_Length)
{
- Int16 Len = htons(a_Length);
- m_Result.append((const char *)&Len, 2);
+ UInt16 Len = htons(a_Length);
+ m_Result.append(reinterpret_cast<const char *>(&Len), 2);
m_Result.append(a_Data, a_Length);
}
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 432e122b5..c87397542 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -495,12 +495,14 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtEnderman: EntityClass = "Enderman"; break;
case mtGhast: EntityClass = "Ghast"; break;
case mtGiant: EntityClass = "Giant"; break;
+ case mtGuardian: EntityClass = "Guardian"; break;
case mtHorse: EntityClass = "Horse"; break;
case mtIronGolem: EntityClass = "VillagerGolem"; break;
case mtMagmaCube: EntityClass = "LavaSlime"; break;
case mtMooshroom: EntityClass = "MushroomCow"; break;
case mtOcelot: EntityClass = "Ozelot"; break;
case mtPig: EntityClass = "Pig"; break;
+ case mtRabbit: EntityClass = "Rabbit"; break;
case mtSheep: EntityClass = "Sheep"; break;
case mtSilverfish: EntityClass = "Silverfish"; break;
case mtSkeleton: EntityClass = "Skeleton"; break;
@@ -627,10 +629,12 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtEnderDragon:
case mtGhast:
case mtGiant:
+ case mtGuardian:
case mtIronGolem:
case mtMooshroom:
case mtOcelot:
case mtPig:
+ case mtRabbit:
case mtSilverfish:
case mtSnowGolem:
case mtSpider:
diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp
index 64f4cb00d..fb881e290 100644
--- a/src/WorldStorage/SchematicFileSerializer.cpp
+++ b/src/WorldStorage/SchematicFileSerializer.cpp
@@ -184,7 +184,9 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
{
LOG("Dimensions are missing from the schematic file (%d, %d, %d), (%d, %d, %d)",
TSizeX, TSizeY, TSizeZ,
- a_NBT.GetType(TSizeX), a_NBT.GetType(TSizeY), a_NBT.GetType(TSizeZ)
+ (TSizeX >= 0) ? a_NBT.GetType(TSizeX) : -1,
+ (TSizeY >= 0) ? a_NBT.GetType(TSizeY) : -1,
+ (TSizeZ >= 0) ? a_NBT.GetType(TSizeZ) : -1
);
return false;
}
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index af65db700..a76e9461a 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -1410,6 +1410,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadGiantFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ else if (strncmp(a_IDTag, "Guardian", a_IDTagLength) == 0)
+ {
+ LoadGuardianFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
else if (strncmp(a_IDTag, "Horse", a_IDTagLength) == 0)
{
LoadHorseFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
@@ -1438,6 +1442,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
LoadPigFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
}
+ else if (strncmp(a_IDTag, "Rabbit", a_IDTagLength) == 0)
+ {
+ LoadRabbitFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
+ }
else if (strncmp(a_IDTag, "Sheep", a_IDTagLength) == 0)
{
LoadSheepFromNBT(a_Entities, a_NBT, a_EntityTagIdx);
@@ -2197,6 +2205,26 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
+void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ std::unique_ptr<cGuardian> Monster(new cGuardian());
+ if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ a_Entities.push_back(Monster.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "Type");
@@ -2339,6 +2367,26 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
+void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
+{
+ std::unique_ptr<cRabbit> Monster(new cRabbit());
+ if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
+ {
+ return;
+ }
+
+ a_Entities.push_back(Monster.release());
+}
+
+
+
+
+
void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
{
int ColorIdx = a_NBT.FindChildByName(a_TagIdx, "Color");
@@ -2897,9 +2945,9 @@ bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int
{
return false;
}
- a_X = a_NBT.GetInt(x);
- a_Y = a_NBT.GetInt(y);
- a_Z = a_NBT.GetInt(z);
+ a_X = Clamp(a_NBT.GetInt(x), -40000000, 40000000); // World is limited to 30M blocks in XZ, we clamp to 40M
+ a_Y = Clamp(a_NBT.GetInt(y), -10000, 10000); // Y is limited to 0 .. 255, we clamp to 10K
+ a_Z = Clamp(a_NBT.GetInt(z), -40000000, 40000000);
return true;
}
diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h
index 974ba932e..362796614 100755
--- a/src/WorldStorage/WSSAnvil.h
+++ b/src/WorldStorage/WSSAnvil.h
@@ -191,12 +191,14 @@ protected:
void LoadEndermanFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadGhastFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadGiantFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadGuardianFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadHorseFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadIronGolemFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMagmaCubeFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadMooshroomFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadOcelotFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadPigFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
+ void LoadRabbitFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSheepFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSilverfishFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
void LoadSkeletonFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);