diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2021-03-05 14:03:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-05 14:03:55 +0100 |
commit | 868cd94ee9a5a0638c014a4cc42224f01ff234c8 (patch) | |
tree | cd23dc866f77de5b0b3e89a5eafeeb2ef24ffbdd /src/WorldStorage/NBTChunkSerializer.cpp | |
parent | fixed the crash on generating in the SinglePiceStructuresGen (#5136) (diff) | |
download | cuberite-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.cpp | 94 |
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. |