[raknet] Implement StatisticsToString

This commit is contained in:
RD42 2023-11-26 23:36:18 +08:00
parent c36a9147bb
commit 66a3722fbf
2 changed files with 362 additions and 0 deletions

217
raknet/RakNetStatistics.cpp Normal file
View File

@ -0,0 +1,217 @@
/// \file
///
/// This file is part of RakNet Copyright 2003 Kevin Jenkins.
///
/// Usage of RakNet is subject to the appropriate license agreement.
/// Creative Commons Licensees are subject to the
/// license found at
/// http://creativecommons.org/licenses/by-nc/2.5/
/// Single application licensees are subject to the license found at
/// http://www.rakkarsoft.com/SingleApplicationLicense.html
/// Custom license users are subject to the terms therein.
/// GPL license users are subject to the GNU General Public
/// License as published by the Free
/// Software Foundation; either version 2 of the License, or (at your
/// option) any later version.
#include "RakNetStatistics.h"
#include <stdio.h> // sprintf
#include "GetTime.h"
#define BITS_TO_BYTES(x) (((x)+7)>>3)
RakNetTime connectionStartTimeSaved=0;
uint64_t totalBitsSentSaved=0;
uint64_t bitsReceivedSaved=0;
// Verbosity level currently supports 0 (low), 1 (medium), 2 (high)
// Buffer must be hold enough to hold the output string. See the source to get an idea of how many bytes will be output
void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityLevel )
{
if ( s == 0 )
{
sprintf( buffer, "stats is a NULL pointer in statsToString\n" );
return ;
}
switch ( verbosityLevel )
{
case 1:
{
RakNetTime time = RakNet::GetTime();
double elapsedTime;
double bpsSent;
double bpsReceived;
if ( connectionStartTimeSaved == 0 )
connectionStartTimeSaved = s->connectionStartTime;
elapsedTime = (time-connectionStartTimeSaved) / 1000.0f;
bpsSent = (double) ((unsigned)s->totalBitsSent-totalBitsSentSaved) / elapsedTime;
bpsReceived = (double) ((unsigned)s->bitsReceived-bitsReceivedSaved) / elapsedTime;
totalBitsSentSaved = s->totalBitsSent;
bitsReceivedSaved = s->bitsReceived;
connectionStartTimeSaved = RakNet::GetTime();
// Verbosity level 1
sprintf( buffer,
"Messages in Send buffer: %u\n"
"Messages sent: %u\n"
"Bytes sent: %u\n"
"Acks sent: %u\n"
"Acks in send buffer: %u\n"
"Messages waiting for ack: %u\n"
"Messages resent: %u\n"
"Bytes resent: %u\n"
"Packetloss: %.1f%%\n"
"Messages received: %u\n"
"Bytes received: %u\n"
"Acks received: %u\n"
"Duplicate acks received: %u\n"
"Inst. KBits per second: %.1f\n"
"KBits per second sent: %.1f\n"
"KBits per second received: %.1f\n",
s->messageSendBuffer[ SYSTEM_PRIORITY ] + s->messageSendBuffer[ HIGH_PRIORITY ] + s->messageSendBuffer[ MEDIUM_PRIORITY ] + s->messageSendBuffer[ LOW_PRIORITY ],
s->messagesSent[ SYSTEM_PRIORITY ] + s->messagesSent[ HIGH_PRIORITY ] + s->messagesSent[ MEDIUM_PRIORITY ] + s->messagesSent[ LOW_PRIORITY ],
( unsigned ) BITS_TO_BYTES( s->totalBitsSent ),
s->acknowlegementsSent,
s->acknowlegementsPending,
s->messagesOnResendQueue,
s->messageResends,
( unsigned ) BITS_TO_BYTES( s->messagesTotalBitsResent ),
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
s->duplicateMessagesReceived + s->invalidMessagesReceived + s->messagesReceived,
( unsigned ) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
s->acknowlegementsReceived,
s->duplicateAcknowlegementsReceived,
s->bitsPerSecond / 1000.0,
bpsSent / 1000.0,
bpsReceived / 1000.0);
break;
}
case 2:
{
RakNetTime time = RakNet::GetTime();
double elapsedTime;
double bpsSent;
double bpsReceived;
elapsedTime = (time-s->connectionStartTime) / 1000.0f;
bpsSent = (double) s->totalBitsSent / elapsedTime;
bpsReceived= (double) s->bitsReceived / elapsedTime;
// Verbosity level 2.
sprintf( buffer,
"Bytes sent:\t\t\t\t%u\n"
"Messages in send buffer:\t\tSP:%u HP:%u MP:%u LP:%u\n"
"Messages sent:\t\t\t\tSP:%u HP:%u MP:%u LP:%u\n"
"Message data bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
"Message header bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
"Message total bytes sent:\t\tSP:%u HP:%u MP:%u LP:%u\n"
"Bytes received:\t\t\t\tTtl:%u Good:%u Bad:%u\n"
"Packets received:\t\t\tTtl:%u Good:%u Bad:%u\n"
"Acks received:\t\t\t\tTtl:%u Good:%u Dup:%u\n"
"Messages received:\t\t\tTotal:%u Valid:%u Invalid:%u Dup:%u\n"
"Packetloss:\t\t\t\t%.1f%%\n"
"Packets sent:\t\t\t\t%u\n"
"Acks sent:\t\t\t\t%u\n"
"Acks in send buffer:\t\t\t%u\n"
"Messages waiting for ack:\t\t%u\n"
"Ack bytes sent:\t\t\t\t%u\n"
"Sent packets containing only acks:\t%u\n"
"Sent packets w/only acks and resends:\t%u\n"
"Reliable messages resent:\t\t%u\n"
"Reliable message data bytes resent:\t%u\n"
"Reliable message header bytes resent:\t%u\n"
"Reliable message total bytes resent:\t%u\n"
"Number of messages split:\t\t%u\n"
"Number of messages unsplit:\t\t%u\n"
"Message splits performed:\t\t%u\n"
"Additional encryption bytes:\t\t%u\n"
"Sequenced messages out of order:\t%u\n"
"Sequenced messages in order:\t\t%u\n"
"Ordered messages out of order:\t\t%u\n"
"Ordered messages in of order:\t\t%u\n"
"Split messages waiting for reassembly:\t%u\n"
"Messages in internal output queue:\t%u\n"
"Inst KBits per second:\t\t\t%.1f\n"
"Elapsed time (sec):\t\t\t%.1f\n"
"KBits per second sent:\t\t\t%.1f\n"
"KBits per second received:\t\t%.1f\n",
BITS_TO_BYTES( s->totalBitsSent ),
s->messageSendBuffer[ SYSTEM_PRIORITY ], s->messageSendBuffer[ HIGH_PRIORITY ], s->messageSendBuffer[ MEDIUM_PRIORITY ], s->messageSendBuffer[ LOW_PRIORITY ],
s->messagesSent[ SYSTEM_PRIORITY ], s->messagesSent[ HIGH_PRIORITY ], s->messagesSent[ MEDIUM_PRIORITY ], s->messagesSent[ LOW_PRIORITY ],
BITS_TO_BYTES( s->messageDataBitsSent[ SYSTEM_PRIORITY ] ), BITS_TO_BYTES( s->messageDataBitsSent[ HIGH_PRIORITY ] ), BITS_TO_BYTES( s->messageDataBitsSent[ MEDIUM_PRIORITY ] ), BITS_TO_BYTES( s->messageDataBitsSent[ LOW_PRIORITY ] ),
BITS_TO_BYTES( s->messageTotalBitsSent[ SYSTEM_PRIORITY ] - s->messageDataBitsSent[ SYSTEM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ HIGH_PRIORITY ] - s->messageDataBitsSent[ HIGH_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ MEDIUM_PRIORITY ] - s->messageDataBitsSent[ MEDIUM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ LOW_PRIORITY ] - s->messageDataBitsSent[ LOW_PRIORITY ] ),
BITS_TO_BYTES( s->messageTotalBitsSent[ SYSTEM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ HIGH_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ MEDIUM_PRIORITY ] ), BITS_TO_BYTES( s->messageTotalBitsSent[ LOW_PRIORITY ] ),
BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ), BITS_TO_BYTES( s->bitsReceived ), BITS_TO_BYTES( s->bitsWithBadCRCReceived ),
s->packetsReceived + s->packetsWithBadCRCReceived, s->packetsReceived, s->packetsWithBadCRCReceived,
s->acknowlegementsReceived + s->duplicateAcknowlegementsReceived, s->acknowlegementsReceived, s->duplicateAcknowlegementsReceived,
s->messagesReceived + s->invalidMessagesReceived + s->duplicateMessagesReceived, s->messagesReceived, s->invalidMessagesReceived, s->duplicateMessagesReceived,
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
s->packetsSent,
s->acknowlegementsSent,
s->acknowlegementsPending,
s->messagesOnResendQueue,
BITS_TO_BYTES( s->acknowlegementBitsSent ),
s->packetsContainingOnlyAcknowlegements,
s->packetsContainingOnlyAcknowlegementsAndResends,
s->messageResends,
BITS_TO_BYTES( s->messageDataBitsResent ),
BITS_TO_BYTES( s->messagesTotalBitsResent - s->messageDataBitsResent ),
BITS_TO_BYTES( s->messagesTotalBitsResent ),
s->numberOfSplitMessages,
s->numberOfUnsplitMessages,
s->totalSplits,
BITS_TO_BYTES( s->encryptionBitsSent ),
s->sequencedMessagesOutOfOrder,
s->sequencedMessagesInOrder,
s->orderedMessagesOutOfOrder,
s->orderedMessagesInOrder,
s->messagesWaitingForReassembly,
s->internalOutputQueueSize,
s->bitsPerSecond/1000.0,
elapsedTime,
bpsSent / 1000.0,
bpsReceived / 1000.0
);
break;
}
case 4:
{
sprintf( buffer,
"Messages in Send buffer: %u\n"
"Messages sent: %u\n"
"Bytes sent: %u\n"
"Acks sent: %u\n"
"Acks in send buffer: %u\n"
"Messages waiting for ack: %u\n"
"Messages resent: %u\n"
"Bytes resent: %u\n"
"Packetloss: %.1f%%\n"
"Messages received: %u\n"
"Bytes received: %u\n"
"Acks received: %u\n"
"Duplicate acks received: %u\n",
s->messageSendBuffer[ SYSTEM_PRIORITY ] + s->messageSendBuffer[ HIGH_PRIORITY ] + s->messageSendBuffer[ MEDIUM_PRIORITY ] + s->messageSendBuffer[ LOW_PRIORITY ],
s->messagesSent[ SYSTEM_PRIORITY ] + s->messagesSent[ HIGH_PRIORITY ] + s->messagesSent[ MEDIUM_PRIORITY ] + s->messagesSent[ LOW_PRIORITY ],
( unsigned ) BITS_TO_BYTES( s->totalBitsSent ),
s->acknowlegementsSent,
s->acknowlegementsPending,
s->messagesOnResendQueue,
s->messageResends,
( unsigned ) BITS_TO_BYTES( s->messagesTotalBitsResent ),
100.0f * ( float ) s->messagesTotalBitsResent / ( float ) s->totalBitsSent,
s->duplicateMessagesReceived + s->invalidMessagesReceived + s->messagesReceived,
( unsigned ) BITS_TO_BYTES( s->bitsReceived + s->bitsWithBadCRCReceived ),
s->acknowlegementsReceived,
s->duplicateAcknowlegementsReceived);
break;
}
}
}

145
raknet/RakNetStatistics.h Normal file
View File

@ -0,0 +1,145 @@
/// \file
/// \brief A structure that holds all statistical data returned by RakNet.
///
/// This file is part of RakNet Copyright 2003 Kevin Jenkins.
///
/// Usage of RakNet is subject to the appropriate license agreement.
/// Creative Commons Licensees are subject to the
/// license found at
/// http://creativecommons.org/licenses/by-nc/2.5/
/// Single application licensees are subject to the license found at
/// http://www.rakkarsoft.com/SingleApplicationLicense.html
/// Custom license users are subject to the terms therein.
/// GPL license users are subject to the GNU General Public
/// License as published by the Free
/// Software Foundation; either version 2 of the License, or (at your
/// option) any later version.
#ifndef __RAK_NET_STATISTICS_H
#define __RAK_NET_STATISTICS_H
#include "PacketPriority.h"
#include "Export.h"
#include "NetworkTypes.h"
typedef unsigned long long uint64_t;
/*
RakNetStatisticsStruct sizes
saco 296u
server W 312u L 296u
npc W 296u L 296u
*/
/// \brief Network Statisics Usage
///
/// Store Statistics information related to network usage
struct RAK_DLL_EXPORT RakNetStatisticsStruct
{
// TODO: RakNetStatisticsStruct
/// Number of Messages in the send Buffer (high, medium, low priority)
unsigned messageSendBuffer[ NUMBER_OF_PRIORITIES ];
/// Number of messages sent (high, medium, low priority)
unsigned messagesSent[ NUMBER_OF_PRIORITIES ];
char _gap20[16];
/// Number of data bits used for user messages
uint64_t messageDataBitsSent[ NUMBER_OF_PRIORITIES ];
/// Number of total bits used for user messages, including headers
uint64_t messageTotalBitsSent[ NUMBER_OF_PRIORITIES ];
/// Number of packets sent containing only acknowledgements
unsigned packetsContainingOnlyAcknowlegements;
/// Number of acknowledgements sent
unsigned acknowlegementsSent;
/// Number of acknowledgements waiting to be sent
unsigned acknowlegementsPending;
#if defined(_WIN32) && defined(SAMPSRV)
unsigned field_7C;
#endif
/// Number of acknowledgements bits sent
uint64_t acknowlegementBitsSent;
/// Number of packets containing only acknowledgements and resends
unsigned packetsContainingOnlyAcknowlegementsAndResends;
/// Number of messages resent
unsigned messageResends;
/// Number of bits resent of actual data
uint64_t messageDataBitsResent;
/// Total number of bits resent, including headers
uint64_t messagesTotalBitsResent;
/// Number of messages waiting for ack (// TODO - rename this)
unsigned messagesOnResendQueue;
/// Number of messages not split for sending
unsigned numberOfUnsplitMessages;
/// Number of messages split for sending
unsigned numberOfSplitMessages;
/// Total number of splits done for sending
unsigned totalSplits;
/// Total packets sent
unsigned packetsSent;
#if defined(_WIN32) && defined(SAMPSRV)
unsigned field_B4;
#endif
/// Number of bits added by encryption
uint64_t encryptionBitsSent;
/// total bits sent
uint64_t totalBitsSent;
/// Number of sequenced messages arrived out of order
unsigned sequencedMessagesOutOfOrder;
/// Number of sequenced messages arrived in order
unsigned sequencedMessagesInOrder;
/// Number of ordered messages arrived out of order
unsigned orderedMessagesOutOfOrder;
/// Number of ordered messages arrived in order
unsigned orderedMessagesInOrder;
/// Packets with a good CRC received
unsigned packetsReceived;
/// Packets with a bad CRC received
unsigned packetsWithBadCRCReceived;
/// Bits with a good CRC received
uint64_t bitsReceived;
/// Bits with a bad CRC received
uint64_t bitsWithBadCRCReceived;
/// Number of acknowledgement messages received for packets we are resending
unsigned acknowlegementsReceived;
/// Number of acknowledgement messages received for packets we are not resending
unsigned duplicateAcknowlegementsReceived;
/// Number of data messages (anything other than an ack) received that are valid and not duplicate
unsigned messagesReceived;
/// Number of data messages (anything other than an ack) received that are invalid
unsigned invalidMessagesReceived;
/// Number of data messages (anything other than an ack) received that are duplicate
unsigned duplicateMessagesReceived;
/// Number of messages waiting for reassembly
unsigned messagesWaitingForReassembly;
/// Number of messages in reliability output queue
unsigned internalOutputQueueSize;
#if defined(_WIN32) && defined(SAMPSRV)
unsigned field_10C;
#endif
/// Current bits per second
double bitsPerSecond;
/// connection start time
RakNetTime connectionStartTime;
char _gap110[25];
};
void StatisticsToString( RakNetStatisticsStruct *s, char *buffer, int verbosityLevel );
#endif