1
0

Added cBlockArea serialization to string.

Fixes #665.
This commit is contained in:
madmaxoft
2014-03-07 09:17:13 +01:00
parent 3e80e63665
commit 97d803e34f
3 changed files with 202 additions and 38 deletions

View File

@@ -1,10 +1,18 @@
// SchematicFileSerializer.cpp
// Implements the cSchematicFileSerializer class representing the interface to load and save cBlockArea to a .schematic file
#include "Globals.h"
#include "OSSupport/GZipFile.h"
#include "FastNBT.h"
#include "SchematicFileSerializer.h"
#include "../StringCompression.h"
bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName)
{
@@ -40,48 +48,51 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c
bool cSchematicFileSerializer::SaveToSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName)
bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData)
{
cFastNBTWriter Writer("Schematic");
Writer.AddShort("Width", a_BlockArea.m_SizeX);
Writer.AddShort("Height", a_BlockArea.m_SizeY);
Writer.AddShort("Length", a_BlockArea.m_SizeZ);
Writer.AddString("Materials", "Alpha");
if (a_BlockArea.HasBlockTypes())
// Uncompress the data:
AString UngzippedData;
if (UncompressStringGZIP(a_SchematicData.data(), a_SchematicData.size(), UngzippedData) != Z_OK)
{
Writer.AddByteArray("Blocks", (const char *)a_BlockArea.m_BlockTypes, a_BlockArea.GetBlockCount());
LOG("%s: Cannot unGZip the schematic data.", __FUNCTION__);
return false;
}
else
// Parse the NBT:
cParsedNBT NBT(UngzippedData.data(), UngzippedData.size());
if (!NBT.IsValid())
{
AString Dummy(a_BlockArea.GetBlockCount(), 0);
Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size());
LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__);
return false;
}
if (a_BlockArea.HasBlockMetas())
return LoadFromSchematicNBT(a_BlockArea, NBT);
}
bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName)
{
// Serialize into NBT data:
AString NBT = SaveToSchematicNBT(a_BlockArea);
if (NBT.empty())
{
Writer.AddByteArray("Data", (const char *)a_BlockArea.m_BlockMetas, a_BlockArea.GetBlockCount());
LOG("%s: Cannot serialize the area into an NBT representation for file \"%s\".", __FUNCTION__, a_FileName.c_str());
return false;
}
else
{
AString Dummy(a_BlockArea.GetBlockCount(), 0);
Writer.AddByteArray("Data", Dummy.data(), Dummy.size());
}
// TODO: Save entities and block entities
Writer.BeginList("Entities", TAG_Compound);
Writer.EndList();
Writer.BeginList("TileEntities", TAG_Compound);
Writer.EndList();
Writer.Finish();
// Save to file
cGZipFile File;
if (!File.Open(a_FileName, cGZipFile::fmWrite))
{
LOG("Cannot open file \"%s\" for writing.", a_FileName.c_str());
LOG("%s: Cannot open file \"%s\" for writing.", __FUNCTION__, a_FileName.c_str());
return false;
}
if (!File.Write(Writer.GetResult()))
if (!File.Write(NBT))
{
LOG("Cannot write data to file \"%s\".", a_FileName.c_str());
LOG("%s: Cannot write data to file \"%s\".", __FUNCTION__, a_FileName.c_str());
return false;
}
return true;
@@ -92,6 +103,31 @@ bool cSchematicFileSerializer::SaveToSchematicFile(cBlockArea & a_BlockArea, con
AString cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockArea)
{
// Serialize into NBT data:
AString NBT = SaveToSchematicNBT(a_BlockArea);
if (NBT.empty())
{
LOG("%s: Cannot serialize the area into an NBT representation.", __FUNCTION__);
return false;
}
// Gzip the data:
AString Compressed;
int res = CompressStringGZIP(NBT.data(), NBT.size(), Compressed);
if (res != Z_OK)
{
LOG("%s: Cannot Gzip the area data NBT representation: %d", __FUNCTION__, res);
return false;
}
return Compressed;
}
bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cParsedNBT & a_NBT)
{
int TMaterials = a_NBT.FindChildByName(a_NBT.GetRoot(), "Materials");
@@ -170,3 +206,45 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP
}
AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockArea)
{
cFastNBTWriter Writer("Schematic");
Writer.AddShort("Width", a_BlockArea.m_SizeX);
Writer.AddShort("Height", a_BlockArea.m_SizeY);
Writer.AddShort("Length", a_BlockArea.m_SizeZ);
Writer.AddString("Materials", "Alpha");
if (a_BlockArea.HasBlockTypes())
{
Writer.AddByteArray("Blocks", (const char *)a_BlockArea.m_BlockTypes, a_BlockArea.GetBlockCount());
}
else
{
AString Dummy(a_BlockArea.GetBlockCount(), 0);
Writer.AddByteArray("Blocks", Dummy.data(), Dummy.size());
}
if (a_BlockArea.HasBlockMetas())
{
Writer.AddByteArray("Data", (const char *)a_BlockArea.m_BlockMetas, a_BlockArea.GetBlockCount());
}
else
{
AString Dummy(a_BlockArea.GetBlockCount(), 0);
Writer.AddByteArray("Data", Dummy.data(), Dummy.size());
}
// TODO: Save entities and block entities
Writer.BeginList("Entities", TAG_Compound);
Writer.EndList();
Writer.BeginList("TileEntities", TAG_Compound);
Writer.EndList();
Writer.Finish();
return Writer.GetResult();
}