Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //=======================================================================================//
  4. #include "sv_recordingsession.h"
  5. #include "sv_recordingsessionmanager.h"
  6. #include "sv_replaycontext.h"
  7. #include "sv_filepublish.h"
  8. #include "sv_recordingsessionblock.h"
  9. #include "vstdlib/jobthread.h"
  10. #include "fmtstr.h"
  11. #include "sv_fileservercleanup.h"
  12. #include <time.h>
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. //----------------------------------------------------------------------------------------
  16. #ifdef _DEBUG
  17. ConVar replay_simulate_expired_sessions( "replay_simulate_expired_sessions", "0", FCVAR_DONTRECORD,
  18. "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.",
  19. true, 0.0f, true, 100.0f );
  20. #endif
  21. //----------------------------------------------------------------------------------------
  22. CServerRecordingSession::CServerRecordingSession( IReplayContext *pContext )
  23. : CBaseRecordingSession( pContext ),
  24. m_bReplaysRequested( false ),
  25. m_nLifeSpan( 0 )
  26. {
  27. }
  28. CServerRecordingSession::~CServerRecordingSession()
  29. {
  30. }
  31. bool CServerRecordingSession::Read( KeyValues *pIn )
  32. {
  33. if ( !BaseClass::Read( pIn ) )
  34. return false;
  35. m_nLifeSpan = pIn->GetInt( "lifespan", 0 );
  36. KeyValues *pRecordTimeSubKey = pIn->FindKey( "record_time" );
  37. if ( pRecordTimeSubKey )
  38. {
  39. m_RecordTime.Read( pRecordTimeSubKey );
  40. }
  41. return true;
  42. }
  43. void CServerRecordingSession::Write( KeyValues *pOut )
  44. {
  45. BaseClass::Write( pOut );
  46. pOut->SetInt( "lifespan", m_nLifeSpan );
  47. KeyValues *pRecordTime = new KeyValues( "record_time" );
  48. pOut->AddSubKey( pRecordTime );
  49. m_RecordTime.Write( pRecordTime );
  50. }
  51. void CServerRecordingSession::OnDelete()
  52. {
  53. BaseClass::OnDelete();
  54. SV_GetFileserverCleaner()->MarkFileForDelete( GetFilename() );
  55. }
  56. void CServerRecordingSession::SetLocked( bool bLocked )
  57. {
  58. BaseClass::SetLocked( bLocked );
  59. // Propagate to contained blocks
  60. FOR_EACH_VEC( m_vecBlocks, i )
  61. {
  62. m_vecBlocks[ i ]->SetLocked( bLocked );
  63. }
  64. }
  65. void CServerRecordingSession::PopulateWithRecordingData( int nCurrentRecordingStartTick )
  66. {
  67. BaseClass::PopulateWithRecordingData( nCurrentRecordingStartTick );
  68. // Create a new session name
  69. m_strName = SV_GetRecordingSessionManager()->GetNewSessionName();
  70. // Cache current date/time and life-span
  71. extern ConVar replay_data_lifespan;
  72. m_nLifeSpan = replay_data_lifespan.GetInt() * 24 * 3600;
  73. m_RecordTime.InitDateAndTimeToNow();
  74. }
  75. bool CServerRecordingSession::ShouldDitchSession() const
  76. {
  77. return BaseClass::ShouldDitchSession() || !m_bReplaysRequested;
  78. }
  79. #ifdef _DEBUG
  80. void CServerRecordingSession::VerifyLocks()
  81. {
  82. const bool bLocked = IsLocked();
  83. FOR_EACH_VEC( m_vecBlocks, i )
  84. {
  85. 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." );
  86. }
  87. }
  88. #endif
  89. double CServerRecordingSession::GetSecondsToExpiration() const
  90. {
  91. tm recordtime_tm;
  92. V_memset( &recordtime_tm, 0, sizeof( recordtime_tm ) );
  93. int nDay, nMonth, nYear;
  94. m_RecordTime.GetDate( nDay, nMonth, nYear );
  95. recordtime_tm.tm_mday = nDay;
  96. recordtime_tm.tm_mon = nMonth - 1;
  97. recordtime_tm.tm_year = nYear - 1900;
  98. int nHour, nMin, nSec;
  99. m_RecordTime.GetTime( nHour, nMin, nSec );
  100. recordtime_tm.tm_hour = nHour;
  101. recordtime_tm.tm_min = nMin;
  102. recordtime_tm.tm_sec = nSec;
  103. time_t recordtime = mktime( &recordtime_tm );
  104. time_t nowtime;
  105. time( &nowtime );
  106. double delta = m_nLifeSpan - difftime( nowtime, recordtime );
  107. #ifdef DBGFLAG_ASSERT
  108. tm *pTest = localtime( &recordtime );
  109. Assert( recordtime_tm.tm_mday == pTest->tm_mday );
  110. Assert( recordtime_tm.tm_mon == pTest->tm_mon );
  111. Assert( recordtime_tm.tm_year == pTest->tm_year );
  112. Assert( recordtime_tm.tm_hour == pTest->tm_hour );
  113. Assert( recordtime_tm.tm_min == pTest->tm_min );
  114. Assert( recordtime_tm.tm_sec == pTest->tm_sec );
  115. #endif
  116. return delta;
  117. }
  118. bool CServerRecordingSession::SessionExpired() const
  119. {
  120. #ifdef _DEBUG
  121. if ( ( 1+rand()%100 ) <= replay_simulate_expired_sessions.GetInt() )
  122. return true;
  123. #endif
  124. return GetSecondsToExpiration() <= 0.0;
  125. }
  126. //----------------------------------------------------------------------------------------