shithub: choc

Download patch

ref: 7a611a627d389d56c333c031ee6f24832c3cef32
parent: 6b1d0a8102b9740990d3defca228dc2c7b9102d2
author: Simon Howard <fraggle@soulsphere.org>
date: Sun Oct 8 14:30:57 EDT 2017

net: Include protocol list in query responses.

If we try to connect to an incompatible server, the server will reject
the connection attempt. Now that we have a more elaborate scheme to
negotiate a common protocol than just comparing version strings, we
can be more confident about ignoring servers that we definitely won't
be able to connect to. So use the protocol list included in query
responses to exclude query responses from servers we aren't compatible
with.

--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -249,6 +249,7 @@
     int gamemode;
     int gamemission;
     char *description;
+    net_protocol_t protocol;
 } net_querydata_t;
 
 // Data sent by the server while waiting for the game to start.
--- a/src/net_structrw.c
+++ b/src/net_structrw.c
@@ -130,27 +130,30 @@
 
 boolean NET_ReadQueryData(net_packet_t *packet, net_querydata_t *query)
 {
-    boolean result;
+    boolean success;
 
     query->version = NET_ReadSafeString(packet);
 
-    result = query->version != NULL
+    success = query->version != NULL
           && NET_ReadInt8(packet, (unsigned int *) &query->server_state)
           && NET_ReadInt8(packet, (unsigned int *) &query->num_players)
           && NET_ReadInt8(packet, (unsigned int *) &query->max_players)
           && NET_ReadInt8(packet, (unsigned int *) &query->gamemode)
           && NET_ReadInt8(packet, (unsigned int *) &query->gamemission);
-    
-    if (result)
-    {
-        query->description = NET_ReadSafeString(packet);
 
-        return query->description != NULL;
-    }   
-    else
+    if (!success)
     {
         return false;
-    } 
+    }
+
+    query->description = NET_ReadSafeString(packet);
+
+    // We read the list of protocols supported by the server. However,
+    // old versions of Chocolate Doom do not support this field; it is
+    // okay if it cannot be successfully read.
+    query->protocol = NET_ReadProtocolList(packet);
+
+    return query->description != NULL;
 }
 
 void NET_WriteQueryData(net_packet_t *packet, net_querydata_t *query)
@@ -162,9 +165,13 @@
     NET_WriteInt8(packet, query->gamemode);
     NET_WriteInt8(packet, query->gamemission);
     NET_WriteString(packet, query->description);
+
+    // Write a list of all supported protocols. Note that the query->protocol
+    // field is ignored here; it is only used when receiving.
+    NET_WriteProtocolList(packet);
 }
 
-void NET_WriteTiccmdDiff(net_packet_t *packet, net_ticdiff_t *diff, 
+void NET_WriteTiccmdDiff(net_packet_t *packet, net_ticdiff_t *diff,
                          boolean lowres_turn)
 {
     // Header
--- a/src/setup/multiplayer.c
+++ b/src/setup/multiplayer.c
@@ -921,6 +921,17 @@
     char ping_time_str[16];
     char description[47];
 
+    // When we connect we'll have to negotiate a common protocol that we
+    // can agree upon between the client and server. If we can't then we
+    // won't be able to connect, so it's pointless to include it in the
+    // results list. If protocol==NET_PROTOCOL_UNKNOWN then this may be
+    // an old, pre-3.0 Chocolate Doom server that doesn't support the new
+    // protocol negotiation mechanism, or it may be an incompatible fork.
+    if (querydata->protocol == NET_PROTOCOL_UNKNOWN)
+    {
+        return;
+    }
+
     M_snprintf(ping_time_str, sizeof(ping_time_str), "%ims", ping_time);
     M_StringCopy(description, querydata->description,
                  sizeof(description));
@@ -945,8 +956,11 @@
 
         if (query_servers_found == 0)
         {
-            TXT_AddWidget(results_table, NULL);
-            TXT_AddWidget(results_table, TXT_NewLabel("No servers found."));
+            TXT_AddWidgets(results_table,
+                TXT_TABLE_EMPTY,
+                TXT_NewLabel("No compatible servers found."),
+                NULL
+            );
         }
     }
 }