foxygit / doom Log in
commit f9ab444cc614db3b2380d02750d142f9b17a8b90
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Thu Dec 2 18:23:09 2010 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Thu Dec 2 18:23:09 2010 +0000

    Register servers with Internet master server.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 2181
---
 src/Makefile.am     |  1 +
 src/d_net.c         |  1 +
 src/net_dedicated.c |  2 +-
 src/net_defs.h      |  8 ++++++
 src/net_query.c     | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/net_query.h     |  4 +++
 src/net_server.c    | 55 ++++++++++++++++++++++++++++++++++++++++-
 src/net_server.h    |  4 +++
 8 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 8b827131..26fe7c7d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,6 +16,7 @@ net_dedicated.c      net_dedicated.h       \
 net_io.c             net_io.h              \
 net_packet.c         net_packet.h          \
 net_sdl.c            net_sdl.h             \
+net_query.c          net_query.h           \
 net_server.c         net_server.h          \
 net_structrw.c       net_structrw.h        \
 z_native.c           z_zone.h
diff --git a/src/d_net.c b/src/d_net.c
index 56f04876..bf9fbf2b 100644
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -270,6 +270,7 @@ void D_CheckNetGame (void)
             NET_SV_Init();
             NET_SV_AddModule(&net_loop_server_module);
             NET_SV_AddModule(&net_sdl_module);
+            NET_SV_RegisterWithMaster();

             net_loop_client_module.InitClient();
             addr = net_loop_client_module.ResolveAddress(NULL);
diff --git a/src/net_dedicated.c b/src/net_dedicated.c
index 6a153300..82909210 100644
--- a/src/net_dedicated.c
+++ b/src/net_dedicated.c
@@ -71,8 +71,8 @@ void NET_DedicatedServer(void)
     CheckForClientOptions();

     NET_SV_Init();
-
     NET_SV_AddModule(&net_sdl_module);
+    NET_SV_RegisterWithMaster();

     while (true)
     {
diff --git a/src/net_defs.h b/src/net_defs.h
index 66b17c77..d9e3b920 100644
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -113,6 +113,14 @@ typedef enum
     NET_PACKET_TYPE_QUERY_RESPONSE,
 } net_packet_type_t;

+typedef enum
+{
+    NET_MASTER_PACKET_TYPE_ADD,
+    NET_MASTER_PACKET_TYPE_ADD_RESPONSE,
+    NET_MASTER_PACKET_TYPE_QUERY,
+    NET_MASTER_PACKET_TYPE_QUERY_RESPONSE
+} net_master_packet_type_t;
+
 typedef struct
 {
     int ticdup;
diff --git a/src/net_query.c b/src/net_query.c
index 72650ac2..deb3744a 100644
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -36,16 +36,86 @@
 #include "net_structrw.h"
 #include "net_sdl.h"

+#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org"
+
 typedef struct
 {
     net_addr_t *addr;
     net_querydata_t data;
 } queryresponse_t;

+static boolean registered_with_master = false;
+
 static net_context_t *query_context;
 static queryresponse_t *responders;
 static int num_responses;

+// Resolve the master server address.
+
+net_addr_t *NET_Query_ResolveMaster(net_context_t *context)
+{
+    net_addr_t *addr;
+
+    addr = NET_ResolveAddress(context, MASTER_SERVER_ADDRESS);
+
+    if (addr == NULL)
+    {
+        fprintf(stderr, "Warning: Failed to resolve address "
+                        "for master server: %s\n", MASTER_SERVER_ADDRESS);
+    }
+
+    return addr;
+}
+
+// Send a registration packet to the master server to register
+// ourselves with the global list.
+
+void NET_Query_AddToMaster(net_addr_t *master_addr)
+{
+    net_packet_t *packet;
+
+    packet = NET_NewPacket(10);
+    NET_WriteInt16(packet, NET_MASTER_PACKET_TYPE_ADD);
+    NET_SendPacket(master_addr, packet);
+    NET_FreePacket(packet);
+}
+
+// Process a packet received from the master server.
+
+void NET_Query_MasterResponse(net_packet_t *packet)
+{
+    unsigned int packet_type;
+    unsigned int result;
+
+    if (!NET_ReadInt16(packet, &packet_type)
+     || !NET_ReadInt16(packet, &result))
+    {
+        return;
+    }
+
+    if (packet_type == NET_MASTER_PACKET_TYPE_ADD_RESPONSE)
+    {
+        if (result != 0)
+        {
+            // Only show the message once.
+
+            if (!registered_with_master)
+            {
+                printf("Registered with master server at %s\n",
+                       MASTER_SERVER_ADDRESS);
+                registered_with_master = true;
+            }
+        }
+        else
+        {
+            // Always show rejections.
+
+            printf("Failed to register with master server at %s\n",
+                   MASTER_SERVER_ADDRESS);
+        }
+    }
+}
+
 // Add a new address to the list of hosts that has responded

 static queryresponse_t *AddResponder(net_addr_t *addr,
@@ -319,3 +389,4 @@ void NET_LANQuery(void)
     exit(0);
 }

+
diff --git a/src/net_query.h b/src/net_query.h
index f682d320..0ed098f1 100644
--- a/src/net_query.h
+++ b/src/net_query.h
@@ -31,5 +31,9 @@ extern void NET_QueryAddress(char *addr);
 extern void NET_LANQuery(void);
 extern net_addr_t *NET_FindLANServer(void);

+net_addr_t *NET_Query_ResolveMaster(net_context_t *context);
+void NET_Query_AddToMaster(net_addr_t *master_addr);
+void NET_Query_MasterResponse(net_packet_t *packet);
+
 #endif /* #ifndef NET_QUERY_H */

diff --git a/src/net_server.c b/src/net_server.c
index 383608be..7b67ea56 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -40,10 +40,15 @@
 #include "net_io.h"
 #include "net_loop.h"
 #include "net_packet.h"
+#include "net_query.h"
 #include "net_server.h"
 #include "net_sdl.h"
 #include "net_structrw.h"

+// How often to refresh our registration with the master server.
+
+#define MASTER_REFRESH_PERIOD 20 * 60 /* 20 minutes */
+
 typedef enum
 {
     // waiting for the game to start
@@ -127,6 +132,11 @@ static unsigned int sv_gamemode;
 static unsigned int sv_gamemission;
 static net_gamesettings_t sv_settings;

+// For registration with master server:
+
+static net_addr_t *master_server = NULL;
+static unsigned int master_refresh_time;
+
 // receive window

 static unsigned int recvwindow_start;
@@ -1108,6 +1118,14 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr)
     net_client_t *client;
     unsigned int packet_type;

+    // Response from master server?
+
+    if (addr != NULL && addr == master_server)
+    {
+        NET_Query_MasterResponse(packet);
+        return;
+    }
+
     // Find which client this packet came from

     client = NET_SV_FindClient(addr);
@@ -1513,6 +1531,32 @@ void NET_SV_Init(void)
     server_initialized = true;
 }

+void NET_SV_RegisterWithMaster(void)
+{
+    //!
+    // When running a server, don't register with the global master server.
+    //
+    // @category net
+    //
+
+    if (!M_CheckParm("-privateserver"))
+    {
+        master_server = NET_Query_ResolveMaster(server_context);
+    }
+    else
+    {
+        master_server = NULL;
+    }
+
+    // Send request.
+
+    if (master_server != NULL)
+    {
+        NET_Query_AddToMaster(master_server);
+        master_refresh_time = I_GetTimeMS();
+    }
+}
+
 // Run server code to check for new packets/send packets as the server
 // requires

@@ -1527,12 +1571,21 @@ void NET_SV_Run(void)
         return;
     }

-    while (NET_RecvPacket(server_context, &addr, &packet))
+    while (NET_RecvPacket(server_context, &addr, &packet))
     {
         NET_SV_Packet(packet, addr);
         NET_FreePacket(packet);
     }

+    // Possibly refresh our registration with the master server.
+
+    if (master_server != NULL
+     && I_GetTimeMS() - master_refresh_time > MASTER_REFRESH_PERIOD * 1000)
+    {
+        NET_Query_AddToMaster(master_server);
+        master_refresh_time = I_GetTimeMS();
+    }
+
     // "Run" any clients that may have things to do, independent of responses
     // to received packets

diff --git a/src/net_server.h b/src/net_server.h
index 93b22fc3..1debbd79 100644
--- a/src/net_server.h
+++ b/src/net_server.h
@@ -41,5 +41,9 @@ void NET_SV_Shutdown(void);

 void NET_SV_AddModule(net_module_t *module);

+// Register server with master server.
+
+void NET_SV_RegisterWithMaster(void);
+
 #endif /* #ifndef NET_SERVER_H */