From 92e85cc96030285bba74837759925866c1be7235 Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 13 Feb 2014 17:13:09 +0200 Subject: Implementation of in-game maps --- src/WorldStorage/MapSerializer.cpp | 189 +++++++++++++++++++++++++++++++++++++ src/WorldStorage/MapSerializer.h | 52 ++++++++++ 2 files changed, 241 insertions(+) create mode 100644 src/WorldStorage/MapSerializer.cpp create mode 100644 src/WorldStorage/MapSerializer.h (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp new file mode 100644 index 000000000..ea0d3ec47 --- /dev/null +++ b/src/WorldStorage/MapSerializer.cpp @@ -0,0 +1,189 @@ + +// MapSerializer.cpp + + +#include "Globals.h" +#include "MapSerializer.h" +#include "../StringCompression.h" +#include "zlib/zlib.h" +#include "FastNBT.h" + +#include "../Map.h" + + + + + +cMapSerializer::cMapSerializer(const AString& a_WorldName, cMap * a_Map) + : m_Map(a_Map) +{ + AString DataPath; + Printf(DataPath, "%s/data", a_WorldName.c_str()); + + Printf(m_Path, "%s/map_%i.dat", DataPath.c_str(), a_Map->GetID()); + + cFile::CreateFolder(FILE_IO_PREFIX + DataPath); +} + + + + + +bool cMapSerializer::Load(void) +{ + AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); + if (Data.empty()) + { + return false; + } + + AString Uncompressed; + int res = UncompressStringGZIP(Data.data(), Data.size(), Uncompressed); + + if (res != Z_OK) + { + return false; + } + + // Parse the NBT data: + cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); + if (!NBT.IsValid()) + { + // NBT Parsing failed + return false; + } + + return LoadMapFromNBT(NBT); +} + + + + + +bool cMapSerializer::Save(void) +{ + cFastNBTWriter Writer; + + SaveMapToNBT(Writer); + + Writer.Finish(); + + #ifdef _DEBUG + cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); + ASSERT(TestParse.IsValid()); + #endif // _DEBUG + + cFile File; + if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite)) + { + return false; + } + + AString Compressed; + int res = CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); + + if (res != Z_OK) + { + return false; + } + + File.Write(Compressed.data(), Compressed.size()); + File.Close(); + + return true; +} + + + + + +void cMapSerializer::SaveMapToNBT(cFastNBTWriter & a_Writer) +{ + a_Writer.BeginCompound("data"); + + a_Writer.AddByte("scale", m_Map->GetScale()); + a_Writer.AddByte("dimension", (int) m_Map->GetDimension()); + + a_Writer.AddShort("width", m_Map->GetWidth()); + a_Writer.AddShort("height", m_Map->GetHeight()); + + a_Writer.AddInt("xCenter", m_Map->GetCenterX()); + a_Writer.AddInt("zCenter", m_Map->GetCenterZ()); + + // Potential bug - The internal representation may change + const cMap::cColorList & Data = m_Map->GetData(); + a_Writer.AddByteArray("colors", (char *) Data.data(), Data.size()); + + a_Writer.EndCompound(); +} + + + + + +bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) +{ + int Data = a_NBT.FindChildByName(0, "data"); + if (Data < 0) + { + return false; + } + + int CurrLine = a_NBT.FindChildByName(Data, "scale"); + if (CurrLine >= 0) + { + unsigned int Scale = a_NBT.GetByte(CurrLine); + m_Map->m_Scale = Scale; + } + + CurrLine = a_NBT.FindChildByName(Data, "dimension"); + if (CurrLine >= 0) + { + eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); + + // ASSERT(Dimension == m_World.GetDimension()); + } + + CurrLine = a_NBT.FindChildByName(Data, "width"); + if (CurrLine >= 0) + { + unsigned int Width = a_NBT.GetShort(CurrLine); + m_Map->m_Width = Width; + } + + CurrLine = a_NBT.FindChildByName(Data, "height"); + if (CurrLine >= 0) + { + unsigned int Height = a_NBT.GetShort(CurrLine); + m_Map->m_Height = Height; + } + + CurrLine = a_NBT.FindChildByName(Data, "xCenter"); + if (CurrLine >= 0) + { + int CenterX = a_NBT.GetInt(CurrLine); + m_Map->m_CenterX = CenterX; + } + + CurrLine = a_NBT.FindChildByName(Data, "zCenter"); + if (CurrLine >= 0) + { + int CenterZ = a_NBT.GetInt(CurrLine); + m_Map->m_CenterZ = CenterZ; + } + + unsigned int NumPixels = m_Map->GetNumPixels(); + m_Map->m_Data.resize(NumPixels); + + // TODO xdot: Parse the byte array. + + return true; +} + + + + + + + + diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h new file mode 100644 index 000000000..71791a2fb --- /dev/null +++ b/src/WorldStorage/MapSerializer.h @@ -0,0 +1,52 @@ + +// MapSerializer.h + +// Declares the cMapSerializer class that is used for saving maps into NBT format used by Anvil + + + + + +#pragma once + + + + + +// fwd: +class cFastNBTWriter; +class cParsedNBT; +class cMap; + + + + +class cMapSerializer +{ +public: + + cMapSerializer(const AString& a_WorldName, cMap * a_Map); + + /// Try to load the scoreboard + bool Load(void); + + /// Try to save the scoreboard + bool Save(void); + + +private: + + void SaveMapToNBT(cFastNBTWriter & a_Writer); + + bool LoadMapFromNBT(const cParsedNBT & a_NBT); + + cMap * m_Map; + + AString m_Path; + + +} ; + + + + -- cgit v1.2.3 From 32b465b8e1e1a6fa9e966a1376209f292331d4ae Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 13 Feb 2014 21:36:24 +0200 Subject: IDCount Serialization --- src/WorldStorage/MapSerializer.cpp | 79 +++++++++++++++++++++++++++++++++++++- src/WorldStorage/MapSerializer.h | 25 ++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index ea0d3ec47..aab4c7816 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -9,6 +9,7 @@ #include "FastNBT.h" #include "../Map.h" +#include "../World.h" @@ -141,7 +142,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); - // ASSERT(Dimension == m_World.GetDimension()); + ASSERT(Dimension == m_Map->m_World->GetDimension()); } CurrLine = a_NBT.FindChildByName(Data, "width"); @@ -184,6 +185,82 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) +cIDCountSerializer::cIDCountSerializer(const AString & a_WorldName) : m_MapCount(0) +{ + AString DataPath; + Printf(DataPath, "%s/data", a_WorldName.c_str()); + + Printf(m_Path, "%s/idcounts.dat", DataPath.c_str()); + + cFile::CreateFolder(FILE_IO_PREFIX + DataPath); +} + + + + + +bool cIDCountSerializer::Load(void) +{ + AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); + if (Data.empty()) + { + return false; + } + + // NOTE: idcounts.dat is not compressed (raw format) + + // Parse the NBT data: + cParsedNBT NBT(Data.data(), Data.size()); + if (!NBT.IsValid()) + { + // NBT Parsing failed + return false; + } + + int CurrLine = NBT.FindChildByName(0, "map"); + if (CurrLine >= 0) + { + m_MapCount = (int)NBT.GetShort(CurrLine); + } + + return true; +} + + + + + +bool cIDCountSerializer::Save(void) +{ + cFastNBTWriter Writer; + + Writer.AddShort("map", m_MapCount); + + Writer.Finish(); + + #ifdef _DEBUG + cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); + ASSERT(TestParse.IsValid()); + #endif // _DEBUG + + cFile File; + if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite)) + { + return false; + } + + // NOTE: idcounts.dat is not compressed (raw format) + + File.Write(Writer.GetResult().data(), Writer.GetResult().size()); + File.Close(); + + return true; +} + + + + + diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index 71791a2fb..d9da107bc 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -50,3 +50,28 @@ private: +class cIDCountSerializer +{ +public: + + cIDCountSerializer(const AString & a_WorldName); + + bool Load(void); + + bool Save(void); + + inline unsigned int GetMapCount(void) const { return m_MapCount; } + + inline void SetMapCount(unsigned int a_MapCount) { m_MapCount = a_MapCount; } + + +private: + + AString m_Path; + + unsigned int m_MapCount; +}; + + + + -- cgit v1.2.3 From 5b92b877bcc0c5072dbea98b6c54106f954aa758 Mon Sep 17 00:00:00 2001 From: andrew Date: Fri, 14 Feb 2014 16:21:16 +0200 Subject: Send map when selected --- src/WorldStorage/MapSerializer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index aab4c7816..6dab19d4f 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -111,7 +111,6 @@ void cMapSerializer::SaveMapToNBT(cFastNBTWriter & a_Writer) a_Writer.AddInt("xCenter", m_Map->GetCenterX()); a_Writer.AddInt("zCenter", m_Map->GetCenterZ()); - // Potential bug - The internal representation may change const cMap::cColorList & Data = m_Map->GetData(); a_Writer.AddByteArray("colors", (char *) Data.data(), Data.size()); @@ -134,7 +133,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) if (CurrLine >= 0) { unsigned int Scale = a_NBT.GetByte(CurrLine); - m_Map->m_Scale = Scale; + m_Map->SetScale(Scale); } CurrLine = a_NBT.FindChildByName(Data, "dimension"); @@ -176,7 +175,11 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) unsigned int NumPixels = m_Map->GetNumPixels(); m_Map->m_Data.resize(NumPixels); - // TODO xdot: Parse the byte array. + CurrLine = a_NBT.FindChildByName(Data, "colors"); + if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_ByteArray)) + { + memcpy(m_Map->m_Data.data(), a_NBT.GetData(CurrLine), NumPixels); + } return true; } -- cgit v1.2.3 From 3b24bc870bb39a8b8812ed307250e1188b9ff788 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 17 Feb 2014 16:27:12 +0200 Subject: Map item handler; Fixed several bugs --- src/WorldStorage/MapSerializer.cpp | 11 +++++++++-- src/WorldStorage/MapSerializer.h | 7 +++++-- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 6dab19d4f..0bbe71a60 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -223,7 +223,11 @@ bool cIDCountSerializer::Load(void) int CurrLine = NBT.FindChildByName(0, "map"); if (CurrLine >= 0) { - m_MapCount = (int)NBT.GetShort(CurrLine); + m_MapCount = (int)NBT.GetShort(CurrLine) + 1; + } + else + { + m_MapCount = 0; } return true; @@ -237,7 +241,10 @@ bool cIDCountSerializer::Save(void) { cFastNBTWriter Writer; - Writer.AddShort("map", m_MapCount); + if (m_MapCount > 0) + { + Writer.AddShort("map", m_MapCount - 1); + } Writer.Finish(); diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index d9da107bc..296cc92c8 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -27,10 +27,10 @@ public: cMapSerializer(const AString& a_WorldName, cMap * a_Map); - /// Try to load the scoreboard + /** Try to load the scoreboard */ bool Load(void); - /// Try to save the scoreboard + /** Try to save the scoreboard */ bool Save(void); @@ -56,8 +56,10 @@ public: cIDCountSerializer(const AString & a_WorldName); + /** Try to load the ID counts */ bool Load(void); + /** Try to save the ID counts */ bool Save(void); inline unsigned int GetMapCount(void) const { return m_MapCount; } @@ -70,6 +72,7 @@ private: AString m_Path; unsigned int m_MapCount; + }; -- cgit v1.2.3 From 4a1ac5740869356880523dde83ec0b7804689d42 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 19 Feb 2014 15:28:48 +0200 Subject: Documented cMap --- src/WorldStorage/MapSerializer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index 296cc92c8..85fe917f5 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -21,6 +21,7 @@ class cMap; +/** Utility class used to serialize maps. */ class cMapSerializer { public: @@ -50,6 +51,7 @@ private: +/** Utility class used to serialize item ID counts. */ class cIDCountSerializer { public: -- cgit v1.2.3 From f47187394572027cbfa07884cba2f54eaa6972ec Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 23 Feb 2014 15:03:40 +0200 Subject: Maps: Improvements --- src/WorldStorage/MapSerializer.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index 85fe917f5..eb7678a08 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -51,7 +51,11 @@ private: -/** Utility class used to serialize item ID counts. */ +/** Utility class used to serialize item ID counts. + * + * In order to perform bounds checking (while loading), + * the last registered ID of each item is serialized to an NBT file. + */ class cIDCountSerializer { public: -- cgit v1.2.3