1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
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
|