source-engine/replay/sv_recordingsession.cpp

161 lines
4.5 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=======================================================================================//
#include "sv_recordingsession.h"
#include "sv_recordingsessionmanager.h"
#include "sv_replaycontext.h"
#include "sv_filepublish.h"
#include "sv_recordingsessionblock.h"
#include "vstdlib/jobthread.h"
#include "fmtstr.h"
#include "sv_fileservercleanup.h"
#include <time.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//----------------------------------------------------------------------------------------
#ifdef _DEBUG
ConVar replay_simulate_expired_sessions( "replay_simulate_expired_sessions", "0", FCVAR_DONTRECORD,
"Simulate expired replay session data - the value of this cvar should be between 0 and 100 and is a probability - any cleanup done (via end of round cleanup or explicit replay_docleanup) will use this value to determine whether data is expired. E.g, use a value of 100 to delete all sessions, or 50 for a 50 chance of a given session being considered expired.",
true, 0.0f, true, 100.0f );
#endif
//----------------------------------------------------------------------------------------
CServerRecordingSession::CServerRecordingSession( IReplayContext *pContext )
: CBaseRecordingSession( pContext ),
m_bReplaysRequested( false ),
m_nLifeSpan( 0 )
{
}
CServerRecordingSession::~CServerRecordingSession()
{
}
bool CServerRecordingSession::Read( KeyValues *pIn )
{
if ( !BaseClass::Read( pIn ) )
return false;
m_nLifeSpan = pIn->GetInt( "lifespan", 0 );
KeyValues *pRecordTimeSubKey = pIn->FindKey( "record_time" );
if ( pRecordTimeSubKey )
{
m_RecordTime.Read( pRecordTimeSubKey );
}
return true;
}
void CServerRecordingSession::Write( KeyValues *pOut )
{
BaseClass::Write( pOut );
pOut->SetInt( "lifespan", m_nLifeSpan );
KeyValues *pRecordTime = new KeyValues( "record_time" );
pOut->AddSubKey( pRecordTime );
m_RecordTime.Write( pRecordTime );
}
void CServerRecordingSession::OnDelete()
{
BaseClass::OnDelete();
SV_GetFileserverCleaner()->MarkFileForDelete( GetFilename() );
}
void CServerRecordingSession::SetLocked( bool bLocked )
{
BaseClass::SetLocked( bLocked );
// Propagate to contained blocks
FOR_EACH_VEC( m_vecBlocks, i )
{
m_vecBlocks[ i ]->SetLocked( bLocked );
}
}
void CServerRecordingSession::PopulateWithRecordingData( int nCurrentRecordingStartTick )
{
BaseClass::PopulateWithRecordingData( nCurrentRecordingStartTick );
// Create a new session name
m_strName = SV_GetRecordingSessionManager()->GetNewSessionName();
// Cache current date/time and life-span
extern ConVar replay_data_lifespan;
m_nLifeSpan = replay_data_lifespan.GetInt() * 24 * 3600;
m_RecordTime.InitDateAndTimeToNow();
}
bool CServerRecordingSession::ShouldDitchSession() const
{
return BaseClass::ShouldDitchSession() || !m_bReplaysRequested;
}
#ifdef _DEBUG
void CServerRecordingSession::VerifyLocks()
{
const bool bLocked = IsLocked();
FOR_EACH_VEC( m_vecBlocks, i )
{
AssertMsg( m_vecBlocks[ i ]->IsLocked() == bLocked, "Parent/child locks out of sync. The block probably needs to inherit the parent's lock value on creation." );
}
}
#endif
double CServerRecordingSession::GetSecondsToExpiration() const
{
tm recordtime_tm;
V_memset( &recordtime_tm, 0, sizeof( recordtime_tm ) );
int nDay, nMonth, nYear;
m_RecordTime.GetDate( nDay, nMonth, nYear );
recordtime_tm.tm_mday = nDay;
recordtime_tm.tm_mon = nMonth - 1;
recordtime_tm.tm_year = nYear - 1900;
int nHour, nMin, nSec;
m_RecordTime.GetTime( nHour, nMin, nSec );
recordtime_tm.tm_hour = nHour;
recordtime_tm.tm_min = nMin;
recordtime_tm.tm_sec = nSec;
time_t recordtime = mktime( &recordtime_tm );
time_t nowtime;
time( &nowtime );
double delta = m_nLifeSpan - difftime( nowtime, recordtime );
#ifdef DBGFLAG_ASSERT
tm *pTest = localtime( &recordtime );
Assert( recordtime_tm.tm_mday == pTest->tm_mday );
Assert( recordtime_tm.tm_mon == pTest->tm_mon );
Assert( recordtime_tm.tm_year == pTest->tm_year );
Assert( recordtime_tm.tm_hour == pTest->tm_hour );
Assert( recordtime_tm.tm_min == pTest->tm_min );
Assert( recordtime_tm.tm_sec == pTest->tm_sec );
#endif
return delta;
}
bool CServerRecordingSession::SessionExpired() const
{
#ifdef _DEBUG
if ( ( 1+rand()%100 ) <= replay_simulate_expired_sessions.GetInt() )
return true;
#endif
return GetSecondsToExpiration() <= 0.0;
}
//----------------------------------------------------------------------------------------