diff options
author | Thilo Schulz <arny@ats.s.bawue.de> | 2011-07-12 11:01:20 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-10 21:57:40 +0000 |
commit | 3bd2ba9e590cb882b684b1eb4b2650b1a4c94f7f (patch) | |
tree | 277a7efa735dfa9854d5e41199b65ef48f0043c2 /src/server/sv_client.c | |
parent | c22cbd3e5552c0599dad9d60c1ea80a56b48f883 (diff) |
- Greatly improve UDP downloading speed for clients - Add download rate control cvar sv_dlRate - Don't send snapshots to downloading clients
Diffstat (limited to 'src/server/sv_client.c')
-rw-r--r-- | src/server/sv_client.c | 134 |
1 files changed, 68 insertions, 66 deletions
diff --git a/src/server/sv_client.c b/src/server/sv_client.c index 082c0417..8ff3f0a1 100644 --- a/src/server/sv_client.c +++ b/src/server/sv_client.c @@ -646,21 +646,19 @@ static void SV_BeginDownload_f( client_t *cl ) { SV_WriteDownloadToClient Check to see if the client wants a file, open it if needed and start pumping the client -Fill up msg with data +Fill up msg with data, return number of download blocks added ================== */ -void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) +int SV_WriteDownloadToClient(client_t *cl, msg_t *msg) { int curindex; - int rate; - int blockspersnap; int unreferenced = 1; char errorMessage[1024]; char pakbuf[MAX_QPATH], *pakptr; int numRefPaks; if (!*cl->downloadName) - return; // Nothing being downloaded + return 0; // Nothing being downloaded if(!cl->download) { @@ -736,7 +734,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) if(cl->download) FS_FCloseFile(cl->download); - return; + return 0; } Com_Printf( "clientDownload: %d : beginning \"%s\"\n", (int) (cl - svs.clients), cl->downloadName ); @@ -781,81 +779,85 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg ) cl->downloadEOF = qtrue; // We have added the EOF block } - // Loop up to window size times based on how many blocks we can fit in the - // client snapMsec and rate + if (cl->downloadClientBlock == cl->downloadCurrentBlock) + return 0; // Nothing to transmit - // based on the rate, how many bytes can we fit in the snapMsec time of the client - // normal rate / snapshotMsec calculation - rate = cl->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; + // Write out the next section of the file, if we have already reached our window, + // automatically start retransmitting + if (cl->downloadXmitBlock == cl->downloadCurrentBlock) + { + // We have transmitted the complete window, should we start resending? + if (svs.time - cl->downloadSendTime > 1000) + cl->downloadXmitBlock = cl->downloadClientBlock; + else + return 0; } - if (!rate) { - blockspersnap = 1; - } else { - blockspersnap = ( (rate * cl->snapshotMsec) / 1000 + MAX_DOWNLOAD_BLKSIZE ) / - MAX_DOWNLOAD_BLKSIZE; - } + // Send current block + curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW); - if (blockspersnap < 0) - blockspersnap = 1; + MSG_WriteByte( msg, svc_download ); + MSG_WriteShort( msg, cl->downloadXmitBlock ); - while (blockspersnap--) { + // block zero is special, contains file size + if ( cl->downloadXmitBlock == 0 ) + MSG_WriteLong( msg, cl->downloadSize ); - // Write out the next section of the file, if we have already reached our window, - // automatically start retransmitting + MSG_WriteShort( msg, cl->downloadBlockSize[curindex] ); - if (cl->downloadClientBlock == cl->downloadCurrentBlock) - return; // Nothing to transmit + // Write the block + if(cl->downloadBlockSize[curindex]) + MSG_WriteData(msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex]); - if (cl->downloadXmitBlock == cl->downloadCurrentBlock) { - // We have transmitted the complete window, should we start resending? + Com_DPrintf( "clientDownload: %d : writing block %d\n", (int) (cl - svs.clients), cl->downloadXmitBlock ); - //FIXME: This uses a hardcoded one second timeout for lost blocks - //the timeout should be based on client rate somehow - if (svs.time - cl->downloadSendTime > 1000) - cl->downloadXmitBlock = cl->downloadClientBlock; - else - return; - } + // Move on to the next block + // It will get sent with next snap shot. The rate will keep us in line. + cl->downloadXmitBlock++; + cl->downloadSendTime = svs.time; - // Send current block - curindex = (cl->downloadXmitBlock % MAX_DOWNLOAD_WINDOW); + return 1; +} - MSG_WriteByte( msg, svc_download ); - MSG_WriteShort( msg, cl->downloadXmitBlock ); +/* +================== +SV_SendDownloadMessages - // block zero is special, contains file size - if ( cl->downloadXmitBlock == 0 ) - MSG_WriteLong( msg, cl->downloadSize ); - - MSG_WriteShort( msg, cl->downloadBlockSize[curindex] ); +Send download messages to all clients +================== +*/ - // Write the block - if ( cl->downloadBlockSize[curindex] ) { - MSG_WriteData( msg, cl->downloadBlocks[curindex], cl->downloadBlockSize[curindex] ); +int SV_SendDownloadMessages(void) +{ + int i, numDLs = 0, retval; + client_t *cl; + msg_t msg; + byte msgBuffer[MAX_MSGLEN]; + + for(i=0, cl = svs.clients ; i < sv_maxclients->integer ; i++, cl++) + { + if(cl->state && *cl->downloadName) + { + if(cl->netchan.unsentFragments) + SV_Netchan_TransmitNextFragment(cl); + else + { + MSG_Init(&msg, msgBuffer, sizeof(msgBuffer)); + MSG_WriteLong(&msg, cl->lastClientCommand); + + retval = SV_WriteDownloadToClient(cl, &msg); + + if(retval) + { + MSG_WriteByte(&msg, svc_EOF); + SV_Netchan_Transmit(cl, &msg); + numDLs += retval; + } + } } - - Com_DPrintf( "clientDownload: %d : writing block %d\n", (int) (cl - svs.clients), cl->downloadXmitBlock ); - - // Move on to the next block - // It will get sent with next snap shot. The rate will keep us in line. - cl->downloadXmitBlock++; - - cl->downloadSendTime = svs.time; } + + return numDLs; } #ifdef USE_VOIP |