summaryrefslogtreecommitdiff
path: root/replay/sv_recordingsession.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'replay/sv_recordingsession.cpp')
-rw-r--r--replay/sv_recordingsession.cpp160
1 files changed, 160 insertions, 0 deletions
diff --git a/replay/sv_recordingsession.cpp b/replay/sv_recordingsession.cpp
new file mode 100644
index 0000000..3b010d1
--- /dev/null
+++ b/replay/sv_recordingsession.cpp
@@ -0,0 +1,160 @@
+//========= 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;
+}
+
+//----------------------------------------------------------------------------------------