mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Add network profiling tool from Spearhead and Breakthrough
Profiling can be enabled with `cl_netprofile` and `sv_netprofile`, the overlay can be shown using `cl_netprofileoverlay` and `sv_netprofileoverlay` and the server can dump network profile using the `netprofiledump` command
This commit is contained in:
parent
23a035e2ca
commit
1ef1bad9ae
14 changed files with 871 additions and 66 deletions
|
@ -192,7 +192,9 @@ typedef struct client_s {
|
|||
int snapshotMsec; // requests a snapshot every snapshotMsec unless rate choked
|
||||
int pureAuthentic;
|
||||
qboolean gotCP; // TTimo - additional flag to distinguish between a bad pure checksum, and no cp command at all
|
||||
netchan_t netchan;
|
||||
netchan_t netchan;
|
||||
// Added in 2.0
|
||||
netprofclient_t netprofile;
|
||||
// TTimo
|
||||
// queuing outgoing fragmented messages to send them properly, without udp packet bursts
|
||||
// in case large fragmented messages are stacking up
|
||||
|
@ -319,6 +321,8 @@ typedef struct {
|
|||
#ifndef DEDICATED
|
||||
soundsystemsavegame_t soundSystem;
|
||||
#endif
|
||||
// Added in 2.0
|
||||
netprofclient_t netprofile;
|
||||
} serverStatic_t;
|
||||
|
||||
#define SERVER_MAXBANS 1024
|
||||
|
@ -621,6 +625,10 @@ void SV_Netchan_Transmit( client_t *client, msg_t *msg);
|
|||
int SV_Netchan_TransmitNextFragment( client_t *client );
|
||||
qboolean SV_Netchan_Process( client_t *client, msg_t *msg );
|
||||
void SV_Netchan_FreeQueue(client_t *client);
|
||||
void SV_NET_OutOfBandPrint(netprofclient_t* netprof, netadr_t adr, const char* format, ...);
|
||||
void SV_NET_UpdateClientNetProfileInfo(netprofclient_t* netprofile, int rate);
|
||||
void SV_NET_UpdateAllNetProfileInfo();
|
||||
void SV_NET_CalcTotalNetProfile(netprofclient_t* netprofile, qboolean server);
|
||||
|
||||
//
|
||||
// sv_gamespy.c
|
||||
|
|
|
@ -502,7 +502,7 @@ static void SV_Ban_f( void ) {
|
|||
|
||||
// otherwise send their ip to the authorize server
|
||||
if ( svs.authorizeAddress.type != NA_BAD ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, svs.authorizeAddress,
|
||||
"banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1],
|
||||
cl->netchan.remoteAddress.ip[2], cl->netchan.remoteAddress.ip[3] );
|
||||
Com_Printf("%s was banned from coming back\n", cl->name);
|
||||
|
@ -556,7 +556,7 @@ static void SV_BanNum_f( void ) {
|
|||
|
||||
// otherwise send their ip to the authorize server
|
||||
if ( svs.authorizeAddress.type != NA_BAD ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, svs.authorizeAddress,
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, svs.authorizeAddress,
|
||||
"banUser %i.%i.%i.%i", cl->netchan.remoteAddress.ip[0], cl->netchan.remoteAddress.ip[1],
|
||||
cl->netchan.remoteAddress.ip[2], cl->netchan.remoteAddress.ip[3] );
|
||||
Com_Printf("%s was banned from coming back\n", cl->name);
|
||||
|
@ -1573,6 +1573,120 @@ void SV_LoadLastGame_f( void )
|
|||
Cbuf_AddText( va( "loadgame %s\n", Cvar_Get( "g_lastsave", "", 0 )->string ) );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NetProfileDump_PrintProf
|
||||
=================
|
||||
*/
|
||||
void SV_NetProfileDump_PrintProf(fileHandle_t file, netprofclient_t* netprofile)
|
||||
{
|
||||
size_t totalProcessed;
|
||||
char buffer[2048];
|
||||
|
||||
totalProcessed = netprofile->outPackets.totalProcessed + netprofile->inPackets.totalProcessed;
|
||||
|
||||
Com_sprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"%4i %4i %4i | %3i %3i %3i | %3i %3i %3i | %3i %3i %3i | %7i %7i %7i\n",
|
||||
netprofile->inPackets.packetsPerSec,
|
||||
netprofile->outPackets.packetsPerSec,
|
||||
netprofile->outPackets.packetsPerSec + netprofile->inPackets.packetsPerSec,
|
||||
netprofile->inPackets.percentFragmented,
|
||||
netprofile->outPackets.percentFragmented,
|
||||
(unsigned int)((float)(netprofile->outPackets.numFragmented + netprofile->inPackets.numFragmented) / totalProcessed),
|
||||
netprofile->inPackets.percentDropped,
|
||||
netprofile->outPackets.percentDropped,
|
||||
(unsigned int)((float)(netprofile->outPackets.numDropped + netprofile->inPackets.numDropped) / totalProcessed),
|
||||
netprofile->inPackets.percentDropped,
|
||||
netprofile->outPackets.percentDropped,
|
||||
(unsigned int)((float)(netprofile->outPackets.totalLengthConnectionLess + netprofile->inPackets.totalLengthConnectionLess) / (float)(netprofile->outPackets.totalSize + netprofile->inPackets.totalSize)),
|
||||
netprofile->inPackets.bytesPerSec,
|
||||
netprofile->outPackets.bytesPerSec,
|
||||
netprofile->outPackets.bytesPerSec + netprofile->inPackets.bytesPerSec
|
||||
);
|
||||
|
||||
FS_Write(buffer, strlen(buffer), file);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NetProfileDump_f
|
||||
=================
|
||||
*/
|
||||
void SV_NetProfileDump_f(void)
|
||||
{
|
||||
static fileHandle_t hFile = 0;
|
||||
client_t *client;
|
||||
int i;
|
||||
char buffer[2048];
|
||||
netprofclient_t netproftotal;
|
||||
|
||||
if (!hFile) {
|
||||
hFile = FS_FOpenTextFileWrite("netprofile.log");
|
||||
FS_ForceFlush(hFile);
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "NetProfile.log\n\n");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "Log Format:\n");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
|
||||
Com_sprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Source: Packets per Second In/Out/Total | %%Fragments In/Out/Total | %%Dropped In/Out/Total | %%OOB Data In/Out/Total"
|
||||
" | Data per Second In/Out/Total\n"
|
||||
"\n");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
}
|
||||
|
||||
if (!sv_netprofile->integer) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
if (!com_cl_running->integer || com_sv_running->integer) {
|
||||
#else
|
||||
if (com_sv_running->integer) {
|
||||
#endif
|
||||
Com_sprintf(buffer, sizeof(buffer), "------------------\nServer Net Profile\n");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
SV_NET_CalcTotalNetProfile(&netproftotal, 1);
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "Total: ");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
SV_NetProfileDump_PrintProf(hFile, &netproftotal);
|
||||
|
||||
Com_sprintf(buffer, sizeof(buffer), "Clientless: ");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
SV_NetProfileDump_PrintProf(hFile, &svs.netprofile);
|
||||
|
||||
for (i = 0; i < svs.iNumClients; i++) {
|
||||
client = &svs.clients[i];
|
||||
if (client->state != CS_ACTIVE || !client->gentity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (client->netchan.remoteAddress.type == NA_LOOPBACK) {
|
||||
Com_sprintf(buffer, sizeof(buffer), "#%2i-Loopback: ");
|
||||
} else {
|
||||
Com_sprintf(buffer, sizeof(buffer), "Client #%2i: ");
|
||||
}
|
||||
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
SV_NetProfileDump_PrintProf(hFile, &client->netprofile);
|
||||
}
|
||||
}
|
||||
#ifndef DEDICATED
|
||||
else if (com_cl_running->integer && cl_netprofile->integer) {
|
||||
Com_sprintf(buffer, sizeof(buffer), "------------------\nClient Net Profile\n");
|
||||
FS_Write(buffer, strlen(buffer), hFile);
|
||||
SV_NetProfileDump_PrintProf(hFile, &cls.netprofile);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_ReloadMap_f
|
||||
|
@ -1730,6 +1844,8 @@ void SV_AddOperatorCommands(void) {
|
|||
Cmd_AddCommand("difficultyMedium", SV_MediumMode_f);
|
||||
Cmd_AddCommand("difficultyHard", SV_HardMode_f);
|
||||
|
||||
// Added in 2.0
|
||||
Cmd_AddCommand("netprofiledump", SV_NetProfileDump_f);
|
||||
// Added in 2.30
|
||||
Cmd_AddCommand("reloadmap", SV_ReloadMap_f);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void SV_GetChallenge(netadr_t from)
|
|||
// it's also way more cool this way :)
|
||||
if ( Sys_IsLANAddress( from ) ) {
|
||||
challenge->pingTime = svs.time;
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "challengeResponse %i", challenge->challenge );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "challengeResponse %i", challenge->challenge );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ void SV_GetChallenge(netadr_t from)
|
|||
// mohaa below 2.0 doesn't handle gamespy key
|
||||
// so send the challenge response directly
|
||||
challenge->pingTime = svs.time;
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "challengeResponse %i", challenge->challenge);
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "challengeResponse %i", challenge->challenge);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -106,12 +106,12 @@ void SV_GetChallenge(netadr_t from)
|
|||
// however, it could be an useful feature for a far future
|
||||
// where players could be authenticated
|
||||
challenge->pingTime = svs.time;
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "challengeResponse %i", challenge->challenge);
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "challengeResponse %i", challenge->challenge);
|
||||
return;
|
||||
}
|
||||
|
||||
// check client's cd key
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "getKey %s", challenge->gsChallenge);
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "getKey %s", challenge->gsChallenge);
|
||||
challenge->pingTime = svs.time;
|
||||
}
|
||||
|
||||
|
@ -158,21 +158,21 @@ void SV_AuthorizeIpPacket( netadr_t from ) {
|
|||
|
||||
if ( !Q_stricmp( s, "demo" ) ) {
|
||||
// they are a demo client trying to connect to a real server
|
||||
NET_OutOfBandPrint( NS_SERVER, challengeptr->adr, "print\nServer is not a demo server\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr, "print\nServer is not a demo server\n" );
|
||||
// clear the challenge record so it won't timeout and let them through
|
||||
Com_Memset( challengeptr, 0, sizeof( *challengeptr ) );
|
||||
return;
|
||||
}
|
||||
if ( !Q_stricmp( s, "accept" ) ) {
|
||||
NET_OutOfBandPrint(NS_SERVER, challengeptr->adr,
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr,
|
||||
"challengeResponse %d %d %d", challengeptr->challenge, challengeptr->clientChallenge, com_protocol->integer);
|
||||
return;
|
||||
}
|
||||
if ( !Q_stricmp( s, "unknown" ) ) {
|
||||
if (!r) {
|
||||
NET_OutOfBandPrint( NS_SERVER, challengeptr->adr, "print\nAwaiting CD key authorization\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr, "print\nAwaiting CD key authorization\n" );
|
||||
} else {
|
||||
NET_OutOfBandPrint( NS_SERVER, challengeptr->adr, "print\n%s\n", r);
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr, "print\n%s\n", r);
|
||||
}
|
||||
// clear the challenge record so it won't timeout and let them through
|
||||
Com_Memset( challengeptr, 0, sizeof( *challengeptr ) );
|
||||
|
@ -181,9 +181,9 @@ void SV_AuthorizeIpPacket( netadr_t from ) {
|
|||
|
||||
// authorization failed
|
||||
if (!r) {
|
||||
NET_OutOfBandPrint( NS_SERVER, challengeptr->adr, "print\nSomeone is using this CD Key\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr, "print\nSomeone is using this CD Key\n" );
|
||||
} else {
|
||||
NET_OutOfBandPrint( NS_SERVER, challengeptr->adr, "print\n%s\n", r );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, challengeptr->adr, "print\n%s\n", r );
|
||||
}
|
||||
|
||||
// clear the challenge record so it won't timeout and let them through
|
||||
|
@ -317,7 +317,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
// Check whether this client is banned.
|
||||
if(SV_IsBanned(&from, qfalse))
|
||||
{
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "droperror\nYou are banned from this server.\n");
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nYou are banned from this server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
// Added in 2.30
|
||||
// Only allow breakthrough clients when targeting mohaab
|
||||
if (strcmp(clientType, "Breakthrough")) {
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "droperror\nRequires Medal of Honor Allied Assault Breakthrough\n");
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nRequires Medal of Honor Allied Assault Breakthrough\n");
|
||||
Com_DPrintf(" rejected connect - only Breakthrough clients allowed.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
{
|
||||
if(version != com_protocol->integer)
|
||||
{
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "droperror\nServer uses protocol version %i "
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nServer uses protocol version %i "
|
||||
"(yours is %i).\n", com_protocol->integer, version);
|
||||
Com_DPrintf(" rejected connect from version %i\n", version);
|
||||
return;
|
||||
|
@ -379,7 +379,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
else
|
||||
ip = (char *)NET_AdrToString( from );
|
||||
if( ( strlen( ip ) + strlen( userinfo ) + 4 ) >= MAX_INFO_STRING ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from,
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from,
|
||||
"droperror\nUserinfo string length exceeded. "
|
||||
"Try removing setu cvars from your config.\n" );
|
||||
return;
|
||||
|
@ -403,7 +403,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
|
||||
if (i == MAX_CHALLENGES)
|
||||
{
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "print\nNo or bad challenge for your address.\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "print\nNo or bad challenge for your address.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -420,13 +420,13 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
// never reject a LAN client based on ping
|
||||
if ( !Sys_IsLANAddress( from ) ) {
|
||||
if ( sv_minPing->value && ping < sv_minPing->value ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for high pings only\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "print\nServer is for high pings only\n" );
|
||||
Com_DPrintf ("Client %i rejected on a too low ping\n", i);
|
||||
challengeptr->wasrefused = qtrue;
|
||||
return;
|
||||
}
|
||||
if ( sv_maxPing->value && ping > sv_maxPing->value ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "print\nServer is for low pings only\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "print\nServer is for low pings only\n" );
|
||||
Com_DPrintf ("Client %i rejected on a too high ping\n", i);
|
||||
challengeptr->wasrefused = qtrue;
|
||||
return;
|
||||
|
@ -509,7 +509,7 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "droperror\nServer is full.\n" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\nServer is full.\n" );
|
||||
Com_DPrintf ("Rejected a connection.\n");
|
||||
return;
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ gotnewcl:
|
|||
// get the game a chance to reject this connection or modify the userinfo
|
||||
denied = ge->ClientConnect( clientNum, qtrue, qfalse );
|
||||
if ( denied ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "droperror\n%s\n", denied );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "droperror\n%s\n", denied );
|
||||
Com_DPrintf ( "Game rejected a connection: %s.\n", denied );
|
||||
return;
|
||||
}
|
||||
|
@ -560,8 +560,12 @@ gotnewcl:
|
|||
|
||||
SV_UserinfoChanged( newcl );
|
||||
|
||||
if (sv_netprofile->integer) {
|
||||
SV_NET_UpdateClientNetProfileInfo(&newcl->netprofile, newcl->rate);
|
||||
}
|
||||
|
||||
// send the connect packet to the client
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "connectResponse %d", challenge);
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "connectResponse %d", challenge);
|
||||
|
||||
Com_DPrintf( "Going from CS_FREE to CS_CONNECTED for %s\n", newcl->name );
|
||||
|
||||
|
|
|
@ -530,7 +530,7 @@ void SVC_Status( netadr_t from ) {
|
|||
}
|
||||
}
|
||||
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "statusResponse\n%s\n%s", infostring, status );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "statusResponse\n%s\n%s", infostring, status );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -618,7 +618,7 @@ void SVC_Info( netadr_t from ) {
|
|||
Info_SetValueForKey(infostring, "gamever", com_target_version->string);
|
||||
Info_SetValueForKey(infostring, "serverType", va("%i", com_target_game->integer));
|
||||
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "infoResponse\n%s", infostring );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "infoResponse\n%s", infostring );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -628,7 +628,7 @@ SVC_FlushRedirect
|
|||
================
|
||||
*/
|
||||
static void SV_FlushRedirect( char *outputbuf ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, svs.redirectAddress, "print\n%s", outputbuf );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, svs.redirectAddress, "print\n%s", outputbuf );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -720,6 +720,10 @@ void SV_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
char *s;
|
||||
char *c;
|
||||
|
||||
if (sv_netprofile->integer) {
|
||||
NetProfileAddPacket(&svs.netprofile.inPackets, msg->cursize, NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
|
||||
MSG_BeginReadingOOB( msg );
|
||||
MSG_ReadLong( msg ); // skip the -1 marker
|
||||
|
||||
|
@ -818,7 +822,7 @@ void SV_PacketEvent( netadr_t from, msg_t *msg ) {
|
|||
|
||||
// if we received a sequenced packet from an address we don't recognize,
|
||||
// send an out of band disconnect packet to it
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "disconnect" );
|
||||
SV_NET_OutOfBandPrint( &svs.netprofile, from, "disconnect" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1023,6 +1027,8 @@ void SV_Frame( int msec ) {
|
|||
return;
|
||||
}
|
||||
|
||||
SV_NET_UpdateAllNetProfileInfo();
|
||||
|
||||
// allow pause if only the local client is connected
|
||||
if ( SV_CheckPaused() ) {
|
||||
return;
|
||||
|
|
|
@ -169,7 +169,7 @@ void SV_Netchan_TransmitNextInQueue(client_t *client)
|
|||
SV_Netchan_Encode(client, &netbuf->msg, netbuf->clientCommandString);
|
||||
#endif
|
||||
|
||||
Netchan_Transmit(&client->netchan, netbuf->msg.cursize, netbuf->msg.data);
|
||||
Netchan_Transmit(&client->netchan, netbuf->msg.cursize, netbuf->msg.data, sv_netprofile->integer ? &client->netprofile.outPackets : NULL);
|
||||
|
||||
// pop from queue
|
||||
client->netchan_start_queue = netbuf->next;
|
||||
|
@ -197,7 +197,7 @@ int SV_Netchan_TransmitNextFragment(client_t *client)
|
|||
{
|
||||
if(client->netchan.unsentFragments)
|
||||
{
|
||||
Netchan_TransmitNextFragment(&client->netchan);
|
||||
Netchan_TransmitNextFragment(&client->netchan, sv_netprofile->integer ? &client->netprofile.outPackets : NULL);
|
||||
return SV_RateMsec(client);
|
||||
}
|
||||
else if(client->netchan_start_queue)
|
||||
|
@ -250,7 +250,7 @@ void SV_Netchan_Transmit( client_t *client, msg_t *msg)
|
|||
if(client->compat)
|
||||
SV_Netchan_Encode(client, msg, client->lastClientCommandString);
|
||||
#endif
|
||||
Netchan_Transmit( &client->netchan, msg->cursize, msg->data );
|
||||
Netchan_Transmit(&client->netchan, msg->cursize, msg->data, sv_netprofile->integer ? &client->netprofile.outPackets : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ Netchan_SV_Process
|
|||
*/
|
||||
qboolean SV_Netchan_Process( client_t *client, msg_t *msg ) {
|
||||
int ret;
|
||||
ret = Netchan_Process( &client->netchan, msg );
|
||||
ret = Netchan_Process( &client->netchan, msg, sv_netprofile->integer ? &client->netprofile.inPackets : NULL );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
|
||||
|
@ -273,3 +273,170 @@ qboolean SV_Netchan_Process( client_t *client, msg_t *msg ) {
|
|||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NET_OutOfBandPrint
|
||||
=================
|
||||
*/
|
||||
void SV_NET_OutOfBandPrint(netprofclient_t* netprof, netadr_t adr, const char* format, ...) {
|
||||
va_list argptr;
|
||||
char string[MAX_MSGLEN];
|
||||
|
||||
va_start(argptr, format);
|
||||
Q_vsnprintf(string, sizeof(string), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
NET_OutOfBandPrint(NS_SERVER, adr, "%s", string);
|
||||
|
||||
if (sv_netprofile->integer && netprof) {
|
||||
NetProfileAddPacket(&netprof->outPackets, strlen(string), NETPROF_PACKET_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NET_UpdateClientNetProfileInfo
|
||||
=================
|
||||
*/
|
||||
void SV_NET_UpdateClientNetProfileInfo(netprofclient_t* netprofile, int rate) {
|
||||
int time;
|
||||
|
||||
if (!netprofile->initialized) {
|
||||
memset(netprofile, 0, sizeof(*netprofile));
|
||||
netprofile->initialized = qtrue;
|
||||
}
|
||||
|
||||
if (netprofile->rate != rate) {
|
||||
netprofile->rate = rate;
|
||||
}
|
||||
|
||||
// set the update time
|
||||
time = Com_Milliseconds();
|
||||
|
||||
netprofile->outPackets.updateTime = time;
|
||||
netprofile->inPackets.updateTime = time;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NET_UpdateAllNetProfileInfo
|
||||
=================
|
||||
*/
|
||||
void SV_NET_UpdateAllNetProfileInfo() {
|
||||
client_t *client;
|
||||
int i;
|
||||
|
||||
if (!sv_netprofile->integer) {
|
||||
//
|
||||
// Clear all netprofile fields
|
||||
//
|
||||
|
||||
svs.netprofile.initialized = qfalse;
|
||||
|
||||
for (i = 0; i < svs.iNumClients; i++) {
|
||||
svs.clients[i].netprofile.initialized = qfalse;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SV_NET_UpdateClientNetProfileInfo(&svs.netprofile, sv_maxRate->integer);
|
||||
|
||||
for (i = 0; i < svs.iNumClients; i++) {
|
||||
client = &svs.clients[i];
|
||||
if (client->state != CS_ACTIVE || !client->gentity) {
|
||||
client->netprofile.initialized = qfalse;
|
||||
continue;
|
||||
}
|
||||
|
||||
SV_NET_UpdateClientNetProfileInfo(&client->netprofile, client->rate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_NET_CalcTotalNetProfile
|
||||
=================
|
||||
*/
|
||||
void SV_NET_CalcTotalNetProfile(netprofclient_t* netprofile, qboolean server) {
|
||||
client_t *client;
|
||||
int i;
|
||||
int numValidClients;
|
||||
|
||||
numValidClients = 0;
|
||||
memset(netprofile, 0, sizeof(*netprofile));
|
||||
|
||||
if (server) {
|
||||
NetProfileCalcStats(&svs.netprofile.outPackets, 0);
|
||||
NetProfileCalcStats(&svs.netprofile.inPackets, 0);
|
||||
} else {
|
||||
NetProfileCalcStats(&svs.netprofile.outPackets, 500);
|
||||
NetProfileCalcStats(&svs.netprofile.inPackets, 500);
|
||||
}
|
||||
|
||||
for (i = 0; i < svs.iNumClients; i++) {
|
||||
client = &svs.clients[i];
|
||||
if (client->state != CS_ACTIVE || !client->gentity) {
|
||||
client->netprofile.initialized = qfalse;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (server) {
|
||||
NetProfileCalcStats(&client->netprofile.outPackets, 0);
|
||||
NetProfileCalcStats(&client->netprofile.inPackets, 0);
|
||||
} else {
|
||||
NetProfileCalcStats(&client->netprofile.outPackets, 500);
|
||||
NetProfileCalcStats(&client->netprofile.inPackets, 500);
|
||||
}
|
||||
|
||||
numValidClients++;
|
||||
|
||||
netprofile->rate += client->netprofile.rate;
|
||||
netprofile->outPackets.totalSize += client->netprofile.outPackets.totalSize;
|
||||
netprofile->outPackets.bytesPerSec += client->netprofile.outPackets.bytesPerSec;
|
||||
netprofile->outPackets.numDropped += client->netprofile.outPackets.numDropped;
|
||||
netprofile->outPackets.percentDropped += client->netprofile.outPackets.percentDropped;
|
||||
netprofile->outPackets.percentFragmented += client->netprofile.outPackets.percentFragmented;
|
||||
netprofile->outPackets.numFragmented += client->netprofile.outPackets.numFragmented;
|
||||
netprofile->outPackets.totalLengthConnectionLess += client->netprofile.outPackets.totalLengthConnectionLess;
|
||||
netprofile->outPackets.percentConnectionLess += client->netprofile.outPackets.percentConnectionLess;
|
||||
netprofile->outPackets.totalProcessed += client->netprofile.outPackets.totalProcessed;
|
||||
netprofile->outPackets.packetsPerSec += client->netprofile.outPackets.packetsPerSec;
|
||||
netprofile->inPackets.totalSize += client->netprofile.inPackets.totalSize;
|
||||
netprofile->inPackets.bytesPerSec += client->netprofile.inPackets.bytesPerSec;
|
||||
netprofile->inPackets.numDropped += client->netprofile.inPackets.numDropped;
|
||||
netprofile->inPackets.percentDropped += client->netprofile.inPackets.percentDropped;
|
||||
netprofile->inPackets.percentFragmented += client->netprofile.inPackets.percentFragmented;
|
||||
netprofile->inPackets.numFragmented += client->netprofile.inPackets.numFragmented;
|
||||
netprofile->inPackets.totalLengthConnectionLess += client->netprofile.inPackets.totalLengthConnectionLess;
|
||||
netprofile->inPackets.percentConnectionLess += client->netprofile.inPackets.percentConnectionLess;
|
||||
netprofile->inPackets.totalProcessed += client->netprofile.inPackets.totalProcessed;
|
||||
netprofile->inPackets.packetsPerSec += client->netprofile.inPackets.packetsPerSec;
|
||||
}
|
||||
|
||||
if (numValidClients && netprofile->rate) {
|
||||
netprofile->rate /= numValidClients;
|
||||
}
|
||||
|
||||
netprofile->outPackets.totalSize += svs.netprofile.outPackets.totalSize;
|
||||
netprofile->outPackets.bytesPerSec += svs.netprofile.outPackets.bytesPerSec;
|
||||
netprofile->outPackets.numDropped += svs.netprofile.outPackets.numDropped;
|
||||
netprofile->outPackets.percentDropped += svs.netprofile.outPackets.percentDropped;
|
||||
netprofile->outPackets.percentFragmented += svs.netprofile.outPackets.percentFragmented;
|
||||
netprofile->outPackets.numFragmented += svs.netprofile.outPackets.numFragmented;
|
||||
netprofile->outPackets.totalLengthConnectionLess += svs.netprofile.outPackets.totalLengthConnectionLess;
|
||||
netprofile->outPackets.percentConnectionLess += svs.netprofile.outPackets.percentConnectionLess;
|
||||
netprofile->outPackets.totalProcessed += svs.netprofile.outPackets.totalProcessed;
|
||||
netprofile->outPackets.packetsPerSec += svs.netprofile.outPackets.packetsPerSec;
|
||||
netprofile->inPackets.totalSize += svs.netprofile.inPackets.totalSize;
|
||||
netprofile->inPackets.bytesPerSec += svs.netprofile.inPackets.bytesPerSec;
|
||||
netprofile->inPackets.numDropped += svs.netprofile.inPackets.numDropped;
|
||||
netprofile->inPackets.percentDropped += svs.netprofile.inPackets.percentDropped;
|
||||
netprofile->inPackets.percentFragmented += svs.netprofile.inPackets.percentFragmented;
|
||||
netprofile->inPackets.numFragmented += svs.netprofile.inPackets.numFragmented;
|
||||
netprofile->inPackets.totalLengthConnectionLess += svs.netprofile.inPackets.totalLengthConnectionLess;
|
||||
netprofile->inPackets.percentConnectionLess += svs.netprofile.inPackets.percentConnectionLess;
|
||||
netprofile->inPackets.totalProcessed += svs.netprofile.inPackets.totalProcessed;
|
||||
netprofile->inPackets.packetsPerSec += svs.netprofile.inPackets.packetsPerSec;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue