summaryrefslogtreecommitdiffstats
path: root/src/WorldStorage
diff options
context:
space:
mode:
authorandrew <xdotftw@gmail.com>2014-01-21 19:40:41 +0100
committerandrew <xdotftw@gmail.com>2014-01-21 19:40:41 +0100
commit9bd8f74b598866539e3e5133188326bd7d14a827 (patch)
tree15f411bd03371e555250b898f3883c0fa20c2b8b /src/WorldStorage
parentScoreboard SendTo() (diff)
parentFix a crash but somewhere... (diff)
downloadcuberite-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.cpp88
-rw-r--r--src/WorldStorage/EnchantmentSerializer.h17
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp3
-rw-r--r--src/WorldStorage/WSSAnvil.cpp3
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;