diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /replay/sv_commands.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'replay/sv_commands.cpp')
| -rw-r--r-- | replay/sv_commands.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/replay/sv_commands.cpp b/replay/sv_commands.cpp new file mode 100644 index 0000000..d2fd72e --- /dev/null +++ b/replay/sv_commands.cpp @@ -0,0 +1,208 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +//=======================================================================================// + +#include "replaysystem.h" +#include "sv_sessionrecorder.h" +#include "utlbuffer.h" +#include "sessioninfoheader.h" +#include "sv_fileservercleanup.h" +#include "sv_publishtest.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//---------------------------------------------------------------------------------------- + +#define ENSURE_DEDICATED() if ( !g_pEngine->IsDedicated() ) return; + +//---------------------------------------------------------------------------------------- + +CON_COMMAND( replay_record, "Starts Replay demo recording." ) +{ + ENSURE_DEDICATED(); + SV_GetSessionRecorder()->StartRecording(); +} + +//---------------------------------------------------------------------------------------- + +CON_COMMAND( replay_stoprecord, "Stop Replay demo recording." ) +{ + ENSURE_DEDICATED(); + g_pReplay->SV_EndRecordingSession(); +} + +//---------------------------------------------------------------------------------------- + +CON_COMMAND( replay_docleanup, "Deletes stale session data from the fileserver. \"replay_docleanup force\" will remove all replay session data." ) +{ + ENSURE_DEDICATED(); + + bool bForceCleanAll = false; + if ( args.ArgC() == 2 ) + { + if ( !V_stricmp( args[1], "force" ) ) + { + bForceCleanAll = true; + } + else + { + ConMsg( "\n ** ERROR: '%s' is not a valid paramter - use 'force' to force clean all replay session data.\n\n", args[1] ); + return; + } + } + + if ( !SV_DoFileserverCleanup( bForceCleanAll, g_pBlockSpewer ) ) + { + Msg( "No demos were deleted.\n" ); + } +} + +//---------------------------------------------------------------------------------------- + +CON_COMMAND_F( replay_dopublishtest, "Do a replay publish test using the current setup.", FCVAR_DONTRECORD ) +{ + ENSURE_DEDICATED(); + + g_pBlockSpewer->PrintBlockStart(); + SV_DoTestPublish(); + g_pBlockSpewer->PrintBlockEnd(); +} + +//---------------------------------------------------------------------------------------- + +void PrintSessionInfo( const char *pFilename ) +{ + CUtlBuffer buf; + if ( !g_pFullFileSystem->ReadFile( pFilename, NULL, buf ) ) + { + Msg( "Failed to read file, \"%s\"\n", pFilename ); + return; + } + + int nFileSize = buf.TellPut(); + + SessionInfoHeader_t header; + if ( !ReadSessionInfoHeader( buf.Base(), nFileSize, header ) ) + { + Msg( "Failed to read header information.\n" ); + return; + } + + char szDigestStr[33]; + V_binarytohex( header.m_aHash, sizeof( header.m_aHash ), szDigestStr, sizeof( szDigestStr ) ); + + Msg( "\n\theader:\n" ); + Msg( "\n" ); + Msg( "\t%27s: %u\n", "version", header.m_uVersion ); + Msg( "\t%27s: %s\n", "session name", header.m_szSessionName ); + Msg( "\t%27s: %s\n", "currently recording?", header.m_bRecording ? "yes" : "no" ); + Msg( "\t%27s: %i\n", "# blocks", header.m_nNumBlocks ); + Msg( "\t%27s: %s\n", "compressor", GetCompressorNameSafe( header.m_nCompressorType ) ); + Msg( "\t%27s: %s\n", "md5 digest", szDigestStr ); + Msg( "\t%27s: %u bytes\n", "payload size (compressed)", header.m_uPayloadSize ); + Msg( "\t%27s: %u bytes\n", "payload size (uncompressed)", header.m_uPayloadSizeUC ); + Msg( "\n" ); + + const uint8 *pPayload = (uint8 *)buf.Base() + sizeof( SessionInfoHeader_t ); + uint32 uUncompressedPayloadSize = header.m_uPayloadSizeUC; + if ( !g_pEngine->MD5_HashBuffer( header.m_aHash, (const uint8 *)pPayload, header.m_uPayloadSize, NULL ) ) + { + Msg( "Data validation failed.\n" ); + return; + } + + const uint8 *pUncompressedPayload; + bool bFreeUncompressedPayload = true; + + if ( header.m_nCompressorType == COMPRESSORTYPE_INVALID ) + { + // The payload is already uncompressed - don't free, since this buffer was allocated by the CUtlBuffer "buf" + pUncompressedPayload = pPayload; + bFreeUncompressedPayload = false; + } + else + { + if ( uUncompressedPayloadSize != header.m_uPayloadSizeUC ) + { + Msg( "Decompressed to a different size (%u) than specified by header (%u)\n", uUncompressedPayloadSize, header.m_uPayloadSizeUC ); + return; + } + + ICompressor *pCompressor = CreateCompressor( header.m_nCompressorType ); + if ( !pCompressor ) + { + Msg( "Failed to create compressor.\n" ); + return; + } + + pUncompressedPayload = new uint8[ uUncompressedPayloadSize ]; + if ( !pUncompressedPayload ) + { + Msg( "Failed to allocate uncompressed payload.\n" ); + delete [] pCompressor; + return; + } + + pCompressor->Decompress( (char *)pUncompressedPayload, &uUncompressedPayloadSize, (const char *)pPayload, header.m_uPayloadSize ); + + delete pCompressor; + } + + if ( uUncompressedPayloadSize <= MIN_SESSION_INFO_PAYLOAD_SIZE ) + { + Msg( "Uncompressed payload not large enough to read a single block.\n" ); + } + else + { + RecordingSessionBlockSpec_t DummyBlock; + CUtlBuffer bufPayload( pUncompressedPayload, uUncompressedPayloadSize, CUtlBuffer::READ_ONLY ); + + Msg( "\n\tblocks:\n\n" ); + Msg( "\t index status MD5 compressor size (uncompressed) size (compressed)\n" ); + + bool bBlockReadFailed = false; + for ( int i = 0; i < header.m_nNumBlocks; ++i ) + { + // Attempt to read the current block from the buffer + bufPayload.Get( &DummyBlock, sizeof( DummyBlock ) ); + if ( !bufPayload.IsValid() ) + { + bBlockReadFailed = true; + break; + } + + V_binarytohex( DummyBlock.m_aHash, sizeof( DummyBlock.m_aHash ), szDigestStr, sizeof( szDigestStr ) ); + + Msg( "\t %5i", DummyBlock.m_iReconstruction ); + Msg( "%20s", CBaseRecordingSessionBlock::GetRemoteStatusStringSafe( (CBaseRecordingSessionBlock::RemoteStatus_t)DummyBlock.m_uRemoteStatus ) ); + Msg( "%35s", szDigestStr ); + Msg( "%8s", GetCompressorNameSafe( (CompressorType_t)DummyBlock.m_nCompressorType ) ); + Msg( "%20u", DummyBlock.m_uFileSize ); + Msg( "%20u", DummyBlock.m_uUncompressedSize ); + Msg( "\n" ); + } + } + + Msg( "\n" ); + + if ( bFreeUncompressedPayload ) + { + delete [] pUncompressedPayload; + } +} + +CON_COMMAND_F( replay_printsessioninfo, "Print session info", FCVAR_DONTRECORD ) +{ + ENSURE_DEDICATED(); + + if ( args.ArgC() != 2 ) + { + Msg( "Usage: replay_printsessioninfo <full path and filename>\n" ); + return; + } + + PrintSessionInfo( args[1] ); +} + +//---------------------------------------------------------------------------------------- |