ref: f9ab444cc614db3b2380d02750d142f9b17a8b90
parent: 74034c0c1bd68fbc8c57daee922103f69c7ddf6d
author: Simon Howard <[email protected]>
date: Thu Dec 2 13:23:09 EST 2010
Register servers with Internet master server. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2181
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,6 +16,7 @@
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
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -270,6 +270,7 @@
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);
--- a/src/net_dedicated.c
+++ b/src/net_dedicated.c
@@ -71,8 +71,8 @@
CheckForClientOptions();
NET_SV_Init();
-
NET_SV_AddModule(&net_sdl_module);
+ NET_SV_RegisterWithMaster();
while (true)
{
--- a/src/net_defs.h
+++ b/src/net_defs.h
@@ -113,6 +113,14 @@
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;
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -36,6 +36,8 @@
#include "net_structrw.h"
#include "net_sdl.h"
+#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org"
+
typedef struct
{
net_addr_t *addr;
@@ -42,10 +44,78 @@
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,
@@ -318,4 +388,5 @@
exit(0);
}
+
--- a/src/net_query.h
+++ b/src/net_query.h
@@ -31,5 +31,9 @@
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 */
--- 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_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 @@
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 @@
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,10 +1571,19 @@
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
--- a/src/net_server.h
+++ b/src/net_server.h
@@ -41,5 +41,9 @@
void NET_SV_AddModule(net_module_t *module);
+// Register server with master server.
+
+void NET_SV_RegisterWithMaster(void);
+
#endif /* #ifndef NET_SERVER_H */