nodemetadata.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. Minetest
  3. Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "nodemetadata.h"
  17. #include "exceptions.h"
  18. #include "gamedef.h"
  19. #include "inventory.h"
  20. #include "log.h"
  21. #include "util/serialize.h"
  22. #include "util/basic_macros.h"
  23. #include "constants.h" // MAP_BLOCKSIZE
  24. #include <sstream>
  25. /*
  26. NodeMetadata
  27. */
  28. NodeMetadata::NodeMetadata(IItemDefManager *item_def_mgr):
  29. m_inventory(new Inventory(item_def_mgr))
  30. {}
  31. NodeMetadata::~NodeMetadata()
  32. {
  33. delete m_inventory;
  34. }
  35. void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk) const
  36. {
  37. int num_vars = disk ? m_stringvars.size() : countNonPrivate();
  38. writeU32(os, num_vars);
  39. for (const auto &sv : m_stringvars) {
  40. bool priv = isPrivate(sv.first);
  41. if (!disk && priv)
  42. continue;
  43. os << serializeString16(sv.first);
  44. os << serializeString32(sv.second);
  45. if (version >= 2)
  46. writeU8(os, (priv) ? 1 : 0);
  47. }
  48. m_inventory->serialize(os);
  49. }
  50. void NodeMetadata::deSerialize(std::istream &is, u8 version)
  51. {
  52. clear();
  53. int num_vars = readU32(is);
  54. for(int i=0; i<num_vars; i++){
  55. std::string name = deSerializeString16(is);
  56. std::string var = deSerializeString32(is);
  57. m_stringvars[name] = var;
  58. if (version >= 2) {
  59. if (readU8(is) == 1)
  60. markPrivate(name, true);
  61. }
  62. }
  63. m_inventory->deSerialize(is);
  64. }
  65. void NodeMetadata::clear()
  66. {
  67. SimpleMetadata::clear();
  68. m_privatevars.clear();
  69. m_inventory->clear();
  70. }
  71. bool NodeMetadata::empty() const
  72. {
  73. return SimpleMetadata::empty() && m_inventory->getLists().empty();
  74. }
  75. void NodeMetadata::markPrivate(const std::string &name, bool set)
  76. {
  77. if (set)
  78. m_privatevars.insert(name);
  79. else
  80. m_privatevars.erase(name);
  81. }
  82. int NodeMetadata::countNonPrivate() const
  83. {
  84. // m_privatevars can contain names not actually present
  85. // DON'T: return m_stringvars.size() - m_privatevars.size();
  86. int n = 0;
  87. for (const auto &sv : m_stringvars) {
  88. if (!isPrivate(sv.first))
  89. n++;
  90. }
  91. return n;
  92. }
  93. /*
  94. NodeMetadataList
  95. */
  96. void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk,
  97. bool absolute_pos, bool include_empty) const
  98. {
  99. /*
  100. Version 0 is a placeholder for "nothing to see here; go away."
  101. */
  102. u16 count = include_empty ? m_data.size() : countNonEmpty();
  103. if (count == 0) {
  104. writeU8(os, 0); // version
  105. return;
  106. }
  107. u8 version = (blockver > 27) ? 2 : 1;
  108. writeU8(os, version);
  109. writeU16(os, count);
  110. for (NodeMetadataMap::const_iterator
  111. i = m_data.begin();
  112. i != m_data.end(); ++i) {
  113. v3s16 p = i->first;
  114. NodeMetadata *data = i->second;
  115. if (!include_empty && data->empty())
  116. continue;
  117. if (absolute_pos) {
  118. writeS16(os, p.X);
  119. writeS16(os, p.Y);
  120. writeS16(os, p.Z);
  121. } else {
  122. // Serialize positions within a mapblock
  123. u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X;
  124. writeU16(os, p16);
  125. }
  126. data->serialize(os, version, disk);
  127. }
  128. }
  129. void NodeMetadataList::deSerialize(std::istream &is,
  130. IItemDefManager *item_def_mgr, bool absolute_pos)
  131. {
  132. clear();
  133. u8 version = readU8(is);
  134. if (version == 0) {
  135. // Nothing
  136. return;
  137. }
  138. if (version > 2) {
  139. std::string err_str = std::string(FUNCTION_NAME)
  140. + ": version " + itos(version) + " not supported";
  141. infostream << err_str << std::endl;
  142. throw SerializationError(err_str);
  143. }
  144. u16 count = readU16(is);
  145. for (u16 i = 0; i < count; i++) {
  146. v3s16 p;
  147. if (absolute_pos) {
  148. p.X = readS16(is);
  149. p.Y = readS16(is);
  150. p.Z = readS16(is);
  151. } else {
  152. u16 p16 = readU16(is);
  153. p.X = p16 & (MAP_BLOCKSIZE - 1);
  154. p16 /= MAP_BLOCKSIZE;
  155. p.Y = p16 & (MAP_BLOCKSIZE - 1);
  156. p16 /= MAP_BLOCKSIZE;
  157. p.Z = p16;
  158. }
  159. if (m_data.find(p) != m_data.end()) {
  160. warningstream << "NodeMetadataList::deSerialize(): "
  161. << "already set data at position " << PP(p)
  162. << ": Ignoring." << std::endl;
  163. continue;
  164. }
  165. NodeMetadata *data = new NodeMetadata(item_def_mgr);
  166. data->deSerialize(is, version);
  167. m_data[p] = data;
  168. }
  169. }
  170. NodeMetadataList::~NodeMetadataList()
  171. {
  172. clear();
  173. }
  174. std::vector<v3s16> NodeMetadataList::getAllKeys()
  175. {
  176. std::vector<v3s16> keys;
  177. keys.reserve(m_data.size());
  178. for (const auto &it : m_data)
  179. keys.push_back(it.first);
  180. return keys;
  181. }
  182. NodeMetadata *NodeMetadataList::get(v3s16 p)
  183. {
  184. NodeMetadataMap::const_iterator n = m_data.find(p);
  185. if (n == m_data.end())
  186. return nullptr;
  187. return n->second;
  188. }
  189. void NodeMetadataList::remove(v3s16 p)
  190. {
  191. NodeMetadata *olddata = get(p);
  192. if (olddata) {
  193. if (m_is_metadata_owner)
  194. delete olddata;
  195. m_data.erase(p);
  196. }
  197. }
  198. void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
  199. {
  200. remove(p);
  201. m_data.emplace(p, d);
  202. }
  203. void NodeMetadataList::clear()
  204. {
  205. if (m_is_metadata_owner) {
  206. NodeMetadataMap::const_iterator it;
  207. for (it = m_data.begin(); it != m_data.end(); ++it)
  208. delete it->second;
  209. }
  210. m_data.clear();
  211. }
  212. int NodeMetadataList::countNonEmpty() const
  213. {
  214. int n = 0;
  215. for (const auto &it : m_data) {
  216. if (!it.second->empty())
  217. n++;
  218. }
  219. return n;
  220. }