From 3d66622772e66154b7624957a27f9be54c4c7c28 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Tue, 4 Dec 2018 20:37:48 +0100 Subject: Send only changed node metadata to clients instead of whole mapblock (#5268) Includes newer style changes and fixes by est31 Improve the block position de-serialization Add type NodeMetadataMap --- src/nodemetadata.cpp | 62 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 23 deletions(-) (limited to 'src/nodemetadata.cpp') diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 708a08099..b84ffc8cb 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -112,7 +112,8 @@ int NodeMetadata::countNonPrivate() const NodeMetadataList */ -void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk) const +void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk, + bool absolute_pos) const { /* Version 0 is a placeholder for "nothing to see here; go away." @@ -128,20 +129,29 @@ void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk) const writeU8(os, version); writeU16(os, count); - for (const auto &it : m_data) { - v3s16 p = it.first; - NodeMetadata *data = it.second; + for (NodeMetadataMap::const_iterator + i = m_data.begin(); + i != m_data.end(); ++i) { + v3s16 p = i->first; + NodeMetadata *data = i->second; if (data->empty()) continue; - u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X; - writeU16(os, p16); - + if (absolute_pos) { + writeS16(os, p.X); + writeS16(os, p.Y); + writeS16(os, p.Z); + } else { + // Serialize positions within a mapblock + u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X; + writeU16(os, p16); + } data->serialize(os, version, disk); } } -void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_mgr) +void NodeMetadataList::deSerialize(std::istream &is, + IItemDefManager *item_def_mgr, bool absolute_pos) { clear(); @@ -162,15 +172,19 @@ void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_m u16 count = readU16(is); for (u16 i = 0; i < count; i++) { - u16 p16 = readU16(is); - v3s16 p; - p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; - p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1; - p.Y = p16 / MAP_BLOCKSIZE; - p16 &= MAP_BLOCKSIZE - 1; - p.X = p16; - + if (absolute_pos) { + p.X = readS16(is); + p.Y = readS16(is); + p.Z = readS16(is); + } else { + u16 p16 = readU16(is); + p.X = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Y = p16 & (MAP_BLOCKSIZE - 1); + p16 /= MAP_BLOCKSIZE; + p.Z = p16; + } if (m_data.find(p) != m_data.end()) { warningstream << "NodeMetadataList::deSerialize(): " << "already set data at position " << PP(p) @@ -193,7 +207,7 @@ std::vector NodeMetadataList::getAllKeys() { std::vector keys; - std::map::const_iterator it; + NodeMetadataMap::const_iterator it; for (it = m_data.begin(); it != m_data.end(); ++it) keys.push_back(it->first); @@ -202,7 +216,7 @@ std::vector NodeMetadataList::getAllKeys() NodeMetadata *NodeMetadataList::get(v3s16 p) { - std::map::const_iterator n = m_data.find(p); + NodeMetadataMap::const_iterator n = m_data.find(p); if (n == m_data.end()) return NULL; return n->second; @@ -212,7 +226,8 @@ void NodeMetadataList::remove(v3s16 p) { NodeMetadata *olddata = get(p); if (olddata) { - delete olddata; + if (m_is_metadata_owner) + delete olddata; m_data.erase(p); } } @@ -225,9 +240,10 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d) void NodeMetadataList::clear() { - std::map::iterator it; - for (it = m_data.begin(); it != m_data.end(); ++it) { - delete it->second; + if (m_is_metadata_owner) { + NodeMetadataMap::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) + delete it->second; } m_data.clear(); } @@ -235,7 +251,7 @@ void NodeMetadataList::clear() int NodeMetadataList::countNonEmpty() const { int n = 0; - std::map::const_iterator it; + NodeMetadataMap::const_iterator it; for (it = m_data.begin(); it != m_data.end(); ++it) { if (!it->second->empty()) n++; -- cgit v1.2.3