mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 01:39:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,720 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Generic in-game abuse reporting
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "abuse_report.h"
|
||||
#include "abuse_report_ui.h"
|
||||
#include "filesystem.h"
|
||||
#include "imageutils.h"
|
||||
#include "econ/confirm_dialog.h"
|
||||
#include "econ/econ_notifications.h"
|
||||
|
||||
inline bool IsLoggedOnToSteam()
|
||||
{
|
||||
return steamapicontext != NULL && steamapicontext->SteamUser() != NULL && steamapicontext->SteamUser()->BLoggedOn();
|
||||
}
|
||||
|
||||
const char CAbuseReportManager::k_rchScreenShotFilenameBase[] = "abuse_report";
|
||||
const char CAbuseReportManager::k_rchScreenShotFilename[] = "screenshots\\abuse_report.jpg";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CEconNotification_AbuseReportReady : public CEconNotification
|
||||
{
|
||||
public:
|
||||
CEconNotification_AbuseReportReady() : CEconNotification()
|
||||
{
|
||||
m_bHasTriggered = false;
|
||||
m_bShowInGame = false;
|
||||
}
|
||||
|
||||
~CEconNotification_AbuseReportReady()
|
||||
{
|
||||
//if ( !m_bHasTriggered )
|
||||
//{
|
||||
// ReallyTrigger();
|
||||
//}
|
||||
}
|
||||
|
||||
virtual void MarkForDeletion()
|
||||
{
|
||||
m_bHasTriggered = true;
|
||||
|
||||
CEconNotification::MarkForDeletion();
|
||||
}
|
||||
|
||||
virtual bool BShowInGameElements() const { return m_bShowInGame; }
|
||||
virtual EType NotificationType() { return eType_Trigger; }
|
||||
virtual void Trigger()
|
||||
{
|
||||
ReallyTrigger();
|
||||
MarkForDeletion();
|
||||
}
|
||||
|
||||
virtual const char *GetUnlocalizedHelpText()
|
||||
{
|
||||
return "#AbuseReport_Notification_Help";
|
||||
}
|
||||
|
||||
static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast< CEconNotification_AbuseReportReady *>( pNotification ) != NULL; }
|
||||
static bool IsInGameNotificationType( CEconNotification *pNotification )
|
||||
{
|
||||
CEconNotification_AbuseReportReady *n = dynamic_cast< CEconNotification_AbuseReportReady *>( pNotification );
|
||||
return n != NULL && n->BShowInGameElements();
|
||||
}
|
||||
|
||||
bool m_bShowInGame;
|
||||
|
||||
private:
|
||||
|
||||
void ReallyTrigger()
|
||||
{
|
||||
Assert( !m_bHasTriggered );
|
||||
m_bHasTriggered = true;
|
||||
engine->ClientCmd_Unrestricted( "abuse_report_submit" );
|
||||
}
|
||||
|
||||
bool m_bHasTriggered;
|
||||
};
|
||||
|
||||
AbuseIncidentData_t::AbuseIncidentData_t()
|
||||
{
|
||||
m_nScreenShotWaitFrames = 5;
|
||||
}
|
||||
|
||||
AbuseIncidentData_t::~AbuseIncidentData_t()
|
||||
{
|
||||
}
|
||||
|
||||
bool AbuseIncidentData_t::Poll()
|
||||
{
|
||||
bool bReady = true;
|
||||
|
||||
// Poll player data
|
||||
for ( int i = 0 ; i < m_vecPlayers.Count() ; ++i )
|
||||
{
|
||||
|
||||
// Make sure sure Steam knows we want the Avatar
|
||||
PlayerData_t *p = &m_vecPlayers[i];
|
||||
if ( p->m_iSteamAvatarIndex < 0 )
|
||||
{
|
||||
if ( steamapicontext && steamapicontext->SteamUser() )
|
||||
{
|
||||
|
||||
p->m_iSteamAvatarIndex = steamapicontext->SteamFriends()->GetLargeFriendAvatar( p->m_steamID );
|
||||
if ( p->m_iSteamAvatarIndex < 0 )
|
||||
{
|
||||
bReady = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->m_iSteamAvatarIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Screenshot ready?
|
||||
if ( !m_bitmapScreenshot.IsValid() && m_nScreenShotWaitFrames > 0 )
|
||||
{
|
||||
--m_nScreenShotWaitFrames;
|
||||
|
||||
// Just load the whole file into a memory buffer
|
||||
char szFullPath[ MAX_PATH ] = "";
|
||||
if ( !g_pFullFileSystem->RelativePathToFullPath( CAbuseReportManager::k_rchScreenShotFilename, NULL, szFullPath, ARRAYSIZE(szFullPath) ) )
|
||||
{
|
||||
Assert( false ); // ???
|
||||
}
|
||||
|
||||
// Load it
|
||||
|
||||
if ( g_pFullFileSystem->FileExists( szFullPath ) )
|
||||
{
|
||||
|
||||
// Load the screenshot into a local buffer
|
||||
if ( !g_pFullFileSystem->ReadFile( CAbuseReportManager::k_rchScreenShotFilename, NULL, m_bufScreenshotFileData ) )
|
||||
{
|
||||
Warning( "Failed to read back %s\n", CAbuseReportManager::k_rchScreenShotFilename );
|
||||
m_nScreenShotWaitFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConversionErrorType nErrorCode = ImgUtl_LoadBitmap( szFullPath, m_bitmapScreenshot );
|
||||
if ( nErrorCode != CE_SUCCESS )
|
||||
{
|
||||
Warning( "Abuse report screenshot %s failed to load with error code %d\n", CAbuseReportManager::k_rchScreenShotFilename, nErrorCode );
|
||||
Assert( nErrorCode == CE_SUCCESS );
|
||||
m_nScreenShotWaitFrames = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// !KLUDGE! Resize to power of two dimensions, since VGUI doesn't like odd sizes
|
||||
ImgUtl_ResizeBitmap( m_bitmapScreenshot, 1024, 1024, &m_bitmapScreenshot );
|
||||
}
|
||||
}
|
||||
g_pFullFileSystem->RemoveFile( CAbuseReportManager::k_rchScreenShotFilename );
|
||||
}
|
||||
}
|
||||
|
||||
return bReady;
|
||||
}
|
||||
|
||||
CAbuseReportManager *g_AbuseReportMgr;
|
||||
|
||||
CAbuseReportManager::CAbuseReportManager()
|
||||
{
|
||||
m_pIncidentData = NULL;
|
||||
m_bTestReport = false;
|
||||
m_eIncidentDataStatus = k_EIncidentDataStatus_None;
|
||||
m_bReportUIPending = false;
|
||||
|
||||
// We're the singleton --- set global pointer
|
||||
Assert( g_AbuseReportMgr == NULL );
|
||||
g_AbuseReportMgr = this;
|
||||
m_timeLastReportReadyNotification = 0.0;
|
||||
m_adrCurrentServer.Clear();
|
||||
}
|
||||
|
||||
CAbuseReportManager::~CAbuseReportManager()
|
||||
{
|
||||
Assert( m_pIncidentData == NULL );
|
||||
}
|
||||
|
||||
char const *CAbuseReportManager::Name()
|
||||
{
|
||||
return "AbuseRepotManager";
|
||||
}
|
||||
|
||||
bool CAbuseReportManager::Init()
|
||||
{
|
||||
// Clean out any temporary files
|
||||
Assert( m_pIncidentData == NULL );
|
||||
DestroyIncidentData();
|
||||
|
||||
ListenForGameEvent( "teamplay_round_win" );
|
||||
ListenForGameEvent( "tf_game_over" );
|
||||
ListenForGameEvent( "player_death" );
|
||||
ListenForGameEvent( "server_spawn" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAbuseReportManager::LevelShutdownPreEntity()
|
||||
{
|
||||
|
||||
// Don't keep the dialog open across a level transition. Don't discard their
|
||||
// report data, but let's kill the dialog
|
||||
if ( g_AbuseReportDlg.Get() != NULL )
|
||||
{
|
||||
Warning( "Abuse report dialog open during level shutdown. Closing it.\n" );
|
||||
g_AbuseReportDlg.Get()->Close();
|
||||
}
|
||||
|
||||
// And clear the 'pending' flag
|
||||
m_bReportUIPending = false;
|
||||
}
|
||||
|
||||
void CAbuseReportManager::FireGameEvent( IGameEvent *event )
|
||||
{
|
||||
//C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
|
||||
const char *eventname = event->GetName();
|
||||
|
||||
if ( !eventname || !eventname[0] )
|
||||
return;
|
||||
|
||||
if (
|
||||
!Q_strcmp( "teamplay_round_win", eventname )
|
||||
|| !Q_strcmp( "tf_game_over", eventname )
|
||||
) {
|
||||
// Periodically remind them that they have a report ready to file
|
||||
CheckCreateReportReadyNotification( 60.0 * 5.0, true, 10.0f );
|
||||
}
|
||||
else if ( !Q_strcmp( "player_death", eventname ) )
|
||||
{
|
||||
// In some maps, the round just never ends.
|
||||
// So make sure we do remind them every now and then about this.
|
||||
// Just not too often
|
||||
CheckCreateReportReadyNotification( 60.0 * 20.0, true, 5.0f );
|
||||
}
|
||||
else if ( !Q_strcmp( "server_spawn", eventname ) )
|
||||
{
|
||||
m_adrCurrentServer.Clear();
|
||||
m_adrCurrentServer.SetFromString( event->GetString( "address", "" ), false );
|
||||
m_adrCurrentServer.SetPort( event->GetInt( "port", 0 ) );
|
||||
|
||||
m_steamIDCurrentServer = CSteamID();
|
||||
if ( steamapicontext && steamapicontext->SteamUser() && GetUniverse() != k_EUniverseInvalid )
|
||||
{
|
||||
m_steamIDCurrentServer.SetFromString( event->GetString( "steamid", "" ), GetUniverse() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAbuseReportManager::Shutdown()
|
||||
{
|
||||
// Close the dialog, if any
|
||||
LevelShutdownPreEntity();
|
||||
|
||||
DestroyIncidentData();
|
||||
|
||||
// Clear global pointer
|
||||
Assert( g_AbuseReportMgr == this );
|
||||
if ( g_AbuseReportMgr == this )
|
||||
{
|
||||
g_AbuseReportMgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CAbuseReportManager::Update( float frametime )
|
||||
{
|
||||
|
||||
// if a dialog is already displayed, make sure we don't try to activate another
|
||||
if ( g_AbuseReportDlg.Get() != NULL )
|
||||
{
|
||||
m_bReportUIPending = false;
|
||||
}
|
||||
|
||||
// Poll report data, if any
|
||||
if ( m_pIncidentData != NULL )
|
||||
{
|
||||
if ( m_eIncidentDataStatus == k_EIncidentDataStatus_Preparing )
|
||||
{
|
||||
if ( m_pIncidentData->Poll() )
|
||||
{
|
||||
m_eIncidentDataStatus = k_EIncidentDataStatus_Ready;
|
||||
CheckCreateReportReadyNotification( 1.0f, true, 7.0f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( m_eIncidentDataStatus == k_EIncidentDataStatus_Ready );
|
||||
}
|
||||
|
||||
if ( m_eIncidentDataStatus == k_EIncidentDataStatus_Ready && m_bReportUIPending )
|
||||
{
|
||||
m_bReportUIPending = false;
|
||||
ActivateSubmitReportUI();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bReportUIPending = false;
|
||||
}
|
||||
|
||||
// Re-create notification constantly in the menu.
|
||||
// While in game, we will only popup notifications
|
||||
// periodically at round end or player death
|
||||
CheckCreateReportReadyNotification( 10.0, false, 999.0f );
|
||||
}
|
||||
|
||||
void CAbuseReportManager::SubmitReportUIRequested()
|
||||
{
|
||||
if ( g_AbuseReportDlg.Get() != NULL )
|
||||
{
|
||||
Assert( g_AbuseReportDlg.Get() == NULL );
|
||||
return;
|
||||
}
|
||||
|
||||
// If no report data already, then create some
|
||||
if ( m_pIncidentData == NULL )
|
||||
{
|
||||
QueueReport();
|
||||
if ( m_pIncidentData == NULL )
|
||||
{
|
||||
// Failed
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set flag to bring up the reporting UI at earliest opportunity,
|
||||
// once all data has been fetched asynchronously
|
||||
m_bReportUIPending = true;
|
||||
}
|
||||
|
||||
bool CAbuseReportManager::CreateAndPopulateIncident()
|
||||
{
|
||||
Assert( m_pIncidentData == NULL );
|
||||
|
||||
// by default, just create the base class version
|
||||
m_pIncidentData = new AbuseIncidentData_t;
|
||||
|
||||
// And populate it
|
||||
return PopulateIncident();
|
||||
}
|
||||
|
||||
bool CAbuseReportManager::PopulateIncident()
|
||||
{
|
||||
if ( m_pIncidentData == NULL )
|
||||
{
|
||||
Assert( m_pIncidentData );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Queue a screenshot
|
||||
CUtlString cmd;
|
||||
cmd.Format( "__screenshot_internal \"%s\"", k_rchScreenShotFilenameBase );
|
||||
engine->ClientCmd_Unrestricted( cmd );
|
||||
|
||||
// Set status as preparing
|
||||
m_eIncidentDataStatus = k_EIncidentDataStatus_Preparing;
|
||||
|
||||
m_pIncidentData->m_bCanReportGameServer = false;
|
||||
|
||||
m_pIncidentData->m_adrGameServer.Clear();
|
||||
if (
|
||||
m_adrCurrentServer.IsValid()
|
||||
&& !m_adrCurrentServer.IsLocalhost()
|
||||
&& m_steamIDCurrentServer.IsValid()
|
||||
&& ( !m_adrCurrentServer.IsReservedAdr() || m_steamIDCurrentServer.GetEUniverse() != k_EUniversePublic )
|
||||
)
|
||||
{
|
||||
m_pIncidentData->m_adrGameServer = m_adrCurrentServer;
|
||||
m_pIncidentData->m_steamIDGameServer = m_steamIDCurrentServer;
|
||||
m_pIncidentData->m_bCanReportGameServer = true;
|
||||
}
|
||||
|
||||
m_pIncidentData->m_matWorldToClip = engine->WorldToScreenMatrix();
|
||||
|
||||
// Add in players
|
||||
for (int i = 1 ; i <= gpGlobals->maxClients ; ++i )
|
||||
{
|
||||
CBasePlayer *player = UTIL_PlayerByIndex( i );
|
||||
|
||||
#ifndef _DEBUG
|
||||
// Skip local players
|
||||
if ( player != NULL && player->IsLocalPlayer() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get player info from the engine. This works even if they haven't spawned yet.
|
||||
player_info_t pi;
|
||||
if ( !engine->GetPlayerInfo( i, &pi ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pi.fakeplayer )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( pi.friendsID == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual );
|
||||
if ( !steamID.IsValid() )
|
||||
{
|
||||
Assert( steamID.IsValid() );
|
||||
continue;
|
||||
}
|
||||
|
||||
int arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail();
|
||||
AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[ arrayIndex ];
|
||||
|
||||
p->m_iClientIndex = i;
|
||||
p->m_steamID = steamID;
|
||||
p->m_sPersona = pi.name;
|
||||
p->m_bHasEntity = false;
|
||||
p->m_bRenderBoundsValid = false;
|
||||
p->m_screenBoundsMin.x = p->m_screenBoundsMin.y = 1.0f;
|
||||
p->m_screenBoundsMax.x = p->m_screenBoundsMax.y = 0.0f;
|
||||
|
||||
if ( player==NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
p->m_bHasEntity = true;
|
||||
player->GetRenderBounds( p->m_vecRenderBoundsMin, p->m_vecRenderBoundsMax );
|
||||
p->m_matModelToWorld.CopyFrom3x4( player->RenderableToWorldTransform() );
|
||||
MatrixMultiply( m_pIncidentData->m_matWorldToClip, p->m_matModelToWorld, p->m_matModelToClip );
|
||||
|
||||
// Gather up screen extents
|
||||
p->m_bRenderBoundsValid = false;
|
||||
for ( int j = 0 ; j < 8 ; ++j )
|
||||
{
|
||||
|
||||
// Get corner point in model space
|
||||
Vector4D modelCorner(
|
||||
( j & 1 ) ? p->m_vecRenderBoundsMax.x : p->m_vecRenderBoundsMin.x,
|
||||
( j & 2 ) ? p->m_vecRenderBoundsMax.y : p->m_vecRenderBoundsMin.y,
|
||||
( j & 4 ) ? p->m_vecRenderBoundsMax.z : p->m_vecRenderBoundsMin.z,
|
||||
1.0f
|
||||
);
|
||||
|
||||
// Transform to clip space
|
||||
Vector4D clipCorner;
|
||||
Vector4DMultiply( p->m_matModelToClip, modelCorner, clipCorner );
|
||||
|
||||
//Msg( "%6.3f, %6.3f, %6.3f, %6.3f\n", clipCorner[0], clipCorner[1], clipCorner[2], clipCorner[3] );
|
||||
|
||||
// If all points behind near clip plane, don't try to
|
||||
// figure out screen space bounds
|
||||
if ( clipCorner[3] > .1f )
|
||||
{
|
||||
p->m_bRenderBoundsValid = true;
|
||||
}
|
||||
|
||||
// Push w forward to "near clip plane"
|
||||
float w = MAX( clipCorner[3], .1f );
|
||||
|
||||
// Divide by w to project, and convert normalized device coordinates
|
||||
// where the view volume is (-1...1), to normalized screen coords, where
|
||||
// they are from 0...1
|
||||
float x = ( clipCorner[0] / w + 1.0f ) / 2.0f;
|
||||
float y = ( -clipCorner[1] / w + 1.0f ) / 2.0f;
|
||||
p->m_screenBoundsMin.x = MIN( p->m_screenBoundsMin.x, x );
|
||||
p->m_screenBoundsMax.x = MAX( p->m_screenBoundsMax.x, x );
|
||||
p->m_screenBoundsMin.y = MIN( p->m_screenBoundsMin.y, y );
|
||||
p->m_screenBoundsMax.y = MAX( p->m_screenBoundsMax.y, y );
|
||||
}
|
||||
|
||||
// Clip projected rect to the screen
|
||||
if ( p->m_bRenderBoundsValid )
|
||||
{
|
||||
p->m_screenBoundsMin.x = MAX( p->m_screenBoundsMin.x, 0.0f );
|
||||
p->m_screenBoundsMax.x = MIN( p->m_screenBoundsMax.x, 1.0f );
|
||||
p->m_screenBoundsMin.y = MAX( p->m_screenBoundsMin.y, 0.0f );
|
||||
p->m_screenBoundsMax.y = MIN( p->m_screenBoundsMax.y, 1.0f );
|
||||
|
||||
p->m_bRenderBoundsValid =
|
||||
p->m_screenBoundsMin.x + .01f < p->m_screenBoundsMax.x
|
||||
&& p->m_screenBoundsMin.y + .01f < p->m_screenBoundsMax.y;
|
||||
}
|
||||
|
||||
// Sanity check that we agree on what their steam ID is!
|
||||
if ( player->GetSteamID( &steamID ) )
|
||||
{
|
||||
Assert( p->m_steamID == steamID );
|
||||
}
|
||||
}
|
||||
|
||||
// Test harness: add in a handful of fake players
|
||||
#ifdef _DEBUG
|
||||
if ( m_bTestReport )
|
||||
{
|
||||
int arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail();
|
||||
AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[ arrayIndex ];
|
||||
|
||||
p->m_iClientIndex = -1;
|
||||
p->m_sPersona = "Lippencott";
|
||||
p->m_steamID.SetFromUint64( 148618791998333672 );
|
||||
|
||||
arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail();
|
||||
p = &m_pIncidentData->m_vecPlayers[ arrayIndex ];
|
||||
|
||||
p->m_iClientIndex = -1;
|
||||
p->m_sPersona = "EricS";
|
||||
p->m_steamID.SetFromUint64( 148618791998195668 );
|
||||
|
||||
arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail();
|
||||
p = &m_pIncidentData->m_vecPlayers[ arrayIndex ];
|
||||
|
||||
p->m_iClientIndex = -1;
|
||||
p->m_sPersona = "Sarenya";
|
||||
p->m_steamID.SetFromUint64( 148618791998429832 );
|
||||
|
||||
arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail();
|
||||
p = &m_pIncidentData->m_vecPlayers[ arrayIndex ];
|
||||
|
||||
|
||||
p->m_iClientIndex = -1;
|
||||
p->m_sPersona = "fletch";
|
||||
p->m_steamID.SetFromUint64( 148618791998436114 );
|
||||
{
|
||||
AbuseIncidentData_t::PlayerImage_t img;
|
||||
img.m_eType = AbuseIncidentData_t::k_PlayerImageType_UGC;
|
||||
img.m_hUGCHandle = 6978249415967519;
|
||||
p->m_vecImages.AddToTail( img );
|
||||
}
|
||||
|
||||
if ( !m_pIncidentData->m_bCanReportGameServer)
|
||||
{
|
||||
m_pIncidentData->m_adrGameServer.SetFromString( "123.45.67.89:27015", false );
|
||||
m_pIncidentData->m_steamIDGameServer = CSteamID( 12345, 0, GetUniverse(), k_EAccountTypeAnonGameServer );
|
||||
m_pIncidentData->m_bCanReportGameServer = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Make sure there is at least one other person we could file a report against!
|
||||
if ( m_pIncidentData->m_vecPlayers.Count() < 1 )
|
||||
{
|
||||
Warning( "No players to accuse of abuse, cannot file report\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAbuseReportManager::DestroyIncidentData()
|
||||
{
|
||||
if ( m_pIncidentData != NULL )
|
||||
{
|
||||
delete m_pIncidentData;
|
||||
m_pIncidentData = NULL;
|
||||
}
|
||||
m_eIncidentDataStatus = k_EIncidentDataStatus_None;
|
||||
|
||||
// Get rid of any existing screenshot file, both locally
|
||||
// and in the cloud. We don't want this to count against
|
||||
// our quota
|
||||
if ( steamapicontext && steamapicontext->SteamRemoteStorage() && steamapicontext->SteamRemoteStorage()->FileExists( k_rchScreenShotFilename ) )
|
||||
{
|
||||
steamapicontext->SteamRemoteStorage()->FileDelete( k_rchScreenShotFilename );
|
||||
}
|
||||
|
||||
if ( g_pFullFileSystem->FileExists( k_rchScreenShotFilename ) ) // !KLUDGE! To prevent warning if the file doesn't exist!
|
||||
{
|
||||
g_pFullFileSystem->RemoveFile( k_rchScreenShotFilename );
|
||||
}
|
||||
|
||||
m_timeLastReportReadyNotification = 0.0;
|
||||
|
||||
// Make sure we don't have any notifications queued
|
||||
NotificationQueue_Remove( &CEconNotification_AbuseReportReady::IsNotificationType );
|
||||
}
|
||||
|
||||
void CAbuseReportManager::QueueReport()
|
||||
{
|
||||
// Dialog is already active?
|
||||
if ( g_AbuseReportDlg.Get() != NULL )
|
||||
{
|
||||
Warning( "Cannot capture another incident report. Submission dialog is active.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy any existing data
|
||||
DestroyIncidentData();
|
||||
|
||||
// Make sure we're logged on to Steam
|
||||
if ( !IsLoggedOnToSteam() )
|
||||
{
|
||||
g_AbuseReportMgr->ShowNoSteamErrorMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( CreateAndPopulateIncident() )
|
||||
{
|
||||
Msg( "Captured data for abuse report.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Warning( "Failed to captured data for abuse report.\n");
|
||||
DestroyIncidentData();
|
||||
}
|
||||
}
|
||||
|
||||
void CAbuseReportManager::ShowNoSteamErrorMessage()
|
||||
{
|
||||
ShowMessageBox( "#AbuseReport_NoSteamTitle", "#AbuseReport_NoSteamMessage", "#GameUI_OK" );
|
||||
}
|
||||
|
||||
void CAbuseReportManager::CheckCreateReportReadyNotification( float flMinSecondsSinceLastNotification, bool bInGame, float flLifetime )
|
||||
{
|
||||
// We have to have some data ready
|
||||
if ( m_pIncidentData == NULL || m_eIncidentDataStatus != k_EIncidentDataStatus_Ready )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't pester them if they are already trying to do something about it
|
||||
if ( g_AbuseReportDlg.Get() != NULL || m_bReportUIPending )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Already notified them too recently?
|
||||
if ( m_timeLastReportReadyNotification != 0.0 && Plat_FloatTime() < m_timeLastReportReadyNotification + flMinSecondsSinceLastNotification )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Already a notification in the queue?
|
||||
if ( bInGame )
|
||||
{
|
||||
if ( NotificationQueue_Count( &CEconNotification_AbuseReportReady::IsInGameNotificationType ) > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( NotificationQueue_Count( &CEconNotification_AbuseReportReady::IsNotificationType ) > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CreateReportReadyNotification( bInGame, flLifetime );
|
||||
}
|
||||
|
||||
void CAbuseReportManager::CreateReportReadyNotification( bool bInGame, float flLifetime )
|
||||
{
|
||||
NotificationQueue_Remove( &CEconNotification_AbuseReportReady::IsNotificationType );
|
||||
CEconNotification_AbuseReportReady *pNotification = new CEconNotification_AbuseReportReady();
|
||||
pNotification->SetText( "AbuseReport_Notification" );
|
||||
pNotification->SetLifetime( flLifetime );
|
||||
pNotification->m_bShowInGame = bInGame;
|
||||
NotificationQueue_Add( pNotification );
|
||||
|
||||
m_timeLastReportReadyNotification = Plat_FloatTime();
|
||||
}
|
||||
|
||||
CON_COMMAND_F( abuse_report_queue, "Capture data for abuse report and queue for submission. Use abose_report_submit to activate UI to submit the report", FCVAR_DONTRECORD )
|
||||
{
|
||||
if ( !g_AbuseReportMgr )
|
||||
{
|
||||
Warning( "abuse_report_queue: No abuse report manager, cannot create report.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
g_AbuseReportMgr->QueueReport();
|
||||
}
|
||||
|
||||
CON_COMMAND_F( abuse_report_submit, "Activate UI to submit queued report. Use abuse_report_queue to capture data for the report the report", FCVAR_DONTRECORD )
|
||||
{
|
||||
if ( !g_AbuseReportMgr )
|
||||
{
|
||||
Warning( "abuse_report_submit: No abuse report manager, cannot submit report.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we're logged on to Steam
|
||||
if ( !IsLoggedOnToSteam() )
|
||||
{
|
||||
g_AbuseReportMgr->ShowNoSteamErrorMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( g_AbuseReportDlg.Get() != NULL )
|
||||
{
|
||||
// Dialog is already active
|
||||
return;
|
||||
}
|
||||
g_AbuseReportMgr->SubmitReportUIRequested();
|
||||
}
|
||||
|
||||
// Test harness
|
||||
#ifdef _DEBUG
|
||||
|
||||
CON_COMMAND_F( abuse_report_test, "Make a test abuse incident and activate UI", FCVAR_DONTRECORD )
|
||||
{
|
||||
if ( !g_AbuseReportMgr )
|
||||
{
|
||||
Assert( g_AbuseReportMgr );
|
||||
return;
|
||||
}
|
||||
g_AbuseReportMgr->m_bTestReport = true;
|
||||
g_AbuseReportMgr->QueueReport();
|
||||
g_AbuseReportMgr->m_bTestReport = false;
|
||||
engine->ClientCmd_Unrestricted( "abuse_report_submit" );
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user