summaryrefslogtreecommitdiff
path: root/src/server/sv_snapshot.c
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-07-13 17:11:30 +0000
committerTim Angus <tim@ngus.net>2013-01-10 22:27:30 +0000
commit2bf2118d79994cfd805c3ffb5b421c6a65658b84 (patch)
tree867a9c4ac0d975e7aca4ee20714de8c97646ccde /src/server/sv_snapshot.c
parent5038ffeb97413a867d0bdadf761e2ba727781742 (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.c126
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;
}
}