parent
3e80e63665
commit
97d803e34f
@ -2483,6 +2483,37 @@ static int tolua_cBlockArea_LoadFromSchematicFile(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_LoadFromSchematicString(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::LoadFromSchematicString
|
||||
// Exported manually because function has been moved to SchematicFileSerilizer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
!L.CheckParamString (2) ||
|
||||
!L.CheckParamEnd (3)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::LoadFromSchematicFile'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AString Data;
|
||||
L.GetStackValue(2, Data);
|
||||
bool res = cSchematicFileSerializer::LoadFromSchematicString(*self, Data);
|
||||
tolua_pushboolean(tolua_S, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::SaveToSchematicFile
|
||||
@ -2512,6 +2543,34 @@ static int tolua_cBlockArea_SaveToSchematicFile(lua_State * tolua_S)
|
||||
|
||||
|
||||
|
||||
static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S)
|
||||
{
|
||||
// function cBlockArea::SaveToSchematicString
|
||||
// Exported manually because function has been moved to SchematicFileSerilizer.cpp
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserType(1, "cBlockArea") ||
|
||||
!L.CheckParamEnd (2)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cBlockArea * self = (cBlockArea *)tolua_tousertype(tolua_S, 1, NULL);
|
||||
if (self == NULL)
|
||||
{
|
||||
tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AString Data = cSchematicFileSerializer::SaveToSchematicString(*self);
|
||||
L.Push(Data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S)
|
||||
{
|
||||
// function cCompositeChat:AddRunCommandPart(Message, Command, [Style])
|
||||
@ -2775,12 +2834,14 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cBlockArea");
|
||||
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
|
||||
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
|
||||
tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile);
|
||||
tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile);
|
||||
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cBlockArea_GetBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetOrigin", tolua_cBlockArea_GetOrigin);
|
||||
tolua_function(tolua_S, "GetRelBlockTypeMeta", tolua_cBlockArea_GetRelBlockTypeMeta);
|
||||
tolua_function(tolua_S, "GetSize", tolua_cBlockArea_GetSize);
|
||||
tolua_function(tolua_S, "LoadFromSchematicFile", tolua_cBlockArea_LoadFromSchematicFile);
|
||||
tolua_function(tolua_S, "LoadFromSchematicString", tolua_cBlockArea_LoadFromSchematicString);
|
||||
tolua_function(tolua_S, "SaveToSchematicFile", tolua_cBlockArea_SaveToSchematicFile);
|
||||
tolua_function(tolua_S, "SaveToSchematicString", tolua_cBlockArea_SaveToSchematicString);
|
||||
tolua_endmodule(tolua_S);
|
||||
|
||||
tolua_beginmodule(tolua_S, "cCompositeChat");
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,12 @@
|
||||
|
||||
// SchematicFileSerializer.h
|
||||
|
||||
// Declares the cSchematicFileSerializer class representing the interface to load and save cBlockArea to a .schematic file
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BlockArea.h"
|
||||
@ -13,17 +21,34 @@ class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
|
||||
class cSchematicFileSerializer
|
||||
{
|
||||
public:
|
||||
|
||||
/// Loads an area from a .schematic file. Returns true if successful
|
||||
/** Loads an area from a .schematic file. Returns true if successful. */
|
||||
static bool LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName);
|
||||
|
||||
/// Saves the area into a .schematic file. Returns true if successful
|
||||
static bool SaveToSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName);
|
||||
/** Loads an area from a string containing the .schematic file data. Returns true if successful. */
|
||||
static bool LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData);
|
||||
|
||||
/** Saves the area into a .schematic file. Returns true if successful. */
|
||||
static bool SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName);
|
||||
|
||||
/** Saves the area into a string containing the .schematic file data.
|
||||
Returns the data, or empty string if failed. */
|
||||
static AString SaveToSchematicString(const cBlockArea & a_BlockArea);
|
||||
|
||||
private:
|
||||
/// Loads the area from a schematic file uncompressed and parsed into a NBT tree. Returns true if successful.
|
||||
/** Loads the area from a schematic file uncompressed and parsed into a NBT tree.
|
||||
Returns true if successful. */
|
||||
static bool LoadFromSchematicNBT(cBlockArea & a_BlockArea, cParsedNBT & a_NBT);
|
||||
|
||||
/** Saves the area into a NBT representation and returns the NBT data as a string.
|
||||
Returns an empty string if failed. */
|
||||
static AString SaveToSchematicNBT(const cBlockArea & a_BlockArea);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user