]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - net_main.c
added some commented out code to Image_HeightmapToNormalmap explaining how to do...
[xonotic/darkplaces.git] / net_main.c
index 63edadcbc0361f0fac211649c25a4087ad91ce13..9b5d556673bcf27672cfd9017c449d64a1d8ddff 100644 (file)
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // net_main.c
 
 #include "quakedef.h"
+#include "net_master.h"
 
 qsocket_t *net_activeSockets = NULL;
 mempool_t *net_mempool;
@@ -46,6 +47,11 @@ static void Slist_Poll(void);
 PollProcedure  slistSendProcedure = {NULL, 0.0, Slist_Send};
 PollProcedure  slistPollProcedure = {NULL, 0.0, Slist_Poll};
 
+static void InetSlist_Send(void);
+static void InetSlist_Poll(void);
+PollProcedure  inetSlistSendProcedure = {NULL, 0.0, InetSlist_Send};
+PollProcedure  inetSlistPollProcedure = {NULL, 0.0, InetSlist_Poll};
+
 
 sizebuf_t              net_message;
 int                            net_activeconnections = 0;
@@ -57,6 +63,7 @@ int unreliableMessagesReceived = 0;
 
 cvar_t net_messagetimeout = {0, "net_messagetimeout","300"};
 cvar_t hostname = {CVAR_SAVE, "hostname", "UNNAMED"};
+cvar_t developer_networking = {0, "developer_networking", "0"};
 
 qboolean       configRestored = false;
 
@@ -66,6 +73,107 @@ qboolean    configRestored = false;
 
 int    net_driverlevel;
 
+/*
+#define SLSERVERS 1024
+#define SLNAME 40
+#define SLMAPNAME 16
+#define SLMODNAME 16
+typedef struct slserver_s
+{
+       unsigned int ipaddr;
+       unsigned short port;
+       unsigned short ping;
+       char name[SLNAME];
+       char mapname[SLMAPNAME];
+       char modname[SLMODNAME];
+}
+slserver_t;
+
+slserver_t sl_server[SLSERVERS];
+int sl_numservers = 0;
+
+void SL_ClearServers(void)
+{
+       sl_numservers = 0;
+}
+
+slserver_t *SL_FindServer(unsigned int ipaddr, unsigned short port)
+{
+       int i;
+       slserver_t *sl;
+       for (i = 0, sl = sl_server;i < sl_numservers;i++, sl++)
+               if (sl->ipaddr == ipaddr && sl->port == port)
+                       return;
+}
+
+void SL_AddServer(unsigned int ipaddr, unsigned short port)
+{
+       if (SL_FindServer(ipaddr, port))
+               return;
+       memset(sl_server + sl_numservers, 0, sizeof(slserver_t));
+       sl_server[sl_numservers].ipaddr = ipaddr;
+       sl_server[sl_numservers].port = port;
+       sl_server[sl_numservers].ping = 0xFFFF;
+       sl_numservers++;
+}
+
+void SL_UpdateServerName(unsigned int ipaddr, unsigned short port, const char *name);
+{
+       int namelen;
+       slserver_t *sl;
+       sl = SL_FindServer(ipaddr, port);
+       if (sl == NULL)
+               return;
+       memset(sl->name, 0, sizeof(sl->name));
+       namelen = strlen(name);
+       if (namelen > sizeof(sl->name) - 1)
+               namelen = sizeof(sl->name) - 1;
+       if (namelen)
+               memcpy(sl->name, name, namelen);
+}
+
+void SL_UpdateServerModName(unsigned int ipaddr, unsigned short port, const char *name);
+{
+       int namelen;
+       slserver_t *sl;
+       sl = SL_FindServer(ipaddr, port);
+       if (sl == NULL)
+               return;
+       memset(sl->modname, 0, sizeof(sl->modname));
+       namelen = strlen(name);
+       if (namelen > sizeof(sl->modname) - 1)
+               namelen = sizeof(sl->modname) - 1;
+       if (namelen)
+               memcpy(sl->modname, name, namelen);
+}
+
+void SL_UpdateServerMapName(unsigned int ipaddr, unsigned short port, const char *name);
+{
+       int namelen;
+       slserver_t *sl;
+       sl = SL_FindServer(ipaddr, port);
+       if (sl == NULL)
+               return;
+       memset(sl->mapname, 0, sizeof(sl->mapname));
+       namelen = strlen(name);
+       if (namelen > sizeof(sl->mapname) - 1)
+               namelen = sizeof(sl->mapname) - 1;
+       if (namelen)
+               memcpy(sl->mapname, name, namelen);
+}
+
+void SL_UpdateServerPing(unsigned int ipaddr, unsigned short port, float ping);
+{
+       int i;
+       slserver_t *sl;
+       sl = SL_FindServer(ipaddr, port);
+       if (sl == NULL)
+               return;
+       i = ping * 1000.0;
+       sl->ping = bound(0, i, 9999);
+}
+*/
+
 
 double                 net_time;
 
@@ -178,7 +286,7 @@ static void MaxPlayers_f (void)
 
        n = atoi(Cmd_Argv(1));
        n = bound(1, n, MAX_SCOREBOARD);
-       if (svs.maxclients 1= n)
+       if (svs.maxclients != n)
                Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
 
        if ((n == 1) && listening)
@@ -220,6 +328,12 @@ static void NET_Port_f (void)
 }
 
 
+static void NET_Heartbeat_f (void)
+{
+       NET_Heartbeat (2);
+}
+
+
 static void PrintSlistHeader(void)
 {
        Con_Printf("Server          Map             Users\n");
@@ -248,31 +362,51 @@ static void PrintSlistTrailer(void)
        if (hostCacheCount)
                Con_Printf("== end list ==\n\n");
        else
-               Con_Printf("No Quake servers found.\n\n");
+       {
+               if (gamemode == GAME_TRANSFUSION)
+                       Con_Printf("No Transfusion servers found.\n\n");
+               else
+                       Con_Printf("No Quake servers found.\n\n");
+       }
 }
 
 
-void NET_Slist_f (void)
+void NET_SlistCommon (PollProcedure *sendProcedure, PollProcedure *pollProcedure)
 {
        if (slistInProgress)
                return;
 
        if (! slistSilent)
        {
-               Con_Printf("Looking for Quake servers...\n");
+               if (gamemode == GAME_TRANSFUSION)
+                       Con_Printf("Looking for Transfusion servers...\n");
+               else
+                       Con_Printf("Looking for Quake servers...\n");
                PrintSlistHeader();
        }
 
        slistInProgress = true;
        slistStartTime = Sys_DoubleTime();
 
-       SchedulePollProcedure(&slistSendProcedure, 0.0);
-       SchedulePollProcedure(&slistPollProcedure, 0.1);
+       SchedulePollProcedure(sendProcedure, 0.0);
+       SchedulePollProcedure(pollProcedure, 0.1);
 
        hostCacheCount = 0;
 }
 
 
+void NET_Slist_f (void)
+{
+       NET_SlistCommon (&slistSendProcedure, &slistPollProcedure);
+}
+
+
+void NET_InetSlist_f (void)
+{
+       NET_SlistCommon (&inetSlistSendProcedure, &inetSlistPollProcedure);
+}
+
+
 static void Slist_Send(void)
 {
        for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
@@ -317,6 +451,60 @@ static void Slist_Poll(void)
 }
 
 
+static void InetSlist_Send(void)
+{
+       const char* host;
+
+       if (!slistInProgress)
+               return;
+
+       while ((host = Master_BuildGetServers ()) != NULL)
+       {
+               for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
+               {
+                       if (!slistLocal && net_driverlevel == 0)
+                               continue;
+                       if (net_drivers[net_driverlevel].initialized == false)
+                               continue;
+                       dfunc.SearchForInetHosts (host);
+               }
+       }
+
+       if ((Sys_DoubleTime() - slistStartTime) < 3.5)
+               SchedulePollProcedure(&inetSlistSendProcedure, 1.0);
+}
+
+
+static void InetSlist_Poll(void)
+{
+       for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++)
+       {
+               if (!slistLocal && net_driverlevel == 0)
+                       continue;
+               if (net_drivers[net_driverlevel].initialized == false)
+                       continue;
+               // We stop as soon as we have one answer (FIXME: bad...)
+               if (dfunc.SearchForInetHosts (NULL))
+                       slistInProgress = false;
+       }
+
+       if (! slistSilent)
+               PrintSlist();
+
+       if (slistInProgress && (Sys_DoubleTime() - slistStartTime) < 4.0)
+       {
+               SchedulePollProcedure(&inetSlistPollProcedure, 0.1);
+               return;
+       }
+
+       if (! slistSilent)
+               PrintSlistTrailer();
+       slistInProgress = false;
+       slistSilent = false;
+       slistLocal = true;
+}
+
+
 /*
 ===================
 NET_Connect
@@ -330,7 +518,6 @@ qsocket_t *NET_Connect (char *host)
 {
        qsocket_t               *ret;
        int                             n;
-       int                             numdrivers = net_numdrivers;
 
        SetNetTime();
 
@@ -339,16 +526,16 @@ qsocket_t *NET_Connect (char *host)
 
        if (host)
        {
-               if (Q_strcasecmp (host, "local") == 0)
+               if (strcasecmp (host, "local") == 0)
                {
-                       numdrivers = 1;
-                       goto JustDoIt;
+                       net_driverlevel = 0;
+                       return dfunc.Connect (host);
                }
 
                if (hostCacheCount)
                {
                        for (n = 0; n < hostCacheCount; n++)
-                               if (Q_strcasecmp (host, hostcache[n].name) == 0)
+                               if (strcasecmp (host, hostcache[n].name) == 0)
                                {
                                        host = hostcache[n].cname;
                                        break;
@@ -374,14 +561,14 @@ qsocket_t *NET_Connect (char *host)
 
        if (hostCacheCount)
                for (n = 0; n < hostCacheCount; n++)
-                       if (Q_strcasecmp (host, hostcache[n].name) == 0)
+                       if (strcasecmp (host, hostcache[n].name) == 0)
                        {
                                host = hostcache[n].cname;
                                break;
                        }
 
 JustDoIt:
-       for (net_driverlevel=0 ; net_driverlevel<numdrivers; net_driverlevel++)
+       for (net_driverlevel = 0;net_driverlevel < net_numdrivers;net_driverlevel++)
        {
                if (net_drivers[net_driverlevel].initialized == false)
                        continue;
@@ -397,7 +584,7 @@ JustDoIt:
                PrintSlist();
                PrintSlistTrailer();
        }
-       
+
        return NULL;
 }
 
@@ -522,7 +709,7 @@ returns -1 if the connection died
 int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
 {
        int             r;
-       
+
        if (!sock)
                return -1;
 
@@ -544,7 +731,7 @@ int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
 int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
 {
        int             r;
-       
+
        if (!sock)
                return -1;
 
@@ -574,7 +761,7 @@ message to be transmitted.
 qboolean NET_CanSendMessage (qsocket_t *sock)
 {
        int             r;
-       
+
        if (!sock)
                return false;
 
@@ -584,81 +771,81 @@ qboolean NET_CanSendMessage (qsocket_t *sock)
        SetNetTime();
 
        r = sfunc.CanSendMessage(sock);
-       
+
        return r;
 }
 
 
-int NET_SendToAll(sizebuf_t *data, int blocktime)
+/*
+====================
+NET_Heartbeat
+
+Send an heartbeat to the master server(s)
+====================
+*/
+void NET_Heartbeat (int priority)
 {
-       double          start;
-       int                     i;
-       int                     count = 0;
-       qboolean        state1 [MAX_SCOREBOARD];
-       qboolean        state2 [MAX_SCOREBOARD];
+       const char* host;
+
+       if (! Master_AllowHeartbeat (priority))
+               return;
 
-       for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
+       while ((host = Master_BuildHeartbeat ()) != NULL)
        {
-               if (!host_client->netconnection)
-                       continue;
-               if (host_client->active)
+               for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
                {
-                       if (host_client->netconnection->driver == 0)
-                       {
-                               NET_SendMessage(host_client->netconnection, data);
-                               state1[i] = true;
-                               state2[i] = true;
+                       if (net_drivers[net_driverlevel].initialized == false)
                                continue;
-                       }
-                       count++;
-                       state1[i] = false;
-                       state2[i] = false;
-               }
-               else
-               {
-                       state1[i] = true;
-                       state2[i] = true;
+                       if (net_driverlevel && listening == false)
+                               continue;
+                       dfunc.Heartbeat (host);
                }
        }
+}
 
+
+int NET_SendToAll(sizebuf_t *data, int blocktime)
+{
+       double          start;
+       int                     i;
+       int                     count = 0;
+       qbyte           state [MAX_SCOREBOARD];
+
+       for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+               state[i] = (host_client->netconnection && host_client->active) ? 0 : 2;
+
+       // for every player (simultaneously) wait for the first CanSendMessage
+       // and send the message, then wait for a second CanSendMessage (verifying
+       // it was received)
        start = Sys_DoubleTime();
-       while (count)
+       do
        {
                count = 0;
-               for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
+               for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                {
-                       if (! state1[i])
-                       {
-                               if (NET_CanSendMessage (host_client->netconnection))
-                               {
-                                       state1[i] = true;
-                                       NET_SendMessage(host_client->netconnection, data);
-                               }
-                               else
-                               {
-                                       NET_GetMessage (host_client->netconnection);
-                               }
-                               count++;
-                               continue;
-                       }
-
-                       if (! state2[i])
+                       if (state[i] < 2)
                        {
+                               // need to send to this one
                                if (NET_CanSendMessage (host_client->netconnection))
                                {
-                                       state2[i] = true;
+                                       if (state[i] == 0)
+                                       {
+                                               if (NET_SendMessage (host_client->netconnection, data) == 1)
+                                                       state[i] = 2; // connection lost
+                                               else
+                                                       count++;
+                                       }
+                                       state[i]++;
                                }
                                else
                                {
                                        NET_GetMessage (host_client->netconnection);
+                                       count++;
                                }
-                               count++;
-                               continue;
                        }
                }
-               if ((Sys_DoubleTime() - start) > blocktime)
-                       break;
        }
+       while (count && (Sys_DoubleTime() - start) < blocktime);
        return count;
 }
 
@@ -703,11 +890,14 @@ void NET_Init (void)
 
        Cvar_RegisterVariable (&net_messagetimeout);
        Cvar_RegisterVariable (&hostname);
+       Cvar_RegisterVariable (&developer_networking);
 
-       Cmd_AddCommand ("slist", NET_Slist_f);
+       Cmd_AddCommand ("net_slist", NET_Slist_f);
+       Cmd_AddCommand ("net_inetslist", NET_InetSlist_f);
        Cmd_AddCommand ("listen", NET_Listen_f);
        Cmd_AddCommand ("maxplayers", MaxPlayers_f);
        Cmd_AddCommand ("port", NET_Port_f);
+       Cmd_AddCommand ("heartbeat", NET_Heartbeat_f);
 
        // initialize all the drivers
        for (net_driverlevel=0 ; net_driverlevel<net_numdrivers ; net_driverlevel++)
@@ -725,6 +915,8 @@ void NET_Init (void)
                Con_DPrintf("IPX address %s\n", my_ipx_address);
        if (*my_tcpip_address)
                Con_DPrintf("TCP/IP address %s\n", my_tcpip_address);
+
+       Master_Init ();
 }
 
 /*