summaryrefslogtreecommitdiff
path: root/game/server/cstrike/cs_gamestats.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/cstrike/cs_gamestats.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/server/cstrike/cs_gamestats.h')
-rw-r--r--game/server/cstrike/cs_gamestats.h340
1 files changed, 340 insertions, 0 deletions
diff --git a/game/server/cstrike/cs_gamestats.h b/game/server/cstrike/cs_gamestats.h
new file mode 100644
index 0000000..4a24efb
--- /dev/null
+++ b/game/server/cstrike/cs_gamestats.h
@@ -0,0 +1,340 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: The CS game stats header
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef CS_GAMESTATS_H
+#define CS_GAMESTATS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "cs_blackmarket.h"
+#include "gamestats.h"
+#include "cs_gamestats_shared.h"
+#include "GameEventListener.h"
+#include "steamworks_gamestats.h"
+#include "weapon_csbase.h"
+
+// forward declares
+class CBreakableProp;
+
+#define CS_STATS_BLOB_VERSION 3
+
+const float cDisseminationTimeHigh = 0.25f; // Time interval for high priority stats sent to the player
+const float cDisseminationTimeLow = 2.5f; // Time interval for medium priority stats sent to the player
+
+int GetCSLevelIndex( const char *pLevelName );
+
+typedef struct
+{
+ char szGameName[8];
+ byte iVersion;
+ char szMapName[32];
+ char ipAddr[4];
+ short port;
+ int serverid;
+} gamestats_header_t;
+
+typedef struct
+{
+ gamestats_header_t header;
+ short iMinutesPlayed;
+
+ short iTerroristVictories[CS_NUM_LEVELS];
+ short iCounterTVictories[CS_NUM_LEVELS];
+ short iBlackMarketPurchases[WEAPON_MAX];
+
+ short iAutoBuyPurchases;
+ short iReBuyPurchases;
+ short iAutoBuyM4A1Purchases;
+ short iAutoBuyAK47Purchases;
+ short iAutoBuyFamasPurchases;
+ short iAutoBuyGalilPurchases;
+ short iAutoBuyVestHelmPurchases;
+ short iAutoBuyVestPurchases;
+
+} cs_gamestats_t;
+
+extern short g_iWeaponPurchases[WEAPON_MAX];
+extern float g_flGameStatsUpdateTime;
+extern short g_iTerroristVictories[CS_NUM_LEVELS];
+extern short g_iCounterTVictories[CS_NUM_LEVELS];
+extern short g_iWeaponPurchases[WEAPON_MAX];
+
+extern short g_iAutoBuyPurchases;
+extern short g_iReBuyPurchases;
+extern short g_iAutoBuyM4A1Purchases;
+extern short g_iAutoBuyAK47Purchases;
+extern short g_iAutoBuyFamasPurchases;
+extern short g_iAutoBuyGalilPurchases;
+extern short g_iAutoBuyVestHelmPurchases;
+extern short g_iAutoBuyVestPurchases;
+
+
+struct sHappyCamperSnipePosition
+{
+ sHappyCamperSnipePosition( int userid, Vector pos ) : m_iUserID(userid), m_vPos(pos) {}
+
+ int m_iUserID;
+ Vector m_vPos;
+};
+
+struct SMarketPurchases : public BaseStatData
+{
+ SMarketPurchases( uint64 ulPlayerID, int iPrice, const char *pName ) : m_nPlayerID(ulPlayerID), ItemCost(iPrice)
+ {
+ if ( pName )
+ {
+ Q_strncpy( ItemID, pName, ARRAYSIZE(ItemID) );
+ }
+ else
+ {
+ Q_strncpy( ItemID, "unknown", ARRAYSIZE(ItemID) );
+ }
+ }
+ uint64 m_nPlayerID;
+ int ItemCost;
+ char ItemID[64];
+
+ BEGIN_STAT_TABLE( "CSSMarketPurchase" )
+ REGISTER_STAT( m_nPlayerID )
+ REGISTER_STAT( ItemCost )
+ REGISTER_STAT_STRING( ItemID )
+ END_STAT_TABLE()
+};
+typedef CUtlVector< SMarketPurchases* > VectorMarketPurchaseData;
+
+struct WeaponStats
+{
+ int shots;
+ int hits;
+ int kills;
+ int damage;
+};
+
+struct SCSSWeaponData : public BaseStatData
+{
+ SCSSWeaponData( const char *pWeaponName, const WeaponStats &wpnData )
+ {
+ if ( pWeaponName )
+ {
+ Q_strncpy( WeaponID, pWeaponName, ARRAYSIZE(WeaponID) );
+ }
+ else
+ {
+ Q_strncpy( WeaponID, "unknown", ARRAYSIZE(WeaponID) );
+ }
+
+ Shots = wpnData.shots;
+ Hits = wpnData.hits;
+ Kills = wpnData.kills;
+ Damage = wpnData.damage;
+ }
+
+ char WeaponID[64];
+ int Shots;
+ int Hits;
+ int Kills;
+ int Damage;
+
+ BEGIN_STAT_TABLE( "CSSWeaponData" )
+ REGISTER_STAT_STRING( WeaponID )
+ REGISTER_STAT( Shots )
+ REGISTER_STAT( Hits )
+ REGISTER_STAT( Kills )
+ REGISTER_STAT( Damage )
+ END_STAT_TABLE()
+};
+typedef CUtlVector< SCSSWeaponData* > CSSWeaponData;
+
+struct SCSSDeathData : public BaseStatData
+{
+ SCSSDeathData( CBasePlayer *pVictim, const CTakeDamageInfo &info )
+ {
+ m_bUseGlobalData = false;
+
+ m_DeathPos = info.GetDamagePosition();
+ m_iVictimTeam = pVictim->GetTeamNumber();
+
+ CCSPlayer *pCSPlayer = ToCSPlayer( info.GetAttacker() );
+ if ( pCSPlayer )
+ {
+ m_iKillerTeam = pCSPlayer->GetTeamNumber();
+ }
+ else
+ {
+ m_iKillerTeam = -1;
+ }
+
+ const char *pszWeaponName = info.GetInflictor() ? info.GetInflictor()->GetClassname() : "unknown";
+
+ if ( pszWeaponName )
+ {
+ if ( V_strcmp(pszWeaponName, "player") == 0 )
+ {
+ // get the player's weapon
+ if ( pCSPlayer && pCSPlayer->GetActiveCSWeapon() )
+ {
+ pszWeaponName = pCSPlayer->GetActiveCSWeapon()->GetClassname();
+ }
+ }
+ }
+
+
+ m_uiDeathParam = WEAPON_NONE;
+ if ( (m_uiDeathParam = AliasToWeaponID( pszWeaponName )) == WEAPON_NONE )
+ {
+ m_uiDeathParam = AliasToWeaponID( pszWeaponName );
+ }
+
+ const char *pszMapName = gpGlobals->mapname.ToCStr() ? gpGlobals->mapname.ToCStr() : "unknown";
+ Q_strncpy( m_szMapName, pszMapName, ARRAYSIZE(m_szMapName) );
+ }
+ Vector m_DeathPos;
+ int m_iVictimTeam;
+ int m_iKillerTeam;
+ int m_iDamageType;
+ uint64 m_uiDeathParam;
+ char m_szMapName[64];
+
+ BEGIN_STAT_TABLE( "Deaths" )
+ REGISTER_STAT_NAMED( m_DeathPos.x, "XCoord" )
+ REGISTER_STAT_NAMED( m_DeathPos.y, "YCoord" )
+ REGISTER_STAT_NAMED( m_DeathPos.z, "ZCoord" )
+ REGISTER_STAT_NAMED( m_iVictimTeam, "Team" )
+ REGISTER_STAT_NAMED( m_iKillerTeam, "DeathCause" )
+ REGISTER_STAT_NAMED( m_uiDeathParam, "DeathParam" )
+ REGISTER_STAT_NAMED( m_szMapName, "DeathMap" )
+ END_STAT_TABLE()
+};
+typedef CUtlVector< SCSSDeathData* > CSSDeathData;
+
+//=============================================================================
+//
+// CS Game Stats Class
+//
+class CCSGameStats : public CBaseGameStats, public CGameEventListener, public CAutoGameSystemPerFrame, public IGameStatTracker
+{
+public:
+
+ // Constructor/Destructor.
+ CCSGameStats( void );
+ ~CCSGameStats( void );
+
+ virtual void Clear( void );
+ virtual bool Init();
+ virtual void PreClientUpdate();
+ virtual void PostInit();
+ virtual void LevelShutdownPreClearSteamAPIContext();
+
+ void UploadRoundStats( void );
+ // Overridden events
+ virtual void Event_LevelInit( void );
+ virtual void Event_LevelShutdown( float flElapsed );
+ virtual void Event_ShotFired( CBasePlayer *pPlayer, CBaseCombatWeapon* pWeapon );
+ virtual void Event_ShotHit( CBasePlayer *pPlayer, const CTakeDamageInfo &info );
+ virtual void Event_PlayerKilled( CBasePlayer *pPlayer, const CTakeDamageInfo &info );
+ virtual void Event_PlayerKilled_PreWeaponDrop( CBasePlayer *pPlayer, const CTakeDamageInfo &info );
+ void UpdatePlayerRoundStats(int winner);
+ virtual void Event_PlayerConnected( CBasePlayer *pPlayer );
+ virtual void Event_PlayerDisconnected( CBasePlayer *pPlayer );
+ virtual void Event_WindowShattered( CBasePlayer *pPlayer );
+ virtual void Event_PlayerKilledOther( CBasePlayer *pAttacker, CBaseEntity *pVictim, const CTakeDamageInfo &info );
+
+
+ // CSS specific events
+ void Event_BombPlanted( CCSPlayer *pPlayer );
+ void Event_BombDefused( CCSPlayer *pPlayer );
+ void Event_PlayerDamage( CBasePlayer *pBasePlayer, const CTakeDamageInfo &info );
+ void Event_BombExploded( CCSPlayer *pPlayer );
+ void Event_MoneyEarned( CCSPlayer *pPlayer, int moneyEarned );
+ void Event_MoneySpent( CCSPlayer *pPlayer, int moneySpent, const char *pItemName );
+ void Event_HostageRescued( CCSPlayer *pPlayer );
+ void Event_PlayerSprayedDecal( CCSPlayer*pPlayer );
+ void Event_AllHostagesRescued();
+ void Event_BreakProp( CCSPlayer *pPlayer, CBreakableProp *pProp );
+ void Event_PlayerDonatedWeapon (CCSPlayer* pPlayer);
+ void Event_PlayerDominatedOther( CCSPlayer* pAttacker, CCSPlayer* pVictim);
+ void Event_PlayerRevenge( CCSPlayer* pAttacker );
+ void Event_PlayerAvengedTeammate( CCSPlayer* pAttacker, CCSPlayer* pAvengedPlayer );
+ void Event_MVPEarned( CCSPlayer* pPlayer );
+ void Event_KnifeUse( CCSPlayer* pPlayer, bool bStab, int iDamage );
+
+ virtual void FireGameEvent( IGameEvent *event );
+
+ void DumpMatchWeaponMetrics();
+
+ const PlayerStats_t& FindPlayerStats( CBasePlayer *pPlayer ) const;
+ void ResetPlayerStats( CBasePlayer *pPlayer );
+ void ResetKillHistory( CBasePlayer *pPlayer );
+ void ResetRoundStats();
+ void ResetPlayerClassMatchStats();
+
+ const StatsCollection_t& GetTeamStats( int iTeamIndex ) const;
+ void ResetAllTeamStats();
+ void ResetAllStats();
+ void ResetWeaponStats();
+ void IncrementTeamStat( int iTeamIndex, int iStatIndex, int iAmount );
+ void CalcDominationAndRevenge( CCSPlayer *pAttacker, CCSPlayer *pVictim, int *piDeathFlags );
+ void CalculateOverkill( CCSPlayer* pAttacker, CCSPlayer* pVictim );
+ void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );
+
+ void IncrementStat( CCSPlayer* pPlayer, CSStatType_t statId, int iValue, bool bPlayerOnly = false );
+ // Steamworks Gamestats
+ virtual void SubmitGameStats( KeyValues *pKV );
+
+ virtual StatContainerList_t* GetStatContainerList( void )
+ {
+ return s_StatLists;
+ }
+
+protected:
+ void SetStat( CCSPlayer *pPlayer, CSStatType_t statId, int iValue );
+ void TrackKillStats( CCSPlayer *pAttacker, CCSPlayer *pVictim );
+ void ComputeRollingStatAverages();
+ void ComputeDirectStatAverages();
+ void SendRollingStatsAveragesToAllPlayers();
+ void SendDirectStatsAveragesToAllPlayers();
+ void SendStatsToPlayer( CCSPlayer * pPlayer, int iMinStatPriority );
+
+private:
+ PlayerStats_t m_aPlayerStats[MAX_PLAYERS+1]; // List of stats for each player for current life - reset after each death
+ StatsCollection_t m_aTeamStats[TEAM_MAXCOUNT - FIRST_GAME_TEAM];
+
+ RoundStatsRollingAverage_t m_rollingCTStatAverages;
+ RoundStatsRollingAverage_t m_rollingTStatAverages;
+ RoundStatsRollingAverage_t m_rollingPlayerStatAverages;
+
+ RoundStatsDirectAverage_t m_directCTStatAverages;
+ RoundStatsDirectAverage_t m_directTStatAverages;
+ RoundStatsDirectAverage_t m_directPlayerStatAverages;
+
+ float m_fDisseminationTimerLow; // how long since last medium priority stat update
+ float m_fDisseminationTimerHigh; // how long since last high priority stat update
+
+ int m_numberOfRoundsForDirectAverages;
+ int m_numberOfTerroristEntriesForDirectAverages;
+ int m_numberOfCounterTerroristEntriesForDirectAverages;
+
+ CUtlDict< CSStatType_t, short > m_PropStatTable;
+
+ CUtlLinkedList<sHappyCamperSnipePosition, int> m_PlayerSnipedPosition;
+ WeaponStats m_weaponStats[WEAPON_MAX][2];
+
+ // Steamworks Gamestats
+ VectorMarketPurchaseData m_MarketPurchases;
+ CSSWeaponData m_WeaponData;
+ CSSDeathData m_DeathData;
+
+ // A static list of all the stat containers, one for each data structure being tracked
+ static StatContainerList_t * s_StatLists;
+
+ bool m_bInRound;
+};
+
+extern CCSGameStats CCS_GameStats;
+
+#endif // CS_GAMESTATS_H