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 /game/client/abuse_report_ui.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/abuse_report_ui.cpp')
| -rw-r--r-- | game/client/abuse_report_ui.cpp | 949 |
1 files changed, 949 insertions, 0 deletions
diff --git a/game/client/abuse_report_ui.cpp b/game/client/abuse_report_ui.cpp new file mode 100644 index 0000000..0d1ab59 --- /dev/null +++ b/game/client/abuse_report_ui.cpp @@ -0,0 +1,949 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Generic in-game abuse reporting +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "abuse_report_ui.h" +#include "econ/econ_controls.h" +#include "ienginevgui.h" +#include "vgui/ISurface.h" +#include <vgui_controls/TextEntry.h> +#include <vgui_controls/ComboBox.h> +#include <vgui_controls/RadioButton.h> +#include "vgui_bitmappanel.h" +#include "vgui_avatarimage.h" +#include "gc_clientsystem.h" +#include "econ/tool_items/tool_items.h" +#include "econ/econ_gcmessages.h" +#include "econ/confirm_dialog.h" +#include "tool_items/custom_texture_cache.h" + +vgui::DHANDLE<CAbuseReportDlg> g_AbuseReportDlg; + +CAbuseReportDlg::CAbuseReportDlg( vgui::Panel *parent, AbuseIncidentData_t *pIncidentData ) +: EditablePanel( parent, "AbuseReportSubmitDialog" ) +, m_pSubmitButton( NULL ) +, m_pScreenShot( NULL ) +, m_pScreenShotAttachCheckButton( NULL ) +, m_pOffensiveImage( NULL ) +, m_pDescriptionTextEntry( NULL ) +, m_pPlayerLabel( NULL ) +, m_pPlayerRadio( NULL ) +, m_pGameServerRadio( NULL ) +, m_pPlayerCombo( NULL ) +, m_pAbuseContentLabel( NULL ) +, m_pAbuseContentCombo( NULL ) +, m_pAbuseTypeLabel( NULL ) +, m_pAbuseTypeCombo( NULL ) +, m_pScreenShotBitmap( NULL ) +, m_pAvatarImage( NULL ) +, m_pNoAvatarLabel( NULL ) +, m_pCustomTextureImagePanel( NULL ) +, m_pNoCustomTexturesLabel( NULL ) +, m_pCustomTextureNextButton( NULL ) +, m_pCustomTexturePrevButton( NULL ) +, m_iUserImageIndex( 0 ) +, m_pIncidentData( pIncidentData ) +{ + vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme" ); + SetScheme(scheme); + SetProportional( true ); + //m_pContainer = new vgui::EditablePanel( this, "Container" ); + + Assert( g_AbuseReportDlg.Get() == NULL ); + g_AbuseReportDlg.Set( this ); + + engine->ExecuteClientCmd("gameui_preventescape"); +} + +CAbuseReportDlg::~CAbuseReportDlg() +{ + Assert( g_AbuseReportDlg.Get() == this ); + if ( g_AbuseReportDlg.Get() == this ) + { + engine->ExecuteClientCmd("gameui_allowescape"); + g_AbuseReportDlg = NULL; + } +} + +void CAbuseReportDlg::OnCommand( const char *command ) +{ + if ( !Q_stricmp( command, "cancel" ) ) + { + Close(); + return; + } + if ( !Q_stricmp( command, "discard" ) ) + { + Close(); + g_AbuseReportMgr->DestroyIncidentData(); + return; + } + if ( !Q_stricmp( command, "submit" ) ) + { + OnSubmitReport(); + return; + } + if ( !Q_stricmp( command, "nextcustomtexture" ) ) + { + ++m_iUserImageIndex; + UpdateCustomTextures(); + return; + } + + if ( !Q_stricmp( command, "prevcustomtexture" ) ) + { + --m_iUserImageIndex; + UpdateCustomTextures(); + return; + } + +} + +void CAbuseReportDlg::MakeModal() +{ + TFModalStack()->PushModal( this ); + MakePopup(); + MoveToFront(); + SetKeyBoardInputEnabled( true ); + SetMouseInputEnabled( true ); + + // !KLUDGE! Initially set the dialog to be hidden, so we can take a screenshot! + SetEnabled( m_pIncidentData != NULL ); + //SetVisible( m_pIncidentData != NULL ); +} + +void CAbuseReportDlg::Close() +{ + TFModalStack()->PopModal( this ); + SetVisible( false ); + MarkForDeletion(); +} + +const char *CAbuseReportDlg::GetResFilename() +{ + return "Resource/UI/AbuseReportSubmitDialog.res"; + //return "Resource/UI/QuickplayDialog.res"; +} + +void CAbuseReportDlg::PerformLayout() +{ + BaseClass::PerformLayout(); + + // Center it, keeping requested size + int x, y, ww, wt, wide, tall; + vgui::surface()->GetWorkspaceBounds( x, y, ww, wt ); + GetSize(wide, tall); + SetPos(x + ((ww - wide) / 2), y + ((wt - tall) / 2)); + + // @todo setup +} + +class CCustomTextureImagePanel : public vgui::Panel +{ +public: + CCustomTextureImagePanel( Panel *parent, const char *panelName ) : vgui::Panel( parent, panelName ) + { + m_ugcHandle = 0; + } + + uint64 m_ugcHandle; + + virtual void Paint() + { + if ( m_ugcHandle == 0 ) + { + return; + } + int iTextureHandle = GetCustomTextureGuiHandle( m_ugcHandle ); + if ( iTextureHandle <= 0) + { + return; + } + + vgui::surface()->DrawSetColor(COLOR_WHITE); + vgui::surface()->DrawSetTexture( iTextureHandle ); + int iWide, iTall; + GetSize( iWide, iTall ); + + vgui::Vertex_t verts[4]; + verts[0].Init( Vector2D( 0, 0 ), Vector2D( 0.0f, 0.0f ) ); + verts[1].Init( Vector2D( iWide, 0 ), Vector2D( 1.0f, 0.0f ) ); + verts[2].Init( Vector2D( iWide, iTall ), Vector2D( 1.0f, 1.0f ) ); + verts[3].Init( Vector2D( 0, iTall ), Vector2D( 0.0f, 1.0f ) ); + + vgui::surface()->DrawTexturedPolygon( 4, verts ); + vgui::surface()->DrawSetColor(COLOR_WHITE); + } + +}; + +class CAbuseReportScreenShotPanel : public CBitmapPanel +{ +public: + CAbuseReportScreenShotPanel( CAbuseReportDlg *pDlg, const char *panelName ) + : CBitmapPanel( pDlg, panelName ) + , m_pDlg( pDlg ) + {} + + CAbuseReportDlg *m_pDlg; + + virtual void Paint() + { + CBitmapPanel::Paint(); + + const AbuseIncidentData_t::PlayerData_t *p = m_pDlg->GetAccusedPlayerPtr(); + if ( p == NULL || !p->m_bRenderBoundsValid ) + { + return; + } + int w, t; + GetSize( w, t ); + + int x0 = int( p->m_screenBoundsMin.x * (float)w ); + int y0 = int( p->m_screenBoundsMin.y * (float)t ); + int x1 = int( p->m_screenBoundsMax.x * (float)w ); + int y1 = int( p->m_screenBoundsMax.y * (float)t ); + + vgui::surface()->DrawSetColor( Color(200, 10, 10, 200 ) ); + vgui::surface()->DrawOutlinedRect( x0, y0, x1, y1 ); + vgui::surface()->DrawSetColor( COLOR_WHITE ); + } +}; + +void CAbuseReportDlg::ApplySchemeSettings( vgui::IScheme *pScheme ) +{ + EditablePanel::ApplySchemeSettings( pScheme ); + + m_pScreenShotBitmap = new CAbuseReportScreenShotPanel( this, "ScreenShotBitmap" ); + m_pCustomTextureImagePanel = new CCustomTextureImagePanel( this, "CustomTextureImage" ); + + LoadControlSettings( GetResFilename() ); + + m_pPlayerRadio = dynamic_cast<vgui::RadioButton *>(FindChildByName( "PlayerRadio", true )); + Assert( m_pPlayerRadio ); + if ( m_pPlayerRadio ) + { + m_pPlayerRadio->SetVisible( m_pIncidentData->m_bCanReportGameServer ); + } + + m_pGameServerRadio = dynamic_cast<vgui::RadioButton *>(FindChildByName( "GameServerRadio", true )); + Assert( m_pGameServerRadio ); + if ( m_pGameServerRadio ) + { + m_pGameServerRadio->SetVisible( m_pIncidentData->m_bCanReportGameServer ); + } + + m_pPlayerLabel = FindChildByName( "PlayerLabel", true ); + Assert( m_pPlayerLabel ); + + m_pScreenShotAttachCheckButton = dynamic_cast<vgui::CheckButton *>(FindChildByName( "ScreenShotAttachCheckButton", true )); + Assert( m_pScreenShotAttachCheckButton ); + if ( m_pScreenShotAttachCheckButton ) + { + m_pScreenShotAttachCheckButton->SetSelected( true ); + } + + m_pSubmitButton = dynamic_cast<vgui::Button *>(FindChildByName( "SubmitButton", true )); + Assert( m_pSubmitButton ); + + m_pDescriptionTextEntry = dynamic_cast<vgui::TextEntry *>(FindChildByName( "DescriptionTextEntry", true )); + Assert( m_pDescriptionTextEntry ); + if ( m_pDescriptionTextEntry ) + { + m_pDescriptionTextEntry->SetMultiline( true ); + } + + m_pAvatarImage = dynamic_cast<CAvatarImagePanel *>(FindChildByName( "AvatarImage", true )); + Assert( m_pAvatarImage ); + + m_pNoAvatarLabel = FindChildByName( "NoAvatarLabel", true ); + Assert( m_pNoAvatarLabel ); + + m_pNoCustomTexturesLabel = FindChildByName( "NoCustomTexturesLabel", true ); + Assert( m_pNoCustomTexturesLabel ); + + m_pCustomTextureNextButton = dynamic_cast<vgui::Button *>(FindChildByName( "CustomTextureNextButton", true )); + Assert( m_pCustomTextureNextButton ); + + m_pCustomTexturePrevButton = dynamic_cast<vgui::Button *>(FindChildByName( "CustomTexturePrevButton", true )); + Assert( m_pCustomTexturePrevButton ); + + m_pPlayerCombo = dynamic_cast<vgui::ComboBox *>(FindChildByName( "PlayerComboBox", true )); + Assert( m_pPlayerCombo ); + + m_pAbuseContentLabel = FindChildByName( "AbuseContentLabel", true ); + Assert( m_pAbuseContentLabel ); + + m_pAbuseContentCombo = dynamic_cast<vgui::ComboBox *>(FindChildByName( "AbuseContentComboBox", true )); + Assert( m_pAbuseContentCombo ); + if ( m_pAbuseContentCombo ) + { + m_pAbuseContentCombo->AddItem( "#AbuseReport_SelectOne", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentNoSelection ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentAvatarImage", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentAvatarImage ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentPlayerName", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentPersonaName ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentItemDecal", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentUGCImage ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentChatText", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentComments ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentCheating", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentCheating ) ); + m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentOther", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentUnspecified ) ); + m_pAbuseContentCombo->SilentActivateItemByRow( 0 ); + m_pAbuseContentCombo->SetNumberOfEditLines( m_pAbuseContentCombo->GetItemCount() ); + } + + m_pAbuseTypeLabel = FindChildByName( "AbuseTypeLabel", true ); + Assert( m_pAbuseTypeLabel ); + + m_pAbuseTypeCombo = dynamic_cast<vgui::ComboBox *>(FindChildByName( "AbuseTypeComboBox", true )); + Assert( m_pAbuseTypeCombo ); + + Assert( m_pScreenShotBitmap ); + if ( m_pScreenShotBitmap && m_pIncidentData->m_bitmapScreenshot.IsValid() ) + { + m_pScreenShotBitmap->SetBitmap( m_pIncidentData->m_bitmapScreenshot ); + } + + PopulatePlayerList(); + SetIsAccusingGameServer( false ); + + SetEnabled( true ); + SetVisible( true ); +} + +bool CAbuseReportDlg::IsAccusingGameServer() +{ + return m_pIncidentData && m_pIncidentData->m_bCanReportGameServer && m_pGameServerRadio && m_pGameServerRadio->IsSelected(); +} + +EAbuseReportContentType CAbuseReportDlg::GetAbuseContentType() +{ + if ( m_pAbuseContentCombo == NULL || IsAccusingGameServer() ) + { + Assert( m_pAbuseContentCombo ); + return k_EAbuseReportContentNoSelection; + } + KeyValues *pUserData = m_pAbuseContentCombo->GetActiveItemUserData(); + if ( pUserData == NULL ) + { + return k_EAbuseReportContentNoSelection; + } + return (EAbuseReportContentType)pUserData->GetInt( "code", k_EAbuseReportContentNoSelection ); +} + +EAbuseReportType CAbuseReportDlg::GetAbuseType() +{ + if ( m_pAbuseTypeCombo == NULL || IsAccusingGameServer() ) + { + Assert( m_pAbuseTypeCombo ); + return k_EAbuseReportTypeNoSelection; + } + KeyValues *pUserData = m_pAbuseTypeCombo->GetActiveItemUserData(); + if ( pUserData == NULL ) + { + return k_EAbuseReportTypeNoSelection; + } + return (EAbuseReportType)pUserData->GetInt( "code", k_EAbuseReportTypeNoSelection ); +} + +CUtlString CAbuseReportDlg::GetAbuseDescription() +{ + char buf[ 1024 ] = ""; + if ( m_pDescriptionTextEntry ) + { + m_pDescriptionTextEntry->GetText( buf, ARRAYSIZE(buf) ); + } + + return CUtlString( buf ); +} + +int CAbuseReportDlg::GetAccusedPlayerIndex() +{ + // If accusing a game server, then there's no player + if ( IsAccusingGameServer() ) + { + return -1; + } + + if ( m_pPlayerCombo == NULL ) + { + Assert( m_pPlayerCombo ); + return -1; + } + + // Item 0 is the "<select one>" item + return m_pPlayerCombo->GetActiveItem() - 1; +} + +const AbuseIncidentData_t::PlayerData_t *CAbuseReportDlg::GetAccusedPlayerPtr() +{ + int iPlayerIndex = GetAccusedPlayerIndex(); + if ( iPlayerIndex < 0 ) + return NULL; + return &m_pIncidentData->m_vecPlayers[ iPlayerIndex ]; +} + +bool CAbuseReportDlg::GetAttachScreenShot() +{ + if ( m_pScreenShotAttachCheckButton == NULL ) + { + return false; + } + if ( !m_pScreenShotAttachCheckButton->IsVisible() ) + { + // We hide the checkbutton when the option is not applicable + return false; + } + return m_pScreenShotAttachCheckButton->IsSelected(); +} + +void CAbuseReportDlg::PopulatePlayerList() +{ + if ( m_pIncidentData == NULL || m_pPlayerCombo == NULL ) + { + Assert( m_pIncidentData ); + Assert( m_pPlayerCombo ); + return; + } + m_pPlayerCombo->RemoveAll(); + m_pPlayerCombo->AddItem( "#AbuseReport_SelectOne", NULL ); + for ( int i = 0 ; i < m_pIncidentData->m_vecPlayers.Count() ; ++i ) + { + AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[i]; + m_pPlayerCombo->AddItem( p->m_sPersona, NULL ); + } + m_pPlayerCombo->SilentActivateItemByRow( 0 ); + + m_pPlayerCombo->SetNumberOfEditLines( MIN( m_pPlayerCombo->GetItemCount()+1, 12 ) ); +} + +void CAbuseReportDlg::UpdateSubmitButton() +{ + if ( !m_pSubmitButton ) + { + Assert( m_pSubmitButton ); + return; + } + + bool bEnable = false; + if ( IsAccusingGameServer() ) + { + bEnable = true; + } + else + { + EAbuseReportContentType eContent = GetAbuseContentType(); + const AbuseIncidentData_t::PlayerData_t *pAccused = GetAccusedPlayerPtr(); + if ( + eContent >= 0 + && GetAbuseType() >= 0 + && pAccused != NULL ) + { + bEnable = true; + if ( eContent == k_EAbuseReportContentAvatarImage && pAccused->m_iSteamAvatarIndex <= 0 ) + { + // Cannot accuse somebody of having a bad avatar image, if they + // don't have one set + bEnable = false; + } + } + } + if ( GetAbuseDescription().IsEmpty() ) + { + bEnable = false; + } + + m_pSubmitButton->SetEnabled( bEnable ); +} + +void CAbuseReportDlg::ContentTypeChanged() +{ + + // Save current abuse type. We want to keep it the same, + // if possible + EAbuseReportType abuseType = GetAbuseType(); + EAbuseReportContentType contentType = GetAbuseContentType(); + + // Show/hide screen shot / image select + bool bShowScreenshot = false; + bool bShowAttach = false; + switch ( contentType ) + { + default: + Assert( false ); + case k_EAbuseReportContentNoSelection: + case k_EAbuseReportContentPersonaName: + bShowScreenshot = true; + bShowAttach = false; + break; + + case k_EAbuseReportContentUnspecified: + case k_EAbuseReportContentComments: + case k_EAbuseReportContentCheating: + bShowScreenshot = true; + bShowAttach = true; + break; + + case k_EAbuseReportContentAvatarImage: + case k_EAbuseReportContentUGCImage: + bShowScreenshot = false; + bShowAttach = false; + break; + } + + bShowScreenshot = bShowScreenshot && m_pIncidentData->m_bitmapScreenshot.IsValid(); + + // Make sure we have everything we need to upload a screenshot + bShowAttach = bShowAttach + && bShowScreenshot + && ( GetAccusedPlayerIndex() >= 0 ) + && m_pIncidentData->m_bufScreenshotFileData.TellPut() > 0 + && steamapicontext + && ( steamapicontext->SteamUtils() != NULL ) + && ( steamapicontext->SteamRemoteStorage() != NULL ); + + if ( m_pScreenShotBitmap ) + { + m_pScreenShotBitmap->SetVisible( bShowScreenshot ); + } + if ( m_pScreenShotAttachCheckButton ) + { + m_pScreenShotAttachCheckButton->SetVisible( bShowAttach ); + } + + UpdateAvatarImage(); + UpdateCustomTextures(); + + // Populate abuse type + if ( m_pAbuseTypeCombo ) + { + + // If the combo box was invisible, then they didn't really make a purposeful decision + if ( !m_pAbuseTypeCombo->IsVisible() ) + { + abuseType = k_EAbuseReportTypeNoSelection; + } + m_pAbuseTypeCombo->RemoveAll(); + switch ( contentType ) + { + default: + Assert( false ); + case k_EAbuseReportContentNoSelection: + m_pAbuseTypeCombo->SetVisible( false ); + abuseType = k_EAbuseReportTypeNoSelection; + m_pAbuseTypeCombo->AddItem( "#AbuseReport_SelectOne", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeNoSelection ) ); + break; + + case k_EAbuseReportContentCheating: + m_pAbuseTypeCombo->SetVisible( false ); + abuseType = k_EAbuseReportTypeCheating; + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeCheating", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeCheating ) ); + break; + + case k_EAbuseReportContentUnspecified: + case k_EAbuseReportContentComments: + case k_EAbuseReportContentPersonaName: + case k_EAbuseReportContentAvatarImage: + case k_EAbuseReportContentUGCImage: + m_pAbuseTypeCombo->SetVisible( true ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_SelectOne", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeNoSelection ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeSpam", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeSpamming ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeAdvertisement", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeAdvertisement ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeLanguage", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeLanguage ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeAdultContent", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeAdultContent ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeHarassment", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeHarassment ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeProhibited", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeProhibited ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeSpoofing", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeSpoofing ) ); + //m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeCheating", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeCheating ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeInappropriate", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeInappropriate ) ); + m_pAbuseTypeCombo->AddItem( "#AbuseReport_TypeOther", new KeyValues( "AbuseType", "code", k_EAbuseReportTypeUnspecified ) ); + break; + } + + // Now select the proper row + int sel = 0; + for ( int i = 0 ; i < m_pAbuseTypeCombo->GetItemCount() ; ++i ) { + if ( m_pAbuseTypeCombo->GetItemUserData(i)->GetInt("code") == abuseType ) + { + sel = i; + break; + } + } + m_pAbuseTypeCombo->SilentActivateItemByRow( sel ); + m_pAbuseTypeCombo->SetNumberOfEditLines( m_pAbuseTypeCombo->GetItemCount() ); + if ( m_pAbuseTypeLabel ) + { + m_pAbuseTypeLabel->SetVisible( m_pAbuseTypeCombo->IsVisible() ); + } + } + + UpdateSubmitButton(); +} + +void CAbuseReportDlg::OnRadioButtonChecked( vgui::Panel *panel ) +{ + if ( panel == m_pPlayerRadio ) + { + SetIsAccusingGameServer( false ); + } + else if ( panel == m_pGameServerRadio ) + { + SetIsAccusingGameServer( true ); + } + else + { + Assert( !"Clicked on unknown radio" ); + } +} + +void CAbuseReportDlg::SetIsAccusingGameServer( bool bAccuseGameServer ) +{ + if ( m_pGameServerRadio && m_pGameServerRadio->IsSelected() != bAccuseGameServer ) + { + m_pGameServerRadio->SetSelected( bAccuseGameServer ); + } + if ( m_pPlayerRadio && m_pPlayerRadio->IsSelected() == bAccuseGameServer) + { + m_pPlayerRadio->SetSelected( !bAccuseGameServer ); + } + if ( m_pPlayerLabel ) + { + m_pPlayerLabel->SetVisible( !bAccuseGameServer ); + } + if ( m_pPlayerCombo ) + { + m_pPlayerCombo->SetVisible( !bAccuseGameServer ); + } + + PlayerChanged(); +} + +void CAbuseReportDlg::PlayerChanged() +{ + m_iUserImageIndex = 0; + + bool bShow = ( GetAccusedPlayerIndex() >= 0 ); + if ( m_pAbuseContentCombo != NULL ) + { + m_pAbuseContentCombo->SetVisible( bShow ); + } + if ( m_pAbuseContentLabel != NULL ) + { + m_pAbuseContentLabel->SetVisible( bShow ); + } + + ContentTypeChanged(); +} + +void CAbuseReportDlg::UpdateAvatarImage() +{ + if ( m_pAvatarImage == NULL || m_pNoAvatarLabel == NULL ) + { + Assert( m_pAvatarImage ); + Assert( m_pNoAvatarLabel ); + return; + } + + const AbuseIncidentData_t::PlayerData_t *pAccused = GetAccusedPlayerPtr(); + if ( GetAbuseContentType() == k_EAbuseReportContentAvatarImage && pAccused != NULL ) + { + if ( pAccused->m_iSteamAvatarIndex > 0 ) + { + m_pAvatarImage->SetShouldDrawFriendIcon( false ); + m_pAvatarImage->SetPlayer( pAccused->m_steamID, k_EAvatarSize184x184 ); + + m_pAvatarImage->SetVisible( true ); + m_pNoAvatarLabel->SetVisible( false ); + } + else + { + m_pAvatarImage->SetVisible( false ); + m_pNoAvatarLabel->SetVisible( true ); + } + } + else + { + m_pAvatarImage->SetVisible( false ); + m_pNoAvatarLabel->SetVisible( false ); + } +} + +void CAbuseReportDlg::UpdateCustomTextures() +{ + if ( m_pCustomTextureImagePanel == NULL || m_pNoCustomTexturesLabel == NULL || m_pCustomTextureNextButton == NULL || m_pCustomTexturePrevButton == NULL ) + { + Assert( m_pCustomTextureImagePanel ); + Assert( m_pNoCustomTexturesLabel ); + Assert( m_pCustomTextureNextButton ); + Assert( m_pCustomTexturePrevButton ); + return; + } + + const AbuseIncidentData_t::PlayerData_t *pAccused = GetAccusedPlayerPtr(); + bool bShowScrollButtons = false; + if ( GetAbuseContentType() == k_EAbuseReportContentUGCImage && pAccused != NULL ) + { + int iSelectedCustomImage = GetSelectedCustomImage(); + + if ( iSelectedCustomImage >= 0 ) + { + + // Currently the only thing we support... + Assert( pAccused->m_vecImages[ iSelectedCustomImage].m_eType == AbuseIncidentData_t::k_PlayerImageType_UGC ); + + m_pCustomTextureImagePanel->m_ugcHandle = pAccused->m_vecImages[ iSelectedCustomImage].m_hUGCHandle; + + m_pCustomTextureImagePanel->SetVisible( true ); + m_pNoCustomTexturesLabel->SetVisible( false ); + + int n = pAccused->m_vecImages.Count(); + if ( n > 1 ) + { + bShowScrollButtons = true; + m_pCustomTextureNextButton->SetEnabled( iSelectedCustomImage < n-1 ); + m_pCustomTexturePrevButton->SetEnabled( iSelectedCustomImage > 0 ); + } + } + else + { + m_pCustomTextureImagePanel->SetVisible( false ); + m_pNoCustomTexturesLabel->SetVisible( true ); + } + } + else + { + m_pCustomTextureImagePanel->SetVisible( false ); + m_pNoCustomTexturesLabel->SetVisible( false ); + } + m_pCustomTextureNextButton->SetVisible( bShowScrollButtons ); + m_pCustomTexturePrevButton->SetVisible( bShowScrollButtons ); +} + +int CAbuseReportDlg::GetSelectedCustomImage() +{ + if ( GetAbuseContentType() != k_EAbuseReportContentUGCImage ) + { + m_iUserImageIndex = 0; + return -1; + } + + const AbuseIncidentData_t::PlayerData_t *pAccused = GetAccusedPlayerPtr(); + if ( pAccused == NULL ) + { + m_iUserImageIndex = 0; + return -1; + } + + int n = pAccused->m_vecImages.Count(); + if ( n < 1 ) + { + m_iUserImageIndex = 0; + return -1; + } + + // Wrap currently selected index + m_iUserImageIndex = ( m_iUserImageIndex + n*10 ) % n; + + // Return it + return m_iUserImageIndex; +} + +void CAbuseReportDlg::OnTextChanged( vgui::Panel *panel ) +{ + if ( panel == m_pPlayerCombo ) + { + PlayerChanged(); + } + else if ( panel == m_pAbuseContentCombo ) + { + ContentTypeChanged(); + } + else + { + UpdateSubmitButton(); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Job to do the async work of submitting the report +//----------------------------------------------------------------------------- +class CSubmitAbuseReportJob : public GCSDK::CGCClientJob +{ +public: + bool m_bGameServer; + + + CSubmitAbuseReportJob( ) + : GCSDK::CGCClientJob( GCClientSystem()->GetGCClient() ) + { + m_bGameServer = false; + } + + virtual bool BYieldingRunGCJob() + { + EResult result = RunJob(); + + // Tear down our dialogs + CloseWaitingDialog(); + + CAbuseReportDlg *pDlg = g_AbuseReportDlg.Get(); + if ( pDlg ) + { + pDlg->Close(); + pDlg = NULL; + } + + // And destroy the queued report! + g_AbuseReportMgr->DestroyIncidentData(); + + // now show a dialog box explaining the outcome + switch ( result ) + { + case k_EResultOK: + ShowMessageBox( "#AbuseReport_SucceededTitle", "#AbuseReport_SucceededMessage", "#GameUI_OK" ); + break; + + case k_EResultLimitExceeded: + ShowMessageBox( + "#AbuseReport_TooMuchFailedTitle", + m_bGameServer ? "#AbuseReport_TooMuchFailedMessageGameServer" : "#AbuseReport_TooMuchFailedMessage", + "#GameUI_OK" + ); + break; + + default: + ShowMessageBox( "#AbuseReport_GenericFailureTitle", "#AbuseReport_GenericFailureMessage", "#GameUI_OK" ); + break; + } + + return true; + } + + EResult RunJob() + { + CAbuseReportDlg *pDlg = g_AbuseReportDlg.Get(); + if ( pDlg == NULL ) + { + return k_EResultFail; + } + m_bGameServer = pDlg->IsAccusingGameServer(); + EAbuseReportContentType eContentSelected = pDlg->GetAbuseContentType(); + EAbuseReportContentType eContentReported = eContentSelected; + EAbuseReportType eAbuseType = pDlg->GetAbuseType(); + const AbuseIncidentData_t::PlayerData_t *pAccused = pDlg->GetAccusedPlayerPtr(); + const AbuseIncidentData_t *pIncidentData = g_AbuseReportMgr->GetIncidentData(); + CUtlString sAbuseDescription = pDlg->GetAbuseDescription(); + netadr_t adrGameServer = pIncidentData->m_adrGameServer; + CSteamID steamIDGameServer = pIncidentData->m_steamIDGameServer; + uint64 gid = 0; + + // Check if we should upload the screenshot + if ( pDlg->GetAttachScreenShot() && steamapicontext && steamapicontext->SteamUtils() && steamapicontext->SteamRemoteStorage() ) + { + + // Write the local copy of the file + if ( !steamapicontext->SteamRemoteStorage()->FileWrite( CAbuseReportManager::k_rchScreenShotFilename, pIncidentData->m_bufScreenshotFileData.Base(), pIncidentData->m_bufScreenshotFileData.TellPut() ) ) + { + Warning( "Failed to save local cloud copy of %s\n", CAbuseReportManager::k_rchScreenShotFilename ); + return k_EResultFail; + } + + // Share it. This initiates the upload to cloud + Msg( "Starting upload of %s to UFS....\n", CAbuseReportManager::k_rchScreenShotFilename ); + SteamAPICall_t hFileShareApiCall = steamapicontext->SteamRemoteStorage()->FileShare( CAbuseReportManager::k_rchScreenShotFilename ); + if ( hFileShareApiCall == k_uAPICallInvalid ) + { + Warning( "Failed to share %s\n", CAbuseReportManager::k_rchScreenShotFilename ); + return k_EResultFail; + } + + // Check if we're busy + bool bFailed; + RemoteStorageFileShareResult_t result; + while ( !steamapicontext->SteamUtils()->GetAPICallResult(hFileShareApiCall, + &result, sizeof(result), RemoteStorageFileShareResult_t::k_iCallback, &bFailed) ) + { + BYield(); + } + + // Clear pointer, it could have been destroyed while we were yielding, make sure we don't reference it + pDlg = NULL; + + if ( bFailed || result.m_eResult != k_EResultOK ) + { + Warning( "Failed to share %s; result code %d\n", CAbuseReportManager::k_rchScreenShotFilename, result.m_eResult ); + return result.m_eResult; + } + + Msg( "%s shared to UGC OK\n", CAbuseReportManager::k_rchScreenShotFilename ); + gid = result.m_hFile; + + // SWitch the content type being reported, so the support tool will know what to + // do with the GID. + eContentReported = k_EAbuseReportContentActorUGCImage; + } + else if ( eContentSelected == k_EAbuseReportContentUGCImage ) + { + Assert( !m_bGameServer ); + int iImageindex = pDlg->GetSelectedCustomImage(); + Assert( iImageindex >= 0 ); + gid = pAccused->m_vecImages[iImageindex].m_hUGCHandle; + } + + // + // Fill out the report message + // + GCSDK::CProtoBufMsg<CMsgGCReportAbuse> msg( k_EMsgGC_ReportAbuse ); + if ( m_bGameServer ) + { + msg.Body().set_target_steam_id( steamIDGameServer.ConvertToUint64() ); + msg.Body().set_target_game_server_ip( adrGameServer.GetIPHostByteOrder() ); + msg.Body().set_target_game_server_port( adrGameServer.GetPort() ); + } + else + { + msg.Body().set_target_steam_id( pAccused->m_steamID.ConvertToUint64() ); + msg.Body().set_content_type( eContentReported ); + msg.Body().set_abuse_type( eAbuseType ); + } + msg.Body().set_description( sAbuseDescription ); + if (gid != 0 ) + { + msg.Body().set_gid( gid ); + } + + // Send the message to the GC, and await the reply + GCSDK::CProtoBufMsg<CMsgGCReportAbuseResponse> msgReply; + if ( !BYldSendMessageAndGetReply( msg, 10, &msgReply, k_EMsgGC_ReportAbuseResponse ) ) + { + Warning( "Abuse report failed: Did not get reply from GC\n" ); + return k_EResultTimeout; + } + + EResult result = (EResult)msgReply.Body().result(); + if ( result != k_EResultOK ) + { + Warning( "Abuse report failed with failure code %d. %s\n", result, msgReply.Body().error_message().c_str() ); + } + + // OK + return result; + } + +}; + +void CAbuseReportDlg::OnSubmitReport() +{ + // throw up a waiting dialog + SetEnabled( false ); + ShowWaitingDialog( new CGenericWaitingDialog( this ), "#AbuseReport_Busy", true, false, 0.0f ); + + // We need to be in the global singleton handle, because that's how the job knows + // to get to us (and how it knows if we've died)! + Assert( g_AbuseReportDlg.Get() == this ); + + // Start a job + CSubmitAbuseReportJob *pJob = new CSubmitAbuseReportJob(); + pJob->StartJob( NULL ); +} |