diff options
author | Tycho <work.tycho+git@gmail.com> | 2014-01-19 16:38:59 +0100 |
---|---|---|
committer | Tycho <work.tycho+git@gmail.com> | 2014-01-19 16:38:59 +0100 |
commit | e14ddff1c00919f1416bfa6da9568e2dff419559 (patch) | |
tree | e05c7c0e5219c165f0f9335726e00ebadab4440c /src/WorldStorage | |
parent | Merge pull request #552 from worktycho/c++11 (diff) | |
download | cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar.gz cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar.bz2 cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar.lz cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar.xz cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.tar.zst cuberite-e14ddff1c00919f1416bfa6da9568e2dff419559.zip |
Diffstat (limited to 'src/WorldStorage')
-rw-r--r-- | src/WorldStorage/EnchantmentSerializer.cpp | 87 | ||||
-rw-r--r-- | src/WorldStorage/EnchantmentSerializer.h | 17 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 3 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 3 |
4 files changed, 108 insertions, 2 deletions
diff --git a/src/WorldStorage/EnchantmentSerializer.cpp b/src/WorldStorage/EnchantmentSerializer.cpp new file mode 100644 index 000000000..a481f1682 --- /dev/null +++ b/src/WorldStorage/EnchantmentSerializer.cpp @@ -0,0 +1,87 @@ + +#include "Globals.h" + +#include "EnchantmentSerializer.h" +#include "FastNBT.h" + +void cEnchantmentSerializer::WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName) +{ + // 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) + { + a_Writer.BeginCompound(""); + a_Writer.AddShort("id", itr->first); + a_Writer.AddShort("lvl", itr->second); + a_Writer.EndCompound(); + } // for itr - m_Enchantments[] + a_Writer.EndList(); +} + + + + + +void cEnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx) +{ + // Read the enchantments from the specified NBT list tag (ench or StoredEnchantments) + + // Verify that the tag is a list: + if (a_NBT.GetType(a_EnchListTagIdx) != TAG_List) + { + LOGWARNING("%s: Invalid EnchListTag type: exp %d, got %d. Enchantments not parsed", + __FUNCTION__, TAG_List, a_NBT.GetType(a_EnchListTagIdx) + ); + ASSERT(!"Bad EnchListTag type"); + return; + } + + // Verify that the list is of Compounds: + if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound) + { + LOGWARNING("%s: Invalid NBT list children type: exp %d, got %d. Enchantments not parsed", + __FUNCTION__, TAG_Compound, a_NBT.GetChildrenType(a_EnchListTagIdx) + ); + 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)) + { + if (a_NBT.GetType(ch) != TAG_Short) + { + continue; + } + if (a_NBT.GetName(ch) == "id") + { + id = a_NBT.GetShort(ch); + } + else if (a_NBT.GetName(ch) == "lvl") + { + 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] = lvl; + } // for tag - children of the ench list tag +} + diff --git a/src/WorldStorage/EnchantmentSerializer.h b/src/WorldStorage/EnchantmentSerializer.h new file mode 100644 index 000000000..d616b0f62 --- /dev/null +++ b/src/WorldStorage/EnchantmentSerializer.h @@ -0,0 +1,17 @@ + +#pragma once + +#include "Enchantments.h" + +class cEnchantmentSerializer +{ + +public: + + /// Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") + static void WriteToNBTCompound(cEnchantments const& a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); + + /// Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) + static void ParseFromNBT(cEnchantments& a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); + +}; diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index e1205f2be..51e1a8d1b 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -4,6 +4,7 @@ #include "Globals.h" #include "NBTChunkSerializer.h" +#include "EnchantmentSerializer.h" #include "../BlockID.h" #include "../ItemGrid.h" #include "../StringCompression.h" @@ -91,7 +92,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin { const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; m_Writer.BeginCompound("tag"); - a_Item.m_Enchantments.WriteToNBTCompound(m_Writer, TagName); + cEnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 16513cd1b..702b809fb 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -7,6 +7,7 @@ #include "WSSAnvil.h" #include "NBTChunkSerializer.h" #include "FastNBT.h" +#include "EnchantmentSerializer.h" #include "zlib/zlib.h" #include "../World.h" #include "../BlockID.h" @@ -639,7 +640,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ int EnchTag = a_NBT.FindChildByName(TagTag, EnchName); if (EnchTag > 0) { - a_Item.m_Enchantments.ParseFromNBT(a_NBT, EnchTag); + cEnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag); } return true; |