456 lines
11 KiB
C++
456 lines
11 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** Confidential - Westwood Studios ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Commando *
|
|
* *
|
|
* $Archive:: /Commando/Code/Commando/apppacketstats.cpp $*
|
|
* *
|
|
* $Author:: Tom_s $*
|
|
* *
|
|
* $Modtime:: 2/21/02 3:01p $*
|
|
* *
|
|
* $Revision:: 24 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "apppacketstats.h"
|
|
|
|
#include <memory.h>
|
|
#include <string.h>
|
|
|
|
#include "wwdebug.h"
|
|
#include "mathutil.h"
|
|
#include "networkobjectmgr.h"
|
|
#include "wwprofile.h"
|
|
|
|
//
|
|
// Class statics
|
|
//
|
|
DWORD cAppPacketStats::PacketsSent[];
|
|
DWORD cAppPacketStats::BitsSent[];
|
|
DWORD cAppPacketStats::BitsSentTier[][PACKET_TIER_COUNT];
|
|
DWORD cAppPacketStats::ObjectTally[];
|
|
StringClass cAppPacketStats::WorkingString;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Reset
|
|
(
|
|
void
|
|
)
|
|
{
|
|
::memset(&PacketsSent, 0, sizeof(PacketsSent));
|
|
::memset(&BitsSent, 0, sizeof(BitsSent));
|
|
::memset(&BitsSentTier, 0, sizeof(BitsSentTier));
|
|
::memset(&ObjectTally, 0, sizeof(ObjectTally));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Dump_Diagnostics
|
|
(
|
|
void
|
|
)
|
|
{
|
|
WWDEBUG_SAY(("\n"));
|
|
WWDEBUG_SAY(("---------------------------------------------------------\n"));
|
|
WWDEBUG_SAY(("cAppPacketStats::Dump_Diagnostics:\n"));
|
|
WWDEBUG_SAY(("%s\n", Get_Heading()));
|
|
|
|
for (BYTE i = 0; i < APPPACKETTYPE_COUNT; i++)
|
|
{
|
|
WWDEBUG_SAY(("%s\n", Get_Description(i)));
|
|
}
|
|
|
|
WWDEBUG_SAY(("\n"));
|
|
WWDEBUG_SAY(("---------------------------------------------------------\n"));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Increment_Packets_Sent
|
|
(
|
|
BYTE app_packet_type
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
|
|
|
PacketsSent[app_packet_type]++;
|
|
|
|
PacketsSent[APPPACKETTYPE_ALL]++;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Increment_Bits_Sent
|
|
(
|
|
BYTE app_packet_type,
|
|
DWORD bits
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
|
WWASSERT(bits >= 0);
|
|
|
|
BitsSent[app_packet_type] += bits;
|
|
|
|
BitsSent[APPPACKETTYPE_ALL] += bits;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Increment_Bits_Sent_Tier
|
|
(
|
|
BYTE app_packet_type,
|
|
PACKET_TIER_ENUM tier,
|
|
DWORD bits
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type != APPPACKETTYPE_ALL && app_packet_type < APPPACKETTYPE_COUNT);
|
|
WWASSERT(bits >= 0);
|
|
|
|
BitsSentTier[app_packet_type][tier] += bits;
|
|
|
|
BitsSentTier[APPPACKETTYPE_ALL][tier] += bits;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
cAppPacketStats::Get_Packets_Sent
|
|
(
|
|
BYTE app_packet_type
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
|
|
|
return PacketsSent[app_packet_type];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
cAppPacketStats::Get_Bits_Sent
|
|
(
|
|
BYTE app_packet_type
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
|
|
|
return BitsSent[app_packet_type];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
cAppPacketStats::Get_Bits_Sent_Tier
|
|
(
|
|
BYTE app_packet_type,
|
|
PACKET_TIER_ENUM tier
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
|
|
|
return BitsSentTier[app_packet_type][tier];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
#define ADD_CASE(exp) case exp: return #exp;
|
|
|
|
LPCSTR
|
|
cAppPacketStats::Interpret_Type
|
|
(
|
|
BYTE app_packet_type
|
|
)
|
|
{
|
|
switch (app_packet_type)
|
|
{
|
|
//
|
|
// S->S
|
|
//
|
|
ADD_CASE(APPPACKETTYPE_UNKNOWN);
|
|
ADD_CASE(APPPACKETTYPE_SIMPLE);
|
|
ADD_CASE(APPPACKETTYPE_SOLDIER);
|
|
ADD_CASE(APPPACKETTYPE_VEHICLE);
|
|
ADD_CASE(APPPACKETTYPE_TURRET);
|
|
ADD_CASE(APPPACKETTYPE_BUILDING);
|
|
ADD_CASE(APPPACKETTYPE_PLAYER);
|
|
ADD_CASE(APPPACKETTYPE_TEAM);
|
|
ADD_CASE(APPPACKETTYPE_GAMEOPTIONSEVENT);
|
|
ADD_CASE(APPPACKETTYPE_PLAYERKILLEVENT);
|
|
ADD_CASE(APPPACKETTYPE_PURCHASERESPONSEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_SCTEXTOBJ);
|
|
ADD_CASE(APPPACKETTYPE_SVRGOODBYEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_WINEVENT);
|
|
ADD_CASE(APPPACKETTYPE_POWERUP);
|
|
ADD_CASE(APPPACKETTYPE_STATIC);
|
|
ADD_CASE(APPPACKETTYPE_DOOR);
|
|
ADD_CASE(APPPACKETTYPE_ELEVATOR);
|
|
ADD_CASE(APPPACKETTYPE_DSAPO);
|
|
ADD_CASE(APPPACKETTYPE_SERVERFPS);
|
|
ADD_CASE(APPPACKETTYPE_CONSOLECOMMANDEVENT);
|
|
ADD_CASE(APPPACKETTYPE_RESETWINSEVENT);
|
|
ADD_CASE(APPPACKETTYPE_EVICTIONEVENT);
|
|
ADD_CASE(APPPACKETTYPE_NETWEATHER);
|
|
ADD_CASE(APPPACKETTYPE_GAMEDATAUPDATEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_SCPINGRESPONSEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_BASECONTROLLER);
|
|
ADD_CASE(APPPACKETTYPE_CINEMATIC);
|
|
ADD_CASE(APPPACKETTYPE_C4);
|
|
ADD_CASE(APPPACKETTYPE_BEACON);
|
|
ADD_CASE(APPPACKETTYPE_SCEXPLOSIONEVENT);
|
|
ADD_CASE(APPPACKETTYPE_SCOBELISKEVENT);
|
|
ADD_CASE(APPPACKETTYPE_SCANNOUNCEMENT);
|
|
ADD_CASE(APPPACKETTYPE_NETBACKGROUND);
|
|
ADD_CASE(APPPACKETTYPE_GAMESPYSCCHALLENGEEVENT);
|
|
|
|
|
|
//
|
|
// C->S
|
|
//
|
|
ADD_CASE(APPPACKETTYPE_CLIENTCONTROL);
|
|
ADD_CASE(APPPACKETTYPE_CSTEXTOBJ);
|
|
ADD_CASE(APPPACKETTYPE_SUICIDEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CHANGETEAMEVENT);
|
|
ADD_CASE(APPPACKETTYPE_MONEYEVENT);
|
|
ADD_CASE(APPPACKETTYPE_WARPEVENT);
|
|
ADD_CASE(APPPACKETTYPE_PURCHASEREQUESTEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CLIENTGOODBYEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_BIOEVENT);
|
|
ADD_CASE(APPPACKETTYPE_LOADINGEVENT);
|
|
ADD_CASE(APPPACKETTYPE_GODMODEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_VIPMODEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_SCOREEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CLIENTBBOEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CLIENTFPS);
|
|
ADD_CASE(APPPACKETTYPE_CSPINGREQUESTEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CSDAMAGEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_REQUESTKILLEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CSCONSOLECOMMANDEVENT);
|
|
ADD_CASE(APPPACKETTYPE_CSHINT);
|
|
ADD_CASE(APPPACKETTYPE_CSANNOUNCEMENT);
|
|
ADD_CASE(APPPACKETTYPE_DONATEEVENT);
|
|
ADD_CASE(APPPACKETTYPE_GAMESPYCSCHALLENGERESPONSEEVENT);
|
|
|
|
//
|
|
// Summation
|
|
//
|
|
ADD_CASE(APPPACKETTYPE_ALL);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return "ERROR";
|
|
DIE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
cAppPacketStats::Update_Object_Tally
|
|
(
|
|
void
|
|
)
|
|
{
|
|
::memset(&ObjectTally, 0, sizeof(ObjectTally));
|
|
|
|
int count = NetworkObjectMgrClass::Get_Object_Count();
|
|
|
|
for (int index = 0; index < count; index ++)
|
|
{
|
|
NetworkObjectClass * p_object = NetworkObjectMgrClass::Get_Object(index);
|
|
|
|
if (p_object != NULL)
|
|
{
|
|
BYTE type = p_object->Get_App_Packet_Type();
|
|
WWASSERT(type < APPPACKETTYPE_ALL);
|
|
|
|
ObjectTally[type]++;
|
|
ObjectTally[APPPACKETTYPE_ALL]++;
|
|
|
|
/*
|
|
if (type == APPPACKETTYPE_UNKNOWN)
|
|
{
|
|
WWDEBUG_SAY(("WTF is this?\n"));
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
DWORD
|
|
cAppPacketStats::Get_Object_Tally
|
|
(
|
|
BYTE app_packet_type
|
|
)
|
|
{
|
|
WWASSERT(app_packet_type < APPPACKETTYPE_COUNT);
|
|
|
|
return ObjectTally[app_packet_type];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
StringClass &
|
|
cAppPacketStats::Get_Heading
|
|
(
|
|
void
|
|
)
|
|
{
|
|
//StringClass description;
|
|
|
|
WorkingString.Format(
|
|
"%-30s %-8s %-10s %-10s %-7s %-7s %-7s %-7s %-7s %-7s",
|
|
"Type",
|
|
"Tally",
|
|
"Packets",
|
|
"Bytes",
|
|
"PC",
|
|
"Avg.",
|
|
"PC TC",
|
|
"PC TR",
|
|
"PC TO",
|
|
"PC TF"
|
|
);
|
|
|
|
return WorkingString;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
StringClass &
|
|
cAppPacketStats::Get_Description
|
|
(
|
|
BYTE type
|
|
)
|
|
{
|
|
WWASSERT(type < APPPACKETTYPE_COUNT);
|
|
|
|
float num_bytes = BitsSent[type] / 8.0f;
|
|
DWORD average_bytes = 0;
|
|
if (PacketsSent[type] > 0)
|
|
{
|
|
average_bytes = cMathUtil::Round(num_bytes / (float) PacketsSent[type]);
|
|
}
|
|
|
|
float percentage = 0;
|
|
if (BitsSent[APPPACKETTYPE_ALL] > 0)
|
|
{
|
|
percentage = 100 * (BitsSent[type] / (float) BitsSent[APPPACKETTYPE_ALL]);
|
|
}
|
|
|
|
//
|
|
// Strip the leading "APPPACKETTYPE_"
|
|
//
|
|
WWASSERT(::strlen(Interpret_Type(type)) > 14);
|
|
char name[200] = "";
|
|
::strcpy(name, &Interpret_Type(type)[14]);
|
|
|
|
//
|
|
// Tier percentages
|
|
//
|
|
DWORD t0 = 0;
|
|
DWORD t1 = 0;
|
|
DWORD t2 = 0;
|
|
DWORD t3 = 0;
|
|
if (BitsSent[type] > 0)
|
|
{
|
|
float bits = BitsSent[type];
|
|
|
|
t0 = cMathUtil::Round(100 * (BitsSentTier[type][0] / bits));
|
|
t1 = cMathUtil::Round(100 * (BitsSentTier[type][1] / bits));
|
|
t2 = cMathUtil::Round(100 * (BitsSentTier[type][2] / bits));
|
|
t3 = cMathUtil::Round(100 * (BitsSentTier[type][3] / bits));
|
|
}
|
|
|
|
//StringClass description;
|
|
WorkingString.Format(
|
|
"%-30s %-8d %-10d %-10d %-7.1f %-7d %-7d %-7d %-7d %-7d",
|
|
name,
|
|
ObjectTally[type],
|
|
PacketsSent[type],
|
|
cMathUtil::Round(num_bytes),
|
|
percentage,
|
|
average_bytes,
|
|
t0,
|
|
t1,
|
|
t2,
|
|
t3
|
|
);
|
|
|
|
/**/
|
|
//
|
|
// Replace all solo zero's with a space.
|
|
//
|
|
char last = ' ';
|
|
char next = ' ';
|
|
char * p = WorkingString.Peek_Buffer();
|
|
for (int i = 0; i < WorkingString.Get_Length(); i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
last = ' ';
|
|
}
|
|
else
|
|
{
|
|
last = p[i - 1];
|
|
}
|
|
|
|
if (i == WorkingString.Get_Length() - 1)
|
|
{
|
|
next = ' ';
|
|
}
|
|
else
|
|
{
|
|
next = p[i + 1];
|
|
}
|
|
|
|
if (last == ' ' && next == ' ' && p[i] == '0')
|
|
{
|
|
p[i] = ' ';
|
|
}
|
|
}
|
|
/**/
|
|
|
|
return WorkingString;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//ADD_CASE(APPPACKETTYPE_FLAGCAPEVENT);
|
|
//ADD_CASE(APPPACKETTYPE_STEALTHEVENT);
|