// [2] u8 SER_FMT_VER_HIGHEST
// [3] u8[20] player_name
// [23] u8[28] password (new in some version)
- // [51] u16 client network protocol version (new in some version)
- SharedBuffer<u8> data(2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2);
+ // [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);
memset((char*)&data[23], 0, PASSWORD_SIZE);
snprintf((char*)&data[23], PASSWORD_SIZE, "%s", m_password.c_str());
- // This should be incremented in each version
- writeU16(&data[51], PROTOCOL_VERSION);
+ writeU16(&data[51], CLIENT_PROTOCOL_VERSION_MIN);
+ writeU16(&data[53], CLIENT_PROTOCOL_VERSION_MAX);
// Send as unreliable
Send(0, data, false);
GENERIC_CMD_SET_ATTACHMENT
*/
-#define PROTOCOL_VERSION 14
+// Server always only supports one version
+#define SERVER_PROTOCOL_VERSION 14
+// Client can support older versions too
+#define CLIENT_PROTOCOL_VERSION_MIN 13
+#define CLIENT_PROTOCOL_VERSION_MAX SERVER_PROTOCOL_VERSION
+
+// Constant that differentiates the protocol from random data and other protocols
#define PROTOCOL_ID 0x4f457403
#define PASSWORD_SIZE 28 // Maximum password length. Allows for
[2] u8 SER_FMT_VER_HIGHEST
[3] u8[20] player_name
[23] u8[28] password (new in some version)
- [51] u16 client network protocol version (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)
*/
TOSERVER_INIT2 = 0x11,
Read and check network protocol version
*/
- u16 net_proto_version = 0;
+ u16 min_net_proto_version = 0;
if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2)
- {
- net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
- }
+ min_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
+
+ // Use min if version field doesn't exist (backwards compatibility)
+ u16 max_net_proto_version = min_net_proto_version;
+ if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2+2)
+ max_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2]);
+
+ u16 net_proto_version = max_net_proto_version;
+ if(max_net_proto_version != SERVER_PROTOCOL_VERSION && min_net_proto_version <= SERVER_PROTOCOL_VERSION)
+ net_proto_version = SERVER_PROTOCOL_VERSION;
+
+ verbosestream<<"Server: "<<peer_id<<" Protocol version: min: "
+ <<min_net_proto_version<<", max: "<<max_net_proto_version
+ <<", chosen: "<<net_proto_version<<std::endl;
getClient(peer_id)->net_proto_version = net_proto_version;
if(g_settings->getBool("strict_protocol_version_checking"))
{
- if(net_proto_version != PROTOCOL_VERSION)
+ if(net_proto_version != SERVER_PROTOCOL_VERSION)
{
actionstream<<"Server: A mismatched client tried to connect"
<<" from "<<addr_s<<std::endl;
L"Server version is ")
+ narrow_to_wide(VERSION_STRING) + L",\n"
+ L"server's PROTOCOL_VERSION is "
- + narrow_to_wide(itos(PROTOCOL_VERSION))
+ + narrow_to_wide(itos(SERVER_PROTOCOL_VERSION))
+ L", client's PROTOCOL_VERSION is "
+ narrow_to_wide(itos(net_proto_version))
);
}
// Warnings about protocol version can be issued here
- if(getClient(peer_id)->net_proto_version < PROTOCOL_VERSION)
+ if(getClient(peer_id)->net_proto_version < SERVER_PROTOCOL_VERSION)
{
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER!");
}