// net_main.c
#include "quakedef.h"
+#include "net_master.h"
qsocket_t *net_activeSockets = NULL;
mempool_t *net_mempool;
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;
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;
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;
}
+static void NET_Heartbeat_f (void)
+{
+ NET_Heartbeat (2);
+}
+
+
static void PrintSlistHeader(void)
{
Con_Printf("Server Map Users\n");
if (hostCacheCount)
Con_Printf("== end list ==\n\n");
else
- Con_Printf("No Quake servers found.\n\n");
+ Con_Printf("No %s servers found.\n\n", gamename);
}
-void NET_Slist_f (void)
+void NET_SlistCommon (PollProcedure *sendProcedure, PollProcedure *pollProcedure)
{
if (slistInProgress)
return;
if (! slistSilent)
{
- Con_Printf("Looking for Quake servers...\n");
+ Con_Printf("Looking for %s servers...\n", gamename);
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++)
}
+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
{
qsocket_t *ret;
int n;
- int numdrivers = net_numdrivers;
SetNetTime();
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;
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;
PrintSlist();
PrintSlistTrailer();
}
-
+
return NULL;
}
int NET_SendMessage (qsocket_t *sock, sizebuf_t *data)
{
int r;
-
+
if (!sock)
return -1;
int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data)
{
int r;
-
+
if (!sock)
return -1;
qboolean NET_CanSendMessage (qsocket_t *sock)
{
int r;
-
+
if (!sock)
return false;
SetNetTime();
r = sfunc.CanSendMessage(sock);
-
+
return r;
}
+/*
+====================
+NET_Heartbeat
+
+Send an heartbeat to the master server(s)
+====================
+*/
+void NET_Heartbeat (int priority)
+{
+ const char* host;
+
+ if (! Master_AllowHeartbeat (priority))
+ return;
+
+ while ((host = Master_BuildHeartbeat ()) != NULL)
+ {
+ for (net_driverlevel=0 ; net_driverlevel<net_numdrivers; net_driverlevel++)
+ {
+ if (net_drivers[net_driverlevel].initialized == false)
+ continue;
+ if (net_driverlevel && listening == false)
+ continue;
+ dfunc.Heartbeat (host);
+ }
+ }
+}
+
+
int NET_SendToAll(sizebuf_t *data, int blocktime)
{
double start;
int i;
int count = 0;
- qboolean state1 [MAX_SCOREBOARD];
- qboolean state2 [MAX_SCOREBOARD];
+ qbyte state [MAX_SCOREBOARD];
- 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 (!host_client->netconnection)
- continue;
- if (host_client->active)
+ state[i] = 2;
+ if (host_client->netconnection && host_client->active)
{
if (host_client->netconnection->driver == 0)
- {
NET_SendMessage(host_client->netconnection, data);
- state1[i] = true;
- state2[i] = true;
- continue;
- }
- count++;
- state1[i] = false;
- state2[i] = false;
- }
- else
- {
- state1[i] = true;
- state2[i] = true;
+ else
+ state[i] = 0;
}
}
+ // 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 (state[i] < 2)
{
- 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])
- {
+ // need to send to this one
if (NET_CanSendMessage (host_client->netconnection))
{
- state2[i] = true;
+ if (state[i] == 0 && NET_SendMessage (host_client->netconnection, data) == -1)
+ state[i] = 2; // connection lost
+ state[i]++;
}
else
- {
NET_GetMessage (host_client->netconnection);
- }
- count++;
- continue;
}
}
- if ((Sys_DoubleTime() - start) > blocktime)
- break;
}
+ while (count && (Sys_DoubleTime() - start) < blocktime);
return count;
}
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++)
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 ();
}
/*