[Server] Faster download
diff --git a/src/engine/API/serverClient_api.hpp b/src/engine/API/serverClient_api.hpp
index 051ce73..9e284d7 100644
--- a/src/engine/API/serverClient_api.hpp
+++ b/src/engine/API/serverClient_api.hpp
@@ -47,6 +47,8 @@ public:
virtual void DirectConnect( netadr_t from ) = 0;
virtual void ExecuteClientMessage( client_t* cl, msg_t* msg ) = 0;
virtual void AuthorizeIpPacket( netadr_t from ) = 0;
+ virtual sint SendQueuedMessages( void ) = 0;
+ virtual sint SendDownloadMessages( void ) = 0;
};
extern idServerClientSystem* serverClientSystem;
diff --git a/src/engine/API/serverMain_api.hpp b/src/engine/API/serverMain_api.hpp
index 4664526..d8c9720 100644
--- a/src/engine/API/serverMain_api.hpp
+++ b/src/engine/API/serverMain_api.hpp
@@ -58,6 +58,8 @@ public:
virtual void PacketEvent( netadr_t from, msg_t* msg ) = 0;
virtual void Frame( sint msec ) = 0;
virtual sint LoadTag( pointer mod_name ) = 0;
+ virtual sint RateMsec( client_t* client ) = 0;
+ virtual sint SendQueuedPackets( void ) = 0;
};
extern idServerMainSystem* serverMainSystem;
diff --git a/src/engine/framework/NetworkChain.cpp b/src/engine/framework/NetworkChain.cpp
index 360e003..5979709 100644
--- a/src/engine/framework/NetworkChain.cpp
+++ b/src/engine/framework/NetworkChain.cpp
@@ -246,7 +246,6 @@ void idNetworkChainSystemLocal::Transmit( netchan_t* chan, sint length, const uc
chan->lastSentTime = idsystem->Milliseconds();
chan->lastSentSize = send.cursize;
-
if( showpackets->integer )
{
Com_Printf( "%s send %4i : s=%i ack=%i\n"
diff --git a/src/engine/server/server.hpp b/src/engine/server/server.hpp
index 3fcae9c..2b5ee7c 100644
--- a/src/engine/server/server.hpp
+++ b/src/engine/server/server.hpp
@@ -548,6 +548,7 @@ extern convar_t* sv_mapname;
extern convar_t* sv_mapChecksum;
extern convar_t* sv_serverid;
extern convar_t* sv_maxRate;
+extern convar_t* sv_dlRate;
extern convar_t* sv_minPing;
extern convar_t* sv_maxPing;
diff --git a/src/engine/server/serverClient.cpp b/src/engine/server/serverClient.cpp
index 802fefb..4be3661 100644
--- a/src/engine/server/serverClient.cpp
+++ b/src/engine/server/serverClient.cpp
@@ -1558,10 +1558,7 @@ void idServerClientSystemLocal::WriteDownloadToClient( client_t* cl, msg_t* msg
if( cl->downloadXmitBlock == cl->downloadCurrentBlock )
{
// We have transmitted the complete window, should we start resending?
-
- //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 )
+ if( svs.time - cl->downloadSendTime > MAX_DOWNLOAD_BLKSIZE * 1000 / rate )
{
cl->downloadXmitBlock = cl->downloadClientBlock;
}
@@ -1602,6 +1599,84 @@ void idServerClientSystemLocal::WriteDownloadToClient( client_t* cl, msg_t* msg
}
/*
+==================
+idServerClientSystemLocal::SendQueuedMessages
+
+Send one round of fragments, or queued messages to all clients that have data pending.
+Return the shortest time interval for sending next packet to client
+==================
+*/
+sint idServerClientSystemLocal::SendQueuedMessages( void )
+{
+ sint i, retVal = -1, nextFragTime;
+ client_t* cl;
+
+ for( i = 0; i < sv_maxclients->integer; i++ )
+ {
+ cl = &svs.clients[i];
+
+ if( cl->state && cl->netchan.unsentFragments )
+ {
+ nextFragTime = serverMainSystem->RateMsec( cl );
+
+ if( !nextFragTime )
+ {
+ networkChainSystem->TransmitNextFragment( &cl->netchan );
+ nextFragTime = serverMainSystem->RateMsec( cl );
+ }
+
+ if( nextFragTime >= 0 && ( retVal == -1 || retVal > nextFragTime ) )
+ {
+ retVal = nextFragTime;
+ }
+ }
+ }
+
+ return retVal;
+}
+
+
+/*
+==================
+idServerClientSystemLocal::SendDownloadMessages
+
+Send one round of download messages to all clients
+==================
+*/
+sint idServerClientSystemLocal::SendDownloadMessages( void )
+{
+ sint i, numDownloads = 0;
+ client_t* client;
+ msg_t message;
+ uchar8 messageBuffer[MAX_MSGLEN];
+
+ for( i = 0; i < sv_maxclients->integer; i++ )
+ {
+ client = &svs.clients[i];
+
+ if( client->state && *client->downloadName )
+ {
+ sint basesize;
+
+ MSG_Init( &message, messageBuffer, sizeof( messageBuffer ) );
+ MSG_WriteLong( &message, client->lastClientCommand );
+
+ basesize = message.cursize;
+ serverClientLocal.WriteDownloadToClient( client, &message );
+
+ if( message.cursize != basesize )
+ {
+ serverSnapshotSystem->SendMessageToClient( &message, client );
+ numDownloads++;
+ }
+ }
+ }
+
+ return numDownloads;
+}
+
+
+/*
=================
idServerClientSystemLocal::Disconnect_f
@@ -1613,9 +1688,12 @@ void idServerClientSystemLocal::Disconnect_f( client_t* cl )
if( cmdSystem->Argc() > 1 )
{
valueType reason[MAX_STRING_CHARS] = { 0 };
+
Q_strncpyz( reason, cmdSystem->Argv( 1 ), sizeof( reason ) );
Q_strstrip( reason, "\r\n;\"", nullptr );
+
serverClientLocal.DropClient( cl, "disconnected" );
+
( cl, va( "disconnected: %s", reason ) );
}
else
diff --git a/src/engine/server/serverClient.hpp b/src/engine/server/serverClient.hpp
index cfe84f3..303e67f 100644
--- a/src/engine/server/serverClient.hpp
+++ b/src/engine/server/serverClient.hpp
@@ -58,6 +58,8 @@ public:
virtual void DirectConnect( netadr_t from );
virtual void ExecuteClientMessage( client_t* cl, msg_t* msg );
virtual void AuthorizeIpPacket( netadr_t from );
+ virtual sint SendQueuedMessages( void );
+ virtual sint SendDownloadMessages( void );
public:
static valueType* isClientBanned( valueType* ip, valueType* password );
diff --git a/src/engine/server/serverInit.cpp b/src/engine/server/serverInit.cpp
index 0875893..9bba6f0 100644
--- a/src/engine/server/serverInit.cpp
+++ b/src/engine/server/serverInit.cpp
@@ -1069,6 +1069,7 @@ void idServerInitSystemLocal::Init( void )
sv_maxRate = cvarSystem->Get( "sv_maxRate", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, "Option to force all clients to play with a max rate. This can be used to limit the advantage of low pings, or to cap bandwidth utilization for a server. Note that rate is ignored for clients that are on the same LAN." );
sv_minPing = cvarSystem->Get( "sv_minPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, "Set the minimum ping aloud on the server to keep low pings out" );
sv_maxPing = cvarSystem->Get( "sv_maxPing", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, "Set the maximum ping allowed on the server to keep high pings out" );
+ sv_dlRate = cvarSystem->Get( "sv_dlRate", "100", CVAR_ARCHIVE | CVAR_SERVERINFO, "Bandwidth allotted to PK3 file downloads via UDP, in kbyte / s" );
sv_floodProtect = cvarSystem->Get( "sv_floodProtect", "1", CVAR_ARCHIVE | CVAR_SERVERINFO, "Whether or not to use flood protection, preventing clients from sending numerous consecutive commands to the server." );
sv_allowAnonymous = cvarSystem->Get( "sv_allowAnonymous", "0", CVAR_SERVERINFO, "Allow anonymous connections in the server" );
sv_friendlyFire = cvarSystem->Get( "g_friendlyFire", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, "Toggles wether players can damage their teammates" ); // NERVE - SMF
diff --git a/src/engine/server/serverMain.cpp b/src/engine/server/serverMain.cpp
index ea6adb6..8ef19dc 100644
--- a/src/engine/server/serverMain.cpp
+++ b/src/engine/server/serverMain.cpp
@@ -75,6 +75,7 @@ convar_t* sv_serverid;
[... diff too long, it was truncated ...]
GitHub
sha: ce552356