nodemetadata.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 << serializeString(sv.first);
  44. os << serializeLongString(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 = deSerializeString(is);
  56. std::string var = deSerializeLongString(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. Metadata::clear();
  68. m_privatevars.clear();
  69. m_inventory->clear();
  70. }
  71. bool NodeMetadata::empty() const
  72. {
  73. return Metadata::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) const
  97. {
  98. /*
  99. Version 0 is a placeholder for "nothing to see here; go away."
  100. */
  101. u16 count = countNonEmpty();
  102. if (count == 0) {
  103. writeU8(os, 0); // version
  104. return;
  105. }
  106. u8 version = (blockver > 27) ? 2 : 1;
  107. writeU8(os, version);
  108. writeU16(os, count);
  109. for (const auto &it : m_data) {
  110. v3s16 p = it.first;
  111. NodeMetadata *data = it.second;
  112. if (data->empty())
  113. continue;
  114. u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X;
  115. writeU16(os, p16);
  116. data->serialize(os, version, disk);
  117. }
  118. }
  119. void NodeMetadataList::deSerialize(std::istream &is, IItemDefManager *item_def_mgr)
  120. {
  121. clear();
  122. u8 version = readU8(is);
  123. if (version == 0) {
  124. // Nothing
  125. return;
  126. }
  127. if (version > 2) {
  128. std::string err_str = std::string(FUNCTION_NAME)
  129. + ": version " + itos(version) + " not supported";
  130. infostream << err_str << std::endl;
  131. throw SerializationError(err_str);
  132. }
  133. u16 count = readU16(is);
  134. for (u16 i = 0; i < count; i++) {
  135. u16 p16 = readU16(is);
  136. v3s16 p;
  137. p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
  138. p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1;
  139. p.Y = p16 / MAP_BLOCKSIZE;
  140. p16 &= MAP_BLOCKSIZE - 1;
  141. p.X = p16;
  142. if (m_data.find(p) != m_data.end()) {
  143. warningstream << "NodeMetadataList::deSerialize(): "
  144. << "already set data at position " << PP(p)
  145. << ": Ignoring." << std::endl;
  146. continue;
  147. }
  148. NodeMetadata *data = new NodeMetadata(item_def_mgr);
  149. data->deSerialize(is, version);
  150. m_data[p] = data;
  151. }
  152. }
  153. NodeMetadataList::~NodeMetadataList()
  154. {
  155. clear();
  156. }
  157. std::vector<v3s16> NodeMetadataList::getAllKeys()
  158. {
  159. std::vector<v3s16> keys;
  160. std::map<v3s16, NodeMetadata *>::const_iterator it;
  161. for (it = m_data.begin(); it != m_data.end(); ++it)
  162. keys.push_back(it->first);
  163. return keys;
  164. }
  165. NodeMetadata *NodeMetadataList::get(v3s16 p)
  166. {
  167. std::map<v3s16, NodeMetadata *>::const_iterator n = m_data.find(p);
  168. if (n == m_data.end())
  169. return NULL;
  170. return n->second;
  171. }
  172. void NodeMetadataList::remove(v3s16 p)
  173. {
  174. NodeMetadata *olddata = get(p);
  175. if (olddata) {
  176. delete olddata;
  177. m_data.erase(p);
  178. }
  179. }
  180. void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
  181. {
  182. remove(p);
  183. m_data.insert(std::make_pair(p, d));
  184. }
  185. void NodeMetadataList::clear()
  186. {
  187. std::map<v3s16, NodeMetadata*>::iterator it;
  188. for (it = m_data.begin(); it != m_data.end(); ++it) {
  189. delete it->second;
  190. }
  191. m_data.clear();
  192. }
  193. int NodeMetadataList::countNonEmpty() const
  194. {
  195. int n = 0;
  196. std::map<v3s16, NodeMetadata*>::const_iterator it;
  197. for (it = m_data.begin(); it != m_data.end(); ++it) {
  198. if (!it->second->empty())
  199. n++;
  200. }
  201. return n;
  202. }