mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
* (bug 2784) help to prevent reliable command overflow in cases when a slow
client is loading the map on a busy server. Specifically, hold back all configstring update commands while the client is CS_PRIMED. Once the client goes from CS_PRIMED to CS_ACTIVE, send the cleint commands for updating each of the configstring indexes which were updated while the client was CS_PRIMED.
This commit is contained in:
parent
41add6c01f
commit
189e8b33f3
4 changed files with 90 additions and 34 deletions
|
@ -168,6 +168,7 @@ typedef struct client_s {
|
|||
netchan_buffer_t **netchan_end_queue;
|
||||
|
||||
int oldServerTime;
|
||||
qboolean csUpdated[MAX_CONFIGSTRINGS+1];
|
||||
} client_t;
|
||||
|
||||
//=============================================================================
|
||||
|
@ -272,6 +273,7 @@ void SV_MasterShutdown (void);
|
|||
//
|
||||
void SV_SetConfigstring( int index, const char *val );
|
||||
void SV_GetConfigstring( int index, char *buffer, int bufferSize );
|
||||
void SV_UpdateConfigstrings( client_t *client );
|
||||
|
||||
void SV_SetUserinfo( int index, const char *val );
|
||||
void SV_GetUserinfo( int index, char *buffer, int bufferSize );
|
||||
|
|
|
@ -620,6 +620,10 @@ void SV_ClientEnterWorld( client_t *client, usercmd_t *cmd ) {
|
|||
Com_DPrintf( "Going from CS_PRIMED to CS_ACTIVE for %s\n", client->name );
|
||||
client->state = CS_ACTIVE;
|
||||
|
||||
// resend all configstrings using the cs commands since these are
|
||||
// no longer sent when the client is CS_PRIMED
|
||||
SV_UpdateConfigstrings( client );
|
||||
|
||||
// set up the entity for the client
|
||||
clientNum = client - svs.clients;
|
||||
ent = SV_GentityNum( clientNum );
|
||||
|
|
|
@ -22,6 +22,81 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "server.h"
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_SendConfigstring
|
||||
|
||||
Creates and sends the server command necessary to update the CS index for the
|
||||
given client
|
||||
===============
|
||||
*/
|
||||
static void SV_SendConfigstring(client_t *client, int index)
|
||||
{
|
||||
int maxChunkSize = MAX_STRING_CHARS - 24;
|
||||
int len;
|
||||
|
||||
len = strlen(sv.configstrings[index]);
|
||||
|
||||
if( len >= maxChunkSize ) {
|
||||
int sent = 0;
|
||||
int remaining = len;
|
||||
char *cmd;
|
||||
char buf[MAX_STRING_CHARS];
|
||||
|
||||
while (remaining > 0 ) {
|
||||
if ( sent == 0 ) {
|
||||
cmd = "bcs0";
|
||||
}
|
||||
else if( remaining < maxChunkSize ) {
|
||||
cmd = "bcs2";
|
||||
}
|
||||
else {
|
||||
cmd = "bcs1";
|
||||
}
|
||||
Q_strncpyz( buf, &sv.configstrings[index][sent],
|
||||
maxChunkSize );
|
||||
|
||||
SV_SendServerCommand( client, "%s %i \"%s\"\n", cmd,
|
||||
index, buf );
|
||||
|
||||
sent += (maxChunkSize - 1);
|
||||
remaining -= (maxChunkSize - 1);
|
||||
}
|
||||
} else {
|
||||
// standard cs, just send it
|
||||
SV_SendServerCommand( client, "cs %i \"%s\"\n", index,
|
||||
sv.configstrings[index] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_UpdateConfigstrings
|
||||
|
||||
Called when a client goes from CS_PRIMED to CS_ACTIVE. Updates all
|
||||
Configstring indexes that have changed while the client was in CS_PRIMED
|
||||
===============
|
||||
*/
|
||||
void SV_UpdateConfigstrings(client_t *client)
|
||||
{
|
||||
int index;
|
||||
|
||||
for( index = 0; index <= MAX_CONFIGSTRINGS; index++ ) {
|
||||
// if the CS hasn't changed since we went to CS_PRIMED, ignore
|
||||
if(!client->csUpdated[index])
|
||||
continue;
|
||||
|
||||
// do not always send server info to all clients
|
||||
if ( index == CS_SERVERINFO && client->gentity &&
|
||||
(client->gentity->r.svFlags & SVF_NOSERVERINFO) ) {
|
||||
continue;
|
||||
}
|
||||
SV_SendConfigstring(client, index);
|
||||
client->csUpdated[index] = qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_SetConfigstring
|
||||
|
@ -30,7 +105,6 @@ SV_SetConfigstring
|
|||
*/
|
||||
void SV_SetConfigstring (int index, const char *val) {
|
||||
int len, i;
|
||||
int maxChunkSize = MAX_STRING_CHARS - 24;
|
||||
client_t *client;
|
||||
|
||||
if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
|
||||
|
@ -56,48 +130,23 @@ void SV_SetConfigstring (int index, const char *val) {
|
|||
|
||||
// send the data to all relevent clients
|
||||
for (i = 0, client = svs.clients; i < sv_maxclients->integer ; i++, client++) {
|
||||
if ( client->state < CS_PRIMED ) {
|
||||
if ( client->state < CS_ACTIVE ) {
|
||||
if ( client->state == CS_PRIMED )
|
||||
client->csUpdated[ index ] = qtrue;
|
||||
continue;
|
||||
}
|
||||
// do not always send server info to all clients
|
||||
if ( index == CS_SERVERINFO && client->gentity && (client->gentity->r.svFlags & SVF_NOSERVERINFO) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
len = strlen( val );
|
||||
if( len >= maxChunkSize ) {
|
||||
int sent = 0;
|
||||
int remaining = len;
|
||||
char *cmd;
|
||||
char buf[MAX_STRING_CHARS];
|
||||
|
||||
while (remaining > 0 ) {
|
||||
if ( sent == 0 ) {
|
||||
cmd = "bcs0";
|
||||
}
|
||||
else if( remaining < maxChunkSize ) {
|
||||
cmd = "bcs2";
|
||||
}
|
||||
else {
|
||||
cmd = "bcs1";
|
||||
}
|
||||
Q_strncpyz( buf, &val[sent], maxChunkSize );
|
||||
|
||||
SV_SendServerCommand( client, "%s %i \"%s\"\n", cmd, index, buf );
|
||||
|
||||
sent += (maxChunkSize - 1);
|
||||
remaining -= (maxChunkSize - 1);
|
||||
}
|
||||
} else {
|
||||
// standard cs, just send it
|
||||
SV_SendServerCommand( client, "cs %i \"%s\"\n", index, val );
|
||||
}
|
||||
SV_SendConfigstring(client, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
SV_GetConfigstring
|
||||
|
|
|
@ -135,6 +135,10 @@ void SV_AddServerCommand( client_t *client, const char *cmd ) {
|
|||
// return;
|
||||
// }
|
||||
|
||||
// do not send commands until the gamestate has been sent
|
||||
if( client->state < CS_PRIMED )
|
||||
return;
|
||||
|
||||
client->reliableSequence++;
|
||||
// if we would be losing an old command that hasn't been acknowledged,
|
||||
// we must drop the connection
|
||||
|
@ -193,9 +197,6 @@ void QDECL SV_SendServerCommand(client_t *cl, const char *fmt, ...) {
|
|||
|
||||
// send the data to all relevent clients
|
||||
for (j = 0, client = svs.clients; j < sv_maxclients->integer ; j++, client++) {
|
||||
if ( client->state < CS_PRIMED ) {
|
||||
continue;
|
||||
}
|
||||
SV_AddServerCommand( client, (char *)message );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue