Spilt Writing of Enchantments to seperate class
Created a new class cEnchantmentSerializer to serilize Enchantments to NBT. This breaks a dependecy chain between cChunkGenerator and cWorld. cEnchantmentSerializer is seperate from NBTWriter as it needs to access private members of cEnchantments so having it seperate reduces the spread of the frein modifier
This commit is contained in:
parent
9aca5b4b99
commit
e14ddff1c0
@ -213,87 +213,8 @@ bool cEnchantments::operator !=(const cEnchantments & a_Other) const
|
||||
|
||||
|
||||
|
||||
void cEnchantments::WriteToNBTCompound(cFastNBTWriter & a_Writer, const AString & a_ListTagName) const
|
||||
{
|
||||
// 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 (cMap::const_iterator itr = m_Enchantments.begin(), end = 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 cEnchantments::ParseFromNBT(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;
|
||||
}
|
||||
|
||||
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:
|
||||
m_Enchantments[id] = lvl;
|
||||
} // for tag - children of the ench list tag
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ Serialization will never put zero-level enchantments into the stringspec and wil
|
||||
*/
|
||||
class cEnchantments
|
||||
{
|
||||
friend class cEnchantmentSerializer;
|
||||
public:
|
||||
/// Individual enchantment IDs, corresponding to their NBT IDs ( http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs )
|
||||
enum
|
||||
@ -96,11 +97,7 @@ public:
|
||||
/// Returns true if a_Other doesn't contain exactly the same enchantments and levels
|
||||
bool operator !=(const cEnchantments & a_Other) const;
|
||||
|
||||
/// Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments")
|
||||
void WriteToNBTCompound(cFastNBTWriter & a_Writer, const AString & a_ListTagName) const;
|
||||
|
||||
/// Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments)
|
||||
void ParseFromNBT(const cParsedNBT & a_NBT, int a_EnchListTagIdx);
|
||||
|
||||
|
||||
protected:
|
||||
/// Maps enchantment ID -> enchantment level
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../UI/Window.h"
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../WorldStorage/FastNBT.h"
|
||||
#include "../WorldStorage/EnchantmentSerializer.h"
|
||||
#include "../StringCompression.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -763,7 +764,7 @@ void cProtocol132::WriteItem(const cItem & a_Item)
|
||||
// Send the enchantments:
|
||||
cFastNBTWriter Writer;
|
||||
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
|
||||
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName);
|
||||
cEnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
|
||||
Writer.Finish();
|
||||
AString Compressed;
|
||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||
@ -849,7 +850,7 @@ int cProtocol132::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
||||
)
|
||||
)
|
||||
{
|
||||
a_Item.m_Enchantments.ParseFromNBT(NBT, tag);
|
||||
cEnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ Implements the 1.7.x protocol classes:
|
||||
#include "../Server.h"
|
||||
#include "../World.h"
|
||||
#include "../WorldStorage/FastNBT.h"
|
||||
#include "../WorldStorage/EnchantmentSerializer.h"
|
||||
#include "../StringCompression.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/Minecart.h"
|
||||
@ -1696,7 +1697,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
||||
)
|
||||
)
|
||||
{
|
||||
a_Item.m_Enchantments.ParseFromNBT(NBT, tag);
|
||||
cEnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag);
|
||||
}
|
||||
else if ((NBT.GetType(tag) == TAG_Compound) && (NBT.GetName(tag) == "display")) // Custom name and lore tag
|
||||
{
|
||||
@ -1781,7 +1782,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
|
||||
if (!a_Item.m_Enchantments.IsEmpty())
|
||||
{
|
||||
const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
|
||||
a_Item.m_Enchantments.WriteToNBTCompound(Writer, TagName);
|
||||
cEnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments,Writer, TagName);
|
||||
}
|
||||
if (!a_Item.IsBothNameAndLoreEmpty())
|
||||
{
|
||||
|
87
src/WorldStorage/EnchantmentSerializer.cpp
Normal file
87
src/WorldStorage/EnchantmentSerializer.cpp
Normal file
@ -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
|
||||
}
|
||||
|
17
src/WorldStorage/EnchantmentSerializer.h
Normal file
17
src/WorldStorage/EnchantmentSerializer.h
Normal file
@ -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);
|
||||
|
||||
};
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user