diff options
author | Perttu Ahola <celeron55@gmail.com> | 2012-11-26 23:59:03 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2012-11-29 22:08:25 +0200 |
commit | 23913f26cd0a075505b7e74df6b93584288afb92 (patch) | |
tree | 928ed52b6fae1c4f6b2dacfa1abde9797a9a6fdd | |
parent | 9714612999dc88e67566be91ec41659c5254321f (diff) | |
download | minetest-23913f26cd0a075505b7e74df6b93584288afb92.tar.gz minetest-23913f26cd0a075505b7e74df6b93584288afb92.tar.bz2 minetest-23913f26cd0a075505b7e74df6b93584288afb92.zip |
Support serialization of protocol 13 ContentFeatures
-rw-r--r-- | src/nodedef.cpp | 296 | ||||
-rw-r--r-- | src/nodedef.h | 8 | ||||
-rw-r--r-- | src/server.cpp | 11 |
3 files changed, 195 insertions, 120 deletions
diff --git a/src/nodedef.cpp b/src/nodedef.cpp index c51b3e6ff..c48e2ff97 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -215,8 +215,13 @@ void ContentFeatures::reset() sound_dug = SimpleSoundSpec(); } -void ContentFeatures::serialize(std::ostream &os) +void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) { + if(protocol_version < 14){ + serializeOld(os, protocol_version); + return; + } + writeU8(os, 6); // version os<<serializeString(name); writeU16(os, groups.size()); @@ -271,117 +276,65 @@ void ContentFeatures::serialize(std::ostream &os) void ContentFeatures::deSerialize(std::istream &is) { int version = readU8(is); - if(version == 6) // In PROTOCOL_VERSION 14 - { - name = deSerializeString(is); - groups.clear(); - u32 groups_size = readU16(is); - for(u32 i=0; i<groups_size; i++){ - std::string name = deSerializeString(is); - int value = readS16(is); - groups[name] = value; - } - drawtype = (enum NodeDrawType)readU8(is); - visual_scale = readF1000(is); - if(readU8(is) != 6) - throw SerializationError("unsupported tile count"); - for(u32 i=0; i<6; i++) - tiledef[i].deSerialize(is); - if(readU8(is) != CF_SPECIAL_COUNT) - throw SerializationError("unsupported CF_SPECIAL_COUNT"); - for(u32 i=0; i<CF_SPECIAL_COUNT; i++) - tiledef_special[i].deSerialize(is); - alpha = readU8(is); - post_effect_color.setAlpha(readU8(is)); - post_effect_color.setRed(readU8(is)); - post_effect_color.setGreen(readU8(is)); - post_effect_color.setBlue(readU8(is)); - param_type = (enum ContentParamType)readU8(is); - param_type_2 = (enum ContentParamType2)readU8(is); - is_ground_content = readU8(is); - light_propagates = readU8(is); - sunlight_propagates = readU8(is); - walkable = readU8(is); - pointable = readU8(is); - diggable = readU8(is); - climbable = readU8(is); - buildable_to = readU8(is); - deSerializeString(is); // legacy: used to be metadata_name - liquid_type = (enum LiquidType)readU8(is); - liquid_alternative_flowing = deSerializeString(is); - liquid_alternative_source = deSerializeString(is); - liquid_viscosity = readU8(is); - liquid_renewable = readU8(is); - light_source = readU8(is); - damage_per_second = readU32(is); - node_box.deSerialize(is); - selection_box.deSerialize(is); - legacy_facedir_simple = readU8(is); - legacy_wallmounted = readU8(is); - deSerializeSimpleSoundSpec(sound_footstep, is); - deSerializeSimpleSoundSpec(sound_dig, is); - deSerializeSimpleSoundSpec(sound_dug, is); - // If you add anything here, insert it primarily inside the try-catch - // block to not need to increase the version. - try{ - // Stuff below should be moved to correct place in a version that - // otherwise changes the protocol version - }catch(SerializationError &e) {}; - } - else if(version == 5) // In PROTOCOL_VERSION 13 - { - name = deSerializeString(is); - groups.clear(); - u32 groups_size = readU16(is); - for(u32 i=0; i<groups_size; i++){ - std::string name = deSerializeString(is); - int value = readS16(is); - groups[name] = value; - } - drawtype = (enum NodeDrawType)readU8(is); - visual_scale = readF1000(is); - if(readU8(is) != 6) - throw SerializationError("unsupported tile count"); - for(u32 i=0; i<6; i++) - tiledef[i].deSerialize(is); - if(readU8(is) != CF_SPECIAL_COUNT) - throw SerializationError("unsupported CF_SPECIAL_COUNT"); - for(u32 i=0; i<CF_SPECIAL_COUNT; i++) - tiledef_special[i].deSerialize(is); - alpha = readU8(is); - post_effect_color.setAlpha(readU8(is)); - post_effect_color.setRed(readU8(is)); - post_effect_color.setGreen(readU8(is)); - post_effect_color.setBlue(readU8(is)); - param_type = (enum ContentParamType)readU8(is); - param_type_2 = (enum ContentParamType2)readU8(is); - is_ground_content = readU8(is); - light_propagates = readU8(is); - sunlight_propagates = readU8(is); - walkable = readU8(is); - pointable = readU8(is); - diggable = readU8(is); - climbable = readU8(is); - buildable_to = readU8(is); - deSerializeString(is); // legacy: used to be metadata_name - liquid_type = (enum LiquidType)readU8(is); - liquid_alternative_flowing = deSerializeString(is); - liquid_alternative_source = deSerializeString(is); - liquid_viscosity = readU8(is); - light_source = readU8(is); - damage_per_second = readU32(is); - node_box.deSerialize(is); - selection_box.deSerialize(is); - legacy_facedir_simple = readU8(is); - legacy_wallmounted = readU8(is); - deSerializeSimpleSoundSpec(sound_footstep, is); - deSerializeSimpleSoundSpec(sound_dig, is); - deSerializeSimpleSoundSpec(sound_dug, is); + if(version != 6){ + deSerializeOld(is, version); + return; } - else - { - throw SerializationError("unsupported ContentFeatures version"); + + name = deSerializeString(is); + groups.clear(); + u32 groups_size = readU16(is); + for(u32 i=0; i<groups_size; i++){ + std::string name = deSerializeString(is); + int value = readS16(is); + groups[name] = value; } + drawtype = (enum NodeDrawType)readU8(is); + visual_scale = readF1000(is); + if(readU8(is) != 6) + throw SerializationError("unsupported tile count"); + for(u32 i=0; i<6; i++) + tiledef[i].deSerialize(is); + if(readU8(is) != CF_SPECIAL_COUNT) + throw SerializationError("unsupported CF_SPECIAL_COUNT"); + for(u32 i=0; i<CF_SPECIAL_COUNT; i++) + tiledef_special[i].deSerialize(is); + alpha = readU8(is); + post_effect_color.setAlpha(readU8(is)); + post_effect_color.setRed(readU8(is)); + post_effect_color.setGreen(readU8(is)); + post_effect_color.setBlue(readU8(is)); + param_type = (enum ContentParamType)readU8(is); + param_type_2 = (enum ContentParamType2)readU8(is); + is_ground_content = readU8(is); + light_propagates = readU8(is); + sunlight_propagates = readU8(is); + walkable = readU8(is); + pointable = readU8(is); + diggable = readU8(is); + climbable = readU8(is); + buildable_to = readU8(is); + deSerializeString(is); // legacy: used to be metadata_name + liquid_type = (enum LiquidType)readU8(is); + liquid_alternative_flowing = deSerializeString(is); + liquid_alternative_source = deSerializeString(is); + liquid_viscosity = readU8(is); + liquid_renewable = readU8(is); + light_source = readU8(is); + damage_per_second = readU32(is); + node_box.deSerialize(is); + selection_box.deSerialize(is); + legacy_facedir_simple = readU8(is); + legacy_wallmounted = readU8(is); + deSerializeSimpleSoundSpec(sound_footstep, is); + deSerializeSimpleSoundSpec(sound_dig, is); + deSerializeSimpleSoundSpec(sound_dug, is); + // If you add anything here, insert it primarily inside the try-catch + // block to not need to increase the version. + try{ + // Stuff below should be moved to correct place in a version that + // otherwise changes the protocol version + }catch(SerializationError &e) {}; } /* @@ -748,7 +701,7 @@ public: } #endif } - void serialize(std::ostream &os) + void serialize(std::ostream &os, u16 protocol_version) { writeU8(os, 1); // version u16 count = 0; @@ -764,7 +717,7 @@ public: // Wrap it in a string to allow different lengths without // strict version incompatibilities std::ostringstream wrapper_os(std::ios::binary); - f->serialize(wrapper_os); + f->serialize(wrapper_os, protocol_version); os2<<serializeString(wrapper_os.str()); count++; } @@ -821,3 +774,122 @@ IWritableNodeDefManager* createNodeDefManager() return new CNodeDefManager(); } +/* + Serialization of old ContentFeatures formats +*/ + +void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version) +{ + if(protocol_version == 13) + { + writeU8(os, 5); // version + os<<serializeString(name); + writeU16(os, groups.size()); + for(ItemGroupList::const_iterator + i = groups.begin(); i != groups.end(); i++){ + os<<serializeString(i->first); + writeS16(os, i->second); + } + writeU8(os, drawtype); + writeF1000(os, visual_scale); + writeU8(os, 6); + for(u32 i=0; i<6; i++) + tiledef[i].serialize(os); + writeU8(os, CF_SPECIAL_COUNT); + for(u32 i=0; i<CF_SPECIAL_COUNT; i++){ + tiledef_special[i].serialize(os); + } + writeU8(os, alpha); + writeU8(os, post_effect_color.getAlpha()); + writeU8(os, post_effect_color.getRed()); + writeU8(os, post_effect_color.getGreen()); + writeU8(os, post_effect_color.getBlue()); + writeU8(os, param_type); + writeU8(os, param_type_2); + writeU8(os, is_ground_content); + writeU8(os, light_propagates); + writeU8(os, sunlight_propagates); + writeU8(os, walkable); + writeU8(os, pointable); + writeU8(os, diggable); + writeU8(os, climbable); + writeU8(os, buildable_to); + os<<serializeString(""); // legacy: used to be metadata_name + writeU8(os, liquid_type); + os<<serializeString(liquid_alternative_flowing); + os<<serializeString(liquid_alternative_source); + writeU8(os, liquid_viscosity); + writeU8(os, light_source); + writeU32(os, damage_per_second); + node_box.serialize(os); + selection_box.serialize(os); + writeU8(os, legacy_facedir_simple); + writeU8(os, legacy_wallmounted); + serializeSimpleSoundSpec(sound_footstep, os); + serializeSimpleSoundSpec(sound_dig, os); + serializeSimpleSoundSpec(sound_dug, os); + } + else + { + throw SerializationError("ContentFeatures::serialize(): Unsupported version requested"); + } +} + +void ContentFeatures::deSerializeOld(std::istream &is, int version) +{ + if(version == 5) // In PROTOCOL_VERSION 13 + { + name = deSerializeString(is); + groups.clear(); + u32 groups_size = readU16(is); + for(u32 i=0; i<groups_size; i++){ + std::string name = deSerializeString(is); + int value = readS16(is); + groups[name] = value; + } + drawtype = (enum NodeDrawType)readU8(is); + visual_scale = readF1000(is); + if(readU8(is) != 6) + throw SerializationError("unsupported tile count"); + for(u32 i=0; i<6; i++) + tiledef[i].deSerialize(is); + if(readU8(is) != CF_SPECIAL_COUNT) + throw SerializationError("unsupported CF_SPECIAL_COUNT"); + for(u32 i=0; i<CF_SPECIAL_COUNT; i++) + tiledef_special[i].deSerialize(is); + alpha = readU8(is); + post_effect_color.setAlpha(readU8(is)); + post_effect_color.setRed(readU8(is)); + post_effect_color.setGreen(readU8(is)); + post_effect_color.setBlue(readU8(is)); + param_type = (enum ContentParamType)readU8(is); + param_type_2 = (enum ContentParamType2)readU8(is); + is_ground_content = readU8(is); + light_propagates = readU8(is); + sunlight_propagates = readU8(is); + walkable = readU8(is); + pointable = readU8(is); + diggable = readU8(is); + climbable = readU8(is); + buildable_to = readU8(is); + deSerializeString(is); // legacy: used to be metadata_name + liquid_type = (enum LiquidType)readU8(is); + liquid_alternative_flowing = deSerializeString(is); + liquid_alternative_source = deSerializeString(is); + liquid_viscosity = readU8(is); + light_source = readU8(is); + damage_per_second = readU32(is); + node_box.deSerialize(is); + selection_box.deSerialize(is); + legacy_facedir_simple = readU8(is); + legacy_wallmounted = readU8(is); + deSerializeSimpleSoundSpec(sound_footstep, is); + deSerializeSimpleSoundSpec(sound_dig, is); + deSerializeSimpleSoundSpec(sound_dug, is); + } + else + { + throw SerializationError("unsupported ContentFeatures version"); + } +} + diff --git a/src/nodedef.h b/src/nodedef.h index 4ff6c6b48..8588caeab 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -234,8 +234,10 @@ struct ContentFeatures ContentFeatures(); ~ContentFeatures(); void reset(); - void serialize(std::ostream &os); + void serialize(std::ostream &os, u16 protocol_version); void deSerialize(std::istream &is); + void serializeOld(std::ostream &os, u16 protocol_version); + void deSerializeOld(std::istream &is, int version); /* Some handy methods @@ -264,7 +266,7 @@ public: const=0; virtual const ContentFeatures& get(const std::string &name) const=0; - virtual void serialize(std::ostream &os)=0; + virtual void serialize(std::ostream &os, u16 protocol_version)=0; }; class IWritableNodeDefManager : public INodeDefManager @@ -305,7 +307,7 @@ public: */ virtual void updateTextures(ITextureSource *tsrc)=0; - virtual void serialize(std::ostream &os)=0; + virtual void serialize(std::ostream &os, u16 protocol_version)=0; virtual void deSerialize(std::istream &is)=0; }; diff --git a/src/server.cpp b/src/server.cpp index cb5447605..f29155ba0 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2255,8 +2255,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) return; } - getClient(peer_id)->serialization_version - = getClient(peer_id)->pending_serialization_version; + RemoteClient *client = getClient(peer_id); + client->serialization_version = + getClient(peer_id)->pending_serialization_version; /* Send some initialization data @@ -2269,7 +2270,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) SendItemDef(m_con, peer_id, m_itemdef); // Send node definitions - SendNodeDef(m_con, peer_id, m_nodedef); + SendNodeDef(m_con, peer_id, m_nodedef, client->net_proto_version); // Send media announcement sendMediaAnnouncement(peer_id); @@ -3521,7 +3522,7 @@ void Server::SendItemDef(con::Connection &con, u16 peer_id, } void Server::SendNodeDef(con::Connection &con, u16 peer_id, - INodeDefManager *nodedef) + INodeDefManager *nodedef, u16 protocol_version) { DSTACK(__FUNCTION_NAME); std::ostringstream os(std::ios_base::binary); @@ -3533,7 +3534,7 @@ void Server::SendNodeDef(con::Connection &con, u16 peer_id, */ writeU16(os, TOCLIENT_NODEDEF); std::ostringstream tmp_os(std::ios::binary); - nodedef->serialize(tmp_os); + nodedef->serialize(tmp_os, protocol_version); std::ostringstream tmp_os2(std::ios::binary); compressZlib(tmp_os.str(), tmp_os2); os<<serializeLongString(tmp_os2.str()); |