// send the unreliable message
CL_SendMove (&cmd);
}
-#ifndef NOROUTINGFIX
else if (cls.signon == 0 && !cls.demoplayback)
{
// LordHavoc: fix for NAT routing of netquake:
}
}
}
-#endif
if (cls.demoplayback)
{
double SetNetTime(void);
-#define HOSTCACHESIZE 8
+#define HOSTCACHESIZE 128
typedef struct
{
- char name[16];
- char map[16];
- char cname[32];
+ char name[64];
+ char map[64];
+ char cname[64];
int users;
int maxusers;
- int driver;
- int ldriver;
- struct qsockaddr addr;
+ //int driver;
+ //int ldriver;
+ //struct qsockaddr addr;
} hostcache_t;
extern int hostCacheCount;
}
}
-
+/*
static qboolean testInProgress = false;
static int testPollCount;
static int testDriver;
SZ_Clear(&net_message);
SchedulePollProcedure(&test2PollProcedure, 0.05);
}
-
+*/
int Datagram_Init (void)
{
#ifdef BAN_TEST
Cmd_AddCommand ("ban", NET_Ban_f);
#endif
- Cmd_AddCommand ("test", Test_f);
- Cmd_AddCommand ("test2", Test2_f);
+ //Cmd_AddCommand ("test", Test_f);
+ //Cmd_AddCommand ("test2", Test2_f);
return 0;
}
//struct qsockaddr myaddr;
int control;
int c, n, i;
+ char cname[256];
if (net_message.cursize < (int)sizeof(int))
return false;
if (c != CCREP_SERVER_INFO)
return false;
- dfunc.GetAddrFromName(MSG_ReadString(), readaddr);
+ // LordHavoc: because the UDP driver reports 0.0.0.0:26000 as the address
+ // string we just ignore it and keep the real address
+ MSG_ReadString();
+ // hostcache only uses text addresses
+ strcpy(cname, dfunc.AddrToString(readaddr));
// search the cache for this server
for (n = 0; n < hostCacheCount; n++)
- if (dfunc.AddrCompare(readaddr, &hostcache[n].addr) == 0)
- break;
-
- // is it already there?
- if (n < hostCacheCount)
- return false;;
+ //if (dfunc.AddrCompare(readaddr, &hostcache[n].addr) == 0)
+ if (!strcmp(cname, hostcache[n].cname))
+ return false;
// add it
hostCacheCount++;
c = MSG_ReadByte();
if (c != NET_PROTOCOL_VERSION)
{
- strcpy(hostcache[n].cname, hostcache[n].name);
- hostcache[n].cname[14] = 0;
+ strncpy(hostcache[n].cname, hostcache[n].name, sizeof(hostcache[n].cname) - 1);
+ hostcache[n].cname[sizeof(hostcache[n].cname) - 1] = 0;
strcpy(hostcache[n].name, "*");
- strcat(hostcache[n].name, hostcache[n].cname);
+ strncat(hostcache[n].name, hostcache[n].cname, sizeof(hostcache[n].name) - 1);
+ hostcache[n].name[sizeof(hostcache[n].name) - 1] = 0;
}
- memcpy(&hostcache[n].addr, readaddr, sizeof(struct qsockaddr));
- hostcache[n].driver = net_driverlevel;
- hostcache[n].ldriver = net_landriverlevel;
- strcpy(hostcache[n].cname, dfunc.AddrToString(readaddr));
+ strcpy(hostcache[n].cname, cname);
+ //memcpy(&hostcache[n].addr, readaddr, sizeof(struct qsockaddr));
+ //hostcache[n].driver = net_driverlevel;
+ //hostcache[n].ldriver = net_landriverlevel;
+ /*
// check for a name conflict
for (i = 0; i < hostCacheCount; i++)
{
i = -1;
}
}
+ */
return true;
}
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
strcpy(hostcache[0].map, sv.name);
hostcache[0].users = net_activeconnections;
hostcache[0].maxusers = svs.maxclients;
- hostcache[0].driver = net_driverlevel;
+ //hostcache[0].driver = net_driverlevel;
strcpy(hostcache[0].cname, "local");
}
{
if (strcmp(host,"local") != 0)
return NULL;
-
+
localconnectpending = true;
if (!loop_client)
loop_client->driverdata = (void *)loop_server;
loop_server->driverdata = (void *)loop_client;
-
- return loop_client;
+
+ return loop_client;
}
static void PrintSlistHeader(void)
{
- Con_Printf("Server Map Users\n");
- Con_Printf("--------------- --------------- -----\n");
+ Con_Printf("Server Address Name/Description Map Users\n");
+ Con_Printf("--------------------- ---------------------------------- --------------- -----\n");
slistLastShown = 0;
}
static void PrintSlist(void)
{
int n;
-
for (n = slistLastShown; n < hostCacheCount; n++)
- {
- if (hostcache[n].maxusers)
- Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
- else
- Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map);
- }
+ Con_Printf("%-21.21s %-34.34s %-15.15s %2u/%2u\n", hostcache[n].cname, hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers);
slistLastShown = n;
}
qsocket_t *NET_Connect (char *host)
{
- qsocket_t *ret;
- int n;
-
- SetNetTime();
-
- if (host && *host == 0)
- host = NULL;
-
- if (host)
- {
- if (strcasecmp (host, "local") == 0)
- {
- net_driverlevel = 0;
- return dfunc.Connect (host);
- }
-
- if (hostCacheCount)
- {
- for (n = 0; n < hostCacheCount; n++)
- if (strcasecmp (host, hostcache[n].name) == 0)
- {
- host = hostcache[n].cname;
- break;
- }
- if (n < hostCacheCount)
- goto JustDoIt;
- }
- }
+ qsocket_t *ret;
- slistSilent = host ? true : false;
- NET_Slist_f ();
+ if (host == NULL || *host == 0)
+ return NULL;
- while(slistInProgress)
- NET_Poll();
+ SetNetTime();
- if (host == NULL)
+ if (host && strcasecmp (host, "local") == 0)
{
- if (hostCacheCount != 1)
- return NULL;
- host = hostcache[0].cname;
- Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host);
+ net_driverlevel = 0;
+ return dfunc.Connect (host);
}
- if (hostCacheCount)
- for (n = 0; n < hostCacheCount; n++)
- if (strcasecmp (host, hostcache[n].name) == 0)
- {
- host = hostcache[n].cname;
- break;
- }
-
-JustDoIt:
for (net_driverlevel = 0;net_driverlevel < net_numdrivers;net_driverlevel++)
{
if (net_drivers[net_driverlevel].initialized == false)
return ret;
}
- if (host)
- {
- Con_Printf("\n");
- PrintSlistHeader();
- PrintSlist();
- PrintSlistTrailer();
- }
-
return NULL;
}
// only valid before spawned
qboolean sendsignon;
-#ifndef NOROUTINGFIX
// LordHavoc: to make netquake protocol get through NAT routers, have to wait for client to ack
// waiting for connect from client (stage 1)
qboolean waitingforconnect;
// send server info in next datagram (stage 2)
qboolean sendserverinfo;
-#endif
// reliable messages must be sent periodically
double last_message;
MSG_WriteByte (&client->message, svc_signonnum);
MSG_WriteByte (&client->message, 1);
-
- client->sendsignon = true;
- client->spawned = false; // need prespawn, spawn, etc
}
/*
client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
}
-#if NOROUTINGFIX
+ client->sendserverinfo = false;
+ client->sendsignon = true;
+ client->spawned = false; // need prespawn, spawn, etc
+ // LordHavoc: 1 = attempt to work through NAT routers
+#if 0
+ // send serverinfo immediately (may get lost if client is behind a NAT router)
+ client->waitingforconnect = false;
SV_SendServerinfo (client);
#else
- // send serverinfo on first nop
+ // send serverinfo only after receiving a nop from client
client->waitingforconnect = true;
- client->sendsignon = true;
- client->spawned = false; // need prespawn, spawn, etc
#endif
}
if (!host_client->active)
continue;
-#ifndef NOROUTINGFIX
- if (host_client->sendserverinfo)
- {
- host_client->sendserverinfo = false;
- SV_SendServerinfo (host_client);
- }
-#endif
-
if (host_client->spawned)
{
if (!SV_SendClientDatagram (host_client))
// between signon stages
if (!host_client->sendsignon)
{
+ if (host_client->sendserverinfo)
+ {
+ host_client->sendserverinfo = false;
+ SV_SendServerinfo (host_client);
+ }
+
if (realtime - host_client->last_message > 5)
SV_SendNop (host_client);
continue; // don't send out non-signon messages
if (!ret)
return true;
+ if (host_client->waitingforconnect)
+ {
+ host_client->waitingforconnect = false;
+ host_client->sendserverinfo = true;
+ }
+
MSG_BeginReading ();
while (1)
cmd = MSG_ReadChar ();
-#ifndef NOROUTINGFIX
- if (cmd != -1 && host_client->waitingforconnect)
- {
- host_client->waitingforconnect = false;
- host_client->sendserverinfo = true;
- }
-#endif
-
switch (cmd)
{
case -1: