Improve node timer format (map format version 25) and update mapformat.txt
authorPerttu Ahola <celeron55@gmail.com>
Tue, 24 Jul 2012 11:56:32 +0000 (14:56 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 24 Jul 2012 12:03:46 +0000 (15:03 +0300)
doc/mapformat.txt
src/mapblock.cpp
src/nodetimer.cpp
src/nodetimer.h
src/serialization.h

index ef16118c54c2754499172bbfb5513182298037e3..89863ea043b5118c351e514b33e57a095df997ce 100644 (file)
@@ -1,11 +1,12 @@
 =============================
-Minetest World Format 22...23
+Minetest World Format 22...25
 =============================
 
 This applies to a world format carrying the block serialization version
-22...23, used at least in
-- 0.4.dev-20120322 ... 0.4.dev-20120606
-- 0.4.0.
+22...25, used at least in
+- 0.4.dev-20120322 ... 0.4.dev-20120606 (22...23)
+- 0.4.0 (23)
+- 24 was never released as stable and existed for ~2 days
 
 The block serialization version does not fully specify every aspect of this
 format; if compliance with this format is to be checked, it needs to be
@@ -262,17 +263,26 @@ u8 flags
 
 u8 content_width
 - Number of bytes in the content (param0) fields of nodes
-- Always 1
+if map format version <= 23:
+    - Always 1
+if map format version >= 24:
+    - Always 2
 
 u8 params_width
 - Number of bytes used for parameters per node
 - Always 2
 
 zlib-compressed node data:
-- content:
-  u8[4096]: param0 fields
-  u8[4096]: param1 fields
-  u8[4096]: param2 fields
+if content_width == 1:
+    - content:
+      u8[4096]: param0 fields
+      u8[4096]: param1 fields
+      u8[4096]: param2 fields
+if content_width == 2:
+    - content:
+      u16[4096]: param0 fields
+      u8[4096]: param1 fields
+      u8[4096]: param2 fields
 - The location of a node in each of those arrays is (z*16*16 + y*16 + x).
 
 zlib-compressed node metadata list
@@ -285,9 +295,19 @@ zlib-compressed node metadata list
     u16 content_size
     u8[content_size] (content of metadata)
 
-- unused node timers (version will be 24 when they are actually used):
-if version == 23:
+- Node timers
+if map format version == 23:
   u8 unused version (always 0)
+if map format version == 24: (NOTE: Not released as stable)
+  u8 nodetimer_version
+  if nodetimer_version == 0:
+    (nothing else)
+  if nodetimer_version == 1:
+    u16 num_of_timers
+    foreach num_of_timers:
+      u16 timer position (z*16*16 + y*16 + x)
+      s32 timeout*1000
+      s32 elapsed*1000
 
 u8 static object version:
 - Always 0
@@ -317,17 +337,29 @@ foreach num_name_id_mappings
   u16 name_len
   u8[name_len] name
 
+- Node timers
+if map format version == 25:
+  u8 length of the data of a single timer (always 2+4+4=10)
+  u16 num_of_timers
+  foreach num_of_timers:
+    u16 timer position (z*16*16 + y*16 + x)
+    s32 timeout*1000
+    s32 elapsed*1000
+
 EOF.
 
 Format of nodes
 ----------------
 A node is composed of the u8 fields param0, param1 and param2.
 
-The content id of a node is determined as so:
-- If param0 < 0x80,
-    content_id = param0
-- Otherwise
-    content_id = (param0<<4) + (param2>>4)
+if map format version <= 23:
+    The content id of a node is determined as so:
+    - If param0 < 0x80,
+        content_id = param0
+    - Otherwise
+        content_id = (param0<<4) + (param2>>4)
+if map format version >= 24:
+    The content id of a node is param0.
 
 The purpose of param1 and param2 depend on the definition of the node.
 
index c7c820d42e7cfc6fa80ab0e00767f7c8c53857b3..b2da768f541b14dfc38572db18f7e7df079430c6 100644 (file)
@@ -612,8 +612,10 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
        */
        if(disk)
        {
-               // Node timers
-               m_node_timers.serialize(os);
+               if(version <= 24){
+                       // Node timers
+                       m_node_timers.serialize(os, version);
+               }
 
                // Static objects
                m_static_objects.serialize(os);
@@ -623,6 +625,11 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk)
 
                // Write block-specific node definition id mapping
                nimap.serialize(os);
+               
+               if(version >= 25){
+                       // Node timers
+                       m_node_timers.serialize(os, version);
+               }
        }
 }
 
@@ -696,10 +703,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
                        // Read unused zero
                        readU8(is);
                }
-               else if(version >= 24){
+               if(version == 24){
                        TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
-                                       <<": Node timers"<<std::endl);
-                       m_node_timers.deSerialize(is);
+                                       <<": Node timers (ver==24)"<<std::endl);
+                       m_node_timers.deSerialize(is, version);
                }
 
                // Static objects
@@ -719,6 +726,12 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk)
                NameIdMapping nimap;
                nimap.deSerialize(is);
                correctBlockNodeIds(&nimap, data, m_gamedef);
+
+               if(version >= 25){
+                       TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
+                                       <<": Node timers (ver>=25)"<<std::endl);
+                       m_node_timers.deSerialize(is, version);
+               }
        }
                
        TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
index b20bcf5788921129351f684558f7ffef8d8268e1..bf1e7435d493285e3ed00131a16eb40d8db5238c 100644 (file)
@@ -42,19 +42,22 @@ void NodeTimer::deSerialize(std::istream &is)
        NodeTimerList
 */
 
-void NodeTimerList::serialize(std::ostream &os) const
+void NodeTimerList::serialize(std::ostream &os, u8 map_format_version) const
 {
-       /*
-               Version 0 is a placeholder for "nothing to see here; go away."
-       */
-
-       if(m_data.size() == 0){
-               writeU8(os, 0); // version
-               return;
+       if(map_format_version == 24){
+               // Version 0 is a placeholder for "nothing to see here; go away."
+               if(m_data.size() == 0){
+                       writeU8(os, 0); // version
+                       return;
+               }
+               writeU8(os, 1); // version
+               writeU16(os, m_data.size());
        }
 
-       writeU8(os, 1); // version
-       writeU16(os, m_data.size());
+       if(map_format_version >= 25){
+               writeU8(os, 2+4+4);
+               writeU16(os, m_data.size());
+       }
 
        for(std::map<v3s16, NodeTimer>::const_iterator
                        i = m_data.begin();
@@ -68,15 +71,23 @@ void NodeTimerList::serialize(std::ostream &os) const
        }
 }
 
-void NodeTimerList::deSerialize(std::istream &is)
+void NodeTimerList::deSerialize(std::istream &is, u8 map_format_version)
 {
        m_data.clear();
+       
+       if(map_format_version == 24){
+               u8 timer_version = readU8(is);
+               if(timer_version == 0)
+                       return;
+               if(timer_version != 1)
+                       throw SerializationError("unsupported NodeTimerList version");
+       }
 
-       u8 version = readU8(is);
-       if(version == 0)
-               return;
-       if(version != 1)
-               throw SerializationError("unsupported NodeTimerList version");
+       if(map_format_version >= 25){
+               u8 timer_data_len = readU8(is);
+               if(timer_data_len != 2+4+4)
+                       throw SerializationError("unsupported NodeTimer data length");
+       }
 
        u16 count = readU16(is);
 
index f8d3e1c5799ee50d0d4c3cfaac05ad0d71478cfc..c643ab888a94ad7d9e8a28908f19e8663bf3598d 100644 (file)
@@ -57,8 +57,8 @@ public:
        NodeTimerList() {}
        ~NodeTimerList() {}
        
-       void serialize(std::ostream &os) const;
-       void deSerialize(std::istream &is);
+       void serialize(std::ostream &os, u8 map_format_version) const;
+       void deSerialize(std::istream &is, u8 map_format_version);
        
        // Get timer
        NodeTimer get(v3s16 p){
index 0d74ccf48fb7ba280ce101416dfa992180638022..533ddc8c446f0704990551ddf7e807c688570d55 100644 (file)
@@ -59,12 +59,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        21: dynamic content type allocation
        22: minerals removed, facedir & wallmounted changed
        23: new node metadata format
-       24: 16-bit node ids and node timers
+       24: 16-bit node ids and node timers (never released as stable)
+       25: Improved node timer format
 */
 // This represents an uninitialized or invalid format
 #define SER_FMT_VER_INVALID 255
 // Highest supported serialization version
-#define SER_FMT_VER_HIGHEST 24
+#define SER_FMT_VER_HIGHEST 25
 // Lowest supported serialization version
 #define SER_FMT_VER_LOWEST 0