diff options
author | LogicParrot <LogicParrot@users.noreply.github.com> | 2016-02-05 22:45:45 +0100 |
---|---|---|
committer | LogicParrot <LogicParrot@users.noreply.github.com> | 2016-02-05 22:50:18 +0100 |
commit | ca6ef58b1ee8521e4b940ee4883dee714960e413 (patch) | |
tree | 8532add455224b07c07a759e3d906f50c0695888 /src/WorldStorage | |
parent | Merge pull request #2972 from marvinkopf/PlayerAutoComplete (diff) | |
download | cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar.gz cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar.bz2 cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar.lz cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar.xz cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.tar.zst cuberite-ca6ef58b1ee8521e4b940ee4883dee714960e413.zip |
Diffstat (limited to 'src/WorldStorage')
-rw-r--r-- | src/WorldStorage/EnchantmentSerializer.cpp | 14 | ||||
-rw-r--r-- | src/WorldStorage/EnchantmentSerializer.h | 4 | ||||
-rw-r--r-- | src/WorldStorage/FastNBT.cpp | 44 | ||||
-rw-r--r-- | src/WorldStorage/FastNBT.h | 70 | ||||
-rw-r--r-- | src/WorldStorage/MapSerializer.cpp | 6 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 16 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.h | 18 | ||||
-rw-r--r-- | src/WorldStorage/SchematicFileSerializer.cpp | 28 | ||||
-rw-r--r-- | src/WorldStorage/SchematicFileSerializer.h | 10 | ||||
-rw-r--r-- | src/WorldStorage/ScoreboardSerializer.cpp | 8 | ||||
-rwxr-xr-x | src/WorldStorage/WSSAnvil.cpp | 240 | ||||
-rwxr-xr-x | src/WorldStorage/WSSAnvil.h | 70 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.cpp | 26 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.h | 24 |
14 files changed, 289 insertions, 289 deletions
diff --git a/src/WorldStorage/EnchantmentSerializer.cpp b/src/WorldStorage/EnchantmentSerializer.cpp index b28e16b1d..9f477f316 100644 --- a/src/WorldStorage/EnchantmentSerializer.cpp +++ b/src/WorldStorage/EnchantmentSerializer.cpp @@ -9,7 +9,7 @@ void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantme { // Write the enchantments into the specified NBT writer // begin with the LIST tag of the specified name ("ench" or "StoredEnchantments") - + a_Writer.BeginList(a_ListTagName, TAG_Compound); for (cEnchantments::cMap::const_iterator itr = a_Enchantments.m_Enchantments.begin(), end = a_Enchantments.m_Enchantments.end(); itr != end; ++itr) { @@ -38,7 +38,7 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c ASSERT(!"Bad EnchListTag type"); return; } - + // Verify that the list is of Compounds: if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound) { @@ -48,15 +48,15 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c ASSERT(!"Bad EnchListTag children type"); return; } - + a_Enchantments.Clear(); - + // Iterate over all the compound children, parse an enchantment from each: for (int tag = a_NBT.GetFirstChild(a_EnchListTagIdx); tag >= 0; tag = a_NBT.GetNextSibling(tag)) { // tag is the compound inside the "ench" list tag ASSERT(a_NBT.GetType(tag) == TAG_Compound); - + // Search for the id and lvl tags' values: int id = -1, lvl = -1; for (int ch = a_NBT.GetFirstChild(tag); ch >= 0; ch = a_NBT.GetNextSibling(ch)) @@ -74,13 +74,13 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c lvl = a_NBT.GetShort(ch); } } // for ch - children of the compound tag - + if ((id == -1) || (lvl <= 0)) { // Failed to parse either the id or the lvl, skip this compound continue; } - + // Store the enchantment: a_Enchantments.m_Enchantments[id] = static_cast<unsigned int>(lvl); } // for tag - children of the ench list tag diff --git a/src/WorldStorage/EnchantmentSerializer.h b/src/WorldStorage/EnchantmentSerializer.h index 5c12e01bc..4dc75cb86 100644 --- a/src/WorldStorage/EnchantmentSerializer.h +++ b/src/WorldStorage/EnchantmentSerializer.h @@ -14,10 +14,10 @@ namespace EnchantmentSerializer /** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */ void WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); - + /** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */ void ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); - + }; diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index 1a81a6469..608269aad 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -69,16 +69,16 @@ bool cParsedNBT::Parse(void) // The top-level tag must be a Compound return false; } - + m_Tags.reserve(NBT_RESERVE_SIZE); - + m_Tags.push_back(cFastNBTTag(TAG_Compound, -1)); - + m_Pos = 1; - + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); RETURN_FALSE_IF_FALSE(ReadCompound()); - + return true; } @@ -145,7 +145,7 @@ bool cParsedNBT::ReadCompound(void) bool cParsedNBT::ReadList(eTagType a_ChildrenType) { // Reads the latest tag as a list of items of type a_ChildrenType - + // Read the count: NEEDBYTES(4); int Count = GetBEInt(m_Data + m_Pos); @@ -190,7 +190,7 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType) m_Pos += LEN; \ return true; \ } - + bool cParsedNBT::ReadTag(void) { cFastNBTTag & Tag = m_Tags.back(); @@ -202,12 +202,12 @@ bool cParsedNBT::ReadTag(void) CASE_SIMPLE_TAG(Long, 8) CASE_SIMPLE_TAG(Float, 4) CASE_SIMPLE_TAG(Double, 8) - + case TAG_String: { return ReadString(Tag.m_DataStart, Tag.m_DataLength); } - + case TAG_ByteArray: { NEEDBYTES(4); @@ -224,7 +224,7 @@ bool cParsedNBT::ReadTag(void) m_Pos += static_cast<size_t>(len); return true; } - + case TAG_List: { NEEDBYTES(1); @@ -233,13 +233,13 @@ bool cParsedNBT::ReadTag(void) RETURN_FALSE_IF_FALSE(ReadList(ItemType)); return true; } - + case TAG_Compound: { RETURN_FALSE_IF_FALSE(ReadCompound()); return true; } - + case TAG_IntArray: { NEEDBYTES(4); @@ -257,7 +257,7 @@ bool cParsedNBT::ReadTag(void) m_Pos += static_cast<size_t>(len); return true; } - + #if !defined(__clang__) default: #endif @@ -284,7 +284,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen { return -1; } - + if (a_NameLength == 0) { a_NameLength = strlen(a_Name); @@ -328,7 +328,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const } Begin = i + 1; } // for i - a_Path[] - + if (Begin < Length) { Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin); @@ -363,9 +363,9 @@ void cFastNBTWriter::BeginCompound(const AString & a_Name) ASSERT(!"Stack overflow"); return; } - + TagCommon(a_Name, TAG_Compound); - + ++m_CurrentStack; m_Stack[m_CurrentStack].m_Type = TAG_Compound; } @@ -378,7 +378,7 @@ void cFastNBTWriter::EndCompound(void) { ASSERT(m_CurrentStack > 0); ASSERT(IsStackTopCompound()); - + m_Result.push_back(TAG_End); --m_CurrentStack; } @@ -394,12 +394,12 @@ void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType) ASSERT(!"Stack overflow"); return; } - + TagCommon(a_Name, TAG_List); - + m_Result.push_back(static_cast<char>(a_ChildrenType)); m_Result.append(4, static_cast<char>(0)); - + ++m_CurrentStack; m_Stack[m_CurrentStack].m_Type = TAG_List; m_Stack[m_CurrentStack].m_Pos = static_cast<int>(m_Result.size()) - 4; @@ -415,7 +415,7 @@ void cFastNBTWriter::EndList(void) { ASSERT(m_CurrentStack > 0); ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); - + // Update the list count: SetBEInt(const_cast<char *>(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count); diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index a23dc7af2..60c9ac293 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -56,16 +56,16 @@ Structure (all with the tree structure it describes) supports moving in memory ( struct cFastNBTTag { public: - + eTagType m_Type; - + // The following members are indices into the data stream. m_DataLength == 0 if no data available // They must not be pointers, because the datastream may be copied into another AString object in the meantime. size_t m_NameStart; size_t m_NameLength; size_t m_DataStart; size_t m_DataLength; - + // The following members are indices into the array returned; -1 if not valid // They must not be pointers, because pointers would not survive std::vector reallocation int m_Parent; @@ -73,7 +73,7 @@ public: int m_NextSibling; int m_FirstChild; int m_LastChild; - + cFastNBTTag(eTagType a_Type, int a_Parent) : m_Type(a_Type), m_NameStart(0), @@ -119,24 +119,24 @@ class cParsedNBT { public: cParsedNBT(const char * a_Data, size_t a_Length); - + bool IsValid(void) const {return m_IsValid; } - + /** Returns the root tag of the hierarchy. */ int GetRoot(void) const {return 0; } /** Returns the first child of the specified tag, or -1 if none / not applicable. */ int GetFirstChild (int a_Tag) const { return m_Tags[static_cast<size_t>(a_Tag)].m_FirstChild; } - + /** Returns the last child of the specified tag, or -1 if none / not applicable. */ int GetLastChild (int a_Tag) const { return m_Tags[static_cast<size_t>(a_Tag)].m_LastChild; } - + /** Returns the next sibling of the specified tag, or -1 if none. */ int GetNextSibling(int a_Tag) const { return m_Tags[static_cast<size_t>(a_Tag)].m_NextSibling; } - + /** Returns the previous sibling of the specified tag, or -1 if none. */ int GetPrevSibling(int a_Tag) const { return m_Tags[static_cast<size_t>(a_Tag)].m_PrevSibling; } - + /** Returns the length of the tag's data, in bytes. Not valid for Compound or List tags! */ size_t GetDataLength (int a_Tag) const @@ -154,35 +154,35 @@ public: ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type != TAG_Compound); return m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart; } - + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const AString & a_Name) const { return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); } - + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; /** Returns the child tag of the specified path (Name1 / Name2 / Name3...), or -1 if no such tag. */ int FindTagByPath(int a_Tag, const AString & a_Path) const; - + eTagType GetType(int a_Tag) const { return m_Tags[static_cast<size_t>(a_Tag)].m_Type; } - + /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_List); return (m_Tags[static_cast<size_t>(a_Tag)].m_FirstChild < 0) ? TAG_End : m_Tags[static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_FirstChild)].m_Type; } - + /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Byte); return static_cast<unsigned char>(m_Data[static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_DataStart)]); } - + /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { @@ -208,20 +208,20 @@ public: inline float GetFloat(int a_Tag) const { ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Float); - + // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4 char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4 UNUSED_VAR(Check1); UNUSED_VAR(Check2); - + Int32 i = GetBEInt(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart); float f; memcpy(&f, &i, sizeof(f)); return f; } - + /** Returns the value stored in a Double tag. Not valid for any other tag type. */ inline double GetDouble(int a_Tag) const { @@ -235,7 +235,7 @@ public: ASSERT(m_Tags[static_cast<size_t>(a_Tag)].m_Type == TAG_Double); return NetworkToHostDouble8(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart); } - + /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { @@ -244,7 +244,7 @@ public: res.assign(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_DataStart, static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_DataLength)); return res; } - + /** Returns the tag's name. For tags that are not named, returns an empty string. */ inline AString GetName(int a_Tag) const { @@ -252,7 +252,7 @@ public: res.assign(m_Data + m_Tags[static_cast<size_t>(a_Tag)].m_NameStart, static_cast<size_t>(m_Tags[static_cast<size_t>(a_Tag)].m_NameLength)); return res; } - + protected: const char * m_Data; size_t m_Length; @@ -277,13 +277,13 @@ class cFastNBTWriter { public: cFastNBTWriter(const AString & a_RootTagName = ""); - + void BeginCompound(const AString & a_Name); void EndCompound(void); - + void BeginList(const AString & a_Name, eTagType a_ChildrenType); void EndList(void); - + void AddByte (const AString & a_Name, unsigned char a_Value); void AddShort (const AString & a_Name, Int16 a_Value); void AddInt (const AString & a_Name, Int32 a_Value); @@ -298,11 +298,11 @@ public: { AddByteArray(a_Name, a_Value.data(), a_Value.size()); } - + const AString & GetResult(void) const {return m_Result; } - + void Finish(void); - + protected: struct sParent @@ -312,24 +312,24 @@ protected: int m_Count; // for TAG_List, the element count eTagType m_ItemType; // for TAG_List, the element type } ; - + static const int MAX_STACK = 50; // Highly doubtful that an NBT would be constructed this many levels deep - + // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. sParent m_Stack[MAX_STACK]; int m_CurrentStack; - + AString m_Result; - + bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); } - + void WriteString(const char * a_Data, UInt16 a_Length); - + inline void TagCommon(const AString & a_Name, eTagType a_Type) { // If we're directly inside a list, check that the list is of the correct type: ASSERT((m_Stack[m_CurrentStack].m_Type != TAG_List) || (m_Stack[m_CurrentStack].m_ItemType == a_Type)); - + if (IsStackTopCompound()) { // Compound: add the type and name: diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 8acfa4696..3899ad505 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -68,7 +68,7 @@ bool cMapSerializer::Save(void) SaveMapToNBT(Writer); Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); @@ -140,7 +140,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { eDimension Dimension = static_cast<eDimension>(a_NBT.GetByte(CurrLine)); - + if (Dimension != m_Map->m_World->GetDimension()) { // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. @@ -259,7 +259,7 @@ bool cIDCountSerializer::Save(void) } Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 3a0823491..86ad10af2 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -65,7 +65,7 @@ void cNBTChunkSerializer::Finish(void) { m_Writer.EndList(); } - + // If light not valid, reset it to all zeroes: if (!m_IsLightValid) { @@ -100,7 +100,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin { m_Writer.AddByte ("Slot", static_cast<unsigned char>(a_Slot)); } - + // Write the tag compound (for enchantment, firework, custom name and repair cost): if ( (!a_Item.m_Enchantments.IsEmpty()) || @@ -142,7 +142,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin } m_Writer.EndCompound(); } - + m_Writer.EndCompound(); } @@ -457,7 +457,7 @@ void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) { m_Writer.BeginCompound(""); - + switch (a_Minecart->GetPayload()) { case cMinecart::mpChest: @@ -490,7 +490,7 @@ void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) break; } } // switch (Payload) - + m_Writer.EndCompound(); } @@ -717,7 +717,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) m_Writer.BeginCompound(""); AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName()); m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0); - + switch (a_Projectile->GetProjectileKind()) { case cProjectileEntity::pkArrow: @@ -734,7 +734,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) case cProjectileEntity::pkSplashPotion: { cSplashPotionEntity * Potion = reinterpret_cast<cSplashPotionEntity *>(a_Projectile); - + m_Writer.AddInt("EffectType", static_cast<Int16>(Potion->GetEntityEffectType())); m_Writer.AddInt("EffectDuration", static_cast<Int16>(Potion->GetEntityEffect().GetDuration())); m_Writer.AddShort("EffectIntensity", Potion->GetEntityEffect().GetIntensity()); @@ -920,7 +920,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) } m_IsTagOpen = true; m_HasHadEntity = true; - + switch (a_Entity->GetEntityType()) { case cEntity::etBoat: AddBoatEntity (reinterpret_cast<cBoat *> (a_Entity)); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 9cdfb1a76..08433c3ec 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -70,19 +70,19 @@ public: /** Close NBT tags that we've opened */ void Finish(void); - + bool IsLightValid(void) const {return m_IsLightValid; } protected: - + /* From cChunkDataSeparateCollector we inherit: - m_BlockTypes[] - m_BlockMetas[] - m_BlockLight[] - m_BlockSkyLight[] */ - + cFastNBTWriter & m_Writer; - + bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. bool m_HasHadEntity; // True if any Entity has already been received and processed bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed @@ -91,10 +91,10 @@ protected: /** Writes an item into the writer, if slot >= 0, adds the Slot tag. The compound is named as requested. */ void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = ""); - + /** Writes an item grid into the writer; begins the stored slot numbers with a_BeginSlotNum. Note that it doesn't begin nor end the list tag */ void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0); - + // Block entities: void AddBasicTileEntity (cBlockEntity * a_Entity, const char * a_EntityTypeID); void AddBeaconEntity (cBeaconEntity * a_Entity); @@ -111,7 +111,7 @@ protected: void AddMobHeadEntity (cMobHeadEntity * a_MobHead); void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock); void AddFlowerPotEntity (cFlowerPotEntity * a_FlowerPot); - + // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBoatEntity (cBoat * a_Boat); @@ -126,9 +126,9 @@ protected: void AddExpOrbEntity (cExpOrb * a_ExpOrb); void AddItemFrameEntity (cItemFrame * a_ItemFrame); void AddPaintingEntity (cPainting * a_Painting); - + void AddMinecartChestContents(cMinecartWithChest * a_Minecart); - + // cChunkDataSeparateCollector overrides: virtual void LightIsValid(bool a_IsLightValid) override; virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override; diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 6267668c5..1b2047574 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -70,7 +70,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c return false; } File.Close(); - + // Parse the NBT: cParsedNBT NBT(Contents.data(), Contents.size()); if (!NBT.IsValid()) @@ -78,7 +78,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c LOG("Cannot parse the NBT in the schematic file \"%s\".", a_FileName.c_str()); return false; } - + return LoadFromSchematicNBT(a_BlockArea, NBT); } @@ -104,7 +104,7 @@ bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__); return false; } - + return LoadFromSchematicNBT(a_BlockArea, NBT); } @@ -121,7 +121,7 @@ bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockAre LOG("%s: Cannot serialize the area into an NBT representation for file \"%s\".", __FUNCTION__, a_FileName.c_str()); return false; } - + // Save to file cGZipFile File; if (!File.Open(a_FileName, cGZipFile::fmWrite)) @@ -151,7 +151,7 @@ bool cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockA LOG("%s: Cannot serialize the area into an NBT representation.", __FUNCTION__); return false; } - + // Gzip the data: int res = CompressStringGZIP(NBT.data(), NBT.size(), a_Out); if (res != Z_OK) @@ -196,7 +196,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP ); return false; } - + int SizeX = a_NBT.GetShort(TSizeX); int SizeY = a_NBT.GetShort(TSizeY); int SizeZ = a_NBT.GetShort(TSizeZ); @@ -205,7 +205,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ); return false; } - + int TBlockTypes = a_NBT.FindChildByName(a_NBT.GetRoot(), "Blocks"); int TBlockMetas = a_NBT.FindChildByName(a_NBT.GetRoot(), "Data"); if ((TBlockTypes < 0) || (a_NBT.GetType(TBlockTypes) != TAG_ByteArray)) @@ -214,14 +214,14 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP return false; } bool AreMetasPresent = (TBlockMetas > 0) && (a_NBT.GetType(TBlockMetas) == TAG_ByteArray); - + a_BlockArea.Clear(); a_BlockArea.SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (cBlockArea::baTypes | cBlockArea::baMetas) : cBlockArea::baTypes); - + int TOffsetX = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetX"); int TOffsetY = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetY"); int TOffsetZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetZ"); - + if ( (TOffsetX < 0) || (TOffsetY < 0) || (TOffsetZ < 0) || (a_NBT.GetType(TOffsetX) != TAG_Int) || @@ -247,7 +247,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP NumTypeBytes = a_NBT.GetDataLength(TBlockTypes); } memcpy(a_BlockArea.m_BlockTypes, a_NBT.GetData(TBlockTypes), NumTypeBytes); - + if (AreMetasPresent) { size_t NumMetaBytes = a_BlockArea.GetBlockCount(); @@ -260,7 +260,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } memcpy(a_BlockArea.m_BlockMetas, a_NBT.GetData(TBlockMetas), NumMetaBytes); } - + return true; } @@ -293,7 +293,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA AString Dummy(a_BlockArea.GetBlockCount(), 0); Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); } - + Writer.AddInt("WEOffsetX", a_BlockArea.m_WEOffset.x); Writer.AddInt("WEOffsetY", a_BlockArea.m_WEOffset.y); Writer.AddInt("WEOffsetZ", a_BlockArea.m_WEOffset.z); @@ -304,7 +304,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA Writer.BeginList("TileEntities", TAG_Compound); Writer.EndList(); Writer.Finish(); - + return Writer.GetResult(); } diff --git a/src/WorldStorage/SchematicFileSerializer.h b/src/WorldStorage/SchematicFileSerializer.h index 05b6c74f4..6aaa0662f 100644 --- a/src/WorldStorage/SchematicFileSerializer.h +++ b/src/WorldStorage/SchematicFileSerializer.h @@ -25,20 +25,20 @@ class cParsedNBT; class cSchematicFileSerializer { public: - + /** Loads an area from a .schematic file. Returns true if successful. */ static bool LoadFromSchematicFile(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 true if successful, false on failure. The data is stored into a_Out. */ static bool SaveToSchematicString(const cBlockArea & a_BlockArea, AString & a_Out); - + private: /** Loads the area from a schematic file uncompressed and parsed into a NBT tree. Returns true if successful. */ diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 01e56dbe1..27ce36455 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -67,7 +67,7 @@ bool cScoreboardSerializer::Save(void) SaveScoreboardToNBT(Writer); Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); @@ -102,7 +102,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.BeginCompound("data"); a_Writer.BeginList("Objectives", TAG_Compound); - + for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it) { const cObjective & Objective = it->second; @@ -133,7 +133,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.AddString("Name", it2->first); a_Writer.AddString("Objective", it->first); - + a_Writer.EndCompound(); } } @@ -141,7 +141,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.EndList(); // PlayerScores a_Writer.BeginList("Teams", TAG_Compound); - + for (cScoreboard::cTeamMap::const_iterator it = m_ScoreBoard->m_Teams.begin(); it != m_ScoreBoard->m_Teams.end(); ++it) { const cTeam & Team = it->second; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 385a3a3ca..4fc855589 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -110,7 +110,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : Writer.AddString("LevelName", a_World->GetName()); Writer.EndCompound(); Writer.Finish(); - + gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb"); if (gz != nullptr) { @@ -145,7 +145,7 @@ bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk) // The reason for failure is already printed in GetChunkData() return false; } - + return LoadChunkFromData(a_Chunk, ChunkData); } @@ -166,7 +166,7 @@ bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk) LOGWARNING("Cannot store chunk [%d, %d] data", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } - + // Everything successful return true; } @@ -266,7 +266,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 >= 0); ASSERT(a_Chunk.m_ChunkX - RegionX * 32 < 32); ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 < 32); - + // Is it already cached? for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) { @@ -282,7 +282,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) return f; } } - + // Load it anew: AString FileName; Printf(FileName, "%s%cregion", m_World->GetName().c_str(), cFile::PathSeparator); @@ -294,7 +294,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) return nullptr; } m_Files.push_front(f); - + // If there are too many MCA files cached, delete the last one used: if (m_Files.size() > MAX_MCA_FILES) { @@ -319,7 +319,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & ChunkLoadFailed(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, "InflateString() failed", a_Data); return false; } - + // Parse the NBT data: cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) @@ -346,7 +346,7 @@ bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) return false; } Writer.Finish(); - + CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data, m_CompressionFactor); return true; } @@ -362,12 +362,12 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT cChunkDef::BlockNibbles MetaData; cChunkDef::BlockNibbles BlockLight; cChunkDef::BlockNibbles SkyLight; - + memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes)); memset(MetaData, 0, sizeof(MetaData)); memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight memset(BlockLight, 0x00, sizeof(BlockLight)); - + // Load the blockdata, blocklight and skylight: int Level = a_NBT.FindChildByName(0, "Level"); if (Level < 0) @@ -405,7 +405,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT CopyNBTData(a_NBT, Child, "SkyLight", reinterpret_cast<char *>(&(SkyLight[y * 2048])), 2048); CopyNBTData(a_NBT, Child, "BlockLight", reinterpret_cast<char *>(&(BlockLight[y * 2048])), 2048); } // for itr - LevelSections[] - + // Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style: cChunkDef::BiomeMap BiomeMap; cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes")); @@ -414,15 +414,15 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT // MCS-style biomes not available, load vanilla-style: Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); } - + // Load the entities from NBT: cEntityList Entities; cBlockEntityList BlockEntities; LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities")); LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities"), BlockTypes, MetaData); - + bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0); - + /* // Uncomment this block for really cool stuff :) // DEBUG magic: Invert the underground, so that we can see the MC generator in action :) @@ -458,7 +458,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT } } // for y //*/ - + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, BlockTypes, MetaData, @@ -501,7 +501,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ return false; } Serializer.Finish(); // Close NBT tags - + // Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): if (Serializer.m_BiomesAreValid) { @@ -535,7 +535,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ a_Writer.EndCompound(); } a_Writer.EndList(); // "Sections" - + // Store the information that the lighting is valid. // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. if (Serializer.IsLightValid()) @@ -545,10 +545,10 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ // Save the world age to the chunk data. Required by vanilla and mcedit. a_Writer.AddLong("LastUpdate", m_World->GetWorldAge()); - + // Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete. a_Writer.AddByte("TerrainPopulated", 1); - + a_Writer.EndCompound(); // "Level" return true; } @@ -619,7 +619,7 @@ void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) @@ -645,7 +645,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { return; } - + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) @@ -761,19 +761,19 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ a_Item.Empty(); return true; } - + int Damage = a_NBT.FindChildByName(a_TagIdx, "Damage"); if ((Damage > 0) && (a_NBT.GetType(Damage) == TAG_Short)) { a_Item.m_ItemDamage = a_NBT.GetShort(Damage); } - + int Count = a_NBT.FindChildByName(a_TagIdx, "Count"); if ((Count > 0) && (a_NBT.GetType(Count) == TAG_Byte)) { a_Item.m_ItemCount = static_cast<char>(a_NBT.GetByte(Count)); } - + // Find the "tag" tag, used for enchantments and other extra data int TagTag = a_NBT.FindChildByName(a_TagIdx, "tag"); if (TagTag <= 0) @@ -819,7 +819,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ { cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, a_NBT, FireworksTag, static_cast<ENUM_ITEM_ID>(a_Item.m_ItemType)); } - + return true; } @@ -1134,7 +1134,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag { return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } - + std::unique_ptr<cFurnaceEntity> Furnace = cpp14::make_unique<cFurnaceEntity>(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World); Furnace->SetLoading(true); @@ -1152,7 +1152,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag Furnace->SetSlot(a_NBT.GetByte(Slot), Item); } } // for itr - ItemDefs[] - + // Load burn time: int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime"); if (BurnTime >= 0) @@ -1161,7 +1161,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100% Furnace->SetBurnTimes(bt, 0); } - + // Load cook time: int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime"); if (CookTime >= 0) @@ -1741,9 +1741,9 @@ void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Load the Push and Fuel tags - + a_Entities.push_back(Minecart.release()); } @@ -1758,7 +1758,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Everything to do with TNT carts a_Entities.push_back(Minecart.release()); @@ -1775,7 +1775,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Everything to do with hopper carts a_Entities.push_back(Minecart.release()); @@ -1798,13 +1798,13 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + std::unique_ptr<cPickup> Pickup = cpp14::make_unique<cPickup>(0, 0, 0, Item, false); // Pickup delay doesn't matter, just say false if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx)) { return; } - + // Load age: int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); if (Age > 0) @@ -1826,14 +1826,14 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + // Load Fuse Ticks: int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); if (FuseTicks > 0) { TNT->SetFuseTicks(static_cast<int>(a_NBT.GetByte(FuseTicks))); } - + a_Entities.push_back(TNT.release()); } @@ -1911,7 +1911,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + std::unique_ptr<cItemFrame> ItemFrame = cpp14::make_unique<cItemFrame>(BLOCK_FACE_NONE, 0.0, 0.0, 0.0); if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx)) { @@ -1920,14 +1920,14 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT ItemFrame->SetItem(Item); LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx); - + // Load Rotation: int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation"); if (Rotation > 0) { ItemFrame->SetItemRotation(static_cast<Byte>(a_NBT.GetByte(Rotation))); } - + a_Entities.push_back(ItemFrame.release()); } @@ -1965,7 +1965,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + // Load pickup state: int PickupIdx = a_NBT.FindChildByName(a_TagIdx, "pickup"); if ((PickupIdx > 0) && (a_NBT.GetType(PickupIdx) == TAG_Byte)) @@ -1981,14 +1981,14 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Arrow->SetPickupState((a_NBT.GetByte(PlayerIdx) == 0) ? cArrowEntity::psNoPickup : cArrowEntity::psInSurvivalOrCreative); } } - + // Load damage: int DamageIdx = a_NBT.FindChildByName(a_TagIdx, "damage"); if ((DamageIdx > 0) && (a_NBT.GetType(DamageIdx) == TAG_Double)) { Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx)); } - + // Load block hit: int InBlockXIdx = a_NBT.FindChildByName(a_TagIdx, "xTile"); int InBlockYIdx = a_NBT.FindChildByName(a_TagIdx, "yTile"); @@ -2020,7 +2020,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } } } - + // Store the new arrow in the entities list: a_Entities.push_back(Arrow.release()); } @@ -2035,15 +2035,15 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN { return; } - + int EffectDuration = a_NBT.FindChildByName(a_TagIdx, "EffectDuration"); int EffectIntensity = a_NBT.FindChildByName(a_TagIdx, "EffectIntensity"); int EffectDistanceModifier = a_NBT.FindChildByName(a_TagIdx, "EffectDistanceModifier"); - + SplashPotion->SetEntityEffectType(static_cast<cEntityEffect::eType>(a_NBT.FindChildByName(a_TagIdx, "EffectType"))); SplashPotion->SetEntityEffect(cEntityEffect(EffectDuration, static_cast<Int16>(EffectIntensity), EffectDistanceModifier)); SplashPotion->SetPotionColor(a_NBT.FindChildByName(a_TagIdx, "PotionName")); - + // Store the new splash potion in the entities list: a_Entities.push_back(SplashPotion.release()); } @@ -2059,7 +2059,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + // Store the new snowball in the entities list: a_Entities.push_back(Snowball.release()); } @@ -2075,7 +2075,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + // Store the new egg in the entities list: a_Entities.push_back(Egg.release()); } @@ -2091,7 +2091,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + // Store the new fireball in the entities list: a_Entities.push_back(Fireball.release()); } @@ -2107,7 +2107,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // Store the new FireCharge in the entities list: a_Entities.push_back(FireCharge.release()); } @@ -2123,7 +2123,7 @@ void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cPar { return; } - + // Store the new enderpearl in the entities list: a_Entities.push_back(Enderpearl.release()); } @@ -2139,7 +2139,7 @@ void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2159,7 +2159,7 @@ void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2179,7 +2179,7 @@ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2199,7 +2199,7 @@ void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2219,7 +2219,7 @@ void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2239,7 +2239,7 @@ void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2259,7 +2259,7 @@ void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2319,7 +2319,7 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2339,7 +2339,7 @@ void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2372,12 +2372,12 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2390,7 +2390,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2405,7 +2405,7 @@ void cWSSAnvil::LoadIronGolemFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2434,7 +2434,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2454,7 +2454,7 @@ void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2474,7 +2474,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2492,7 +2492,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2507,12 +2507,12 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2525,7 +2525,7 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2551,12 +2551,12 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2569,7 +2569,7 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2591,7 +2591,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2602,7 +2602,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0); } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2615,7 +2615,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2630,7 +2630,7 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2658,7 +2658,7 @@ void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2687,7 +2687,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2707,7 +2707,7 @@ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2727,7 +2727,7 @@ void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2747,7 +2747,7 @@ void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2775,12 +2775,12 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2793,8 +2793,8 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & } Monster->SetAge(Age); } - - + + a_Entities.push_back(Monster.release()); } @@ -2809,7 +2809,7 @@ void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2829,7 +2829,7 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2859,7 +2859,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N { return; } - + LoadWolfOwner(*Monster.get(), a_NBT, a_TagIdx); int SittingIdx = a_NBT.FindChildByName(a_TagIdx, "Sitting"); @@ -2894,7 +2894,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N } } } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2907,7 +2907,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2930,12 +2930,12 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2948,7 +2948,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2968,7 +2968,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2981,7 +2981,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -3008,7 +3008,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta // There is no owner, bail out: return; } - + // Convert name to UUID, if needed: if (OwnerUUID.empty()) { @@ -3026,7 +3026,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta // Normalize the UUID: OwnerUUID = cMojangAPI::MakeUUIDShort(OwnerUUID); } - + // Convert UUID to name, if needed: if (OwnerName.empty()) { @@ -3038,7 +3038,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta return; } } - + a_Wolf.SetOwner(OwnerName, OwnerUUID); a_Wolf.SetIsTame(true); } @@ -3055,7 +3055,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N return false; } a_Entity.SetPosition(Pos[0], Pos[1], Pos[2]); - + double Speed[3]; if (!LoadDoublesListFromNBT(Speed, 3, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Motion"))) { @@ -3065,7 +3065,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N Speed[2] = 0; } a_Entity.SetSpeed(Speed[0], Speed[1], Speed[2]); - + double Rotation[3]; if (!LoadDoublesListFromNBT(Rotation, 2, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Rotation"))) { @@ -3079,7 +3079,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N // Load health: int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); a_Entity.SetHealth(Health > 0 ? a_NBT.GetShort(Health) : a_Entity.GetMaxHealth()); - + return true; } @@ -3133,7 +3133,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP { return false; } - + bool IsInGround = false; int InGroundIdx = a_NBT.FindChildByName(a_TagIdx, "inGround"); if (InGroundIdx > 0) @@ -3141,7 +3141,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP IsInGround = (a_NBT.GetByte(InGroundIdx) != 0); } a_Entity.SetIsInGround(IsInGround); - + return true; } @@ -3230,13 +3230,13 @@ cWSSAnvil::cMCAFile::cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_File bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) { bool writeOutNeeded = false; - + if (m_File.IsOpen()) { // Already open return true; } - + if (a_IsForReading) { if (!cFile::Exists(m_FileName)) @@ -3245,13 +3245,13 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) return false; } } - + if (!m_File.Open(m_FileName, cFile::fmReadWrite)) { // The file failed to open return false; } - + // Load the header: if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) { @@ -3269,7 +3269,7 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) memset(m_TimeStamps, 0, sizeof(m_TimeStamps)); writeOutNeeded = true; } - + if (writeOutNeeded) { m_File.Seek(0); @@ -3296,7 +3296,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a { return false; } - + int LocalX = a_Chunk.m_ChunkX % 32; if (LocalX < 0) { @@ -3313,9 +3313,9 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a { return false; } - + m_File.Seek(static_cast<int>(ChunkOffset * 4096)); - + UInt32 ChunkSize = 0; if (m_File.Read(&ChunkSize, 4) != 4) { @@ -3337,7 +3337,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a return false; } ChunkSize--; - + a_Data = m_File.Read(ChunkSize); if (a_Data.size() != ChunkSize) { @@ -3376,7 +3376,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri { LocalZ = 32 + LocalZ; } - + unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); // Store the chunk data: @@ -3398,7 +3398,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri LOGWARNING("Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } - + // Add padding to 4K boundary: size_t BytesWritten = a_Data.size() + MCA_CHUNK_HEADER_LENGTH; if (BytesWritten % 4096 != 0) @@ -3406,7 +3406,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri static const char Padding[4095] = {0}; m_File.Write(Padding, 4096 - (BytesWritten % 4096)); } - + // Store the header: ChunkSize = (static_cast<u_long>(a_Data.size()) + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size up to nearest 4KB sector, make it a sector number if (ChunkSize > 255) @@ -3416,7 +3416,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri ); return false; } - + // Store the header info in the table m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); @@ -3438,7 +3438,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri LOGWARNING("Cannot save chunk [%d, %d], writing timestamps to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } - + return true; } @@ -3455,7 +3455,7 @@ unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const { return ChunkLocation >> 8; } - + // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later) unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++) diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 03fa22457..0bd12af57 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -31,10 +31,10 @@ enum { /** Maximum number of chunks in an MCA file - also the count of the header items */ MCA_MAX_CHUNKS = 32 * 32, - + /** The MCA header is 8 KiB */ MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8, - + /** There are 5 bytes of header in front of each chunk */ MCA_CHUNK_HEADER_LENGTH = 5, } ; @@ -47,55 +47,55 @@ class cWSSAnvil : public cWSSchema { typedef cWSSchema super; - + public: cWSSAnvil(cWorld * a_World, int a_CompressionFactor); virtual ~cWSSAnvil(); - + protected: class cMCAFile { public: - + cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_FileName, int a_RegionX, int a_RegionZ); - + bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data); bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data); bool EraseChunkData(const cChunkCoords & a_Chunk); - + int GetRegionX (void) const {return m_RegionX; } int GetRegionZ (void) const {return m_RegionZ; } const AString & GetFileName(void) const {return m_FileName; } - + protected: cWSSAnvil & m_ParentSchema; - + int m_RegionX; int m_RegionZ; cFile m_File; AString m_FileName; - + // The header, copied from the file so we don't have to seek to it all the time // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count unsigned m_Header[MCA_MAX_CHUNKS]; - + // Chunk timestamps, following the chunk headers unsigned m_TimeStamps[MCA_MAX_CHUNKS]; - + /** Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. */ unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data); - + /** Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) */ bool OpenFile(bool a_IsForReading); } ; typedef std::list<cMCAFile *> cMCAFiles; - + cCriticalSection m_CS; cMCAFiles m_Files; // a MRU cache of MCA files - + int m_CompressionFactor; @@ -110,41 +110,41 @@ protected: /** Loads the chunk from the data (no locking needed) */ bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data); - + /** Saves the chunk into datastream (no locking needed) */ bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data); - + /** Loads the chunk from NBT data (no locking needed). a_RawChunkData is the raw (compressed) chunk data, used for offloading when chunk loading fails. */ bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT, const AString & a_RawChunkData); - + /** Saves the chunk into NBT data using a_Writer; returns true on success */ bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); - + /** Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */ cChunkDef::BiomeMap * LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */ cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) */ void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag); - + /** Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) */ void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); - + /** Loads the data for a block entity from the specified NBT tag. Returns the loaded block entity, or nullptr upon failure. */ cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /** Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag */ bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads contentents of an Items[] list tag into a cItemGrid ItemGrid begins at the specified slot offset Slots outside the ItemGrid range are ignored */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); - + /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */ bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType); @@ -162,9 +162,9 @@ protected: cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType); - + void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength); - + void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); @@ -220,19 +220,19 @@ protected: void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the wolf's owner information from the NBT into the specified wolf entity. */ void LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads entity common data from the NBT compound; returns true if successful */ bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads monster common data from the NBT compound; returns true if successful */ bool LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads projectile common data from the NBT compound; returns true if successful */ bool LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIx); - + /** Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns true if successful */ bool LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx); @@ -241,13 +241,13 @@ protected: /** Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful */ bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); - + /** Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked */ cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk); - + /** Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer */ void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, size_t a_Length); - + // cWSSchema overrides: virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 3a2385848..55555d731 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -22,7 +22,7 @@ class cWSSForgetful : { public: cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {} - + protected: // cWSSchema overrides: virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; } @@ -65,7 +65,7 @@ bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName, m_World = a_World; m_StorageSchemaName = a_StorageSchemaName; InitSchemas(a_StorageCompressionFactor); - + return super::Start(); } @@ -85,14 +85,14 @@ void cWorldStorage::Stop(void) void cWorldStorage::WaitForFinish(void) { LOGD("Waiting for the world storage to finish saving"); - + { m_LoadQueue.Clear(); } - + // Wait for the saving to finish: WaitForSaveQueueEmpty(); - + // Wait for the thread to finish: m_ShouldTerminate = true; m_Event.Set(); // Wake up the thread if waiting @@ -170,7 +170,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSForgetful(m_World)); // Add new schemas here - + if (NoCaseCompare(m_StorageSchemaName, "default") == 0) { m_SaveSchema = m_Schemas.front(); @@ -184,7 +184,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) return; } } // for itr - m_Schemas[] - + // Unknown schema selected, let the admin know: LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() @@ -213,7 +213,7 @@ void cWorldStorage::Execute(void) { return; } - + Success = LoadOneChunk(); Success |= SaveOneChunk(); } while (Success); @@ -258,7 +258,7 @@ bool cWorldStorage::SaveOneChunk(void) { return false; } - + // Save the chunk, if it's valid: bool Status = false; if (m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) @@ -286,7 +286,7 @@ bool cWorldStorage::SaveOneChunk(void) bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ)); - + cChunkCoords Coords(a_ChunkX, a_ChunkZ); // First try the schema that is used for saving @@ -294,7 +294,7 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { return true; } - + // If it didn't have the chunk, try all the other schemas: for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) { @@ -303,10 +303,10 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) return true; } } - + // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): m_World->ChunkLoadFailed(a_ChunkX, a_ChunkZ); - + return false; } diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index ab8a7f44b..e171aad43 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -37,11 +37,11 @@ class cWSSchema abstract public: cWSSchema(cWorld * a_World) : m_World(a_World) {} virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual - + virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0; virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0; virtual const AString GetName(void) const = 0; - + protected: cWorld * m_World; @@ -58,7 +58,7 @@ class cWorldStorage : public cIsThread { typedef cIsThread super; - + public: cWorldStorage(void); @@ -71,16 +71,16 @@ public: /** Queues a chunk to be saved, asynchronously. The callback, if specified, will be called with the result of the save operation. */ void QueueSaveChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr); - + bool Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor); // Hide the cIsThread's Start() method, we need to provide args void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event void WaitForFinish(void); void WaitForLoadQueueEmpty(void); void WaitForSaveQueueEmpty(void); - + size_t GetLoadQueueLength(void); size_t GetSaveQueueLength(void); - + protected: cWorld * m_World; @@ -88,27 +88,27 @@ protected: cChunkCoordsQueue m_LoadQueue; cChunkCoordsQueue m_SaveQueue; - + /** All the storage schemas (all used for loading) */ cWSSchemaList m_Schemas; - + /** The one storage schema used for saving */ cWSSchema * m_SaveSchema; /** Set when there's any addition to the queues */ cEvent m_Event; - + /** Loads the chunk specified; returns true on success, false on failure */ bool LoadChunk(int a_ChunkX, int a_ChunkZ); void InitSchemas(int a_StorageCompressionFactor); - + virtual void Execute(void) override; - + /** Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue */ bool LoadOneChunk(void); - + /** Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue */ bool SaveOneChunk(void); } ; |