void CEP2GameStats::Event_LoadGame( void ) { BaseClass::Event_LoadGame(); Ep2LevelStats_t *map = m_pCurrentMap; if ( !map ) return; ++map->m_IntCounters[ Ep2LevelStats_t::COUNTER_LOADS ]; StatsLog( " %I64uth load on this map\n", map->m_IntCounters[ Ep2LevelStats_t::COUNTER_LOADS ] ); char const *pchSaveFile = engine->GetMostRecentlyLoadedFileName(); if ( !pchSaveFile || !pchSaveFile[ 0 ] ) return; char name[ 512 ]; Q_snprintf( name, sizeof( name ), "SAVE/%s", pchSaveFile ); Q_DefaultExtension( name, IsX360() ? ".360.sav" : ".sav", sizeof( name ) ); Q_FixSlashes( name ); Q_strlower( name ); Ep2LevelStats_t::SaveGameInfo_t *pSaveGameInfo = &map->m_SaveGameInfo; if ( pSaveGameInfo->m_nCurrentSaveFileTime == 0 || pSaveGameInfo->m_sCurrentSaveFile != name ) { unsigned int uFileTime = filesystem->GetFileTime( name, "GAME" ); // Latch off previous StatsLog( "Relatching save game file due to time or filename change (%s : %u)\n", name, uFileTime ); pSaveGameInfo->Latch( name, uFileTime ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CEP2GameStats::Event_PlayerKilled( CBasePlayer *pPlayer, const CTakeDamageInfo &info ) { BaseClass::Event_PlayerKilled( pPlayer, info ); if ( info.GetDamageType() & DMG_FALL ) { ++m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_FALLINGDEATHS ]; } Ep2LevelStats_t::PlayerDeathsLump_t death; // set the location where the target died const Vector &org = pPlayer->GetAbsOrigin(); death.nPosition[ 0 ] = static_cast<short>( org.x ); death.nPosition[ 1 ] = static_cast<short>( org.y ); death.nPosition[ 2 ] = static_cast<short>( org.z ); StatsLog( "CEP2GameStats::Event_PlayerKilled at location [%d %d %d]\n", (int)death.nPosition[ 0 ], (int)death.nPosition[ 1 ], (int)death.nPosition[ 2 ] ); // set the class of the attacker CBaseEntity *pInflictor = info.GetInflictor(); CBaseEntity *pKiller = info.GetAttacker(); if ( pInflictor ) { StatsLog( "Inflictor: %s\n", pInflictor->GetClassname() ); } if ( pKiller ) { char const *pchKiller = pKiller->GetClassname(); Ep2LevelStats_t::EntityDeathsLump_t *lump = FindDeathsLump( pchKiller ); if ( lump ) { ++lump->m_nKilledPlayer; StatsLog( "Player has been killed %d times by %s's\n", lump->m_nKilledPlayer, pchKiller ); } else { StatsLog( "Player killed by %s (not tracked)\n", pchKiller ); } } // add it to the list of deaths Ep2LevelStats_t *map = FindOrAddMapStats( STRING( gpGlobals->mapname ) ); int slot = map->m_aPlayerDeaths.AddToTail( death ); Ep2LevelStats_t::SaveGameInfoRecord2_t *rec = map->m_SaveGameInfo.m_pCurrentRecord; if ( rec ) { if ( rec->m_nFirstDeathIndex == -1 ) { rec->m_nFirstDeathIndex = slot; } ++rec->m_nNumDeaths; StatsLog( "Player has died %d times since last save/load\n", rec->m_nNumDeaths ); } }
void CBaseGameStats::Event_Shutdown( void ) { #ifdef GAME_DLL StatsLog( "CBaseGameStats::Event_Shutdown [%dth session]\n", m_BasicStats.m_Summary.m_nCount ); StatsLog( "\n====================================================================\n\n" ); #endif }
void CBaseGameStats::Event_LoadGame( void ) { #ifdef GAME_DLL char const *pchSaveFile = engine->GetMostRecentlyLoadedFileName(); StatsLog( "CBaseGameStats::Event_LoadGame [%s] from %s\n", CBGSDriver.m_PrevMapName.String(), pchSaveFile ); #endif }
void CBaseGameStats::Event_Credits() { StatsLog( "CBaseGameStats::Event_Credits\n" ); float elapsed = 0.0f; if( CBGSDriver.m_bInLevel ) { elapsed = gpGlobals->realtime - CBGSDriver.m_flLevelStartTime; } if( elapsed < 0.0f ) { Assert( 0 ); Warning( "EVENT_CREDITS with negative elapsed time (rt %f starttime %f)\n", gpGlobals->realtime, CBGSDriver.m_flLevelStartTime ); elapsed = 0.0f; } // Only set this one time!!! if( gamestats->m_BasicStats.m_nSecondsToCompleteGame == 0 ) { if( gamestats->UserPlayedAllTheMaps() ) { gamestats->m_BasicStats.m_nSecondsToCompleteGame = elapsed + gamestats->m_BasicStats.m_Summary.m_nSeconds; gamestats->SaveToFileNOW(); } } }
bool CBaseGameStats::SaveToFileNOW( bool bForceSyncWrite /* = false */ ) { if ( !StatsTrackingIsFullyEnabled() ) return false; // this code path is only for old format stats. Products that use new format take a different path. if ( !gamestats->UseOldFormat() ) return false; CUtlBuffer buf; buf.PutShort( GAMESTATS_FILE_VERSION ); buf.Put( s_szPseudoUniqueID, 16 ); if( ShouldTrackStandardStats() ) m_BasicStats.SaveToBuffer( buf ); else buf.PutInt( GAMESTATS_STANDARD_NOT_SAVED ); gamestats->AppendCustomDataToSaveBuffer( buf ); char fullpath[ 512 ] = { 0 }; if ( filesystem->FileExists( GetStatSaveFileName(), GAMESTATS_PATHID ) ) { filesystem->RelativePathToFullPath( GetStatSaveFileName(), GAMESTATS_PATHID, fullpath, sizeof( fullpath ) ); } else { // filename is local to game dir for Steam, so we need to prepend game dir for regular file save char gamePath[256]; engine->GetGameDir( gamePath, 256 ); Q_StripTrailingSlash( gamePath ); Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", gamePath, GetStatSaveFileName() ); Q_strlower( fullpath ); Q_FixSlashes( fullpath ); } // StatsLog( "SaveToFileNOW '%s'\n", fullpath ); if( CBGSDriver.m_bShuttingDown || bForceSyncWrite ) //write synchronously { filesystem->WriteFile( fullpath, GAMESTATS_PATHID, buf ); StatsLog( "Shut down wrote to '%s'\n", fullpath ); } else { // Allocate memory for async system to use (and free afterward!!!) size_t nBufferSize = buf.TellPut(); void *pMem = malloc(nBufferSize); CUtlBuffer statsBuffer( pMem, nBufferSize ); statsBuffer.Put( buf.Base(), nBufferSize ); // Write data async filesystem->AsyncWrite( fullpath, statsBuffer.Base(), statsBuffer.TellPut(), true, false ); } return true; }
void CEP2GameStats::Event_SaveGame( void ) { BaseClass::Event_SaveGame(); Ep2LevelStats_t *map = m_pCurrentMap; if ( !map ) return; ++map->m_IntCounters[ Ep2LevelStats_t::COUNTER_SAVES ]; StatsLog( " %I64uth save on this map\n", map->m_IntCounters[ Ep2LevelStats_t::COUNTER_SAVES ] ); char const *pchSaveFile = engine->GetSaveFileName(); if ( !pchSaveFile || !pchSaveFile[ 0 ] ) return; char name[ 512 ]; Q_strncpy( name, pchSaveFile, sizeof( name ) ); Q_strlower( name ); Q_FixSlashes( name ); unsigned int uFileTime = filesystem->GetFileTime( name, "GAME" ); // Latch off previous map->m_SaveGameInfo.Latch( name, uFileTime ); Ep2LevelStats_t::SaveGameInfoRecord2_t *rec = map->m_SaveGameInfo.m_pCurrentRecord; CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( pPlayer ) { Vector pos = pPlayer->GetAbsOrigin(); rec->m_nSavePos[ 0 ] = (short)pos.x; rec->m_nSavePos[ 1 ] = (short)pos.y; rec->m_nSavePos[ 2 ] = (short)pos.z; rec->m_nSaveHealth = clamp( pPlayer->GetHealth(), 0, 100 ); rec->m_SaveType = Q_stristr( pchSaveFile, "autosave" ) ? Ep2LevelStats_t::SaveGameInfoRecord2_t::TYPE_AUTOSAVE : Ep2LevelStats_t::SaveGameInfoRecord2_t::TYPE_USERSAVE; StatsLog( "save pos %i %i %i w/ health %d\n", rec->m_nSavePos[ 0 ], rec->m_nSavePos[ 1 ], rec->m_nSavePos[ 2 ], rec->m_nSaveHealth ); } }
void CBaseGameStats::Event_PlayerKilled( CBasePlayer *pPlayer, const CTakeDamageInfo &info ) { ++m_BasicStats.m_Summary.m_nDeaths; if( CBGSDriver.m_bInLevel ) { BasicGameStatsRecord_t *map = m_BasicStats.FindOrAddRecordForMap( CBGSDriver.m_PrevMapName.String() ); ++map->m_nDeaths; StatsLog( " Player died %dth time in level [%s]!!!\n", map->m_nDeaths, CBGSDriver.m_PrevMapName.String() ); } else { StatsLog( " Player died, but not in a level!!!\n" ); Assert( 0 ); } StatsLog( "CBaseGameStats::Event_PlayerKilled [%s] [%dth death]\n", pPlayer->GetPlayerName(), m_BasicStats.m_Summary.m_nDeaths ); }
void CEP2GameStats::Event_DecrementPlayerEnteredNoClip( CBasePlayer *pBasePlayer ) { BaseClass::Event_DecrementPlayerEnteredNoClip( pBasePlayer ); if ( m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_NOCLIPS ] > 0 ) { --m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_NOCLIPS ]; } StatsLog( "%I64u decrement entering NOCLIP (entering vehicle doesn't count)\n", m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_NOCLIPS ] ); }
void CBaseGameStats::Event_LevelShutdown( float flElapsed ) { BasicGameStatsRecord_t *map = m_BasicStats.FindOrAddRecordForMap( CBGSDriver.m_PrevMapName.String() ); Assert( map ); map->m_nSeconds += (int)flElapsed; gamestats->m_BasicStats.m_Summary.m_nSeconds += (int)flElapsed; StatsLog( "CBaseGameStats::Event_LevelShutdown [%s] %.2f elapsed %d total\n", CBGSDriver.m_PrevMapName.String(), flElapsed, gamestats->m_BasicStats.m_Summary.m_nSeconds ); }
void CBaseGameStats::Event_Commentary() { if( CBGSDriver.m_bInLevel ) { BasicGameStatsRecord_t *map = m_BasicStats.FindOrAddRecordForMap( CBGSDriver.m_PrevMapName.String() ); ++map->m_nCommentary; } ++m_BasicStats.m_Summary.m_nCommentary; StatsLog( "CBaseGameStats::Event_Commentary [%d]\n", m_BasicStats.m_Summary.m_nCommentary ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CEP2GameStats::Event_PlayerKilledOther( CBasePlayer *pAttacker, CBaseEntity *pVictim, const CTakeDamageInfo &info ) { BaseClass::Event_PlayerKilledOther( pAttacker, pVictim, info ); if ( pAttacker ) { StatsLog( "Attacker: %s\n", pAttacker->GetClassname() ); } if ( !pVictim ) { return; } char const *pchVictim = pVictim->GetClassname(); Ep2LevelStats_t::EntityDeathsLump_t *lump = FindDeathsLump( pchVictim ); if ( lump ) { ++lump->m_nBodyCount; StatsLog( "Player has killed %d %s's\n", lump->m_nBodyCount, pchVictim ); CPropVehicleDriveable *veh = dynamic_cast< CPropVehicleDriveable * >( pAttacker ); if ( !veh ) veh = dynamic_cast< CPropVehicleDriveable * >( info.GetInflictor() ); if ( veh ) { CBaseEntity *driver = veh->GetDriver(); if ( driver && driver->IsPlayer() ) { ++m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_VEHICULARHOMICIDES ]; StatsLog( " Vehicular homicide [%I64d] of %s's\n", m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_VEHICULARHOMICIDES ], pchVictim ); } } } else { StatsLog( "Player killed %s (not tracked)\n", pchVictim ); } }
void CBaseGameStats::Event_Init( void ) { SetHL2UnlockedChapterStatistic(); SetSteamStatistic( filesystem->IsSteam() ); SetCyberCafeStatistic( gamestatsuploader->IsCyberCafeUser() ); ConVarRef pDXLevel( "mat_dxlevel" ); if( pDXLevel.IsValid() ) { SetDXLevelStatistic( pDXLevel.GetInt() ); } ++m_BasicStats.m_Summary.m_nCount; StatsLog( "CBaseGameStats::Event_Init [%dth session]\n", m_BasicStats.m_Summary.m_nCount ); }
void CEP2GameStats::Event_PreSaveGameLoaded( char const *pSaveName, bool bInGame ) { BaseClass::Event_PreSaveGameLoaded( pSaveName, bInGame ); // Not currently in a level if ( !bInGame ) return; CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( !pPlayer ) return; // We're loading a saved game while the player is still alive (are they stuck?) if ( pPlayer->IsAlive() ) { ++m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_LOADGAME_STILLALIVE ]; StatsLog( "%I64u game loaded with living player\n", m_pCurrentMap->m_IntCounters[ Ep2LevelStats_t::COUNTER_LOADGAME_STILLALIVE ] ); } }
void CBaseGameStats::Event_LevelInit( void ) { StatsLog( "CBaseGameStats::Event_LevelInit [%s]\n", CBGSDriver.m_PrevMapName.String() ); BasicGameStatsRecord_t *map = gamestats->m_BasicStats.FindOrAddRecordForMap( CBGSDriver.m_PrevMapName.String() ); ++map->m_nCount; // HACK HACK: Punching this hole through only works in single player!!! if ( gpGlobals->maxClients == 1 ) { ConVarRef closecaption( "closecaption" ); if( closecaption.IsValid() ) SetCaptionsStatistic( closecaption.GetBool() ); SetHDRStatistic( gamestatsuploader->IsHDREnabled() ); SetSkillStatistic( skill.GetInt() ); SetSteamStatistic( filesystem->IsSteam() ); SetCyberCafeStatistic( gamestatsuploader->IsCyberCafeUser() ); } }
void CBaseGameStats::Event_IncrementCountedStatistic( const Vector& vecAbsOrigin, char const *pchStatisticName, float flIncrementAmount ) { StatsLog( "Incrementing %s by %f at pos (%d, %d, %d)\n", pchStatisticName, flIncrementAmount, (int)vecAbsOrigin.x, (int)vecAbsOrigin.y, (int)vecAbsOrigin.z ); }
void CBaseGameStats::Event_DecrementPlayerEnteredNoClip( CBasePlayer *pBasePlayer ) { StatsLog( "CBaseGameStats::Event_DecrementPlayerEnteredNoClip [%s] decrementing NOCLIPe\n", pBasePlayer->GetPlayerName() ); }
void CBaseGameStats::Event_PlayerEnteredGodMode( CBasePlayer *pBasePlayer ) { StatsLog( "CBaseGameStats::Event_PlayerEnteredGodMode [%s] entered GOD mode\n", pBasePlayer->GetPlayerName() ); }
void CBaseGameStats::Event_WeaponHit( CBasePlayer *pShooter, bool bPrimary, char const *pchWeaponName, const CTakeDamageInfo &info ) { StatsLog( "CBaseGameStats::Event_WeaponHit [%s] %s weapon [%s] damage [%f]\n", pShooter->GetPlayerName(), bPrimary ? "primary" : "secondary", pchWeaponName, info.GetDamage() ); }
void CBaseGameStats::Event_WeaponFired( CBasePlayer *pShooter, bool bPrimary, char const *pchWeaponName ) { StatsLog( "CBaseGameStats::Event_WeaponFired [%s] %s weapon [%s]\n", pShooter->GetPlayerName(), bPrimary ? "primary" : "secondary", pchWeaponName ); }
void CBaseGameStats::Event_PlayerKilledOther( CBasePlayer *pAttacker, CBaseEntity *pVictim, const CTakeDamageInfo &info ) { StatsLog( "CBaseGameStats::Event_PlayerKilledOther [%s] killed [%s]\n", pAttacker->GetPlayerName(), pVictim->GetClassname() ); }
void CBaseGameStats::Event_MapChange( const char *szOldMapName, const char *szNewMapName ) { StatsLog( "CBaseGameStats::Event_MapChange to [%s]\n", szNewMapName ); }
// Called before .sav file is actually loaded (player should still be in previous level, if any) void CBaseGameStats::Event_PreSaveGameLoaded( char const *pSaveName, bool bInGame ) { StatsLog( "CBaseGameStats::Event_PreSaveGameLoaded [%s] %s\n", pSaveName, bInGame ? "in-game" : "at console" ); }
void CBaseGameStats::Event_FlippedVehicle( CBasePlayer *pDriver, CPropVehicleDriveable *pVehicle ) { StatsLog( "CBaseGameStats::Event_FlippedVehicle [%s] flipped [%s]\n", pDriver->GetPlayerName(), pVehicle->GetClassname() ); }
void CBaseGameStats::Event_Punted( CBaseEntity *pObject ) { StatsLog( "CBaseGameStats::Event_Punted [%s]\n", pObject->GetClassname() ); }
void CBaseGameStats::Event_CrateSmashed() { StatsLog( "CBaseGameStats::Event_CrateSmashed\n" ); }
void CBaseGameStats::LoadingEvent_PlayerIDDifferentThanLoadedStats( void ) { StatsLog( "CBaseGameStats::LoadingEvent_PlayerIDDifferentThanLoadedStats\n" ); }
void CBaseGameStats::Event_PlayerDisconnected( CBasePlayer *pBasePlayer ) { StatsLog( "CBaseGameStats::Event_PlayerDisconnected\n", pBasePlayer->GetPlayerName() ); }
bool CBaseGameStats::LoadFromFile( void ) { if ( filesystem->FileExists( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID ) ) { char fullpath[ 512 ]; filesystem->RelativePathToFullPath( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID, fullpath, sizeof( fullpath ) ); StatsLog( "Loading stats from '%s'\n", fullpath ); } CUtlBuffer buf; if ( filesystem->ReadFile( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID, buf ) ) { bool bRetVal = true; int version = buf.GetShort(); if ( version > GAMESTATS_FILE_VERSION ) return false; //file is beyond our comprehension // Set global parse version CBGSDriver.m_iLoadedVersion = version; buf.Get( CBGSDriver.m_szLoadedUserID, 16 ); CBGSDriver.m_szLoadedUserID[ sizeof( CBGSDriver.m_szLoadedUserID ) - 1 ] = 0; if ( s_szPseudoUniqueID[ 0 ] != 0 ) { if ( Q_stricmp( CBGSDriver.m_szLoadedUserID, s_szPseudoUniqueID ) ) { //UserID changed, blow away log!!! filesystem->RemoveFile( gamestats->GetStatSaveFileName(), GAMESTATS_PATHID ); filesystem->RemoveFile( GAMESTATS_LOG_FILE, GAMESTATS_PATHID ); Warning( "Userid changed, clearing stats file\n" ); CBGSDriver.m_szLoadedUserID[0] = '\0'; CBGSDriver.m_iLoadedVersion = -1; gamestats->m_BasicStats.Clear(); gamestats->LoadingEvent_PlayerIDDifferentThanLoadedStats(); bRetVal = false; } if ( version <= GAMESTATS_FILE_VERSION_OLD5 ) { gamestats->m_BasicStats.Clear(); bRetVal = false; } else { // Peek ahead in buffer to see if we have the "no default stats" secret flag set. int iCheckForStandardStatsInFile = *( int * )buf.PeekGet(); bool bValid = true; if ( iCheckForStandardStatsInFile != GAMESTATS_STANDARD_NOT_SAVED ) { //the GAMESTATS_STANDARD_NOT_SAVED flag coincides with user completion time, rewind so the gamestats parser can grab it bValid = gamestats->m_BasicStats.ParseFromBuffer( buf, version ); } else { // skip over the flag buf.GetInt(); } if( !bValid ) { m_BasicStats.Clear(); } if( ( buf.TellPut() - buf.TellGet() ) != 0 ) //more data left, must be custom data { gamestats->LoadCustomDataFromBuffer( buf ); } } } return bRetVal; } else { filesystem->RemoveFile( GAMESTATS_LOG_FILE, GAMESTATS_PATHID ); } return false; }
void CBaseGameStats::Event_SaveGame( void ) { StatsLog( "CBaseGameStats::Event_SaveGame [%s]\n", CBGSDriver.m_PrevMapName.String() ); }