|
|
//========= 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
|