diff options
author | Perttu Ahola <celeron55@gmail.com> | 2012-07-23 07:20:13 +0300 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2012-07-23 08:18:39 +0300 |
commit | fd845f27f5b3e3c6587c472be76235567a7b934d (patch) | |
tree | 53915de3f1c512e0e4ec8d29cd42160a9af5e826 | |
parent | ea62ee4b61371107ef3d693bda4c410ba02ca7e6 (diff) | |
download | minetest-fd845f27f5b3e3c6587c472be76235567a7b934d.tar.gz minetest-fd845f27f5b3e3c6587c472be76235567a7b934d.tar.bz2 minetest-fd845f27f5b3e3c6587c472be76235567a7b934d.zip |
Fix map deserialization and remove old serialization code
-rw-r--r-- | src/clientserver.h | 4 | ||||
-rw-r--r-- | src/content_mapnode.cpp | 17 | ||||
-rw-r--r-- | src/content_mapnode.h | 1 | ||||
-rw-r--r-- | src/mapblock.cpp | 242 | ||||
-rw-r--r-- | src/mapblock.h | 1 | ||||
-rw-r--r-- | src/mapnode.cpp | 111 | ||||
-rw-r--r-- | src/mapnode.h | 7 | ||||
-rw-r--r-- | src/nodedef.cpp | 23 | ||||
-rw-r--r-- | src/serialization.h | 2 |
9 files changed, 45 insertions, 363 deletions
diff --git a/src/clientserver.h b/src/clientserver.h index 521406844..d43220962 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -61,10 +61,12 @@ with this program; if not, write to the Free Software Foundation, Inc., (some dev snapshot) TOCLIENT_INVENTORY_FORMSPEC (0.4.0, 0.4.1) + PROTOCOL_VERSION 12: TOSERVER_INVENTORY_FIELDS + 16-bit node ids */ -#define PROTOCOL_VERSION 11 +#define PROTOCOL_VERSION 12 #define PROTOCOL_ID 0x4f457403 diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 410aaa911..c3fdb4a42 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -102,23 +102,6 @@ content_t trans_table_19[21][2] = { {CONTENT_BOOKSHELF, 29}, }; -MapNode mapnode_translate_from_internal(MapNode n_from, u8 version) -{ - MapNode result = n_from; - if(version <= 19) - { - content_t c_from = n_from.getContent(); - for(u32 i=0; i<sizeof(trans_table_19)/sizeof(trans_table_19[0]); i++) - { - if(trans_table_19[i][0] == c_from) - { - result.setContent(trans_table_19[i][1]); - break; - } - } - } - return result; -} MapNode mapnode_translate_to_internal(MapNode n_from, u8 version) { MapNode result = n_from; diff --git a/src/content_mapnode.h b/src/content_mapnode.h index cc11cd224..45c2b0763 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -28,7 +28,6 @@ with this program; if not, write to the Free Software Foundation, Inc., // Backwards compatibility for non-extended content types in v19 extern content_t trans_table_19[21][2]; -MapNode mapnode_translate_from_internal(MapNode n_from, u8 version); MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); // Get legacy node name mapping for loading old blocks diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 571c2082d..c7c820d42 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -552,12 +552,12 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) throw SerializationError("ERROR: Not writing dummy block."); } - if(version <= 21) - { - serialize_pre22(os, version, disk); - return; - } - + // Can't do this anymore; we have 16-bit dynamically allocated node IDs + // in memory; conversion just won't work in this direction. + if(version < 24) + throw SerializationError("MapBlock::serialize: serialization to " + "version < 24 not possible"); + // First byte u8 flags = 0; if(is_underground) @@ -582,7 +582,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) tmp_nodes[i] = data[i]; getBlockNodeIdMapping(&nimap, tmp_nodes, m_gamedef->ndef()); - u8 content_width = (version < 24) ? 1 : 2; + u8 content_width = 2; u8 params_width = 2; writeU8(os, content_width); writeU8(os, params_width); @@ -604,10 +604,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) Node metadata */ std::ostringstream oss(std::ios_base::binary); - if(version >= 23) - m_node_metadata.serialize(oss); - else - content_nodemeta_serialize_legacy(oss, &m_node_metadata); + m_node_metadata.serialize(oss); compressZlib(oss.str(), os); /* @@ -615,13 +612,8 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) */ if(disk) { - // Version 23 doesn't actually contain node timers - // (this field should have not been added) - if(version == 23) - writeU8(os, 0); - // Node timers are in version 24 - if(version >= 24) - m_node_timers.serialize(os); + // Node timers + m_node_timers.serialize(os); // Static objects m_static_objects.serialize(os); @@ -634,7 +626,6 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk) } } - void MapBlock::deSerialize(std::istream &is, u8 version, bool disk) { if(!ser_ver_supported(version)) @@ -738,219 +729,6 @@ void MapBlock::deSerialize(std::istream &is, u8 version, bool disk) Legacy serialization */ -// List relevant id-name pairs for ids in the block using nodedef -// Before serialization version 22 -static void getBlockNodeIdMapping_pre22(NameIdMapping *nimap, MapNode *nodes, - INodeDefManager *nodedef) -{ - std::set<content_t> unknown_contents; - for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++) - { - content_t id = nodes[i].getContent(); - const ContentFeatures &f = nodedef->get(id); - const std::string &name = f.name; - if(name == "") - unknown_contents.insert(id); - else - nimap->set(id, name); - } - for(std::set<content_t>::const_iterator - i = unknown_contents.begin(); - i != unknown_contents.end(); i++){ - errorstream<<"getBlockNodeIdMapping_pre22(): IGNORING ERROR: " - <<"Name for node id "<<(*i)<<" not known"<<std::endl; - } -} -void MapBlock::serialize_pre22(std::ostream &os, u8 version, bool disk) -{ - u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; - - MapNode *tmp_data = new MapNode[nodecount]; - - // Legacy data changes - // This code has to change from post-22 to pre-22 format. - INodeDefManager *nodedef = m_gamedef->ndef(); - for(u32 i=0; i<nodecount; i++) - { - const ContentFeatures &f = nodedef->get(tmp_data[i].getContent()); - // Mineral - if(nodedef->getId("default:stone_with_coal") == tmp_data[i].getContent()) - { - tmp_data[i].setContent(nodedef->getId("default:stone")); - tmp_data[i].setParam1(1); // MINERAL_COAL - } - else if(nodedef->getId("default:stone_with_iron") == tmp_data[i].getContent()) - { - tmp_data[i].setContent(nodedef->getId("default:stone")); - tmp_data[i].setParam1(2); // MINERAL_IRON - } - // facedir_simple - if(f.legacy_facedir_simple) - { - tmp_data[i].setParam1(tmp_data[i].getParam2()); - tmp_data[i].setParam2(0); - } - // wall_mounted - if(f.legacy_wallmounted) - { - u8 wallmounted_new_to_old[8] = {0x04, 0x08, 0x01, 0x02, 0x10, 0x20, 0, 0}; - u8 dir_new_format = tmp_data[i].getParam2() & 7; // lowest 3 bits - u8 dir_old_format = wallmounted_new_to_old[dir_new_format]; - tmp_data[i].setParam2(dir_old_format); - } - } - - // Serialize nodes - u32 ser_length = MapNode::serializedLength(version); - SharedBuffer<u8> databuf_nodelist(nodecount * ser_length); - for(u32 i=0; i<nodecount; i++) - { - tmp_data[i].serialize(&databuf_nodelist[i*ser_length], version); - } - - delete[] tmp_data; - - // These have no compression - if(version <= 3 || version == 5 || version == 6) - { - writeU8(os, is_underground); - os.write((char*)*databuf_nodelist, databuf_nodelist.getSize()); - } - else if(version <= 10) - { - /* - With compression. - Compress the materials and the params separately. - */ - - // First byte - writeU8(os, is_underground); - - // Get and compress materials - SharedBuffer<u8> materialdata(nodecount); - for(u32 i=0; i<nodecount; i++) - { - materialdata[i] = databuf_nodelist[i*ser_length]; - } - compress(materialdata, os, version); - - // Get and compress lights - SharedBuffer<u8> lightdata(nodecount); - for(u32 i=0; i<nodecount; i++) - { - lightdata[i] = databuf_nodelist[i*ser_length+1]; - } - compress(lightdata, os, version); - - if(version >= 10) - { - // Get and compress param2 - SharedBuffer<u8> param2data(nodecount); - for(u32 i=0; i<nodecount; i++) - { - param2data[i] = databuf_nodelist[i*ser_length+2]; - } - compress(param2data, os, version); - } - } - // All other versions (newest) - else - { - // First byte - u8 flags = 0; - if(is_underground) - flags |= 0x01; - if(getDayNightDiff()) - flags |= 0x02; - if(m_lighting_expired) - flags |= 0x04; - if(version >= 18) - { - if(m_generated == false) - flags |= 0x08; - } - writeU8(os, flags); - - /* - Get data - */ - - // Create buffer with different parameters sorted - SharedBuffer<u8> databuf(nodecount*3); - for(u32 i=0; i<nodecount; i++) - { - databuf[i] = databuf_nodelist[i*ser_length]; - databuf[i+nodecount] = databuf_nodelist[i*ser_length+1]; - databuf[i+nodecount*2] = databuf_nodelist[i*ser_length+2]; - } - - /* - Compress data to output stream - */ - - compress(databuf, os, version); - - /* - NodeMetadata - */ - if(version >= 14) - { - if(version <= 15) - { - try{ - std::ostringstream oss(std::ios_base::binary); - content_nodemeta_serialize_legacy(oss, &m_node_metadata); - os<<serializeString(oss.str()); - } - // This will happen if the string is longer than 65535 - catch(SerializationError &e) - { - // Use an empty string - os<<serializeString(""); - } - } - else - { - std::ostringstream oss(std::ios_base::binary); - content_nodemeta_serialize_legacy(oss, &m_node_metadata); - compressZlib(oss.str(), os); - //os<<serializeLongString(oss.str()); - } - } - } - - - if(disk) - { - // Versions up from 9 have block objects. (DEPRECATED) - if(version >= 9) - { - // count=0 - writeU16(os, 0); - } - - // Versions up from 15 have static objects. - if(version >= 15) - { - m_static_objects.serialize(os); - } - - // Timestamp - if(version >= 17) - { - writeU32(os, getTimestamp()); - } - - // Scan and write node definition id mapping - if(version >= 21) - { - NameIdMapping nimap; - getBlockNodeIdMapping_pre22(&nimap, data, m_gamedef->ndef()); - nimap.serialize(os); - } - } -} - void MapBlock::deSerialize_pre22(std::istream &is, u8 version, bool disk) { u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; diff --git a/src/mapblock.h b/src/mapblock.h index adb3324f6..7f901e5d3 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -467,7 +467,6 @@ private: Private methods */ - void serialize_pre22(std::ostream &os, u8 version, bool disk); void deSerialize_pre22(std::istream &is, u8 version, bool disk); /* diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 0479d2e55..c616e0117 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -241,28 +241,16 @@ void MapNode::serialize(u8 *dest, u8 version) { if(!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapNode format not supported"); - - if(version <= 21) - { - serialize_pre22(dest, version); - return; - } - - if(version >= 24){ - writeU16(dest+0, param0); - writeU8(dest+2, param1); - writeU8(dest+3, param2); - } - else{ - writeU8(dest+0, (param0&0xFF)); - writeU8(dest+1, param1); - if (param0 > 0x7F){ - writeU8(dest+2, ((param2&0x0F) | ((param0&0x0F00)>>4))); - } - else{ - writeU8(dest+2, param2); - } - } + + // Can't do this anymore; we have 16-bit dynamically allocated node IDs + // in memory; conversion just won't work in this direction. + if(version < 24) + throw SerializationError("MapNode::serialize: serialization to " + "version < 24 not possible"); + + writeU16(dest+0, param0); + writeU8(dest+2, param1); + writeU8(dest+3, param2); } void MapNode::deSerialize(u8 *source, u8 version) { @@ -297,22 +285,20 @@ void MapNode::serializeBulk(std::ostream &os, int version, if(!ser_ver_supported(version)) throw VersionMismatchException("ERROR: MapNode format not supported"); - assert(version >= 22); - assert(content_width == 1 || content_width == 2); + assert(content_width == 2); assert(params_width == 2); + // Can't do this anymore; we have 16-bit dynamically allocated node IDs + // in memory; conversion just won't work in this direction. + if(version < 24) + throw SerializationError("MapNode::serializeBulk: serialization to " + "version < 24 not possible"); + SharedBuffer<u8> databuf(nodecount * (content_width + params_width)); // Serialize content - if(content_width == 1) - { - for(u32 i=0; i<nodecount; i++) - writeU8(&databuf[i], (nodes[i].param0&0x00FF)); - }else if(content_width == 2) - { - for(u32 i=0; i<nodecount; i++) - writeU16(&databuf[i*2], nodes[i].param0); - } + for(u32 i=0; i<nodecount; i++) + writeU16(&databuf[i*2], nodes[i].param0); // Serialize param1 u32 start1 = content_width * nodecount; @@ -321,21 +307,8 @@ void MapNode::serializeBulk(std::ostream &os, int version, // Serialize param2 u32 start2 = (content_width + 1) * nodecount; - if(content_width == 1) - { - for(u32 i=0; i<nodecount; i++) { - if(nodes[i].param0 > 0x7F){ - writeU8(&databuf[start2 + i], ((nodes[i].param2&0x0F) | ((nodes[i].param0&0x0F00)>>4))); - } - else{ - writeU8(&databuf[start2 + i], nodes[i].param2); - } - } - }else if(content_width == 2) - { - for(u32 i=0; i<nodecount; i++) - writeU8(&databuf[start2 + i], nodes[i].param2); - } + for(u32 i=0; i<nodecount; i++) + writeU8(&databuf[start2 + i], nodes[i].param2); /* Compress data to output stream @@ -408,7 +381,8 @@ void MapNode::deSerializeBulk(std::istream &is, int version, for(u32 i=0; i<nodecount; i++) { nodes[i].param2 = readU8(&databuf[start2 + i]); if(nodes[i].param0 > 0x7F){ - nodes[i].param0 |= ((nodes[i].param2&0xF0)<<4); + nodes[i].param0 <<= 4; + nodes[i].param0 |= (nodes[i].param2&0xF0)>>4; nodes[i].param2 &= 0x0F; } } @@ -423,40 +397,6 @@ void MapNode::deSerializeBulk(std::istream &is, int version, /* Legacy serialization */ -void MapNode::serialize_pre22(u8 *dest, u8 version) -{ - // Translate to wanted version - MapNode n_foreign = mapnode_translate_from_internal(*this, version); - - u8 actual_param0 = n_foreign.param0; - - // Convert special values from new version to old - if(version <= 18) - { - // In these versions, CONTENT_IGNORE and CONTENT_AIR - // are 255 and 254 - if(actual_param0 == CONTENT_IGNORE) - actual_param0 = 255; - else if(actual_param0 == CONTENT_AIR) - actual_param0 = 254; - } - - if(version == 0) - { - dest[0] = actual_param0; - } - else if(version <= 9) - { - dest[0] = actual_param0; - dest[1] = n_foreign.param1; - } - else - { - dest[0] = actual_param0; - dest[1] = n_foreign.param1; - dest[2] = n_foreign.param2; - } -} void MapNode::deSerialize_pre22(u8 *source, u8 version) { if(version <= 1) @@ -473,6 +413,11 @@ void MapNode::deSerialize_pre22(u8 *source, u8 version) param0 = source[0]; param1 = source[1]; param2 = source[2]; + if(param0 > 0x7f){ + param0 <<= 4; + param0 |= (param2&0xf0)>>4; + param2 &= 0x0f; + } } // Convert special values from old version to new diff --git a/src/mapnode.h b/src/mapnode.h index fe656fa5c..a95497ef5 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -33,10 +33,6 @@ class INodeDefManager; - Material = irrlicht's Material class - Content = (content_t) content of a node - Tile = TileSpec at some side of a node of some content type - - Content ranges: - 0x000...0x07f: param2 is fully usable - 0x800...0xfff: param2 lower 4 bits are free */ typedef u16 content_t; #define MAX_CONTENT 0xfff @@ -84,8 +80,6 @@ struct MapNode { /* Main content - 0x00-0x7f: Short content type - 0x80-0xff: Long content type */ u16 param0; @@ -208,7 +202,6 @@ struct MapNode private: // Deprecated serialization methods - void serialize_pre22(u8 *dest, u8 version); void deSerialize_pre22(u8 *source, u8 version); }; diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 47a29a6fc..e38061e30 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -377,18 +377,9 @@ public: } } // CONTENT_IGNORE = not found - content_t getFreeId(bool require_full_param2) + content_t getFreeId() { - // If allowed, first search in the large 4-bit-param2 pool - if(!require_full_param2){ - for(u16 i=0x800; i<=0xfff; i++){ - const ContentFeatures &f = m_content_features[i]; - if(f.name == "") - return i; - } - } - // Then search from the small 8-bit-param2 pool - for(u16 i=0; i<=125; i++){ + for(u32 i=0; i<=0xffff; i++){ const ContentFeatures &f = m_content_features[i]; if(f.name == "") return i; @@ -492,16 +483,8 @@ public: u16 id = CONTENT_IGNORE; bool found = m_name_id_mapping.getId(name, id); // ignore aliases if(!found){ - // Determine if full param2 is required - bool require_full_param2 = ( - def.param_type_2 == CPT2_FULL - || - def.param_type_2 == CPT2_FLOWINGLIQUID - || - def.legacy_wallmounted - ); // Get some id - id = getFreeId(require_full_param2); + id = getFreeId(); if(id == CONTENT_IGNORE) return CONTENT_IGNORE; if(name != "") diff --git a/src/serialization.h b/src/serialization.h index 266eada17..0d74ccf48 100644 --- a/src/serialization.h +++ b/src/serialization.h @@ -59,7 +59,7 @@ 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: NodeTimers + 24: 16-bit node ids and node timers */ // This represents an uninitialized or invalid format #define SER_FMT_VER_INVALID 255 |