From 4fa4340b95165bb4cdc88ee6d7cf2d0609d6df13 Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Mon, 26 Nov 2012 09:49:31 +0200
Subject: Proper versioning of new network-serialized stuff

---
 src/content_cao.cpp       |  32 ++++++---
 src/environment.cpp       |   5 +-
 src/nodedef.cpp           | 163 +++++++++++++++++++++++++++++++---------------
 src/object_properties.cpp |  84 ++++++++++++++++--------
 4 files changed, 193 insertions(+), 91 deletions(-)

(limited to 'src')

diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index ce41c8312..c7d21d278 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -647,22 +647,36 @@ public:
 	{
 		infostream<<"GenericCAO: Got init data"<<std::endl;
 		std::istringstream is(data, std::ios::binary);
+		int num_messages = 0;
 		// version
 		u8 version = readU8(is);
 		// check version
-		if(version != 1){
+		if(version == 1) // In PROTOCOL_VERSION 14
+		{
+			m_name = deSerializeString(is);
+			m_is_player = readU8(is);
+			m_id = readS16(is);
+			m_position = readV3F1000(is);
+			m_yaw = readF1000(is);
+			m_hp = readS16(is);
+			num_messages = readU8(is);
+		}
+		else if(version == 0) // In PROTOCOL_VERSION 13
+		{
+			m_name = deSerializeString(is);
+			m_is_player = readU8(is);
+			m_position = readV3F1000(is);
+			m_yaw = readF1000(is);
+			m_hp = readS16(is);
+			num_messages = readU8(is);
+		}
+		else
+		{
 			errorstream<<"GenericCAO: Unsupported init data version"
 					<<std::endl;
 			return;
 		}
-		m_name = deSerializeString(is);
-		m_is_player = readU8(is);
-		m_id = readS16(is);
-		m_position = readV3F1000(is);
-		m_yaw = readF1000(is);
-		m_hp = readS16(is);
-		
-		int num_messages = readU8(is);
+
 		for(int i=0; i<num_messages; i++){
 			std::string message = deSerializeLongString(is);
 			processMessage(message);
diff --git a/src/environment.cpp b/src/environment.cpp
index bf90710d6..889990ca5 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -2296,8 +2296,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
 	{
 		errorstream<<"ClientEnvironment::addActiveObject():"
 				<<" id="<<id<<" type="<<type
-				<<": SerializationError in initialize(),"
-				<<" init_data="<<serializeJsonString(init_data)
+				<<": SerializationError in initialize(): "
+				<<e.what()
+				<<": init_data="<<serializeJsonString(init_data)
 				<<std::endl;
 	}
 
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index 38c04a59d..c51b3e6ff 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -271,62 +271,117 @@ void ContentFeatures::serialize(std::ostream &os)
 void ContentFeatures::deSerialize(std::istream &is)
 {
 	int version = readU8(is);
-	if(version != 6)
+	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);
+	}
+	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) {};
 }
 
 /*
diff --git a/src/object_properties.cpp b/src/object_properties.cpp
index 79b3eaf72..3368a5883 100644
--- a/src/object_properties.cpp
+++ b/src/object_properties.cpp
@@ -74,7 +74,7 @@ std::string ObjectProperties::dump()
 
 void ObjectProperties::serialize(std::ostream &os) const
 {
-	writeU8(os, 1); // version
+	writeU8(os, 2); // version
 	writeS16(os, hp_max);
 	writeU8(os, physical);
 	writeF1000(os, weight);
@@ -96,37 +96,69 @@ void ObjectProperties::serialize(std::ostream &os) const
 	writeU8(os, is_visible);
 	writeU8(os, makes_footstep_sound);
 	writeF1000(os, automatic_rotate);
+	// Stuff below should be moved to correct place in a version that otherwise changes
+	// the protocol version
 }
 
 void ObjectProperties::deSerialize(std::istream &is)
 {
 	int version = readU8(is);
-	if(version != 1) throw SerializationError(
-			"unsupported ObjectProperties version");
-	hp_max = readS16(is);
-	physical = readU8(is);
-	weight = readF1000(is);
-	collisionbox.MinEdge = readV3F1000(is);
-	collisionbox.MaxEdge = readV3F1000(is);
-	visual = deSerializeString(is);
-	mesh = deSerializeString(is);
-	visual_size = readV2F1000(is);
-	textures.clear();
-	u32 texture_count = readU16(is);
-	for(u32 i=0; i<texture_count; i++){
-		textures.push_back(deSerializeString(is));
+	if(version == 2) // In PROTOCOL_VERSION 14
+	{
+		hp_max = readS16(is);
+		physical = readU8(is);
+		weight = readF1000(is);
+		collisionbox.MinEdge = readV3F1000(is);
+		collisionbox.MaxEdge = readV3F1000(is);
+		visual = deSerializeString(is);
+		mesh = deSerializeString(is);
+		visual_size = readV2F1000(is);
+		textures.clear();
+		u32 texture_count = readU16(is);
+		for(u32 i=0; i<texture_count; i++){
+			textures.push_back(deSerializeString(is));
+		}
+		u32 color_count = readU16(is);
+		for(u32 i=0; i<color_count; i++){
+			colors.push_back(readARGB8(is));
+		}
+		spritediv = readV2S16(is);
+		initial_sprite_basepos = readV2S16(is);
+		is_visible = readU8(is);
+		makes_footstep_sound = readU8(is);
+		automatic_rotate = readF1000(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){}
 	}
-	u32 color_count = readU16(is);
-	for(u32 i=0; i<color_count; i++){
-		colors.push_back(readARGB8(is));
+	else if(version == 1) // In PROTOCOL_VERSION 13
+	{
+		hp_max = readS16(is);
+		physical = readU8(is);
+		weight = readF1000(is);
+		collisionbox.MinEdge = readV3F1000(is);
+		collisionbox.MaxEdge = readV3F1000(is);
+		visual = deSerializeString(is);
+		visual_size = readV2F1000(is);
+		textures.clear();
+		u32 texture_count = readU16(is);
+		for(u32 i=0; i<texture_count; i++){
+			textures.push_back(deSerializeString(is));
+		}
+		spritediv = readV2S16(is);
+		initial_sprite_basepos = readV2S16(is);
+		is_visible = readU8(is);
+		makes_footstep_sound = readU8(is);
+		try{
+			automatic_rotate = readF1000(is);
+		}catch(SerializationError &e){}
+	}
+	else
+	{
+		throw SerializationError("unsupported ObjectProperties version");
 	}
-	spritediv = readV2S16(is);
-	initial_sprite_basepos = readV2S16(is);
-	is_visible = readU8(is);
-	makes_footstep_sound = readU8(is);
-	try{
-		automatic_rotate = readF1000(is);
-	}catch(SerializationError &e){}
 }
 
-
-- 
cgit v1.2.3