content_nodemeta.cpp 5.2 KB

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