summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-07-15 16:51:54 +0000
committerTim Angus <tim@ngus.net>2013-01-10 22:29:59 +0000
commit46aaeb56660ef727c30841718331fef45e8377be (patch)
tree02134c1b7aa6bca7ed85983b89246b95a8d13e45 /src/server
parentf5712eeab32ebbd4b283d1031cd37eaa12573596 (diff)
Move rate limiting / queued packet sending logic from Com_Frame() to sv_main.c
Diffstat (limited to 'src/server')
-rw-r--r--src/server/server.h3
-rw-r--r--src/server/sv_init.c1
-rw-r--r--src/server/sv_main.c81
3 files changed, 85 insertions, 0 deletions
diff --git a/src/server/server.h b/src/server/server.h
index 9fcce725..3f3c2a3b 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -272,6 +272,7 @@ extern cvar_t *sv_mapChecksum;
extern cvar_t *sv_serverid;
extern cvar_t *sv_minRate;
extern cvar_t *sv_maxRate;
+extern cvar_t *sv_dlRate;
extern cvar_t *sv_minPing;
extern cvar_t *sv_maxPing;
extern cvar_t *sv_pure;
@@ -338,6 +339,8 @@ void SV_ExecuteClientCommand( client_t *cl, const char *s, qboolean clientOK );
void SV_ClientThink (client_t *cl, usercmd_t *cmd);
int SV_WriteDownloadToClient(client_t *cl , msg_t *msg);
+int SV_SendDownloadMessages(void);
+int SV_SendQueuedMessages(void);
#ifdef USE_VOIP
void SV_WriteVoipToClient( client_t *cl, msg_t *msg );
diff --git a/src/server/sv_init.c b/src/server/sv_init.c
index 4c0ae128..c5d11e74 100644
--- a/src/server/sv_init.c
+++ b/src/server/sv_init.c
@@ -634,6 +634,7 @@ void SV_Init (void)
sv_minRate = Cvar_Get ("sv_minRate", "0", CVAR_ARCHIVE | CVAR_SERVERINFO );
sv_maxRate = Cvar_Get ("sv_maxRate", "0", CVAR_ARCHIVE | CVAR_SERVERINFO );
+ sv_dlRate = Cvar_Get("sv_dlRate", "100", CVAR_ARCHIVE | CVAR_SERVERINFO);
sv_minPing = Cvar_Get ("sv_minPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO );
sv_maxPing = Cvar_Get ("sv_maxPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO );
diff --git a/src/server/sv_main.c b/src/server/sv_main.c
index 166e2241..fdd7127b 100644
--- a/src/server/sv_main.c
+++ b/src/server/sv_main.c
@@ -51,6 +51,7 @@ cvar_t *sv_mapChecksum;
cvar_t *sv_serverid;
cvar_t *sv_minRate;
cvar_t *sv_maxRate;
+cvar_t *sv_dlRate;
cvar_t *sv_minPing;
cvar_t *sv_maxPing;
cvar_t *sv_pure;
@@ -1188,3 +1189,83 @@ int SV_RateMsec(client_t *client)
else
return rateMsec - rate;
}
+
+/*
+====================
+SV_SendQueuedPackets
+
+Send download messages and queued packets in the time that we're idle, i.e.
+not computing a server frame or sending client snapshots.
+Return the time in msec until we expect to be called next
+====================
+*/
+
+int SV_SendQueuedPackets()
+{
+ int numBlocks;
+ int dlStart, deltaT, delayT;
+ static int dlNextRound = 0;
+ int timeVal = INT_MAX;
+
+ // Send out fragmented packets now that we're idle
+ delayT = SV_SendQueuedMessages();
+ if(delayT >= 0)
+ timeVal = delayT;
+
+ if(sv_dlRate->integer)
+ {
+ // Rate limiting. This is very imprecise for high
+ // download rates due to millisecond timedelta resolution
+ dlStart = Sys_Milliseconds();
+ deltaT = dlNextRound - dlStart;
+
+ if(deltaT > 0)
+ {
+ if(deltaT < timeVal)
+ timeVal = deltaT + 1;
+ }
+ else
+ {
+ numBlocks = SV_SendDownloadMessages();
+
+ if(numBlocks)
+ {
+ // There are active downloads
+ deltaT = Sys_Milliseconds() - dlStart;
+
+ delayT = 1000 * numBlocks * MAX_DOWNLOAD_BLKSIZE;
+ delayT /= sv_dlRate->integer * 1024;
+
+ if(delayT <= deltaT + 1)
+ {
+ // Sending the last round of download messages
+ // took too long for given rate, don't wait for
+ // next round, but always enforce a 1ms delay
+ // between DL message rounds so we don't hog
+ // all of the bandwidth. This will result in an
+ // effective maximum rate of 1MB/s per user, but the
+ // low download window size limits this anyways.
+ if(timeVal > 2)
+ timeVal = 2;
+
+ dlNextRound = dlStart + deltaT + 1;
+ }
+ else
+ {
+ dlNextRound = dlStart + delayT;
+ delayT -= deltaT;
+
+ if(delayT < timeVal)
+ timeVal = delayT;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(SV_SendDownloadMessages())
+ timeVal = 0;
+ }
+
+ return timeVal;
+}