|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef CS_GAMESTATS_SHARED_H
#define CS_GAMESTATS_SHARED_H
#ifdef _WIN32
#pragma once
#endif
#include "cbase.h"
// #include "tier1/utlvector.h"
// #include "tier1/utldict.h"
#include "shareddefs.h"
#include "cs_shareddefs.h"
#include "cs_weapon_parse.h"
#include "fmtstr.h"
#define CS_NUM_LEVELS 18
//=============================================================================
// Helper class for simple manipulation of bit arrays.
// Used for server->client packets containing delta stats
//=============================================================================
template <int BitLength> class BitArray { enum { ByteLength = (BitLength + 7) / 8 }; public: BitArray() { ClearAll(); }
void SetBit(int n) { m_bytes[n / 8] |= 1 << (n & 7); } void ClearBit(int n) { m_bytes[n / 8] &= (~(1 << (n & 7))); } bool IsBitSet(int n) const { return (m_bytes[n / 8] & (1 << (n & 7))) != 0;}
void ClearAll() { V_memset(m_bytes, 0, sizeof(m_bytes)); } int NumBits() { return BitLength; } int NumBytes() { return ByteLength; }
byte* RawPointer() { return m_bytes; }
private: byte m_bytes[ByteLength]; };
//=============================================================================
//
// CS Game Stats Enums
//
// WARNING! ANY CHANGE TO THE ORDERING OR NUMBER OF STATS WILL REQUIRE
// SYNCHRONOUS UPDATE OF CLIENT AND SERVER DLLS. If you change these enums
// (including adding new stats) without forcing an update of both the client
// and server, stats will become corrupted on the game client and these
// corrupted values will be uploaded to steam, which is very very bad.
//
// If you add new stats, if will be safest to add them at the end of the enum
// (although this will still require a server update); make sure you also add
// the stats to the CSStatProperty_Table in cs_gamestats_shared.cpp at the
// appropriate location.
enum CSStatType_t { CSSTAT_UNDEFINED = -1, CSSTAT_SHOTS_HIT, CSSTAT_SHOTS_FIRED, CSSTAT_KILLS, CSSTAT_DEATHS, CSSTAT_DAMAGE, CSSTAT_NUM_BOMBS_PLANTED, CSSTAT_NUM_BOMBS_DEFUSED, CSSTAT_PLAYTIME, CSSTAT_ROUNDS_WON, CSSTAT_T_ROUNDS_WON, CSSTAT_CT_ROUNDS_WON, CSSTAT_ROUNDS_PLAYED, CSSTAT_PISTOLROUNDS_WON, CSSTAT_MONEY_EARNED, CSSTAT_OBJECTIVES_COMPLETED, CSSTAT_BOMBS_DEFUSED_WITHKIT,
CSSTAT_KILLS_DEAGLE, CSSTAT_KILLS_USP, CSSTAT_KILLS_GLOCK, CSSTAT_KILLS_P228, CSSTAT_KILLS_ELITE, CSSTAT_KILLS_FIVESEVEN, CSSTAT_KILLS_AWP, CSSTAT_KILLS_AK47, CSSTAT_KILLS_M4A1, CSSTAT_KILLS_AUG, CSSTAT_KILLS_SG552, CSSTAT_KILLS_SG550, CSSTAT_KILLS_GALIL, CSSTAT_KILLS_FAMAS, CSSTAT_KILLS_SCOUT, CSSTAT_KILLS_G3SG1, CSSTAT_KILLS_P90, CSSTAT_KILLS_MP5NAVY, CSSTAT_KILLS_TMP, CSSTAT_KILLS_MAC10, CSSTAT_KILLS_UMP45, CSSTAT_KILLS_M3, CSSTAT_KILLS_XM1014, CSSTAT_KILLS_M249, CSSTAT_KILLS_KNIFE, CSSTAT_KILLS_HEGRENADE,
CSSTAT_SHOTS_DEAGLE, CSSTAT_SHOTS_USP, CSSTAT_SHOTS_GLOCK, CSSTAT_SHOTS_P228, CSSTAT_SHOTS_ELITE, CSSTAT_SHOTS_FIVESEVEN, CSSTAT_SHOTS_AWP, CSSTAT_SHOTS_AK47, CSSTAT_SHOTS_M4A1, CSSTAT_SHOTS_AUG, CSSTAT_SHOTS_SG552, CSSTAT_SHOTS_SG550, CSSTAT_SHOTS_GALIL, CSSTAT_SHOTS_FAMAS, CSSTAT_SHOTS_SCOUT, CSSTAT_SHOTS_G3SG1, CSSTAT_SHOTS_P90, CSSTAT_SHOTS_MP5NAVY, CSSTAT_SHOTS_TMP, CSSTAT_SHOTS_MAC10, CSSTAT_SHOTS_UMP45, CSSTAT_SHOTS_M3, CSSTAT_SHOTS_XM1014, CSSTAT_SHOTS_M249, CSSTAT_SHOTS_KNIFE, CSSTAT_SHOTS_HEGRENADE,
CSSTAT_HITS_DEAGLE, CSSTAT_HITS_USP, CSSTAT_HITS_GLOCK, CSSTAT_HITS_P228, CSSTAT_HITS_ELITE, CSSTAT_HITS_FIVESEVEN, CSSTAT_HITS_AWP, CSSTAT_HITS_AK47, CSSTAT_HITS_M4A1, CSSTAT_HITS_AUG, CSSTAT_HITS_SG552, CSSTAT_HITS_SG550, CSSTAT_HITS_GALIL, CSSTAT_HITS_FAMAS, CSSTAT_HITS_SCOUT, CSSTAT_HITS_G3SG1, CSSTAT_HITS_P90, CSSTAT_HITS_MP5NAVY, CSSTAT_HITS_TMP, CSSTAT_HITS_MAC10, CSSTAT_HITS_UMP45, CSSTAT_HITS_M3, CSSTAT_HITS_XM1014, CSSTAT_HITS_M249, CSSTAT_HITS_KNIFE, CSSTAT_HITS_HEGRENADE,
CSSTAT_DAMAGE_DEAGLE, CSSTAT_DAMAGE_USP, CSSTAT_DAMAGE_GLOCK, CSSTAT_DAMAGE_P228, CSSTAT_DAMAGE_ELITE, CSSTAT_DAMAGE_FIVESEVEN, CSSTAT_DAMAGE_AWP, CSSTAT_DAMAGE_AK47, CSSTAT_DAMAGE_M4A1, CSSTAT_DAMAGE_AUG, CSSTAT_DAMAGE_SG552, CSSTAT_DAMAGE_SG550, CSSTAT_DAMAGE_GALIL, CSSTAT_DAMAGE_FAMAS, CSSTAT_DAMAGE_SCOUT, CSSTAT_DAMAGE_G3SG1, CSSTAT_DAMAGE_P90, CSSTAT_DAMAGE_MP5NAVY, CSSTAT_DAMAGE_TMP, CSSTAT_DAMAGE_MAC10, CSSTAT_DAMAGE_UMP45, CSSTAT_DAMAGE_M3, CSSTAT_DAMAGE_XM1014, CSSTAT_DAMAGE_M249, CSSTAT_DAMAGE_KNIFE, CSSTAT_DAMAGE_HEGRENADE,
CSSTAT_KILLS_HEADSHOT, CSSTAT_KILLS_ENEMY_BLINDED, CSSTAT_KILLS_WHILE_BLINDED, CSSTAT_KILLS_WITH_LAST_ROUND, CSSTAT_KILLS_ENEMY_WEAPON, CSSTAT_KILLS_KNIFE_FIGHT, CSSTAT_KILLS_WHILE_DEFENDING_BOMB,
CSSTAT_DECAL_SPRAYS, CSSTAT_TOTAL_JUMPS, CSSTAT_NIGHTVISION_DAMAGE, CSSTAT_KILLS_WHILE_LAST_PLAYER_ALIVE, CSSTAT_KILLS_ENEMY_WOUNDED, CSSTAT_FALL_DAMAGE,
CSSTAT_NUM_HOSTAGES_RESCUED,
CSSTAT_NUM_BROKEN_WINDOWS, CSSTAT_PROPSBROKEN_ALL, CSSTAT_PROPSBROKEN_MELON, CSSTAT_PROPSBROKEN_OFFICEELECTRONICS, CSSTAT_PROPSBROKEN_OFFICERADIO, CSSTAT_PROPSBROKEN_OFFICEJUNK, CSSTAT_PROPSBROKEN_ITALY_MELON,
CSSTAT_KILLS_AGAINST_ZOOMED_SNIPER,
CSSTAT_WEAPONS_DONATED,
CSSTAT_ITEMS_PURCHASED, CSSTAT_MONEY_SPENT,
CSSTAT_DOMINATIONS, CSSTAT_DOMINATION_OVERKILLS, CSSTAT_REVENGES,
CSSTAT_MVPS,
CSSTAT_GRENADE_DAMAGE, CSSTAT_GRENADE_POSTHUMOUSKILLS, CSSTAT_GRENADES_THROWN,
CSTAT_ITEMS_DROPPED_VALUE,
//Map win stats
CSSTAT_MAP_WINS_CS_ASSAULT, CSSTAT_MAP_WINS_CS_COMPOUND, CSSTAT_MAP_WINS_CS_HAVANA, CSSTAT_MAP_WINS_CS_ITALY, CSSTAT_MAP_WINS_CS_MILITIA, CSSTAT_MAP_WINS_CS_OFFICE, CSSTAT_MAP_WINS_DE_AZTEC, CSSTAT_MAP_WINS_DE_CBBLE, CSSTAT_MAP_WINS_DE_CHATEAU, CSSTAT_MAP_WINS_DE_DUST2, CSSTAT_MAP_WINS_DE_DUST, CSSTAT_MAP_WINS_DE_INFERNO, CSSTAT_MAP_WINS_DE_NUKE, CSSTAT_MAP_WINS_DE_PIRANESI, CSSTAT_MAP_WINS_DE_PORT, CSSTAT_MAP_WINS_DE_PRODIGY, CSSTAT_MAP_WINS_DE_TIDES, CSSTAT_MAP_WINS_DE_TRAIN,
CSSTAT_MAP_ROUNDS_CS_ASSAULT, CSSTAT_MAP_ROUNDS_CS_COMPOUND, CSSTAT_MAP_ROUNDS_CS_HAVANA, CSSTAT_MAP_ROUNDS_CS_ITALY, CSSTAT_MAP_ROUNDS_CS_MILITIA, CSSTAT_MAP_ROUNDS_CS_OFFICE, CSSTAT_MAP_ROUNDS_DE_AZTEC, CSSTAT_MAP_ROUNDS_DE_CBBLE, CSSTAT_MAP_ROUNDS_DE_CHATEAU, CSSTAT_MAP_ROUNDS_DE_DUST2, CSSTAT_MAP_ROUNDS_DE_DUST, CSSTAT_MAP_ROUNDS_DE_INFERNO, CSSTAT_MAP_ROUNDS_DE_NUKE, CSSTAT_MAP_ROUNDS_DE_PIRANESI, CSSTAT_MAP_ROUNDS_DE_PORT, CSSTAT_MAP_ROUNDS_DE_PRODIGY, CSSTAT_MAP_ROUNDS_DE_TIDES, CSSTAT_MAP_ROUNDS_DE_TRAIN,
CSSTAT_LASTMATCH_T_ROUNDS_WON, CSSTAT_LASTMATCH_CT_ROUNDS_WON, CSSTAT_LASTMATCH_ROUNDS_WON, CSSTAT_LASTMATCH_KILLS, CSSTAT_LASTMATCH_DEATHS, CSSTAT_LASTMATCH_MVPS, CSSTAT_LASTMATCH_DAMAGE, CSSTAT_LASTMATCH_MONEYSPENT, CSSTAT_LASTMATCH_DOMINATIONS, CSSTAT_LASTMATCH_REVENGES, CSSTAT_LASTMATCH_MAX_PLAYERS, CSSTAT_LASTMATCH_FAVWEAPON_ID, CSSTAT_LASTMATCH_FAVWEAPON_SHOTS, CSSTAT_LASTMATCH_FAVWEAPON_HITS, CSSTAT_LASTMATCH_FAVWEAPON_KILLS,
CSSTAT_MAX //Must be last entry.
};
#define CSSTAT_FIRST (CSSTAT_UNDEFINED+1)
#define CSSTAT_LAST (CSSTAT_MAX-1)
//
// CS Game Stats Flags
//
#define CSSTAT_PRIORITY_MASK 0x000F
#define CSSTAT_PRIORITY_NEVER 0x0000 // not sent to client
#define CSSTAT_PRIORITY_ENDROUND 0x0001 // sent at end of round
#define CSSTAT_PRIORITY_LOW 0x0002 // sent every 2500ms
#define CSSTAT_PRIORITY_HIGH 0x0003 // sent every 250ms
struct CSStatProperty { int statId; // verify that table ordering is correct
const char* szSteamName; // name of the stat on steam
const char* szLocalizationToken; // localization token for the stat
uint flags; // priority flags for sending to client
};
extern CSStatProperty CSStatProperty_Table[];
//=============================================================================
//
// CS Player Round Stats
//
struct StatsCollection_t { StatsCollection_t() { Reset(); }
inline int Get( int i ) const { AssertMsg( i >= CSSTAT_FIRST && i < CSSTAT_MAX, "Stat index out of range!" ); if ( i >= 0 ) return m_iValue[ i ]; return 0; }
inline void Set( int i, int nValue ) { AssertMsg( i >= CSSTAT_FIRST && i < CSSTAT_MAX, "Stat index out of range!" ); if ( i >= 0 ) m_iValue[ i ] = nValue; }
void Reset() { for ( int i = 0; i < ARRAYSIZE( m_iValue ); i++ ) { m_iValue[i] = 0; } }
int operator[] ( int index ) const { Assert(index >= 0 && index < ARRAYSIZE(m_iValue)); return m_iValue[index]; }
int& operator[] ( int index ) { Assert(index >= 0 && index < ARRAYSIZE(m_iValue)); return m_iValue[index]; }
void Aggregate( const StatsCollection_t& other );
private: int m_iValue[CSSTAT_MAX]; };
//=============================================================================
// HPE_BEGIN:
// [tj] A couple variations on the RoundStats structure to handle extra operations
// for averaging and accumulating
//=============================================================================
struct RoundStatsDirectAverage_t { float m_fStat[CSSTAT_MAX];
RoundStatsDirectAverage_t() { Reset(); }
void Reset() { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] = 0; } }
RoundStatsDirectAverage_t& operator +=( const StatsCollection_t &other ) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] += other[i]; } return *this; }
RoundStatsDirectAverage_t& operator /=( const float &divisor) { if (divisor > 0) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] /= divisor; } } return *this; }
RoundStatsDirectAverage_t& operator *=( const float &divisor) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] *= divisor; } return *this; } };
struct RoundStatsRollingAverage_t { float m_fStat[CSSTAT_MAX]; int m_numberOfDataSets;
RoundStatsRollingAverage_t() { Reset(); }
void Reset() { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] = 0; } m_numberOfDataSets = 0; }
RoundStatsRollingAverage_t& operator +=( const RoundStatsRollingAverage_t &other ) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] += other.m_fStat[i]; } return *this; }
RoundStatsRollingAverage_t& operator +=( const StatsCollection_t &other ) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] += other[i]; } return *this; }
RoundStatsRollingAverage_t& operator /=( const float &divisor) { if (divisor > 0) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] /= divisor; } } return *this; }
void RollDataSetIntoAverage ( const RoundStatsRollingAverage_t &other ) { for ( int i = 0; i < ARRAYSIZE( m_fStat ); i++ ) { m_fStat[i] *= m_numberOfDataSets; m_fStat[i] += other.m_fStat[i]; m_fStat[i] /= (m_numberOfDataSets + 1); } m_numberOfDataSets++; } }; //=============================================================================
// HPE_END
//=============================================================================
enum CSGameStatsVersions_t { CS_GAMESTATS_FILE_VERSION = 006, CS_GAMESTATS_MAGIC = 0xDEADBEEF };
struct CS_Gamestats_Version_t { int m_iMagic; // always CS_GAMESTATS_MAGIC
int m_iVersion; };
struct KillStats_t { KillStats_t() { Reset(); }
void Reset() { Q_memset( iNumKilled, 0, sizeof( iNumKilled ) ); Q_memset( iNumKilledBy, 0, sizeof( iNumKilledBy ) ); Q_memset( iNumKilledByUnanswered, 0, sizeof( iNumKilledByUnanswered ) ); }
int iNumKilled[MAX_PLAYERS+1]; // how many times this player has killed each other player
int iNumKilledBy[MAX_PLAYERS+1]; // how many times this player has been killed by each other player
int iNumKilledByUnanswered[MAX_PLAYERS+1]; // how many unanswered kills this player has been dealt by each other player
};
//=============================================================================
//
// CS Player Stats
//
struct PlayerStats_t { PlayerStats_t() { Reset(); }
void Reset() { statsDelta.Reset(); statsCurrentRound.Reset(); statsCurrentMatch.Reset(); statsKills.Reset(); }
PlayerStats_t( const PlayerStats_t &other ) { statsDelta = other.statsDelta; statsCurrentRound = other.statsCurrentRound; statsCurrentMatch = other.statsCurrentMatch; }
StatsCollection_t statsDelta; StatsCollection_t statsCurrentRound; StatsCollection_t statsCurrentMatch; KillStats_t statsKills; };
struct WeaponName_StatId { CSWeaponID weaponId; CSStatType_t killStatId; CSStatType_t shotStatId; CSStatType_t hitStatId; CSStatType_t damageStatId; };
struct MapName_MapStatId { const char* szMapName; CSStatType_t statWinsId; CSStatType_t statRoundsId; };
extern const MapName_MapStatId MapName_StatId_Table[];
//A mapping from weapon names to weapon stat IDs
extern const WeaponName_StatId WeaponName_StatId_Table[];
//Used to look up the appropriate entry by the ID of the actual weapon
const WeaponName_StatId& GetWeaponTableEntryFromWeaponId(CSWeaponID id);
#include "steamworks_gamestats.h"
//=============================================================================
//
// Helper functions for creating key values
//
void AddDataToKV( KeyValues* pKV, const char* name, int data ); void AddDataToKV( KeyValues* pKV, const char* name, uint64 data ); void AddDataToKV( KeyValues* pKV, const char* name, float data ); void AddDataToKV( KeyValues* pKV, const char* name, bool data ); void AddDataToKV( KeyValues* pKV, const char* name, const char* data ); void AddDataToKV( KeyValues* pKV, const char* name, const Color& data ); void AddDataToKV( KeyValues* pKV, const char* name, short data ); void AddDataToKV( KeyValues* pKV, const char* name, unsigned data ); void AddDataToKV( KeyValues* pKV, const char* name, const Vector& data ); void AddPositionDataToKV( KeyValues* pKV, const char* name, const Vector &data ); //=============================================================================
//=============================================================================
//
// Helper functions for creating key values from arrays
//
void AddArrayDataToKV( KeyValues* pKV, const char* name, const short *data, unsigned size ); void AddArrayDataToKV( KeyValues* pKV, const char* name, const byte *data, unsigned size ); void AddArrayDataToKV( KeyValues* pKV, const char* name, const unsigned *data, unsigned size ); void AddStringDataToKV( KeyValues* pKV, const char* name, const char *data );
//=============================================================================
// Macros to ease the creation of SendData method for stats structs/classes
#define BEGIN_STAT_TABLE( tableName ) \
static const char* GetStatTableName( void ) { return tableName; } \ void BuildGamestatDataTable( KeyValues* pKV ) \ { \ pKV->SetName( GetStatTableName() );
#define REGISTER_STAT( varName ) \
AddDataToKV(pKV, #varName, varName);
#define REGISTER_STAT_NAMED( varName, dbName ) \
AddDataToKV(pKV, dbName, varName);
#define REGISTER_STAT_POSITION( varName ) \
AddPositionDataToKV(pKV, #varName, varName);
#define REGISTER_STAT_POSITION_NAMED( varName, dbName ) \
AddPositionDataToKV(pKV, dbName, varName);
#define REGISTER_STAT_ARRAY( varName ) \
AddArrayDataToKV( pKV, #varName, varName, ARRAYSIZE( varName ) );
#define REGISTER_STAT_ARRAY_NAMED( varName, dbName ) \
AddArrayDataToKV( pKV, dbName, varName, ARRAYSIZE( varName ) );
#define REGISTER_STAT_STRING( varName ) \
AddStringDataToKV( pKV, #varName, varName );
#define REGISTER_STAT_STRING_NAMED( varName, dbName ) \
AddStringDataToKV( pKV, dbName, varName );
#define AUTO_STAT_TABLE_KEY() \
pKV->SetInt( "TimeSubmitted", GetUniqueIDForStatTable( *this ) );
#define END_STAT_TABLE() \
pKV->SetUint64( ::BaseStatData::m_bUseGlobalData ? "TimeSubmitted" : "SessionTime", ::BaseStatData::TimeSubmitted ); \ GetSteamWorksSGameStatsUploader().AddStatsForUpload( pKV ); \ }
//-----------------------------------------------------------------------------
// Purpose: Templatized class for getting unique ID's for stat tables that need
// to be submitted multiple times per-session.
//-----------------------------------------------------------------------------
template < typename T > class UniqueStatID_t { public: static unsigned GetNext( void ) { return ++s_nLastID; }
static void Reset( void ) { s_nLastID = 0; }
private: static unsigned s_nLastID; };
template < typename T > unsigned UniqueStatID_t< T >::s_nLastID = 0;
template < typename T > unsigned GetUniqueIDForStatTable( const T &table ) { return UniqueStatID_t< T >::GetNext(); }
//=============================================================================
//
// An interface for tracking gamestats.
//
class IGameStatTracker { public:
//-----------------------------------------------------------------------------
// Templatized methods to track a per-mission stat.
// The stat is copied, then deleted after it's sent to the SQL server.
//-----------------------------------------------------------------------------
template < typename T > void SubmitStat( T& stat ) { // Make a copy of the stat. All of the stat lists require pointers,
// so we need to protect against a stat allocated on the stack
T* pT = new T(); if( !pT ) return;
*pT = stat; SubmitStat( pT ); }
//-----------------------------------------------------------------------------
// Templatized methods to track a per-mission stat (by pointer)
// The stat is deleted after it's sent to the SQL server
//-----------------------------------------------------------------------------
template < typename T > void SubmitStat( T* pStat ) { // Get the static stat table for this type and add the stat to it
GetStatTable<T>()->AddToTail( pStat ); }
//-----------------------------------------------------------------------------
// Add all stats to an existing key value file for submit.
//-----------------------------------------------------------------------------
virtual void SubmitGameStats( KeyValues *pKV ) = 0;
//-----------------------------------------------------------------------------
// Prints the memory usage of all of the stats being tracked
//-----------------------------------------------------------------------------
void PrintGamestatMemoryUsage( void );
protected: //=============================================================================
//
// Used as a base interface to store a list of all templatized stat containers
//
class IStatContainer { public: virtual void SendData( KeyValues *pKV ) = 0; virtual void Clear( void ) = 0; virtual void PrintMemoryUsage( void ) = 0; };
// Defines a list of stat containers.
typedef CUtlVector< IStatContainer* > StatContainerList_t;
//-----------------------------------------------------------------------------
// Used to get a list of all stats containers being tracked by the deriving class
//-----------------------------------------------------------------------------
virtual StatContainerList_t* GetStatContainerList( void ) = 0;
private:
//=============================================================================
//
// Templatized list of stats submitted
//
template < typename T > class CGameStatList : public IStatContainer, public CUtlVector< T* > { public: //-----------------------------------------------------------------------------
// Get data ready to send to the SQL server
//-----------------------------------------------------------------------------
virtual void SendData( KeyValues *pKV ) { //ASSERT( pKV != NULL );
// Duplicate the master KeyValue for each stat instance
for( int i=0; i < this->m_Size; ++i ) { // Make a copy of the master key value and build the stat table
KeyValues *pKVCopy = this->operator [](i)->m_bUseGlobalData ? pKV->MakeCopy() : new KeyValues( "" ); this->operator [](i)->BuildGamestatDataTable( pKVCopy ); }
// Reset unique ID counter for the stat type
UniqueStatID_t< T >::Reset(); }
//-----------------------------------------------------------------------------
// Clear and delete every stat in this list
//-----------------------------------------------------------------------------
virtual void Clear( void ) { this->PurgeAndDeleteElements(); }
//-----------------------------------------------------------------------------
// Print out details about this lists memory usage
//-----------------------------------------------------------------------------
virtual void PrintMemoryUsage( void ) { if( this->m_Size == 0 ) return;
// Compute the memory used as the size of type times the list count
unsigned uMemoryUsed = this->m_Size * ( sizeof( T ) );
Msg( " %d\tbytes used by %s table\n", uMemoryUsed, T::GetStatTableName() ); } };
//-----------------------------------------------------------------------------
// Templatized method to get a single instance of a stat list per data type.
//-----------------------------------------------------------------------------
template < typename T > CGameStatList< T >* GetStatTable( void ) { static CGameStatList< T > *s_vecOfType = 0; if( s_vecOfType == 0 ) { s_vecOfType = new CGameStatList< T >(); GetStatContainerList()->AddToTail( s_vecOfType ); } return s_vecOfType; }
};
struct BaseStatData { BaseStatData( bool bUseGlobalData = true ) : m_bUseGlobalData( bUseGlobalData ) { TimeSubmitted = GetSteamWorksSGameStatsUploader().GetTimeSinceEpoch(); }
bool m_bUseGlobalData; uint64 TimeSubmitted;
};
extern ConVar sv_noroundstats;
#endif // CS_GAMESTATS_SHARED_H
|