diff options
author | andrew <xdotftw@gmail.com> | 2014-01-21 19:40:41 +0100 |
---|---|---|
committer | andrew <xdotftw@gmail.com> | 2014-01-21 19:40:41 +0100 |
commit | 9bd8f74b598866539e3e5133188326bd7d14a827 (patch) | |
tree | 15f411bd03371e555250b898f3883c0fa20c2b8b /src/WorldStorage | |
parent | Scoreboard SendTo() (diff) | |
parent | Fix a crash but somewhere... (diff) | |
download | cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar.gz cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar.bz2 cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar.lz cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar.xz cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.tar.zst cuberite-9bd8f74b598866539e3e5133188326bd7d14a827.zip |
Diffstat (limited to 'src/WorldStorage')
-rw-r--r-- | src/WorldStorage/EnchantmentSerializer.cpp | 88 | ||||
-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, 109 insertions, 2 deletions
diff --git a/src/WorldStorage/EnchantmentSerializer.cpp b/src/WorldStorage/EnchantmentSerializer.cpp new file mode 100644 index 000000000..56072207f --- /dev/null +++ b/src/WorldStorage/EnchantmentSerializer.cpp @@ -0,0 +1,88 @@ + +#include "Globals.h" + +#include "EnchantmentSerializer.h" +#include "Enchantments.h" +#include "FastNBT.h" + +void EnchantmentSerializer::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 EnchantmentSerializer::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..9ed362900 --- /dev/null +++ b/src/WorldStorage/EnchantmentSerializer.h @@ -0,0 +1,17 @@ + +#pragma once + +class cEnchantments; +class cFastNBTWriter; +class cParsedNBT; + +namespace EnchantmentSerializer +{ + + /// Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") + 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) + 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 447296c7f..c84128022 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" @@ -92,7 +93,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); + EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, m_Writer, TagName); m_Writer.EndCompound(); } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 600eb0a51..8be6372e2 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" @@ -644,7 +645,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); + EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, a_NBT, EnchTag); } return true; |