#define MASTER_PORT 27950
cvar_t sv_public = {0, "sv_public", "1"};
-static cvar_t sv_heartbeatperiod = {CVAR_SAVE, "sv_heartbeatperiod", "180"};
+static cvar_t sv_heartbeatperiod = {CVAR_SAVE, "sv_heartbeatperiod", "120"};
// FIXME: resolve DNS on masters whenever their value changes and cache it (to avoid major delays in active servers when they heartbeat)
static cvar_t sv_masters [] =
{CVAR_SAVE, "sv_master4", ""},
{0, "sv_masterextra1", "ghdigital.com"}, //69.59.212.88
{0, "sv_masterextra2", "dpmaster.deathmask.net"}, //209.164.24.243
- {0, "sv_masterextra3", "blaze.mindphukd.org"}, //12.166.196.192
+ {0, "sv_masterextra3", "12.166.196.192"}, //blaze.mindphukd.org (doesn't resolve currently but works as an ip)
{0, NULL, NULL}
};
static void _ServerList_ViewList_Helper_InsertBefore( int index, serverlist_entry_t *entry )
{
int i;
- if( serverlist_viewcount == SERVERLIST_VIEWLISTSIZE )
- return;
+ if( serverlist_viewcount < SERVERLIST_VIEWLISTSIZE ) {
+ i = serverlist_viewcount++;
+ } else {
+ i = SERVERLIST_VIEWLISTSIZE - 1;
+ }
- for( i = serverlist_viewcount ; i > index ; i-- )
+ for( ; i > index ; i-- )
serverlist_viewlist[ i ] = serverlist_viewlist[ i - 1 ];
serverlist_viewlist[index] = entry;
- serverlist_viewcount++;
}
// we suppose serverlist_viewcount to be valid, ie > 0
{
int start, end, mid;
- if( serverlist_viewcount == SERVERLIST_VIEWLISTSIZE )
- return;
-
+ // FIXME: change this to be more readable (...)
// now check whether it passes through the masks
for( start = 0 ; serverlist_andmasks[start].active && start < SERVERLIST_ANDMASKCOUNT ; start++ )
if( !_ServerList_Entry_Mask( &serverlist_andmasks[start], &entry->info ) )
if( !serverlist_viewcount ) {
_ServerList_ViewList_Helper_InsertBefore( 0, entry );
return;
- }
+ }
// ok, insert it, we just need to find out where exactly:
// two special cases
serverlist_viewcount = 0;
for( i = 0 ; i < serverlist_cachecount ; i++ )
- if( serverlist_cache[i].finished )
+ if( serverlist_cache[i].query == SQS_QUERIED )
ServerList_ViewList_Insert( &serverlist_cache[i] );
}
int i;
for( i = 0 ; i < 1024 ; i++ ) {
memset( &serverlist_cache[serverlist_cachecount], 0, sizeof( serverlist_entry_t ) );
- serverlist_cache[serverlist_cachecount].info.ping = rand() % 450 + 250;
+ serverlist_cache[serverlist_cachecount].info.ping = 1000 + 1024 - i;
dpsnprintf( serverlist_cache[serverlist_cachecount].info.name, 128, "Black's ServerList Test %i", i );
serverlist_cache[serverlist_cachecount].finished = true;
sprintf( serverlist_cache[serverlist_cachecount].line1, "%i %s", serverlist_cache[serverlist_cachecount].info.ping, serverlist_cache[serverlist_cachecount].info.name );
serverlist_cachecount = 0;
serverlist_viewcount = 0;
serverlist_consoleoutput = false;
- NetConn_QueryMasters();
-
+
//_ServerList_Test();
+
+ NetConn_QueryMasters();
}
// rest
unsigned int count;
unsigned int flags;
unsigned int sequence;
+ int qlength;
if (length >= 8)
{
- length = BigLong(((int *)data)[0]);
- flags = length & ~NETFLAG_LENGTH_MASK;
- length &= NETFLAG_LENGTH_MASK;
+ qlength = (unsigned int)BigLong(((int *)data)[0]);
+ flags = qlength & ~NETFLAG_LENGTH_MASK;
+ qlength &= NETFLAG_LENGTH_MASK;
// control packets were already handled
- if (!(flags & NETFLAG_CTL))
+ if (!(flags & NETFLAG_CTL) && qlength == length)
{
sequence = BigLong(((int *)data)[1]);
packetsReceived++;
conn->lastMessageTime = realtime;
conn->timeout = realtime + net_messagetimeout.value;
conn->receiveSequence++;
- memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length);
- conn->receiveMessageLength += length;
+ if( conn->receiveMessageLength + length <= sizeof( conn->receiveMessage ) ) {
+ memcpy(conn->receiveMessage + conn->receiveMessageLength, data, length);
+ conn->receiveMessageLength += length;
+ } else {
+ Con_Printf( "Reliable message (seq: %i) too big for message buffer!\n"
+ "Dropping the message!\n", sequence );
+ conn->receiveMessageLength = 0;
+ return 1;
+ }
if (flags & NETFLAG_EOM)
{
reliableMessagesReceived++;
int NetConn_ClientParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress)
{
int ret, c, control;
- lhnetaddress_t svaddress;
const char *s;
char *string, addressstring2[128], cname[128], ipstring[32];
char stringbuf[16384];
if (length > 10 && !memcmp(string, "challenge ", 10) && cls.connect_trying)
{
+ char protocolnames[1400];
+ Protocol_Names(protocolnames, sizeof(protocolnames));
LHNETADDRESS_ToString(peeraddress, addressstring2, sizeof(addressstring2), true);
Con_Printf("\"%s\" received, sending connect request back to %s\n", string, addressstring2);
M_Update_Return_Reason("Got challenge response");
- NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\challenge\\%s", string + 10), peeraddress);
+ NetConn_WriteString(mysocket, va("\377\377\377\377connect\\protocol\\darkplaces 3\\protocols\\%s\\challenge\\%s", protocolnames, string + 10), peeraddress);
return true;
}
if (length == 6 && !memcmp(string, "accept", 6) && cls.connect_trying)
for( n = 0; n < serverlist_cachecount; n++ )
if( !strcmp( cname, serverlist_cache[n].info.cname ) )
break;
- if( n == serverlist_cachecount )
- return true;
+ if( n == serverlist_cachecount ) {
+ // LAN search doesnt require an answer from the master server so we wont
+ // know the ping nor will it be initialized already...
+
+ // find a slot
+ if( serverlist_cachecount == SERVERLIST_TOTALSIZE )
+ return true;
+
+ memset(&serverlist_cache[serverlist_cachecount], 0, sizeof(serverlist_cache[serverlist_cachecount]));
+ // store the data the engine cares about (address and ping)
+ strlcpy (serverlist_cache[serverlist_cachecount].info.cname, cname, sizeof (serverlist_cache[serverlist_cachecount].info.cname));
+ serverlist_cache[serverlist_cachecount].info.ping = 100000;
+ serverlist_cache[serverlist_cachecount].querytime = realtime;
+ // if not in the slist menu we should print the server to console
+ if (serverlist_consoleoutput) {
+ Con_Printf("querying %s\n", ipstring);
+ }
+
+ ++serverlist_cachecount;
+ }
info = &serverlist_cache[n].info;
if ((s = SearchInfostring(string, "gamename" )) != NULL) strlcpy(info->game, s, sizeof (info->game));else info->game[0] = 0;
if (serverlist_cache[n].line1[i] != ' ')
serverlist_cache[n].line1[i] -= 30;
}
- // and finally, update the view set
- if( serverlist_cache[n].finished )
- ServerList_ViewList_Remove( &serverlist_cache[n] );
- // else if not in the slist menu we should print the server to console (if wanted)
+ if( serverlist_cache[n].query == SQS_QUERIED ) {
+ ServerList_ViewList_Remove( &serverlist_cache[n] );
+ }
+ // if not in the slist menu we should print the server to console (if wanted)
else if( serverlist_consoleoutput )
Con_Printf("%s\n%s\n", serverlist_cache[n].line1, serverlist_cache[n].line2);
+ // and finally, update the view set
ServerList_ViewList_Insert( &serverlist_cache[n] );
- serverlist_cache[n].finished = true;
+ serverlist_cache[n].query = SQS_QUERIED;
return true;
}
{
serverquerycount++;
- LHNETADDRESS_FromString(&svaddress, ipstring, 0);
- NetConn_WriteString(mysocket, "\377\377\377\377getinfo", &svaddress);
-
memset(&serverlist_cache[serverlist_cachecount], 0, sizeof(serverlist_cache[serverlist_cachecount]));
// store the data the engine cares about (address and ping)
strlcpy (serverlist_cache[serverlist_cachecount].info.cname, ipstring, sizeof (serverlist_cache[serverlist_cachecount].info.cname));
serverlist_cache[serverlist_cachecount].info.ping = 100000;
- serverlist_cache[serverlist_cachecount].querytime = realtime;
- // if not in the slist menu we should print the server to console
- if (serverlist_consoleoutput)
- Con_Printf("querying %s\n", ipstring);
+ serverlist_cache[serverlist_cachecount].query = SQS_PENDING;
++serverlist_cachecount;
}
return ret;
}
+#define QUERIES_PER_FRAME 4
+void NetConn_QueryQueueFrame(void)
+{
+ int index = 0;
+ int queries = 0;
+ static float time = -1;
+ int maxqueries = 0;
+
+ if( time == -1 ) {
+ time = realtime;
+ }
+
+ maxqueries = QUERIES_PER_FRAME * (realtime - time );
+
+ if( maxqueries == 0 ) {
+ return;
+ }
+
+ for( ; index < serverlist_cachecount && queries < QUERIES_PER_FRAME ; index++ )
+ {
+ if( serverlist_cache[ index ].query == SQS_PENDING )
+ {
+ lhnetaddress_t address;
+ int socket;
+
+ LHNETADDRESS_FromString(&address, serverlist_cache[ index ].info.cname, 0);
+ for (socket = 0; socket < cl_numsockets ; socket++) {
+ NetConn_WriteString(cl_sockets[socket], "\377\377\377\377getinfo", &address);
+ }
+
+ serverlist_cache[ index ].querytime = realtime;
+ serverlist_cache[ index ].query = SQS_QUERYING;
+
+ // if not in the slist menu we should print the server to console
+ if (serverlist_consoleoutput)
+ Con_Printf("querying %s\n", serverlist_cache[ index ].info.cname);
+
+
+ queries++;
+ }
+ }
+
+ time = realtime;
+}
+
void NetConn_ClientFrame(void)
{
int i, length;
NetConn_Write(cls.connect_mysocket, net_message.data, net_message.cursize, &cls.connect_address);
SZ_Clear(&net_message);
}
- for (i = 0;i < cl_numsockets;i++)
- while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
+ for (i = 0;i < cl_numsockets;i++) {
+ while (cl_sockets[i] && (length = NetConn_Read(cl_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0) {
NetConn_ClientParsePacket(cl_sockets[i], readbuffer, length, &peeraddress);
+ }
+ }
+ NetConn_QueryQueueFrame();
if (cls.netcon && realtime > cls.netcon->timeout)
{
Con_Print("Connection timed out\n");
buffer[i] = 0;
}
+extern void SV_SendServerinfo (client_t *client);
int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress)
{
int i, n, ret, clientnum, responselength, best;
for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
break;
- if (clientnum < svs.maxclients)
+ if (clientnum < svs.maxclients && realtime - client->connecttime < net_messagerejointimeout.value)
+ {
+ // client is still trying to connect,
+ // so we send a duplicate reply
+ if (developer.integer)
+ Con_Printf("Datagram_ParseConnectionless: sending duplicate accept to %s.\n", addressstring2);
+ NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
+ }
+#if 0
+ else if (clientnum < svs.maxclients)
{
- // duplicate connection request
- if (realtime - client->connecttime < 2.0)
- {
- // client is still trying to connect,
- // so we send a duplicate reply
- if (developer.integer)
- Con_Printf("Datagram_ParseConnectionless: sending duplicate accept to %s.\n", addressstring2);
- NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
- }
- // only kick if old connection seems dead
if (realtime - client->netconnection->lastMessageTime >= net_messagerejointimeout.value)
{
- // kick off connection and await retry
- client->deadsocket = true;
+ // client crashed and is coming back, keep their stuff intact
+ SV_SendServerinfo(client);
+ //host_client = client;
+ //SV_DropClient (true);
}
+ // else ignore them
}
+#endif
else
{
// this is a new client, find a slot
NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
SZ_Clear(&net_message);
}
+#if 0
else if (realtime - client->netconnection->lastMessageTime >= net_messagerejointimeout.value)
{
+ SV_SendServerinfo(client);
// the old client hasn't sent us anything
// in quite a while, so kick off and let
// the retry take care of it...
- client->deadsocket = true;
+ //host_client = client;
+ //SV_DropClient (true);
}
+#endif
}
else
{
MSG_WriteByte(&net_message, playerNumber);
MSG_WriteString(&net_message, client->name);
MSG_WriteLong(&net_message, client->colors);
- MSG_WriteLong(&net_message, (int)client->edict->v->frags);
+ MSG_WriteLong(&net_message, (int)client->edict->fields.server->frags);
MSG_WriteLong(&net_message, (int)(realtime - client->connecttime));
MSG_WriteString(&net_message, client->netconnection ? client->netconnection->address : "botclient");
*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));