content_nodemeta.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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 "content_nodemeta.h"
  17. #include "nodemetadata.h"
  18. #include "nodetimer.h"
  19. #include "inventory.h"
  20. #include "log.h"
  21. #include "serialization.h"
  22. #include "util/serialize.h"
  23. #include "util/string.h"
  24. #include "constants.h" // MAP_BLOCKSIZE
  25. #include <sstream>
  26. #define NODEMETA_GENERIC 1
  27. #define NODEMETA_SIGN 14
  28. #define NODEMETA_CHEST 15
  29. #define NODEMETA_FURNACE 16
  30. #define NODEMETA_LOCKABLE_CHEST 17
  31. // Returns true if node timer must be set
  32. static bool content_nodemeta_deserialize_legacy_body(
  33. std::istream &is, s16 id, NodeMetadata *meta)
  34. {
  35. meta->clear();
  36. if(id == NODEMETA_GENERIC) // GenericNodeMetadata (0.4-dev)
  37. {
  38. meta->getInventory()->deSerialize(is);
  39. deSerializeLongString(is); // m_text
  40. deSerializeString(is); // m_owner
  41. meta->setString("infotext",deSerializeString(is));
  42. meta->setString("formspec",deSerializeString(is));
  43. readU8(is); // m_allow_text_input
  44. readU8(is); // m_allow_removal
  45. readU8(is); // m_enforce_owner
  46. int num_vars = readU32(is);
  47. for(int i=0; i<num_vars; i++){
  48. std::string name = deSerializeString(is);
  49. std::string var = deSerializeLongString(is);
  50. meta->setString(name, var);
  51. }
  52. return false;
  53. }
  54. else if(id == NODEMETA_SIGN) // SignNodeMetadata
  55. {
  56. meta->setString("text", deSerializeString(is));
  57. //meta->setString("infotext","\"${text}\"");
  58. meta->setString("infotext",
  59. std::string("\"") + meta->getString("text") + "\"");
  60. meta->setString("formspec","field[text;;${text}]");
  61. return false;
  62. }
  63. else if(id == NODEMETA_CHEST) // ChestNodeMetadata
  64. {
  65. meta->getInventory()->deSerialize(is);
  66. // Rename inventory list "0" to "main"
  67. Inventory *inv = meta->getInventory();
  68. if(!inv->getList("main") && inv->getList("0")){
  69. inv->getList("0")->setName("main");
  70. }
  71. assert(inv->getList("main") && !inv->getList("0"));
  72. meta->setString("formspec","size[8,9]"
  73. "list[current_name;main;0,0;8,4;]"
  74. "list[current_player;main;0,5;8,4;]");
  75. return false;
  76. }
  77. else if(id == NODEMETA_LOCKABLE_CHEST) // LockingChestNodeMetadata
  78. {
  79. meta->setString("owner", deSerializeString(is));
  80. meta->getInventory()->deSerialize(is);
  81. // Rename inventory list "0" to "main"
  82. Inventory *inv = meta->getInventory();
  83. if(!inv->getList("main") && inv->getList("0")){
  84. inv->getList("0")->setName("main");
  85. }
  86. assert(inv->getList("main") && !inv->getList("0"));
  87. meta->setString("formspec","size[8,9]"
  88. "list[current_name;main;0,0;8,4;]"
  89. "list[current_player;main;0,5;8,4;]");
  90. return false;
  91. }
  92. else if(id == NODEMETA_FURNACE) // FurnaceNodeMetadata
  93. {
  94. meta->getInventory()->deSerialize(is);
  95. int temp = 0;
  96. is>>temp;
  97. meta->setString("fuel_totaltime", ftos((float)temp/10));
  98. temp = 0;
  99. is>>temp;
  100. meta->setString("fuel_time", ftos((float)temp/10));
  101. temp = 0;
  102. is>>temp;
  103. //meta->setString("src_totaltime", ftos((float)temp/10));
  104. temp = 0;
  105. is>>temp;
  106. meta->setString("src_time", ftos((float)temp/10));
  107. meta->setString("formspec","size[8,9]"
  108. "list[current_name;fuel;2,3;1,1;]"
  109. "list[current_name;src;2,1;1,1;]"
  110. "list[current_name;dst;5,1;2,2;]"
  111. "list[current_player;main;0,5;8,4;]");
  112. return true;
  113. }
  114. else
  115. {
  116. throw SerializationError("Unknown legacy node metadata");
  117. }
  118. }
  119. static bool content_nodemeta_deserialize_legacy_meta(
  120. std::istream &is, NodeMetadata *meta)
  121. {
  122. // Read id
  123. s16 id = readS16(is);
  124. // Read data
  125. std::string data = deSerializeString(is);
  126. std::istringstream tmp_is(data, std::ios::binary);
  127. return content_nodemeta_deserialize_legacy_body(tmp_is, id, meta);
  128. }
  129. void content_nodemeta_deserialize_legacy(std::istream &is,
  130. NodeMetadataList *meta, NodeTimerList *timers,
  131. IItemDefManager *item_def_mgr)
  132. {
  133. meta->clear();
  134. timers->clear();
  135. u16 version = readU16(is);
  136. if(version > 1)
  137. {
  138. infostream<<FUNCTION_NAME<<": version "<<version<<" not supported"
  139. <<std::endl;
  140. throw SerializationError(FUNCTION_NAME);
  141. }
  142. u16 count = readU16(is);
  143. for(u16 i=0; i<count; i++)
  144. {
  145. u16 p16 = readU16(is);
  146. v3s16 p(0,0,0);
  147. p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE;
  148. p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE;
  149. p.Y += p16 / MAP_BLOCKSIZE;
  150. p16 -= p.Y * MAP_BLOCKSIZE;
  151. p.X += p16;
  152. if(meta->get(p) != NULL)
  153. {
  154. warningstream<<FUNCTION_NAME<<": "
  155. <<"already set data at position"
  156. <<"("<<p.X<<","<<p.Y<<","<<p.Z<<"): Ignoring."
  157. <<std::endl;
  158. continue;
  159. }
  160. NodeMetadata *data = new NodeMetadata(item_def_mgr);
  161. bool need_timer = content_nodemeta_deserialize_legacy_meta(is, data);
  162. meta->set(p, data);
  163. if(need_timer)
  164. timers->set(NodeTimer(1., 0., p));
  165. }
  166. }