Ranged support of protocol version on server side
authorPerttu Ahola <celeron55@gmail.com>
Mon, 26 Nov 2012 21:58:27 +0000 (23:58 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Thu, 29 Nov 2012 20:08:25 +0000 (22:08 +0200)
src/clientserver.h
src/server.cpp
src/server.h
src/test.cpp

index 6d4998550b683066015d2b947bf1e153ca9a337a..d777724163b2fe13911c0651cc0420e648fa1d8f 100644 (file)
@@ -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
index f29155ba0b070bd9502c6fc3bdee5a2db0dadec0..41765ed19059bf1b664a82c4fd6117c3b88d0a4c 100644 (file)
@@ -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!");
                }
 
                /*
index 223c1b0ffd1314ad76863f08017a4290455da8f8..f770fa3d44ba170e859f7a7b0690bcfe3903b6d9 100644 (file)
@@ -602,7 +602,7 @@ private:
        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.
index 52782fa36791976cae8fc9625e61fffc66067d81..bc0692a78325f05ee5fcfb6fac7d2d81b4619081 100644 (file)
@@ -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;