summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-11-26 23:59:03 +0200
committerPerttu Ahola <celeron55@gmail.com>2012-11-29 22:08:25 +0200
commit23913f26cd0a075505b7e74df6b93584288afb92 (patch)
tree928ed52b6fae1c4f6b2dacfa1abde9797a9a6fdd
parent9714612999dc88e67566be91ec41659c5254321f (diff)
downloadminetest-23913f26cd0a075505b7e74df6b93584288afb92.tar.gz
minetest-23913f26cd0a075505b7e74df6b93584288afb92.tar.bz2
minetest-23913f26cd0a075505b7e74df6b93584288afb92.zip
Support serialization of protocol 13 ContentFeatures
-rw-r--r--src/nodedef.cpp296
-rw-r--r--src/nodedef.h8
-rw-r--r--src/server.cpp11
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());