Skip to content
Snippets Groups Projects
Commit 8ccdd3bd authored by Perttu Ahola's avatar Perttu Ahola
Browse files

Ranged support of protocol version on server side

parent 23913f26
No related branches found
No related tags found
No related merge requests found
......@@ -75,14 +75,19 @@ SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
GENERIC_CMD_SET_ANIMATION
GENERIC_CMD_SET_BONE_POSITION
GENERIC_CMD_SET_ATTACHMENT
PROTOCOL_VERSION 15:
Serialization format changes
*/
// Server always only supports one version
#define SERVER_PROTOCOL_VERSION 14
#define LATEST_PROTOCOL_VERSION 15
// Client can support older versions too
// Server's supported network protocol range
#define SERVER_PROTOCOL_VERSION_MIN 14
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
// Client's supported network protocol range
#define CLIENT_PROTOCOL_VERSION_MIN 13
#define CLIENT_PROTOCOL_VERSION_MAX SERVER_PROTOCOL_VERSION
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
// Constant that differentiates the protocol from random data and other protocols
#define PROTOCOL_ID 0x4f457403
......
......@@ -2042,14 +2042,26 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(datasize >= 2+1+PLAYERNAME_SIZE+PASSWORD_SIZE+2)
min_net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
// Use min if version field doesn't exist (backwards compatibility)
// Use same version as minimum and maximum if maximum 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]);
// Start with client's maximum version
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;
// Figure out a working version if it is possible at all
if(max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN ||
min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX)
{
// If maximum is larger than our maximum, go with our maximum
if(max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
net_proto_version = SERVER_PROTOCOL_VERSION_MAX;
// Else go with client's maximum
else
net_proto_version = max_net_proto_version;
}
verbosestream<<"Server: "<<peer_id<<" Protocol version: min: "
<<min_net_proto_version<<", max: "<<max_net_proto_version
......@@ -2071,7 +2083,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(g_settings->getBool("strict_protocol_version_checking"))
{
if(net_proto_version != SERVER_PROTOCOL_VERSION)
if(net_proto_version < SERVER_PROTOCOL_VERSION_MIN ||
net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
{
actionstream<<"Server: A mismatched client tried to connect"
<<" from "<<addr_s<<std::endl;
......@@ -2080,9 +2093,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
L"Server version is ")
+ narrow_to_wide(VERSION_STRING) + L",\n"
+ L"server's PROTOCOL_VERSION is "
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION))
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MIN))
+ L"..."
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MAX))
+ L", client's PROTOCOL_VERSION is "
+ narrow_to_wide(itos(net_proto_version))
+ narrow_to_wide(itos(min_net_proto_version))
+ L"..."
+ narrow_to_wide(itos(max_net_proto_version))
);
return;
}
......@@ -2324,9 +2341,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
// Warnings about protocol version can be issued here
if(getClient(peer_id)->net_proto_version < SERVER_PROTOCOL_VERSION)
if(getClient(peer_id)->net_proto_version < LATEST_PROTOCOL_VERSION)
{
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER!");
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD "
L"AND MAY NOT FULLY WORK WITH THIS SERVER!");
}
/*
......
......@@ -602,7 +602,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
static void SendItemDef(con::Connection &con, u16 peer_id,
IItemDefManager *itemdef);
static void SendNodeDef(con::Connection &con, u16 peer_id,
INodeDefManager *nodedef);
INodeDefManager *nodedef, u16 protocol_version);
/*
Non-static send methods.
......
......@@ -41,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/numeric.h"
#include "util/serialize.h"
#include "noise.h" // PseudoRandom used for random data for compression
#include "clientserver.h" // LATEST_PROTOCOL_VERSION
/*
Asserts that the exception occurs
......@@ -324,7 +325,7 @@ struct TestNodedefSerialization: public TestBase
f.tiledef[i].name = "default_stone.png";
f.is_ground_content = true;
std::ostringstream os(std::ios::binary);
f.serialize(os);
f.serialize(os, LATEST_PROTOCOL_VERSION);
verbosestream<<"Test ContentFeatures size: "<<os.str().size()<<std::endl;
std::istringstream is(os.str(), std::ios::binary);
ContentFeatures f2;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment