// Send TOSERVER_INIT
// [0] u16 TOSERVER_INIT
- // [2] u8 SER_FMT_VER_HIGHEST
+ // [2] u8 SER_FMT_VER_HIGHEST_READ
// [3] u8[20] player_name
// [23] u8[28] password (new in some version)
// [51] u16 minimum supported network protocol version (added sometime)
// [53] u16 maximum supported network protocol version (added later than the previous one)
SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2);
writeU16(&data[0], TOSERVER_INIT);
- writeU8(&data[2], SER_FMT_VER_HIGHEST);
+ writeU8(&data[2], SER_FMT_VER_HIGHEST_READ);
memset((char*)&data[3], 0, PLAYERNAME_SIZE);
snprintf((char*)&data[3], PLAYERNAME_SIZE, "%s", myplayer->getName());
infostream<<"Client: TOCLIENT_INIT received with "
"deployed="<<((int)deployed&0xff)<<std::endl;
- if(deployed < SER_FMT_VER_LOWEST
- || deployed > SER_FMT_VER_HIGHEST)
+ if(!ser_ver_supported(deployed))
{
infostream<<"Client: TOCLIENT_INIT: Server sent "
<<"unsupported ser_fmt_ver"<<std::endl;
*/
//infostream<<"Updating"<<std::endl;
block->deSerialize(istr, ser_version, false);
+ block->deSerializeNetworkSpecific(istr);
}
else
{
//infostream<<"Creating new"<<std::endl;
block = new MapBlock(&m_env.getMap(), p, this);
block->deSerialize(istr, ser_version, false);
+ block->deSerializeNetworkSpecific(istr);
sector->insertBlock(block);
}
range added to ItemDefinition
drowning, leveled and liquid_range added to ContentFeatures
stepheight and collideWithObjects added to object properties
+ version, heat and humidity transfer in MapBock
*/
#define LATEST_PROTOCOL_VERSION 21
Sent first after connected.
[0] u16 TOSERVER_INIT
- [2] u8 SER_FMT_VER_HIGHEST
+ [2] u8 SER_FMT_VER_HIGHEST_READ
[3] u8[20] player_name
[23] u8[28] password (new in some version)
[51] u16 minimum supported network protocol version (added sometime)
// Print startup message
infostream<<PROJECT_NAME<<
- " "<<_("with")<<" SER_FMT_VER_HIGHEST="<<(int)SER_FMT_VER_HIGHEST
+ " "<<_("with")<<" SER_FMT_VER_HIGHEST_READ="<<(int)SER_FMT_VER_HIGHEST_READ
<<", "<<BUILD_INFO
<<std::endl;
{
DSTACK(__FUNCTION_NAME);
// Format used for writing
- u8 version = SER_FMT_VER_HIGHEST;
+ u8 version = SER_FMT_VER_HIGHEST_WRITE;
// Get destination
v2s16 pos = sector->getPos();
std::string dir = getSectorDir(pos);
}
// Format used for writing
- u8 version = SER_FMT_VER_HIGHEST;
+ u8 version = SER_FMT_VER_HIGHEST_WRITE;
// Get destination
v3s16 p3d = block->getPos();
Save blocks loaded in old format in new format
*/
- if(version < SER_FMT_VER_HIGHEST || save_after_load)
+ if(version < SER_FMT_VER_HIGHEST_WRITE || save_after_load)
{
saveBlock(block);
Save blocks loaded in old format in new format
*/
- //if(version < SER_FMT_VER_HIGHEST || save_after_load)
+ //if(version < SER_FMT_VER_HIGHEST_READ || save_after_load)
// Only save if asked to; no need to update version
if(save_after_load)
saveBlock(block);
// Node timers
m_node_timers.serialize(os, version);
}
- } else {
- if(version >= 26){
- writeF1000(os, heat);
- writeF1000(os, humidity);
- }
+ }
+}
+
+void MapBlock::serializeNetworkSpecific(std::ostream &os, u16 net_proto_version)
+{
+ if(data == NULL)
+ {
+ throw SerializationError("ERROR: Not writing dummy block.");
+ }
+
+ if(net_proto_version >= 21){
+ int version = 1;
+ writeU8(os, version);
+ writeF1000(os, heat);
+ writeF1000(os, humidity);
}
}
<<": Node timers (ver>=25)"<<std::endl);
m_node_timers.deSerialize(is, version);
}
- } else {
- if(version >= 26){
- heat = readF1000(is);
- humidity = readF1000(is);
- }
}
TRACESTREAM(<<"MapBlock::deSerialize "<<PP(getPos())
<<": Done."<<std::endl);
}
+void MapBlock::deSerializeNetworkSpecific(std::istream &is)
+{
+ try {
+ int version = readU8(is);
+ //if(version != 1)
+ // throw SerializationError("unsupported MapBlock version");
+ if(version >= 1) {
+ heat = readF1000(is);
+ humidity = readF1000(is);
+ }
+ }
+ catch(SerializationError &e)
+ {
+ errorstream<<"WARNING: MapBlock::deSerializeNetworkSpecific(): Ignoring an error"
+ <<": "<<e.what()<<std::endl;
+ }
+}
+
/*
Legacy serialization
*/
// unknown blocks from id-name mapping to wndef
void deSerialize(std::istream &is, u8 version, bool disk);
+ void serializeNetworkSpecific(std::ostream &os, u16 net_proto_version);
+ void deSerializeNetworkSpecific(std::istream &is);
+
private:
/*
Private methods
delete schematic;
schematic = new MapNode[nodecount];
- MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST, schematic,
+ MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST_READ, schematic,
nodecount, 2, 2, true);
return true;
os << serializeString(ndef->get(usednodes[i]).name); // node names
// compressed bulk node data
- MapNode::serializeBulk(os, SER_FMT_VER_HIGHEST, schematic,
+ MapNode::serializeBulk(os, SER_FMT_VER_HIGHEST_WRITE, schematic,
nodecount, 2, 2, true);
}
23: new node metadata format
24: 16-bit node ids and node timers (never released as stable)
25: Improved node timer format
- 26: MapBlocks contain heat and humidity
+ 26: Never written; read the same as 25
*/
// This represents an uninitialized or invalid format
#define SER_FMT_VER_INVALID 255
// Highest supported serialization version
-#define SER_FMT_VER_HIGHEST 26
+#define SER_FMT_VER_HIGHEST_READ 26
+// Saved on disk version
+#define SER_FMT_VER_HIGHEST_WRITE 25
// Lowest supported serialization version
#define SER_FMT_VER_LOWEST 0
-#define ser_ver_supported(v) (v >= SER_FMT_VER_LOWEST && v <= SER_FMT_VER_HIGHEST)
+#define ser_ver_supported(v) (v >= SER_FMT_VER_LOWEST && v <= SER_FMT_VER_HIGHEST_READ)
/*
Misc. serialization functions
if(command == TOSERVER_INIT)
{
// [0] u16 TOSERVER_INIT
- // [2] u8 SER_FMT_VER_HIGHEST
+ // [2] u8 SER_FMT_VER_HIGHEST_READ
// [3] u8[20] player_name
// [23] u8[28] password <--- can be sent without this, from old versions
// First byte after command is maximum supported
// serialization version
u8 client_max = data[2];
- u8 our_max = SER_FMT_VER_HIGHEST;
+ u8 our_max = SER_FMT_VER_HIGHEST_READ;
// Use the highest version supported by both
u8 deployed = std::min(client_max, our_max);
// If it's lower than the lowest supported, give up.
}
}
-void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
+void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version)
{
DSTACK(__FUNCTION_NAME);
std::ostringstream os(std::ios_base::binary);
block->serialize(os, ver, false);
+ block->serializeNetworkSpecific(os, net_proto_version);
std::string s = os.str();
SharedBuffer<u8> blockdata((u8*)s.c_str(), s.size());
RemoteClient *client = getClient(q.peer_id);
- SendBlockNoLock(q.peer_id, block, client->serialization_version);
+ SendBlockNoLock(q.peer_id, block, client->serialization_version, client->net_proto_version);
client->SentBlock(q.pos);
void setBlockNotSent(v3s16 p);
// Environment and Connection must be locked when called
- void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
+ void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
// Sends blocks to clients (locks env and con on its own)
void SendBlocks(float dtime);
fromdata[3]=1;
std::ostringstream os(std::ios_base::binary);
- compress(fromdata, os, SER_FMT_VER_HIGHEST);
+ compress(fromdata, os, SER_FMT_VER_HIGHEST_READ);
std::string str_out = os.str();
std::istringstream is(str_out, std::ios_base::binary);
std::ostringstream os2(std::ios_base::binary);
- decompress(is, os2, SER_FMT_VER_HIGHEST);
+ decompress(is, os2, SER_FMT_VER_HIGHEST_READ);
std::string str_out2 = os2.str();
infostream<<"decompress: ";