Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
8.8 KiB

  1. //====== Copyright 1996-2006, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose: Uploads gamestats via the SteamWorks API. Client version.
  4. //
  5. //=============================================================================//
  6. #ifndef STEAMWORKS_GAMESTATS_CLIENT_H
  7. #define STEAMWORKS_GAMESTATS_CLIENT_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "steamworks_gamestats.h"
  12. //used to drive most of the game stat event handlers as well as track basic stats under the hood of CBaseGameStats
  13. class CSteamWorksGameStatsClient : public CSteamWorksGameStatsUploader
  14. {
  15. DECLARE_CLASS( CSteamWorksGameStatsClient, CSteamWorksGameStatsUploader )
  16. public:
  17. CSteamWorksGameStatsClient();
  18. virtual bool Init() OVERRIDE; // return true on success. false to abort DLL init!
  19. virtual void FireGameEvent( IGameEvent *event ) OVERRIDE;
  20. virtual void OnSteamSessionIssued( GameStatsSessionIssued_t *pResult, bool bError ) OVERRIDE;
  21. virtual void WriteSessionRow();
  22. int GetFriendCountInGame();
  23. virtual void ClientDisconnect();
  24. void SetServerSessionID( uint64 serverID );
  25. void ClearServerSessionID() { m_ServerSessionID = 0 ;}
  26. uint64 GetServerSessionID( void ) { return m_ServerSessionID; }
  27. bool AddCsgoGameEventStat( char const *szMapName, char const *szEvent, Vector const &pos, QAngle const &ang, uint64 ullData, int16 nRound, int16 numRoundSecondsElapsed );
  28. void AddClientPerfData( KeyValues *pKV );
  29. void AddVPKLoadStats( KeyValues *pKV );
  30. void AddVPKFileLoadErrorData( KeyValues *pKV );
  31. protected:
  32. virtual EGameStatsAccountType GetGameStatsAccountType() OVERRIDE { return k_EGameStatsAccountType_Steam; }
  33. // called before a row is committed, allows derived classes to add sessionIDs, etc.
  34. virtual void AddSessionIDsToTable( int iTableID ) OVERRIDE;
  35. virtual void Reset() OVERRIDE;
  36. uint64 m_ServerSessionID;
  37. int m_HumanCntInGame;
  38. int m_FriendCntInGame;
  39. char m_pzPlayerName[MAX_PATH];
  40. };
  41. CSteamWorksGameStatsClient& GetSteamWorksGameStatsClient();
  42. // Macros to ease the creation of SendData method for stats structs/classes
  43. #define BEGIN_STAT_TABLE( tableName ) \
  44. static const char* GetStatTableName( void ) { return tableName; } \
  45. void BuildGamestatDataTable( KeyValues* pKV ) \
  46. { \
  47. pKV->SetName( GetStatTableName() );
  48. #define REGISTER_STAT( varName ) \
  49. AddDataToKV(pKV, #varName, varName);
  50. #define REGISTER_STAT_NAMED( varName, dbName ) \
  51. AddDataToKV(pKV, dbName, varName);
  52. #define REGISTER_STAT_POSITION( varName ) \
  53. AddPositionDataToKV(pKV, #varName, varName);
  54. #define REGISTER_STAT_POSITION_NAMED( varName, dbName ) \
  55. AddPositionDataToKV(pKV, dbName, varName);
  56. #define REGISTER_STAT_ARRAY( varName ) \
  57. AddArrayDataToKV( pKV, #varName, varName, ARRAYSIZE( varName ) );
  58. #define REGISTER_STAT_ARRAY_NAMED( varName, dbName ) \
  59. AddArrayDataToKV( pKV, dbName, varName, ARRAYSIZE( varName ) );
  60. #define REGISTER_STAT_STRING( varName ) \
  61. AddStringDataToKV( pKV, #varName, varName );
  62. #define REGISTER_STAT_STRING_NAMED( varName, dbName ) \
  63. AddStringDataToKV( pKV, dbName, varName );
  64. #define AUTO_STAT_TABLE_KEY() \
  65. pKV->SetInt( "TimeSubmitted", GetUniqueIDForStatTable( *this ) );
  66. #define END_STAT_TABLE() \
  67. pKV->SetUint64( ::BaseStatData::m_bUseGlobalData ? "TimeSubmitted" : "SessionTime", ::BaseStatData::TimeSubmitted ); \
  68. GetSteamWorksGameStatsClient().AddStatsForUpload( pKV ); \
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Purpose: Templatized class for getting unique ID's for stat tables that need
  72. // to be submitted multiple times per-session.
  73. //-----------------------------------------------------------------------------
  74. template < typename T >
  75. class UniqueStatID_t
  76. {
  77. public:
  78. static unsigned GetNext( void )
  79. {
  80. return ++s_nLastID;
  81. }
  82. static void Reset( void )
  83. {
  84. s_nLastID = 0;
  85. }
  86. private:
  87. static unsigned s_nLastID;
  88. };
  89. template < typename T >
  90. unsigned UniqueStatID_t< T >::s_nLastID = 0;
  91. template < typename T >
  92. unsigned GetUniqueIDForStatTable( const T &table )
  93. {
  94. return UniqueStatID_t< T >::GetNext();
  95. }
  96. //=============================================================================
  97. //
  98. // An interface for tracking gamestats.
  99. //
  100. class IGameStatTracker
  101. {
  102. public:
  103. //-----------------------------------------------------------------------------
  104. // Templatized methods to track a per-mission stat.
  105. // The stat is copied, then deleted after it's sent to the SQL server.
  106. //-----------------------------------------------------------------------------
  107. template < typename T >
  108. void SubmitStat( T& stat )
  109. {
  110. // Make a copy of the stat. All of the stat lists require pointers,
  111. // so we need to protect against a stat allocated on the stack
  112. T* pT = new T();
  113. if( !pT )
  114. return;
  115. *pT = stat;
  116. SubmitStat( pT );
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Templatized methods to track a per-mission stat (by pointer)
  120. // The stat is deleted after it's sent to the SQL server
  121. //-----------------------------------------------------------------------------
  122. template < typename T >
  123. void SubmitStat( T* pStat )
  124. {
  125. // Get the static stat table for this type and add the stat to it
  126. GetStatTable<T>()->AddToTail( pStat );
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Add all stats to an existing key value file for submit.
  130. //-----------------------------------------------------------------------------
  131. virtual void SubmitGameStats( KeyValues *pKV ) = 0;
  132. //-----------------------------------------------------------------------------
  133. // Prints the memory usage of all of the stats being tracked
  134. //-----------------------------------------------------------------------------
  135. void PrintGamestatMemoryUsage( void );
  136. protected:
  137. //=============================================================================
  138. //
  139. // Used as a base interface to store a list of all templatized stat containers
  140. //
  141. class IStatContainer
  142. {
  143. public:
  144. virtual void SendData( KeyValues *pKV ) = 0;
  145. virtual void Clear( void ) = 0;
  146. virtual void PrintMemoryUsage( void ) = 0;
  147. };
  148. // Defines a list of stat containers.
  149. typedef CUtlVector< IStatContainer* > StatContainerList_t;
  150. //-----------------------------------------------------------------------------
  151. // Used to get a list of all stats containers being tracked by the deriving class
  152. //-----------------------------------------------------------------------------
  153. virtual StatContainerList_t* GetStatContainerList( void ) = 0;
  154. private:
  155. //=============================================================================
  156. //
  157. // Templatized list of stats submitted
  158. //
  159. template < typename T >
  160. class CGameStatList : public IStatContainer, public CUtlVector< T* >
  161. {
  162. public:
  163. //-----------------------------------------------------------------------------
  164. // Get data ready to send to the SQL server
  165. //-----------------------------------------------------------------------------
  166. virtual void SendData( KeyValues *pKV )
  167. {
  168. //ASSERT( pKV != NULL );
  169. // Duplicate the master KeyValue for each stat instance
  170. for( int i=0; i < this->m_Size; ++i )
  171. {
  172. // Make a copy of the master key value and build the stat table
  173. KeyValues *pKVCopy = this->operator [](i)->m_bUseGlobalData ? pKV->MakeCopy() : new KeyValues( "" );
  174. this->operator [](i)->BuildGamestatDataTable( pKVCopy );
  175. }
  176. // Reset unique ID counter for the stat type
  177. UniqueStatID_t< T >::Reset();
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Clear and delete every stat in this list
  181. //-----------------------------------------------------------------------------
  182. virtual void Clear( void )
  183. {
  184. this->Purge();
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Print out details about this lists memory usage
  188. //-----------------------------------------------------------------------------
  189. virtual void PrintMemoryUsage( void )
  190. {
  191. if( this->m_Size == 0 )
  192. return;
  193. // Compute the memory used as the size of type times the list count
  194. unsigned uMemoryUsed = this->m_Size * ( sizeof( T ) );
  195. Msg( " %d\tbytes used by %s table\n", uMemoryUsed, T::GetStatTableName() );
  196. }
  197. };
  198. //-----------------------------------------------------------------------------
  199. // Templatized method to get a single instance of a stat list per data type.
  200. //-----------------------------------------------------------------------------
  201. template < typename T >
  202. CGameStatList< T >* GetStatTable( void )
  203. {
  204. static CGameStatList< T > *s_vecOfType = 0;
  205. if( s_vecOfType == 0 )
  206. {
  207. s_vecOfType = new CGameStatList< T >();
  208. GetStatContainerList()->AddToTail( s_vecOfType );
  209. }
  210. return s_vecOfType;
  211. }
  212. };
  213. struct BaseStatData
  214. {
  215. explicit BaseStatData( bool bUseGlobalData = true ) : m_bUseGlobalData( bUseGlobalData )
  216. {
  217. TimeSubmitted = GetSteamWorksGameStatsClient().GetTimeSinceEpoch();
  218. }
  219. bool m_bUseGlobalData;
  220. uint64 TimeSubmitted;
  221. };
  222. #endif // STEAMWORKS_GAMESTATS_CLIENT_H