summaryrefslogtreecommitdiffstats
path: root/src/WorldStorage/NBTChunkSerializer.cpp
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@outlook.com>2021-03-05 14:03:55 +0100
committerGitHub <noreply@github.com>2021-03-05 14:03:55 +0100
commit868cd94ee9a5a0638c014a4cc42224f01ff234c8 (patch)
treecd23dc866f77de5b0b3e89a5eafeeb2ef24ffbdd /src/WorldStorage/NBTChunkSerializer.cpp
parentfixed the crash on generating in the SinglePiceStructuresGen (#5136) (diff)
downloadcuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.gz
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.bz2
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.lz
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.xz
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.tar.zst
cuberite-868cd94ee9a5a0638c014a4cc42224f01ff234c8.zip
Diffstat (limited to '')
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp94
1 files changed, 49 insertions, 45 deletions
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 2542cd2da..714c65a91 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -53,16 +53,14 @@
/** Collects and stores the chunk data via the cChunkDataCallback interface */
-class SerializerCollector:
+class SerializerCollector final :
public cChunkDataCopyCollector
{
public:
// The data collected from the chunk:
- cChunkDef::BiomeMap mBiomes;
- UInt8 mVanillaBiomes[cChunkDef::Width * cChunkDef::Width];
- int mVanillaHeightMap[cChunkDef::Width * cChunkDef::Width];
- bool mBiomesAreValid;
+ UInt8 Biomes[cChunkDef::Width * cChunkDef::Width];
+ int Heights[cChunkDef::Width * cChunkDef::Width];
/** True if a tag has been opened in the callbacks and not yet closed. */
bool mIsTagOpen;
@@ -84,7 +82,6 @@ public:
SerializerCollector(cFastNBTWriter & aWriter):
- mBiomesAreValid(false),
mIsTagOpen(false),
mHasHadEntity(false),
mHasHadBlockEntity(false),
@@ -106,14 +103,13 @@ public:
- virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override
+ virtual void HeightMap(const cChunkDef::HeightMap & a_HeightMap) override
{
- for (int RelX = 0; RelX < cChunkDef::Width; RelX++)
+ for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++)
{
- for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++)
+ for (int RelX = 0; RelX < cChunkDef::Width; RelX++)
{
- int Height = cChunkDef::GetHeight(*a_HeightMap, RelX, RelZ);
- mVanillaHeightMap[(RelZ << 4) | RelX] = Height;
+ Heights[RelX + RelZ * cChunkDef::Width] = cChunkDef::GetHeight(a_HeightMap, RelX, RelZ);
}
}
}
@@ -122,15 +118,14 @@ public:
- virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override
+ virtual void BiomeMap(const cChunkDef::BiomeMap & a_BiomeMap) override
{
- memcpy(mBiomes, a_BiomeMap, sizeof(mBiomes));
- for (size_t i = 0; i < ARRAYCOUNT(mBiomes); i++)
+ for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
{
- if ((*a_BiomeMap)[i] < 255)
+ if (a_BiomeMap[i] < 255)
{
// Normal MC biome, copy as-is:
- mVanillaBiomes[i] = static_cast<Byte>((*a_BiomeMap)[i]);
+ Biomes[i] = static_cast<Byte>(a_BiomeMap[i]);
}
else
{
@@ -139,7 +134,6 @@ public:
return;
}
} // for i - mBiomeMap[]
- mBiomesAreValid = true;
}
@@ -252,13 +246,6 @@ public:
mWriter.EndList();
}
- // If light not valid, reset it to defaults:
- if (!mIsLightValid)
- {
- m_Data.FillBlockLight(0x00);
- m_Data.FillSkyLight(0x0f);
- }
-
// Check if "Entity" and "TileEntities" lists exists. MCEdit requires this.
if (!mHasHadEntity)
{
@@ -1187,40 +1174,57 @@ void NBTChunkSerializer::Serialize(const cWorld & aWorld, cChunkCoords aCoords,
ASSERT(Result);
serializer.Finish(); // Close NBT tags
- // Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray):
- if (serializer.mBiomesAreValid)
- {
- aWriter.AddByteArray("Biomes", reinterpret_cast<const char *>(serializer.mVanillaBiomes), ARRAYCOUNT(serializer.mVanillaBiomes));
- aWriter.AddIntArray ("MCSBiomes", reinterpret_cast<const int *>(serializer.mBiomes), ARRAYCOUNT(serializer.mBiomes));
- }
+ // Save biomes:
+ aWriter.AddByteArray("Biomes", reinterpret_cast<const char *>(serializer.Biomes), ARRAYCOUNT(serializer.Biomes));
// Save heightmap (Vanilla require this):
- aWriter.AddIntArray("HeightMap", reinterpret_cast<const int *>(serializer.mVanillaHeightMap), ARRAYCOUNT(serializer.mVanillaHeightMap));
+ aWriter.AddIntArray("HeightMap", reinterpret_cast<const int *>(serializer.Heights), ARRAYCOUNT(serializer.Heights));
// Save blockdata:
aWriter.BeginList("Sections", TAG_Compound);
- for (size_t Y = 0; Y != cChunkData::NumSections; ++Y)
+ ChunkDef::ForEachSection(serializer.m_BlockData, serializer.m_LightData, [&aWriter](const auto Y, const auto Blocks, const auto Metas, const auto BlockLights, const auto SkyLights)
{
- auto section = serializer.m_Data.GetSection(Y);
- if (section == nullptr)
+ aWriter.BeginCompound("");
+
+ if (Blocks != nullptr)
{
- continue;
+ aWriter.AddByteArray("Blocks", reinterpret_cast<const char *>(Blocks->data()), Blocks->size());
+ }
+ else
+ {
+ aWriter.AddByteArray("Blocks", ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue);
}
- aWriter.BeginCompound("");
- aWriter.AddByteArray("Blocks", reinterpret_cast<const char *>(section->m_BlockTypes), ARRAYCOUNT(section->m_BlockTypes));
- aWriter.AddByteArray("Data", reinterpret_cast<const char *>(section->m_BlockMetas), ARRAYCOUNT(section->m_BlockMetas));
+ if (Metas != nullptr)
+ {
+ aWriter.AddByteArray("Data", reinterpret_cast<const char *>(Metas->data()), Metas->size());
+ }
+ else
+ {
+ aWriter.AddByteArray("Data", ChunkBlockData::SectionMetaCount, ChunkBlockData::DefaultMetaValue);
+ }
+
+ if (BlockLights != nullptr)
+ {
+ aWriter.AddByteArray("BlockLight", reinterpret_cast<const char *>(BlockLights->data()), BlockLights->size());
+ }
+ else
+ {
+ aWriter.AddByteArray("BlockLight", ChunkLightData::SectionLightCount, ChunkLightData::DefaultBlockLightValue);
+ }
- #ifdef DEBUG_SKYLIGHT
- aWriter.AddByteArray("BlockLight", reinterpret_cast<const char *>(section->m_BlockSkyLight), ARRAYCOUNT(section->m_BlockSkyLight));
- #else
- aWriter.AddByteArray("BlockLight", reinterpret_cast<const char *>(section->m_BlockLight), ARRAYCOUNT(section->m_BlockLight));
- #endif
+ if (SkyLights != nullptr)
+ {
+ aWriter.AddByteArray("SkyLight", reinterpret_cast<const char *>(SkyLights->data()), SkyLights->size());
+ }
+ else
+ {
+ aWriter.AddByteArray("SkyLight", ChunkLightData::SectionLightCount, ChunkLightData::DefaultSkyLightValue);
+ }
- aWriter.AddByteArray("SkyLight", reinterpret_cast<const char *>(section->m_BlockSkyLight), ARRAYCOUNT(section->m_BlockSkyLight));
aWriter.AddByte("Y", static_cast<unsigned char>(Y));
aWriter.EndCompound();
- }
+ });
aWriter.EndList(); // "Sections"
// Store the information that the lighting is valid.