Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

ContentFeatures serialization using BKVL

  • Loading branch information...
commit b93b88e9b26985d6f9b1eb31546fd3dd53a0dd1a 1 parent bcdb0d0
@celeron55 authored
Showing with 319 additions and 103 deletions.
  1. +319 −103 src/nodedef.cpp
View
422 src/nodedef.cpp
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "nameidmapping.h"
#include "util/serialize.h"
+#include "util/template_serialize.h"
/*
NodeBox
@@ -103,6 +104,32 @@ void NodeBox::deSerialize(std::istream &is)
}
}
+template<>
+struct STraits<NodeBox>
+{
+ static u8 type()
+ {
+ return VALUE_TYPE_RAW;
+ }
+ static bool read(const std::vector<u8> &src, NodeBox *result)
+ {
+ if(result){
+ std::istringstream is(std::string((char*)&src[0], src.size()),
+ std::ios::binary);
+ result->deSerialize(is);
+ }
+ return true;
+ }
+ static void write(const NodeBox &src, std::vector<u8> &result)
+ {
+ std::ostringstream os(std::ios::binary);
+ src.serialize(os);
+ std::string s = os.str();
+ result.insert(result.begin(), (u8*)s.c_str(),
+ (u8*)s.c_str() + s.size());
+ }
+};
+
/*
TileDef
*/
@@ -129,6 +156,32 @@ void TileDef::deSerialize(std::istream &is)
animation.length = readF1000(is);
}
+template<>
+struct STraits<TileDef>
+{
+ static u8 type()
+ {
+ return VALUE_TYPE_RAW;
+ }
+ static bool read(const std::vector<u8> &src, TileDef *result)
+ {
+ if(result){
+ std::istringstream is(std::string((char*)&src[0], src.size()),
+ std::ios::binary);
+ result->deSerialize(is);
+ }
+ return true;
+ }
+ static void write(const TileDef &src, std::vector<u8> &result)
+ {
+ std::ostringstream os(std::ios::binary);
+ src.serialize(os);
+ std::string s = os.str();
+ result.insert(result.begin(), (u8*)s.c_str(),
+ (u8*)s.c_str() + s.size());
+ }
+};
+
/*
SimpleSoundSpec serialization
*/
@@ -145,6 +198,32 @@ static void deSerializeSimpleSoundSpec(SimpleSoundSpec &ss, std::istream &is)
ss.gain = readF1000(is);
}
+template<>
+struct STraits<SimpleSoundSpec>
+{
+ static u8 type()
+ {
+ return VALUE_TYPE_RAW;
+ }
+ static bool read(const std::vector<u8> &src, SimpleSoundSpec *result)
+ {
+ if(result){
+ std::istringstream is(std::string((char*)&src[0], src.size()),
+ std::ios::binary);
+ deSerializeSimpleSoundSpec(*result, is);
+ }
+ return true;
+ }
+ static void write(const SimpleSoundSpec &src, std::vector<u8> &result)
+ {
+ std::ostringstream os(std::ios::binary);
+ serializeSimpleSoundSpec(src, os);
+ std::string s = os.str();
+ result.insert(result.begin(), (u8*)s.c_str(),
+ (u8*)s.c_str() + s.size());
+ }
+};
+
/*
ContentFeatures
*/
@@ -215,126 +294,156 @@ void ContentFeatures::reset()
sound_dug = SimpleSoundSpec();
}
+// NEVER remove anything from this list
+// NEVER put anything in between of items in this list
+// This enum is licensed under WTFPL.
+enum{
+ NODEDEF_NAME,
+ NODEDEF_GROUP_NAMES,
+ NODEDEF_GROUP_VALUES,
+ NODEDEF_DRAWTYPE,
+ NODEDEF_VISUAL_SCALE,
+ NODEDEF_TILEDEFS,
+ NODEDEF_TILEDEF_SPECIALS,
+ NODEDEF_ALPHA,
+ NODEDEF_POST_EFFECT_COLOR,
+ NODEDEF_PARAM_TYPE,
+ NODEDEF_PARAM_TYPE_2,
+ NODEDEF_IS_GROUND_CONTENT,
+ NODEDEF_LIGHT_PROPAGATES,
+ NODEDEF_SUNLIGHT_PROPAGATES,
+ NODEDEF_WALKABLE,
+ NODEDEF_POINTABLE,
+ NODEDEF_DIGGABLE,
+ NODEDEF_CLIMBABLE,
+ NODEDEF_BUILDABLE_TO,
+ NODEDEF_LIQUID_TYPE,
+ NODEDEF_LIQUID_ALTERNATIVE_FLOWING,
+ NODEDEF_LIQUID_ALTERNATIVE_SOURCE,
+ NODEDEF_LIQUID_VISCOSITY,
+ NODEDEF_LIQUID_RENEWABLE,
+ NODEDEF_LIGHT_SOURCE,
+ NODEDEF_DAMAGE_PER_SECOND,
+ NODEDEF_NODE_BOX,
+ NODEDEF_SELECTION_BOX,
+ NODEDEF_LEGACY_FACEDIR_SIMPLE,
+ NODEDEF_LEGACY_WALLMOUNTED,
+ NODEDEF_SOUND_FOOTSTEP,
+ NODEDEF_SOUND_DIG,
+ NODEDEF_SOUND_DUG,
+};
+
void ContentFeatures::serialize(std::ostream &os, u16 protocol_version)
{
- if(protocol_version < 14){
+ if(protocol_version < 15){
serializeOld(os, protocol_version);
return;
}
- writeU8(os, 6); // version
- os<<serializeString(name);
- writeU16(os, groups.size());
+ writeU8(os, 7); // version
+ BKVL bv;
+ bv.append(NODEDEF_NAME, name);
for(ItemGroupList::const_iterator
i = groups.begin(); i != groups.end(); i++){
- os<<serializeString(i->first);
- writeS16(os, i->second);
+ bv.append(NODEDEF_GROUP_NAMES, i->first);
+ bv.append<s16>(NODEDEF_GROUP_VALUES, i->second);
}
- writeU8(os, drawtype);
- writeF1000(os, visual_scale);
- writeU8(os, 6);
+ bv.append<u8>(NODEDEF_DRAWTYPE, drawtype);
+ bv.append(NODEDEF_VISUAL_SCALE, F1000(visual_scale));
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, liquid_renewable);
- 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);
- // Stuff below should be moved to correct place in a version that otherwise changes
- // the protocol version
+ bv.append(NODEDEF_TILEDEFS, tiledef[i]);
+ for(u32 i=0; i<CF_SPECIAL_COUNT; i++)
+ bv.append(NODEDEF_TILEDEF_SPECIALS, tiledef_special[i]);
+ bv.append(NODEDEF_ALPHA, alpha);
+ bv.append(NODEDEF_POST_EFFECT_COLOR, post_effect_color);
+ bv.append<u8>(NODEDEF_PARAM_TYPE, param_type);
+ bv.append<u8>(NODEDEF_PARAM_TYPE_2, param_type_2);
+ bv.append(NODEDEF_IS_GROUND_CONTENT, is_ground_content);
+ bv.append(NODEDEF_LIGHT_PROPAGATES, light_propagates);
+ bv.append(NODEDEF_SUNLIGHT_PROPAGATES, sunlight_propagates);
+ bv.append(NODEDEF_WALKABLE, walkable);
+ bv.append(NODEDEF_POINTABLE, pointable);
+ bv.append(NODEDEF_DIGGABLE, diggable);
+ bv.append(NODEDEF_CLIMBABLE, climbable);
+ bv.append(NODEDEF_BUILDABLE_TO, buildable_to);
+ bv.append<u8>(NODEDEF_LIQUID_TYPE, liquid_type);
+ bv.append(NODEDEF_LIQUID_ALTERNATIVE_FLOWING, liquid_alternative_flowing);
+ bv.append(NODEDEF_LIQUID_ALTERNATIVE_SOURCE, liquid_alternative_source);
+ bv.append(NODEDEF_LIQUID_VISCOSITY, liquid_viscosity);
+ bv.append(NODEDEF_LIQUID_RENEWABLE, liquid_renewable);
+ bv.append(NODEDEF_LIGHT_SOURCE, light_source);
+ bv.append(NODEDEF_DAMAGE_PER_SECOND, damage_per_second);
+ bv.append(NODEDEF_NODE_BOX, node_box);
+ bv.append(NODEDEF_SELECTION_BOX, selection_box);
+ bv.append(NODEDEF_LEGACY_FACEDIR_SIMPLE, legacy_facedir_simple);
+ bv.append(NODEDEF_LEGACY_WALLMOUNTED, legacy_wallmounted);
+ bv.append(NODEDEF_SOUND_FOOTSTEP, sound_footstep);
+ bv.append(NODEDEF_SOUND_DIG, sound_dig);
+ bv.append(NODEDEF_SOUND_DUG, sound_dug);
+ bv.serialize(os);
}
void ContentFeatures::deSerialize(std::istream &is)
{
int version = readU8(is);
- if(version != 6){
+ if(version != 7){
deSerializeOld(is, version);
return;
}
- 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) {};
+ reset();
+ BKVL bv;
+ bv.deSerialize(is);
+ bv.get(NODEDEF_NAME, 0, name);
+ for(u32 i=0; i<bv.valueCount(NODEDEF_GROUP_NAMES); i++){
+ std::string name;
+ if(!bv.get(NODEDEF_GROUP_NAMES, i, name))
+ continue;
+ groups[name] = bv.getDirect(NODEDEF_GROUP_VALUES, i, 1);
+ }
+ u8 drawtype_tmp;
+ if(bv.get<u8>(NODEDEF_DRAWTYPE, 0, drawtype_tmp))
+ drawtype = (NodeDrawType)drawtype_tmp;
+ for(u32 i=0; i<bv.valueCount(NODEDEF_TILEDEFS) &&
+ i < 6; i++){
+ bv.get(NODEDEF_TILEDEFS, i, tiledef[i]);
+ }
+ for(u32 i=0; i<bv.valueCount(NODEDEF_TILEDEF_SPECIALS) &&
+ i < CF_SPECIAL_COUNT; i++){
+ bv.get(NODEDEF_TILEDEF_SPECIALS, i, tiledef_special[i]);
+ }
+ bv.get(NODEDEF_ALPHA, 0, alpha);
+ bv.get(NODEDEF_POST_EFFECT_COLOR, 0, post_effect_color);
+ u8 param_type_tmp;
+ if(bv.get(NODEDEF_PARAM_TYPE, 0, param_type_tmp))
+ param_type = (ContentParamType)param_type_tmp;
+ u8 param_type_2_tmp;
+ if(bv.get(NODEDEF_PARAM_TYPE_2, 0, param_type_2_tmp))
+ param_type_2 = (ContentParamType2)param_type_2_tmp;
+ bv.get(NODEDEF_IS_GROUND_CONTENT, 0, is_ground_content);
+ bv.get(NODEDEF_LIGHT_PROPAGATES, 0, light_propagates);
+ bv.get(NODEDEF_SUNLIGHT_PROPAGATES, 0, sunlight_propagates);
+ bv.get(NODEDEF_WALKABLE, 0, walkable);
+ bv.get(NODEDEF_POINTABLE, 0, pointable);
+ bv.get(NODEDEF_DIGGABLE, 0, diggable);
+ bv.get(NODEDEF_CLIMBABLE, 0, climbable);
+ bv.get(NODEDEF_BUILDABLE_TO, 0, buildable_to);
+ u8 liquid_type_tmp;
+ if(bv.get(NODEDEF_LIQUID_TYPE, 0, liquid_type_tmp))
+ liquid_type = (LiquidType)liquid_type_tmp;
+ bv.get(NODEDEF_LIQUID_ALTERNATIVE_FLOWING, 0, liquid_alternative_flowing);
+ bv.get(NODEDEF_LIQUID_ALTERNATIVE_SOURCE, 0, liquid_alternative_source);
+ bv.get(NODEDEF_LIQUID_VISCOSITY, 0, liquid_viscosity);
+ bv.get(NODEDEF_LIQUID_RENEWABLE, 0, liquid_renewable);
+ bv.get(NODEDEF_LIGHT_SOURCE, 0, light_source);
+ bv.get(NODEDEF_DAMAGE_PER_SECOND, 0, damage_per_second);
+ bv.get(NODEDEF_NODE_BOX, 0, node_box);
+ bv.get(NODEDEF_SELECTION_BOX, 0, selection_box);
+ bv.get(NODEDEF_LEGACY_FACEDIR_SIMPLE, 0, legacy_facedir_simple);
+ bv.get(NODEDEF_LEGACY_WALLMOUNTED, 0, legacy_wallmounted);
+ bv.get(NODEDEF_SOUND_FOOTSTEP, 0, sound_footstep);
+ bv.get(NODEDEF_SOUND_DIG, 0, sound_dig);
+ bv.get(NODEDEF_SOUND_DUG, 0, sound_dug);
}
/*
@@ -789,7 +898,57 @@ IWritableNodeDefManager* createNodeDefManager()
void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version)
{
- if(protocol_version == 13)
+ if(protocol_version == 14)
+ {
+ writeU8(os, 6); // 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, liquid_renewable);
+ 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 if(protocol_version == 13)
{
writeU8(os, 5); // version
os<<serializeString(name);
@@ -846,7 +1005,64 @@ void ContentFeatures::serializeOld(std::ostream &os, u16 protocol_version)
void ContentFeatures::deSerializeOld(std::istream &is, int version)
{
- if(version == 5) // In PROTOCOL_VERSION 13
+ 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();
Please sign in to comment.
Something went wrong with that request. Please try again.