Some serialization version stuff

master
Perttu Ahola 2012-03-25 18:45:27 +03:00
parent 677456d319
commit f01c988094
2 changed files with 31 additions and 9 deletions

View File

@ -991,6 +991,7 @@ void the_game(
server->start(port); server->start(port);
} }
try{
do{ // Client scope (breakable do-while(0)) do{ // Client scope (breakable do-while(0))
/* /*
@ -2911,6 +2912,14 @@ void the_game(
// Client scope (client is destructed before destructing *def and tsrc) // Client scope (client is destructed before destructing *def and tsrc)
}while(0); }while(0);
} // try-catch
catch(SerializationError &e)
{
error_message = L"A serialization error occurred:\n"
+ narrow_to_wide(e.what()) + L"\n\nThe server is probably "
L" running a different version of Minetest.";
errorstream<<wide_to_narrow(error_message)<<std::endl;
}
if(!sound_is_dummy) if(!sound_is_dummy)
delete sound; delete sound;

View File

@ -162,7 +162,7 @@ void ContentFeatures::reset()
void ContentFeatures::serialize(std::ostream &os) void ContentFeatures::serialize(std::ostream &os)
{ {
writeU8(os, 2); // version writeU8(os, 3); // version
os<<serializeString(name); os<<serializeString(name);
writeU16(os, groups.size()); writeU16(os, groups.size());
for(ItemGroupList::const_iterator for(ItemGroupList::const_iterator
@ -212,7 +212,7 @@ void ContentFeatures::serialize(std::ostream &os)
void ContentFeatures::deSerialize(std::istream &is) void ContentFeatures::deSerialize(std::istream &is)
{ {
int version = readU8(is); int version = readU8(is);
if(version != 2) if(version != 3)
throw SerializationError("unsupported ContentFeatures version"); throw SerializationError("unsupported ContentFeatures version");
name = deSerializeString(is); name = deSerializeString(is);
groups.clear(); groups.clear();
@ -258,6 +258,8 @@ void ContentFeatures::deSerialize(std::istream &is)
selection_box.deSerialize(is); selection_box.deSerialize(is);
legacy_facedir_simple = readU8(is); legacy_facedir_simple = readU8(is);
legacy_wallmounted = readU8(is); legacy_wallmounted = readU8(is);
// If you add anything here, insert it primarily inside the try-catch
// block to not need to increase the version.
try{ try{
deSerializeSimpleSoundSpec(sound_footstep, is); deSerializeSimpleSoundSpec(sound_footstep, is);
deSerializeSimpleSoundSpec(sound_dig, is); deSerializeSimpleSoundSpec(sound_dig, is);
@ -566,8 +568,9 @@ public:
} }
void serialize(std::ostream &os) void serialize(std::ostream &os)
{ {
writeU8(os, 1); // version
u16 count = 0; u16 count = 0;
std::ostringstream tmp_os(std::ios::binary); std::ostringstream os2(std::ios::binary);
for(u16 i=0; i<=MAX_CONTENT; i++) for(u16 i=0; i<=MAX_CONTENT; i++)
{ {
if(i == CONTENT_IGNORE || i == CONTENT_AIR) if(i == CONTENT_IGNORE || i == CONTENT_AIR)
@ -575,20 +578,27 @@ public:
ContentFeatures *f = &m_content_features[i]; ContentFeatures *f = &m_content_features[i];
if(f->name == "") if(f->name == "")
continue; continue;
writeU16(tmp_os, i); writeU16(os2, i);
f->serialize(tmp_os); // Wrap it in a string to allow different lengths without
// strict version incompatibilities
std::ostringstream wrapper_os(std::ios::binary);
f->serialize(wrapper_os);
os2<<serializeString(wrapper_os.str());
count++; count++;
} }
writeU16(os, count); writeU16(os, count);
os<<serializeLongString(tmp_os.str()); os<<serializeLongString(os2.str());
} }
void deSerialize(std::istream &is) void deSerialize(std::istream &is)
{ {
clear(); clear();
int version = readU8(is);
if(version != 1)
throw SerializationError("unsupported NodeDefinitionManager version");
u16 count = readU16(is); u16 count = readU16(is);
std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary); std::istringstream is2(deSerializeLongString(is), std::ios::binary);
for(u16 n=0; n<count; n++){ for(u16 n=0; n<count; n++){
u16 i = readU16(tmp_is); u16 i = readU16(is2);
if(i > MAX_CONTENT){ if(i > MAX_CONTENT){
errorstream<<"ContentFeatures::deSerialize(): " errorstream<<"ContentFeatures::deSerialize(): "
<<"Too large content id: "<<i<<std::endl; <<"Too large content id: "<<i<<std::endl;
@ -598,7 +608,10 @@ public:
if(i == CONTENT_IGNORE || i == CONTENT_AIR) if(i == CONTENT_IGNORE || i == CONTENT_AIR)
continue;*/ continue;*/
ContentFeatures *f = &m_content_features[i]; ContentFeatures *f = &m_content_features[i];
f->deSerialize(tmp_is); // Read it from the string wrapper
std::string wrapper = deSerializeString(is2);
std::istringstream wrapper_is(wrapper, std::ios::binary);
f->deSerialize(wrapper_is);
if(f->name != "") if(f->name != "")
addNameIdMapping(i, f->name); addNameIdMapping(i, f->name);
} }