Merge pull request #569 from worktycho/EnchantmentsFix
Enchantments fix
This commit is contained in:
commit
865016abe2
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WorldStorage/EnchantmentSerializer.h"
|
||||
|
||||
|
||||
|
||||
@ -20,7 +21,6 @@ class cParsedNBT;
|
||||
|
||||
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/** Class that stores item enchantments or stored-enchantments
|
||||
The enchantments may be serialized to a stringspec and read back from such stringspec.
|
||||
@ -29,10 +29,12 @@ mapping each enchantment's id onto its level. ID may be either a number or the e
|
||||
Level value of 0 means no such enchantment, and it will not be stored in the m_Enchantments.
|
||||
Serialization will never put zero-level enchantments into the stringspec and will always use numeric IDs.
|
||||
*/
|
||||
// tolua_begin
|
||||
class cEnchantments
|
||||
{
|
||||
public:
|
||||
/// Individual enchantment IDs, corresponding to their NBT IDs ( http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs )
|
||||
|
||||
enum
|
||||
{
|
||||
enchProtection = 0,
|
||||
@ -97,10 +99,10 @@ public:
|
||||
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;
|
||||
friend void EnchantmentSerializer::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(const cParsedNBT & a_NBT, int a_EnchListTagIdx);
|
||||
friend void EnchantmentSerializer::ParseFromNBT(cEnchantments& a_Enchantments, 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);
|
||||
EnchantmentSerializer::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);
|
||||
EnchantmentSerializer::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"
|
||||
@ -1719,7 +1720,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
|
||||
)
|
||||
)
|
||||
{
|
||||
a_Item.m_Enchantments.ParseFromNBT(NBT, tag);
|
||||
EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag);
|
||||
}
|
||||
else if ((NBT.GetType(tag) == TAG_Compound) && (NBT.GetName(tag) == "display")) // Custom name and lore tag
|
||||
{
|
||||
@ -1804,7 +1805,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);
|
||||
EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments,Writer, TagName);
|
||||
}
|
||||
if (!a_Item.IsBothNameAndLoreEmpty())
|
||||
{
|
||||
|
88
src/WorldStorage/EnchantmentSerializer.cpp
Normal file
88
src/WorldStorage/EnchantmentSerializer.cpp
Normal file
@ -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
|
||||
}
|
||||
|
17
src/WorldStorage/EnchantmentSerializer.h
Normal file
17
src/WorldStorage/EnchantmentSerializer.h
Normal file
@ -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);
|
||||
|
||||
};
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user