/*
** 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 .
*/
/***********************************************************************************************
*** 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
#include
#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);