diff options
Diffstat (limited to 'game/client/tf/c_tf_gamestats.h')
| -rw-r--r-- | game/client/tf/c_tf_gamestats.h | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/game/client/tf/c_tf_gamestats.h b/game/client/tf/c_tf_gamestats.h new file mode 100644 index 0000000..d194da9 --- /dev/null +++ b/game/client/tf/c_tf_gamestats.h @@ -0,0 +1,344 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// +#ifndef C_TF_GAMESTATS_H +#define C_TF_GAMESTATS_H +#ifdef _WIN32 +#pragma once +#endif + +#include "gamestats.h" +#include "tf_gamestats_shared.h" +#include "GameEventListener.h" +#include "c_tf_player.h" +#include "econ_store.h" +#include "store/store_panel.h" + +class CTFPlayer; + +struct TF_Gamestats_ClientSession_t +{ +public: + + TF_Gamestats_ClientSession_t(); + +private: + TF_Gamestats_ClientSession_t( const TF_Gamestats_ClientSession_t &stats ) {} + +public: + void Reset(); + + struct SessionSummary_t + { + int iClassesPlayed; + int iMapsPlayed; + int iRoundsPlayed; + int iFavoriteClass; + int iFavoriteWeapon; + char szFavoriteMap[64]; + int iKills; + int iDeaths; + int iSuicides; + int iAssists; + int iBuildingsBuilt; + int iBuildingsUpgraded; + int iBuildingsDestroyed; + int iHeadshots; + int iDominations; + int iRevenges; + int iInvulns; + int iTeleports; + int iDamageDone; + int iHealingDone; + int iCrits; + int iBackstabs; + int iAchievementsEarned; + }; + + SessionSummary_t m_Summary; + + RTime32 m_SessionStart; + RTime32 m_FirstConnect; + int m_iMapsPlayed; + int m_iRoundsPlayed; + CBitVecT< CFixedBitVecBase<32> > m_ClassesPlayed; +}; + +struct TF_Gamestats_WeaponInfo_t +{ + TF_Gamestats_WeaponInfo_t(); + + int weaponID; + int critsFired; + int shotsFired; + int shotsHit; + int shotsMissed; + int avgDamage; + int totalDamage; + int critHits; + float lastUpdateTime; +}; + +struct TF_Gamestats_AchievementEvent_t +{ + TF_Gamestats_AchievementEvent_t( int in_achievementNum, const char* in_achievementID ); + + int eventTime; + int achievementNum; + const char* achievementID; +}; + +// Item event baseclass. +class TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_ItemEvent( int in_eventNum, CEconItemView* in_item ); + + int eventNum; + int eventTime; + const char* eventID; + + item_definition_index_t itemDefIndex; + itemid_t itemID; + const char* itemName; + char itemNameBuf[512]; + bool bUseNameBuf; + + const char* GetItemName() + { + if ( bUseNameBuf ) + return itemNameBuf; + else + return itemName; + } +}; + +// Mann Co Catalog Usage Tracking +class TF_Gamestats_CatalogEvent : public TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_CatalogEvent( int in_eventNum, CEconItemView* in_item, const char* in_filter ); + + const char* catalogFilter; +}; + +// Crafting System Usage Tracking +class TF_Gamestats_CraftingEvent : public TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_CraftingEvent( int in_eventNum, CEconItemView* in_item, int in_numAttempts, int in_recipe ); + + int numAttempts; + int recipeFound; +}; + +// Store Usage Tracking +class TF_Gamestats_StoreEvent : public TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_StoreEvent( int in_eventNum, CEconItemView* in_item, + const char* in_panelName, int in_classId, const cart_item_t* in_cartItem, + int in_checkoutAttempts, const char* in_storeError, int in_totalPrice, int in_currencyCode ); + + int classId; + int cartQuantity; + int cartItemCost; + int currencyCode; + int checkoutAttempt; + const char* storeError; + const char* panelName; +}; + +// General client-subjective item transaction tracking. +class TF_Gamestats_ItemTransactionEvent : public TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_ItemTransactionEvent( int in_eventNum, CEconItemView* in_item, const char* in_reason, int in_quality ); + + const char* reason; + int itemQuality; +}; + +// Trade Usage Tracking +class TF_Gamestats_TradeEvent : public TF_Gamestats_ItemEvent +{ +public: + TF_Gamestats_TradeEvent( int eventID, CEconItemView* item, bool localPlayerIsPartyA, + uint64 steamIDPartyA, uint64 steamIDPartyB, int iTradeRequests, int iTradeAttempts ); + TF_Gamestats_TradeEvent( int eventID, uint64 steamIDRequested, int iTradeRequests, int iTradeAttempts ); + TF_Gamestats_TradeEvent( int eventID, int iTradeRequests, const char* reason, int iTradeAttempts ); + + bool localPlayerPartyMatters; + bool localPlayerIsPartyA; + uint64 steamIDPartyA; + uint64 steamIDPartyB; + + uint64 steamIDRequested; + int tradeRequests; + int tradeAttempts; + + const char* reason; +}; + +// Matchmaking stats +struct TF_Gamestats_QuickPlay_t +{ + // Status code for the search as a whole + enum eResult + { + k_Result_InternalError = -1, + k_Result_UserCancel = 10, + k_Result_NoServersFound = 20, + k_Result_NoServersMetCrtieria = 30, + //k_Result_NeverHeardBackFromGC = 40, + //k_Result_ReceivedZeroGCScores = 50, + k_Result_FinalPingFailed = 60, + k_Result_TriedToConnect = 100, + }; + + // Status codes for the servers + enum eServerStatus + { + k_Server_Invalid = -1, // we have a bug if this gets reported + k_Server_Ineligible = 10, + k_Server_Eligible = 20, + k_Server_RequestedScore = 30, + k_Server_Scored = 40, + k_Server_Pinged = 50, + k_Server_PingTimedOut = 60, + k_Server_PingIneligible = 70, + k_Server_Connected = 100, + }; + + TF_Gamestats_QuickPlay_t() + { + m_fUserHoursPlayed = -1.0f; + m_sUserGameMode; + m_fSearchTime = -1.0; + m_eResultCode = k_Result_UserCancel; + m_iExperimentGroup = 0; + } + + float m_fUserHoursPlayed; + CUtlString m_sUserGameMode; + float m_fSearchTime; + eResult m_eResultCode; + int m_iExperimentGroup; // TF2ScoringNumbers_t::ExperimentGroup_t + + struct Server_t + { + uint32 m_ip; + uint16 m_port; + bool m_bRegistered; + bool m_bValve; + bool m_bSecure; + bool m_bMapIsNewUserFriendly; + bool m_bMapIsQuickPlayOK; + int m_nPlayers; + int m_nMaxPlayers; + CUtlString m_sMapName; + CUtlString m_sTags; + int m_iPing; + float m_fScoreClient; + float m_fScoreServer; + float m_fScoreGC; + eServerStatus m_eStatus; + }; + CUtlVector<Server_t> m_vecServers; +}; + +//============================================================================= +// +// TF Game Stats Class +// + +class C_CTFGameStats : public CBaseGameStats, public CGameEventListener, public CAutoGameSystem +{ +public: + + // Constructor/Destructor. + C_CTFGameStats( void ); + ~C_CTFGameStats( void ); + + virtual void Clear( void ); + + virtual bool UseOldFormat() { return false; } + virtual bool AddDataForSend( KeyValues *pKV, StatSendType_t sendType ); + + virtual bool Init(); + virtual void Shutdown(); + + void ResetRoundStats(); + + void ClientDisconnect( int iReason ); + + // Events. + virtual void Event_LevelInit( void ); + virtual void Event_LevelShutdown( float flElapsed ); + virtual void Event_RoundActive(); + virtual void Event_RoundEnd( int winningTeam, float roundTime, int fullRound ); + virtual void Event_PlayerChangeClass( int userid, int classid ); + virtual void Event_AchievementProgress( int achievementID, const char* achievementName ); + virtual void Event_PlayerHurt( IGameEvent* event /*player_hurt*/ ); + virtual void Event_PlayerFiredWeapon( C_TFPlayer *pPlayer, bool bCritical ); + virtual void Event_Catalog( int eventID, const char* filter=NULL, CEconItemView* item=NULL ); + virtual void Event_Crafting( int eventID, CEconItemView* item=NULL, int numAttempts=0, int recipeFound=0 ); + virtual void Event_Store( int eventID, CEconItemView* item=NULL, const char* panelName=NULL, + int classId=0, const cart_item_t* in_cartItem=NULL, int in_checkoutAttempts=0, const char* storeError=NULL, int in_totalPrice=0, int in_currencyCode=0 ); + virtual void Event_ItemTransaction( int eventID, CEconItemView* item, const char* pszReason=NULL, int iQuality=0 ); + virtual void Event_Trading( int eventID, CEconItemView* item=NULL, bool localPlayerIsPartyA=false, + uint64 steamIDPartyA=0, uint64 steamIDPartyB=0, int iTradeRequests=0, int iTradeAttempts=0 ); + virtual void Event_Trading( int eventID, uint64 steamIDRequested=0, int iTradeRequests=0, int iTradeAttempts=0 ); + virtual void Event_Trading( int eventID, int iTradeRequests=0, const char* reason=NULL, int iTradeAttempts=0 ); + virtual void Event_Trading( TF_Gamestats_TradeEvent& event ); + + virtual void FireGameEvent( IGameEvent * event ); + + void SW_GameStats_WriteClientSessionSummary(); + void SW_GameStats_WriteClientWeapons(); + void SW_GameStats_WriteClientRound( int winningTeam, int fullRound, int endReason ); + void SW_GameStats_WriteClientMap(); + + void SetExperimentValue( uint64 experimentValue ) { m_ulExperimentValue = experimentValue; } + + static void ImmediateWriteInterfaceEvent( const char *pszEventType, const char *pszEventDesc ); + + /* + void SW_GameStats_WriteClientAchievements(); + void SW_GameStats_WriteClientCatalogEvents(); + void SW_GameStats_WriteClientCraftingEvents(); + void SW_GameStats_WriteClientStoreEvents(); + void SW_GameStats_WriteClientItemTransactionEvents(); + void SW_GameStats_WriteClientTradeEvents(); + */ + + void QuickplayResults( const TF_Gamestats_QuickPlay_t &info ); + +private: + char m_szCountryCode[64]; + char m_szAudioLanguage[64]; + char m_szTextLanguage[64]; + + TF_Gamestats_ClientSession_t m_currentSession; + TF_Gamestats_RoundStats_t m_currentRound; + TF_Gamestats_LevelStats_t m_currentMap; + CUtlVector<TF_Gamestats_AchievementEvent_t> m_vecAchievementEvents; + CUtlMap<int, TF_Gamestats_WeaponInfo_t> m_mapWeaponInfo; + + CUtlVector<TF_Gamestats_CatalogEvent> m_vecCatalogEvents; + CUtlVector<TF_Gamestats_CraftingEvent> m_vecCraftingEvents; + CUtlVector<TF_Gamestats_StoreEvent> m_vecStoreEvents; + CUtlVector<TF_Gamestats_ItemTransactionEvent> m_vecItemTransactionEvents; + CUtlVector<TF_Gamestats_TradeEvent> m_vecTradeEvents; + + uint64 m_ulExperimentValue; + + bool m_bRoundActive; + bool m_bIsDisconnecting; +}; + +extern C_CTFGameStats C_CTF_GameStats; + +#endif // C_TF_GAMESTATS_H |