//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include "cbase.h" #include "tf_notification.h" #include "c_tf_notification.h" #include "tf_gc_client.h" #include "econ/econ_notifications.h" /// /// Support message notification dialog /// class CTFSupportNotificationDialog : public CTFMessageBoxDialog { DECLARE_CLASS_SIMPLE( CTFSupportNotificationDialog, CTFMessageBoxDialog ); public: CTFSupportNotificationDialog( int iNotificationID, const char *pszSupportMessage ) : CTFMessageBoxDialog( NULL, pszSupportMessage, NULL, NULL, NULL ) , m_iNotificationID( iNotificationID ) , m_pConfirmDialog( NULL ) { SetDialogVariable( "text", GetText() ); } void CleanupConfirmDialog() { if ( m_pConfirmDialog ) { m_pConfirmDialog->SetVisible( false ); m_pConfirmDialog->MarkForDeletion(); m_pConfirmDialog = NULL; } } virtual ~CTFSupportNotificationDialog() { CleanupConfirmDialog(); } void ConfirmDialogCallback( bool bConfirmed ) { CleanupConfirmDialog(); if ( bConfirmed ) { // User acknowledged the message, tell the notification it can go away now CClientNotification *pNotification = dynamic_cast< CClientNotification * >( NotificationQueue_Get( m_iNotificationID ) ); if ( pNotification ) { pNotification->OnDialogAcknowledged(); } BaseClass::OnCommand( "confirm" ); } } static void StaticConfirmDialogCallback( bool bConfirmed, void *pContext ) { static_cast< CTFSupportNotificationDialog * >( pContext )->ConfirmDialogCallback( bConfirmed ); } virtual void OnCommand( const char *command ) OVERRIDE { if ( FStrEq( "acknowledge", command ) ) { // Confirm this, it's going away forever! CleanupConfirmDialog(); m_pConfirmDialog = ShowConfirmDialog( "#DeleteConfirmDefault", "#TF_Support_Message_Confirm_Acknowledge_Text", "#TF_Support_Message_Acknowledge", "#Cancel", &StaticConfirmDialogCallback ); m_pConfirmDialog->SetContext( this ); return; } else if ( FStrEq( "show_later", command ) ) { // User selected "show this later" -- leave notification as is and close. CleanupConfirmDialog(); BaseClass::OnCommand( "confirm" ); return; } BaseClass::OnCommand( command ); } virtual const char *GetResFile() OVERRIDE { return "Resource/UI/SupportNotificationDialog.res"; } private: // Associated notification to clear int m_iNotificationID; CTFGenericConfirmDialog *m_pConfirmDialog; }; /// /// The notification class /// CClientNotification::CClientNotification() { m_pText = NULL; m_flExpireTime = CRTime::RTime32TimeCur(); m_ulNotificationID = 0; m_unAccountID = 0; m_bSupportMessage = false; } CClientNotification::~CClientNotification() {} void CClientNotification::Update( const CTFNotification* notification ) { // Custom type handling. For now only support message does anything special. m_bSupportMessage = false; switch ( notification->Obj().type() ) { case CMsgGCNotification_NotificationType_NOTIFICATION_REPORTED_PLAYER_BANNED: case CMsgGCNotification_NotificationType_NOTIFICATION_CUSTOM_STRING: case CMsgGCNotification_NotificationType_NOTIFICATION_MM_BAN_DUE_TO_EXCESSIVE_REPORTS: case CMsgGCNotification_NotificationType_NOTIFICATION_REPORTED_PLAYER_WAS_BANNED: // All identical. // // Really, the other types could be used to avoid having to send a localization string down? Otherwise // they're all just redundant with CUSTOM_STRING for now. break; case CMsgGCNotification_NotificationType_NOTIFICATION_SUPPORT_MESSAGE: m_bSupportMessage = true; break; default: Assert( !"Unhandled enum value" ); } m_pText = NULL; m_strText = notification->Obj().notification_string().c_str(); if ( m_bSupportMessage ) { // Use generic notification, save actual notification contents for dialog m_pText = "#TF_Support_Message_Notification"; } else { // Just use our message m_pText = m_strText.Get(); } // 0 -> does not expire RTime32 rtExpire = notification->Obj().expiration_time(); m_flExpireTime = rtExpire > 0 ? (float)rtExpire : FLT_MAX; m_ulNotificationID = notification->Obj().notification_id(); m_unAccountID = notification->Obj().account_id(); } void CClientNotification::GCAcknowledge() { GTFGCClientSystem()->AcknowledgeNotification( m_unAccountID, m_ulNotificationID ); } void CClientNotification::Deleted() { if ( m_bSupportMessage ) { AssertMsg( !m_bSupportMessage, "Support messages should only be able to be triggered, not deleted" ); return; } GCAcknowledge(); } void CClientNotification::Expired() { // No action, we don't want de-sync'd client clock to acknowledge these incorrectly, GC will expire them on its end. } CClientNotification::EType CClientNotification::NotificationType() { // Support messages are "must trigger" type -- no delete action, user must click "view" if ( m_bSupportMessage ) { return eType_MustTrigger; } return eType_Basic; } bool CClientNotification::BHighPriority() { return m_bSupportMessage; } void CClientNotification::Trigger() { if ( !m_bSupportMessage ) { AssertMsg( m_bSupportMessage, "Don't expect to be trigger-able when not in support message mode" ); return; } CTFSupportNotificationDialog *pDialog = vgui::SETUP_PANEL( new CTFSupportNotificationDialog( GetID(), m_strText.Get() ) ); pDialog->Show(); } void CClientNotification::OnDialogAcknowledged() { if ( !m_bSupportMessage ) { AssertMsg( m_bSupportMessage, "Don't expect to be getting callbacks from the support message dialog when not in support message mode" ); return; } GCAcknowledge(); MarkForDeletion(); } //----------------------------------------------------------------------------- // CAutobalanceVolunteerNotification //----------------------------------------------------------------------------- void CAutobalanceVolunteerNotification::SendResponse( bool bResponse ) { KeyValues *kv = new KeyValues( "AutoBalanceVolunteerReply" ); kv->SetBool( "response", bResponse ); engine->ServerCmdKeyValues( kv ); MarkForDeletion(); }