mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 17:59:37 +00:00
1
This commit is contained in:
@@ -0,0 +1,230 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
//=======================================================================================//
|
||||
|
||||
#include "errorsystem.h"
|
||||
#include "replay/ienginereplay.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "shared_replaycontext.h"
|
||||
|
||||
#if !defined( DEDICATED )
|
||||
|
||||
#include "cl_downloader.h"
|
||||
#include "cl_sessionblockdownloader.h"
|
||||
#include "cl_recordingsessionblock.h"
|
||||
#include "replay/iclientreplay.h"
|
||||
|
||||
extern IClientReplay *g_pClient;
|
||||
|
||||
#endif // !defined( DEDICATED )
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
extern IEngineReplay *g_pEngine;
|
||||
extern vgui::ILocalize *g_pVGuiLocalize;
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
CErrorSystem::CErrorSystem( IErrorReporter *pErrorReporter )
|
||||
: m_pErrorReporter( pErrorReporter )
|
||||
{
|
||||
}
|
||||
|
||||
CErrorSystem::~CErrorSystem()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CErrorSystem::Clear()
|
||||
{
|
||||
FOR_EACH_LL( m_lstErrors, i )
|
||||
{
|
||||
wchar_t *pText = m_lstErrors[ i ];
|
||||
delete [] pText;
|
||||
}
|
||||
|
||||
m_lstErrors.RemoveAll();
|
||||
}
|
||||
|
||||
void CErrorSystem::AddError( const wchar_t *pError )
|
||||
{
|
||||
if ( !pError || !pError[0] )
|
||||
return;
|
||||
|
||||
// Cache a copied version of the string
|
||||
const int nLen = wcslen( pError ) + 1;
|
||||
wchar_t *pNewError = new wchar_t[ nLen ];
|
||||
const int nSize = nLen * sizeof( wchar_t );
|
||||
V_wcsncpy( pNewError, pError, nSize );
|
||||
|
||||
m_lstErrors.AddToTail( pNewError );
|
||||
}
|
||||
|
||||
void CErrorSystem::AddError( const char *pError )
|
||||
{
|
||||
if ( !pError || !pError[0] )
|
||||
return;
|
||||
|
||||
wchar_t wszError[1024];
|
||||
V_UTF8ToUnicode( pError, wszError, sizeof( wszError ) );
|
||||
|
||||
AddError( wszError );
|
||||
}
|
||||
|
||||
void CErrorSystem::AddErrorFromTokenName( const char *pToken )
|
||||
{
|
||||
if ( g_pVGuiLocalize )
|
||||
{
|
||||
AddError( g_pVGuiLocalize->Find( pToken ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddError( pToken );
|
||||
}
|
||||
}
|
||||
|
||||
void CErrorSystem::AddFormattedErrorFromTokenName( const char *pFormatToken/*=NULL*/, KeyValues *pFormatArgs/*=NULL*/ )
|
||||
{
|
||||
if ( !pFormatToken )
|
||||
{
|
||||
AssertMsg( 0, "Error token should always be valid." );
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t wszErrorStr[1024];
|
||||
if ( g_pVGuiLocalize )
|
||||
{
|
||||
g_pVGuiLocalize->ConstructString( wszErrorStr, sizeof( wszErrorStr ), pFormatToken, pFormatArgs );
|
||||
}
|
||||
else
|
||||
{
|
||||
V_UTF8ToUnicode( pFormatToken, wszErrorStr, sizeof( wszErrorStr ) );
|
||||
}
|
||||
|
||||
|
||||
// Add the error
|
||||
AddError( wszErrorStr );
|
||||
|
||||
// Delete args
|
||||
pFormatArgs->deleteThis();
|
||||
}
|
||||
|
||||
#if !defined( DEDICATED )
|
||||
|
||||
int g_nGenericErrorCounter = 0;
|
||||
|
||||
void CErrorSystem::OGS_ReportSessionBlockDownloadError( const CHttpDownloader *pDownloader, const CClientRecordingSessionBlock *pBlock,
|
||||
int nLocalFileSize, int nMaxBlock, const bool *pSizesDiffer,
|
||||
const bool *pHashFail, uint8 *pLocalHash )
|
||||
|
||||
{
|
||||
// Create a download error and queue for upload
|
||||
KeyValues *pDownloadError = pDownloader->GetOgsRow( g_nGenericErrorCounter );
|
||||
g_pClient->UploadOgsData( pDownloadError, false );
|
||||
|
||||
// Create block download error
|
||||
KeyValues *pBlockDownloadError = new KeyValues( "TF2ReplayBlockDownloadErrors" );
|
||||
pBlockDownloadError->SetInt( "ErrorCounter", g_nGenericErrorCounter );
|
||||
pBlockDownloadError->SetInt( "NumCurrentDownloads", CSessionBlockDownloader::sm_nNumCurrentDownloads );
|
||||
pBlockDownloadError->SetInt( "MaxBlock", nMaxBlock );
|
||||
pBlockDownloadError->SetInt( "RemoteStatus", (int)pBlock->m_nRemoteStatus );
|
||||
pBlockDownloadError->SetInt( "ReconstructionIndex", pBlock->m_iReconstruction );
|
||||
pBlockDownloadError->SetInt( "RemoteFileSize", (int)pBlock->m_uFileSize );
|
||||
pBlockDownloadError->SetInt( "LocalFileSize", nLocalFileSize );
|
||||
pBlockDownloadError->SetInt( "NumDownloadAttempts", pBlock->GetNumDownloadAttempts() );
|
||||
|
||||
// Only include these if appropriate - otherwise, let them be NULL for the given row
|
||||
if ( pSizesDiffer )
|
||||
{
|
||||
pBlockDownloadError->SetInt( "SizesDiffer", (int)*pSizesDiffer );
|
||||
}
|
||||
|
||||
if ( pHashFail )
|
||||
{
|
||||
pBlockDownloadError->SetInt( "HashFail", (int)*pHashFail );
|
||||
|
||||
// Include hashes
|
||||
char szRemoteHash[64], szLocalHash[64];
|
||||
V_binarytohex( pBlock->m_aHash, sizeof( pBlock->m_aHash ), szRemoteHash, sizeof( szRemoteHash ) );
|
||||
V_binarytohex( pLocalHash, sizeof( pBlock->m_aHash ), szLocalHash, sizeof( szLocalHash ) );
|
||||
pBlockDownloadError->SetString( "RemoteHash", szRemoteHash );
|
||||
pBlockDownloadError->SetString( "LocalHash", szLocalHash );
|
||||
}
|
||||
|
||||
// Upload block download error
|
||||
g_pClient->UploadOgsData( pBlockDownloadError, false );
|
||||
|
||||
// Upload generic error and link to this specific block error.
|
||||
OGS_ReportGenericError( "Block download failed" );
|
||||
}
|
||||
|
||||
void CErrorSystem::OGS_ReportSessioInfoDownloadError( const CHttpDownloader *pDownloader, const char *pErrorToken )
|
||||
{
|
||||
// Create a download error and queue for upload
|
||||
KeyValues *pDownloadError = pDownloader->GetOgsRow( g_nGenericErrorCounter );
|
||||
g_pClient->UploadOgsData( pDownloadError, false );
|
||||
|
||||
// Create session info download error
|
||||
KeyValues *pSessionInfoDownloadError = new KeyValues( "TF2ReplaySessionInfoDownloadErrors" );
|
||||
pSessionInfoDownloadError->SetInt( "ErrorCounter", g_nGenericErrorCounter++ );
|
||||
pSessionInfoDownloadError->SetString( "SessionInfoDownloadErrorID", pErrorToken );
|
||||
g_pClient->UploadOgsData( pSessionInfoDownloadError, false );
|
||||
|
||||
// Upload generic error and link to this specific block error.
|
||||
OGS_ReportGenericError( "Session info download failed" );
|
||||
}
|
||||
|
||||
// Note: we use the ErrorCounter as part of the key and so it must be unique. This means that all
|
||||
// special error tables (ie., session info download errors) must call back into this base function
|
||||
// to write out the base error and increment the counter.
|
||||
void CErrorSystem::OGS_ReportGenericError( const char *pGenericErrorToken )
|
||||
{
|
||||
KeyValues *pGenericError = new KeyValues( "TF2ReplayErrors" );
|
||||
pGenericError->SetInt( "ErrorCounter", g_nGenericErrorCounter++ );
|
||||
pGenericError->SetString( "ReplayErrorID", pGenericErrorToken );
|
||||
|
||||
// Upload the generic error row now
|
||||
g_pClient->UploadOgsData( pGenericError, true );
|
||||
|
||||
// Next error!
|
||||
++g_nGenericErrorCounter;
|
||||
}
|
||||
|
||||
#endif // !defined( DEDICATED )
|
||||
|
||||
float CErrorSystem::GetNextThinkTime() const
|
||||
{
|
||||
return g_pEngine->GetHostTime() + 5.0f;
|
||||
}
|
||||
|
||||
void CErrorSystem::Think()
|
||||
{
|
||||
CBaseThinker::Think();
|
||||
|
||||
if ( m_lstErrors.Count() == 0 )
|
||||
return;
|
||||
|
||||
const int nMaxLen = 4096;
|
||||
wchar_t wszErrorText[ nMaxLen ] = L"";
|
||||
FOR_EACH_LL( m_lstErrors, i )
|
||||
{
|
||||
const wchar_t *pError = m_lstErrors[ i ];
|
||||
if ( wcslen( wszErrorText ) + wcslen( pError ) + 1 >= nMaxLen )
|
||||
break;
|
||||
|
||||
wcscat( wszErrorText, pError );
|
||||
wcscat( wszErrorText, L"\n" );
|
||||
}
|
||||
|
||||
// Report now
|
||||
m_pErrorReporter->ReportErrorsToUser( wszErrorText );
|
||||
|
||||
// Clear
|
||||
Clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user