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.

311 lines
9.1 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef CS_STEAMSTATS_H
  8. #define CS_STEAMSTATS_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "steam/steam_api.h"
  13. #include "GameEventListener.h"
  14. #include "cs_gamestats_shared.h"
  15. #include "matchmaking/cstrike15/imatchext_cstrike15.h"
  16. #include "steamworks_gamestats_client.h"
  17. #include "gametypes.h"
  18. #include "cs_gamerules.h"
  19. struct PlayerStatData_t
  20. {
  21. wchar_t* pStatDisplayName; // Localized display name of the stat
  22. int iStatId; // CSStatType_t enum value of stat
  23. int32 iStatValue; // Value of the stat
  24. };
  25. enum CSSyncStatValueDirection_t
  26. {
  27. CSSTAT_WRITE_STAT,
  28. CSSTAT_READ_STAT
  29. };
  30. enum CSClientCsgoGameEventType_t
  31. {
  32. // WARNING: must be in sync with the g_CSClientCsgoGameEventTypeNames[] in cpp
  33. k_CSClientCsgoGameEventType_SprayApplication = 1,
  34. k_CSClientCsgoGameEventType_ConnectionProblem_Generic = 2,
  35. k_CSClientCsgoGameEventType_ConnectionProblem_Loss = 3,
  36. k_CSClientCsgoGameEventType_ConnectionProblem_Choke = 4,
  37. // WARNING: must be in sync with the g_CSClientCsgoGameEventTypeNames[] in cpp
  38. };
  39. #define CSCLIENTCSGOGAMEEVENTTYPE_AUTODETECT_INT16 (-32768)
  40. //=============================================================================
  41. //
  42. // OGS Gamestats
  43. //
  44. #if !defined( _GAMECONSOLE )
  45. struct SRoundData : public BaseStatData
  46. {
  47. explicit SRoundData( const StatsCollection_t *pRoundData )
  48. {
  49. nRoundTime = (*pRoundData)[CSSTAT_PLAYTIME];
  50. nWasKilled = (*pRoundData)[CSSTAT_DEATHS];
  51. nIsMVP = (*pRoundData)[CSSTAT_MVPS];
  52. nMoneySpent = (*pRoundData)[CSSTAT_MONEY_SPENT];
  53. nStartingMoney = -1;// We'll get this data separately
  54. nRoundScore = 0;
  55. nRevenges = (*pRoundData)[CSSTAT_REVENGES];
  56. nDamageDealt = (*pRoundData)[CSSTAT_DAMAGE];
  57. llExperimental = 0;
  58. nTeamID = 0;
  59. nWinningTeamID = 0;
  60. if ( (*pRoundData)[CSSTAT_T_ROUNDS_WON] )
  61. {
  62. nWinningTeamID = TEAM_TERRORIST;
  63. /*
  64. if ( (*pRoundData)[CSSTAT_ROUNDS_WON] )
  65. {
  66. nTeamID = TEAM_TERRORIST;
  67. }
  68. else
  69. {
  70. nTeamID = TEAM_CT;
  71. }
  72. */
  73. }
  74. else if ( (*pRoundData)[CSSTAT_CT_ROUNDS_WON] )
  75. {
  76. nWinningTeamID = TEAM_CT;
  77. /*
  78. if ( (*pRoundData)[CSSTAT_ROUNDS_WON] )
  79. {
  80. nTeamID = TEAM_CT;
  81. }
  82. else
  83. {
  84. nTeamID = TEAM_TERRORIST;
  85. }
  86. */
  87. }
  88. //nGameType = g_pGameTypes ? g_pGameTypes->GetCurrentGameType() : -1;
  89. // HACK: Game type isn't useful to record in stats because for official servers
  90. // the map can tell us that. Game mode, however, isn't being captured.
  91. // Game type is now game mode.
  92. nGameType = g_pGameTypes ? g_pGameTypes->GetCurrentGameMode() : -1;
  93. nRound = -1; // We'll get this data seperately, need to get it from the matchstats
  94. nReason = Invalid_Round_End_Reason; // We track this seperately since we normally get the round stats from the server but not all the pieces
  95. }
  96. uint32 nRoundTime;
  97. int nTeamID;
  98. int nWinningTeamID;
  99. int nWasKilled;
  100. int nIsMVP;
  101. int nDamageDealt;
  102. int nMoneySpent;
  103. int nStartingMoney;
  104. int nRoundScore;
  105. int nRevenges;
  106. int nGameType;
  107. int nRound;
  108. int nReason;
  109. uint64 llExperimental;
  110. BEGIN_STAT_TABLE( "CSGORoundData" )
  111. REGISTER_STAT_NAMED( nRoundTime, "RoundTime" )
  112. REGISTER_STAT_NAMED( nTeamID, "TeamID" )
  113. REGISTER_STAT_NAMED( nWinningTeamID, "WinningTeamID" )
  114. REGISTER_STAT_NAMED( nWasKilled, "WasKilled" )
  115. REGISTER_STAT_NAMED( nIsMVP, "IsMvp" )
  116. REGISTER_STAT_NAMED( nDamageDealt, "DamageDealt" )
  117. REGISTER_STAT_NAMED( nMoneySpent, "MoneySpent" )
  118. REGISTER_STAT_NAMED( nStartingMoney, "StartingMoney" )
  119. REGISTER_STAT_NAMED( nRoundScore, "RoundScore" )
  120. REGISTER_STAT_NAMED( nRevenges, "Revenges" )
  121. REGISTER_STAT_NAMED( nGameType, "GameTypeID" )
  122. REGISTER_STAT_NAMED( nRound, "Round" )
  123. REGISTER_STAT_NAMED( nReason, "RoundEndReason" )
  124. REGISTER_STAT_NAMED( llExperimental, "Experimental" )
  125. END_STAT_TABLE()
  126. };
  127. #endif
  128. class CCSClientGameStats : public CAutoGameSystem, public CGameEventListener
  129. #if !defined( _GAMECONSOLE )
  130. , public IGameStatTracker
  131. #endif
  132. {
  133. public:
  134. CCSClientGameStats();
  135. virtual void PostInit();
  136. virtual void LevelShutdownPreEntity();
  137. virtual void LevelInitPostEntity();
  138. int GetStatCount();
  139. void AddClientCSGOGameEvent( CSClientCsgoGameEventType_t eEvent, Vector const &pos, QAngle const &ang, uint64 ullData = 0ull, char const *szMapName = NULL, int16 nRound = CSCLIENTCSGOGAMEEVENTTYPE_AUTODETECT_INT16, int16 nRoundSecondsElapsed = CSCLIENTCSGOGAMEEVENTTYPE_AUTODETECT_INT16 );
  140. PlayerStatData_t GetStatById(int id, int nUserSlot );
  141. void ResetAllStats( int nUserSlot );
  142. void ResetAllStatsAndAchievements( void );
  143. void ResetMatchStats( void );
  144. void UpdateLastMatchStats( void );
  145. // [jhail] Reset the round stats
  146. void ResetRoundStats( void );
  147. // [jhail] Reset all leaderboard data on partnernet. Does not work on retail builds/hardware.
  148. void ResetLeaderboardStats( void );
  149. void IncrementMatchmakingData( const StatsCollection_t &stats );
  150. void UpdateMatchmakingData( void );
  151. void ResetMatchmakingData( MatchmakingDataScope mmDataScope );
  152. const StatsCollection_t& GetLifetimeStats( int nUserSlot );
  153. const StatsCollection_t& GetMatchStats( int nUserSlot );
  154. // [jhail] Retrieve the per-round stats
  155. const StatsCollection_t& GetRoundStats( int nUserSlot );
  156. bool MsgFunc_PlayerStatsUpdate( const CCSUsrMsg_PlayerStatsUpdate &msg );
  157. bool ValidateTitleBlockVersion( struct TitleDataFieldsDescription_t const *pFields, class IPlayerLocal *pPlayerLocal, CSSyncStatValueDirection_t eOp, int titleBlockNo );
  158. bool SyncCSStatsToTitleData( int iController, CSSyncStatValueDirection_t eOp );
  159. bool SyncCSLoadoutsToTitleData( int iController, CSSyncStatValueDirection_t eOp );
  160. bool SyncCSMatchmakingDataToTitleData( int iController, CSSyncStatValueDirection_t eOp );
  161. bool SyncCSRankingDataToTitleData( int iController, CSSyncStatValueDirection_t eOp );
  162. // [jhail] write stats to the leaderboard
  163. void WriteLeaderboardStats( void );
  164. // Public OGS functions and data
  165. #if !defined( _GAMECONSOLE )
  166. virtual void SubmitGameStats( KeyValues *pKV )
  167. {
  168. int listCount = s_StatLists->Count();
  169. for( int i=0; i < listCount; ++i )
  170. {
  171. // Create a master key value that has stats everybody should share (map name, session ID, etc)
  172. (*s_StatLists)[i]->SendData(pKV);
  173. (*s_StatLists)[i]->Clear();
  174. }
  175. }
  176. virtual StatContainerList_t* GetStatContainerList( void )
  177. {
  178. return s_StatLists;
  179. }
  180. void UploadRoundStats();
  181. #endif
  182. CUserMessageBinder m_UMCMsgPlayerStatsUpdate;
  183. CUserMessageBinder m_UMCMsgXRankGet;
  184. CUserMessageBinder m_UMCMsgXRankUpd;
  185. protected:
  186. void FireGameEvent( IGameEvent *event );
  187. void UpdateSteamStats();
  188. void RetrieveSteamStats();
  189. void UpdateStats( const StatsCollection_t &stats, int nUserSlot );
  190. void CalculateMatchFavoriteWeapons();
  191. private:
  192. struct CsgoGameEvent_t
  193. {
  194. CSClientCsgoGameEventType_t m_eEvent;
  195. Vector m_pos;
  196. QAngle m_ang;
  197. uint64 m_ullData;
  198. CUtlSymbol m_symMap;
  199. int16 m_nRound;
  200. int16 m_numRoundSeconds;
  201. bool m_bRequireMoreReliableUpload;
  202. };
  203. CUtlVector< CsgoGameEvent_t > m_arrClientCsgoGameEvents;
  204. StatsCollection_t m_lifetimeStats[MAX_SPLITSCREEN_PLAYERS];
  205. StatsCollection_t m_matchStats[MAX_SPLITSCREEN_PLAYERS];
  206. StatsCollection_t m_roundStats[MAX_SPLITSCREEN_PLAYERS];
  207. // Value of the lifetime stats collection last time we updated steam with our current values.
  208. // we keep this to prevent spamming IPC calls for stats that haven't changed.
  209. StatsCollection_t m_lifetimeStatsLastUpload[MAX_SPLITSCREEN_PLAYERS];
  210. int m_matchMaxPlayerCount;
  211. bool m_bSteamStatsDownload;
  212. // Private OGS functions and data
  213. #if !defined( _GAMECONSOLE )
  214. int m_RoundEndReason;
  215. bool m_bObjectiveAttempted;
  216. // A static list of all the stat containers, one for each data structure being tracked
  217. static StatContainerList_t * s_StatLists;
  218. #endif
  219. };
  220. extern CCSClientGameStats g_CSClientGameStats;
  221. #ifdef _X360
  222. #define MAX_PROPS_CONTRIBSCORE 8
  223. #define MAX_PROPS_KILLDEATH 6
  224. #define MAX_PROPS_WINS 7
  225. #define MAX_PROPS_STARS 5
  226. #define MAX_PROPS_GAMESPLAYED 23
  227. #define NUM_VIEW_PROPERTIES 5
  228. class CAsyncLeaderboardWriteThread
  229. {
  230. public:
  231. CAsyncLeaderboardWriteThread();
  232. ~CAsyncLeaderboardWriteThread();
  233. struct LeaderboardWriteData_t
  234. {
  235. int userID;
  236. XUID xuid;
  237. XSESSION_VIEW_PROPERTIES viewProperties[NUM_VIEW_PROPERTIES];
  238. XUSER_PROPERTY propertiesContribScore[MAX_PROPS_CONTRIBSCORE];
  239. XUSER_PROPERTY propertiesKillDeath[MAX_PROPS_KILLDEATH];
  240. XUSER_PROPERTY propertiesWins[MAX_PROPS_WINS];
  241. XUSER_PROPERTY propertiesStars[MAX_PROPS_STARS];
  242. XUSER_PROPERTY propertiesGamesPlayed[MAX_PROPS_GAMESPLAYED];
  243. };
  244. LeaderboardWriteData_t* CreateLeaderboardWriteData( void );
  245. static unsigned CallbackThreadProc( void *pvParam ) { reinterpret_cast<CAsyncLeaderboardWriteThread*>(pvParam)->ThreadProc(); return 0; }
  246. void ThreadProc( void );
  247. void QueueData( LeaderboardWriteData_t* pData );
  248. protected:
  249. ThreadHandle_t m_hThread;
  250. CThreadFastMutex m_mutex;
  251. CUtlVector<LeaderboardWriteData_t*> m_queue;
  252. HANDLE m_hEvent;
  253. };
  254. void MsgFunc_ClientInfo( bf_read &msg );
  255. #endif // _X360
  256. #endif //CS_STEAMSTATS_H