diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-07-13 17:11:30 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-10 22:27:30 +0000 |
commit | 2bf2118d79994cfd805c3ffb5b421c6a65658b84 (patch) | |
tree | 867a9c4ac0d975e7aca4ee20714de8c97646ccde /src/server/sv_snapshot.c | |
parent | 5038ffeb97413a867d0bdadf761e2ba727781742 (diff) |
- Improve snapshot rate and data rate control - Make server send packet fragments and queued packets when server is idle - Voip protocol detection is tied to com_protocol making past-end-of-message reading unncessary - Use Hunk_AllocateTempMemory() for buffering VOIP packets and fix buffering scheme that ryan hates so much - Disable packet scrambling for new protocol as it is useless now - Get rid of the old packet scrambling functions predating latest point release - Use Hunk_AllocateTempMemory() for netchan packet queue to fix memory leak when client gets disconnected with packets in the queue - Use Hunk_AllocateTempMemory() for download blocks to fix memory leak when client gets disconnected with download blocks in the queue - Fix SV_RateMsec to account for udp/udp6 packet lengths
Diffstat (limited to 'src/server/sv_snapshot.c')
-rw-r--r-- | src/server/sv_snapshot.c | 126 |
1 files changed, 34 insertions, 92 deletions
diff --git a/src/server/sv_snapshot.c b/src/server/sv_snapshot.c index 590cfd7e..d57acf5c 100644 --- a/src/server/sv_snapshot.c +++ b/src/server/sv_snapshot.c @@ -522,45 +522,6 @@ static void SV_BuildClientSnapshot( client_t *client ) { } } - -/* -==================== -SV_RateMsec - -Return the number of msec a given size message is supposed -to take to clear, based on the current rate -==================== -*/ -#define HEADER_RATE_BYTES 48 // include our header, IP header, and some overhead -static int SV_RateMsec( client_t *client, int messageSize ) { - int rate; - int rateMsec; - - // individual messages will never be larger than fragment size - if ( messageSize > 1500 ) { - messageSize = 1500; - } - rate = client->rate; - if ( sv_maxRate->integer ) { - if ( sv_maxRate->integer < 1000 ) { - Cvar_Set( "sv_MaxRate", "1000" ); - } - if ( sv_maxRate->integer < rate ) { - rate = sv_maxRate->integer; - } - } - if ( sv_minRate->integer ) { - if ( sv_minRate->integer < 1000 ) - Cvar_Set( "sv_minRate", "1000" ); - if ( sv_minRate->integer > rate ) - rate = sv_minRate->integer; - } - - rateMsec = ( messageSize + HEADER_RATE_BYTES ) * 1000 / ((int) (rate * com_timescale->value)); - - return rateMsec; -} - /* ======================= SV_SendMessageToClient @@ -568,48 +529,15 @@ SV_SendMessageToClient Called by SV_SendClientSnapshot and SV_SendClientGameState ======================= */ -void SV_SendMessageToClient( msg_t *msg, client_t *client ) { - int rateMsec; - +void SV_SendMessageToClient(msg_t *msg, client_t *client) +{ // record information about the message client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSize = msg->cursize; client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageSent = svs.time; client->frames[client->netchan.outgoingSequence & PACKET_MASK].messageAcked = -1; // send the datagram - SV_Netchan_Transmit( client, msg ); //msg->cursize, msg->data ); - - // set nextSnapshotTime based on rate and requested number of updates - - // local clients get snapshots every server frame - // TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=491 - // added sv_lanForceRate check - if ( client->netchan.remoteAddress.type == NA_LOOPBACK || (sv_lanForceRate->integer && Sys_IsLANAddress (client->netchan.remoteAddress)) ) { - client->nextSnapshotTime = svs.time + ((int) (1000.0 / sv_fps->integer * com_timescale->value)); - return; - } - - // normal rate / snapshotMsec calculation - rateMsec = SV_RateMsec(client, msg->cursize); - - if ( rateMsec < client->snapshotMsec * com_timescale->value) { - // never send more packets than this, no matter what the rate is at - rateMsec = client->snapshotMsec * com_timescale->value; - client->rateDelayed = qfalse; - } else { - client->rateDelayed = qtrue; - } - - client->nextSnapshotTime = svs.time + ((int) (rateMsec * com_timescale->value)); - - // don't pile up empty snapshots while connecting - if ( client->state != CS_ACTIVE ) { - // a gigantic connection message may have already put the nextSnapshotTime - // more than a second away, so don't shorten it - // do shorten if client is downloading - if (!*client->downloadName && client->nextSnapshotTime < svs.time + ((int) (1000.0 * com_timescale->value))) - client->nextSnapshotTime = svs.time + ((int) (1000 * com_timescale->value)); - } + SV_Netchan_Transmit(client, msg); } @@ -661,33 +589,47 @@ void SV_SendClientSnapshot( client_t *client ) { SV_SendClientMessages ======================= */ -void SV_SendClientMessages( void ) { - int i; +void SV_SendClientMessages(void) +{ + int i; client_t *c; // send a message to each connected client - for (i=0, c = svs.clients ; i < sv_maxclients->integer ; i++, c++) { - if (!c->state) { + for(i=0; i < sv_maxclients->integer; i++) + { + c = &svs.clients[i]; + + if(!c->state) continue; // not connected - } - - if ( svs.time < c->nextSnapshotTime ) { - continue; // not time yet - } if(*c->downloadName) continue; // Client is downloading, don't send snapshots - // send additional message fragments if the last message - // was too large to send at once - if ( c->netchan.unsentFragments ) { - c->nextSnapshotTime = svs.time + - SV_RateMsec( c, c->netchan.unsentLength - c->netchan.unsentFragmentStart ); - SV_Netchan_TransmitNextFragment( c ); - continue; + if(!(c->netchan.remoteAddress.type == NA_LOOPBACK || + (sv_lanForceRate->integer && Sys_IsLANAddress(c->netchan.remoteAddress)))) + { + // rate control for clients not on LAN + + if(svs.time - c->lastSnapshotTime < c->snapshotMsec * com_timescale->value) + continue; // It's not time yet + + if(c->netchan.unsentFragments || c->netchan_start_queue) + { + c->rateDelayed = qtrue; + continue; // Drop this snapshot if the packet queue is still full + } + + if(SV_RateMsec(c) > 0) + { + // Not enough time since last packet passed through the line + c->rateDelayed = qtrue; + continue; + } } // generate and send a new message - SV_SendClientSnapshot( c ); + SV_SendClientSnapshot(c); + c->lastSnapshotTime = svs.time; + c->rateDelayed = qfalse; } } |