diff options
Diffstat (limited to 'game/client/tf/c_tf_freeaccount.cpp')
| -rw-r--r-- | game/client/tf/c_tf_freeaccount.cpp | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/game/client/tf/c_tf_freeaccount.cpp b/game/client/tf/c_tf_freeaccount.cpp new file mode 100644 index 0000000..f2814d6 --- /dev/null +++ b/game/client/tf/c_tf_freeaccount.cpp @@ -0,0 +1,388 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" + +#include "c_tf_freeaccount.h" + +#include "gcsdk/sharedobjectcache.h" +#include "tf_gcmessages.h" +#include "econ_game_account_client.h" +#include "tf_item_inventory.h" +#include "tf_player_info.h" + +#include <vgui/ILocalize.h> +#include "confirm_dialog.h" +#include "econ/econ_notifications.h" +#include "select_player_dialog.h" + +#include "gc_clientsystem.h" + +//----------------------------------------------------------------------------- + +class CSelectMostHelpfulFriendDialog : public CSelectPlayerDialog +{ +public: + CSelectMostHelpfulFriendDialog( vgui::Panel *parent ) + : CSelectPlayerDialog( parent ) + , m_iNumFriends( 0 ) + , m_bRefreshing( false ) + { + } + + virtual void UpdatePlayerList() + { + CSelectPlayerDialog::UpdatePlayerList(); + + vgui::Label *pLabelEmpty = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("EmptyPlayerListLabel") ); + vgui::Label *pLabelQuery = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("QueryLabel") ); + vgui::Label *pLabelRetrieving = dynamic_cast<vgui::Label*>( m_pStatePanels[m_iCurrentState]->FindChildByName("RetrievingPlayerListLabel") ); + + if ( pLabelEmpty ) + { + pLabelEmpty->SetVisible( m_bRefreshing == false && pLabelEmpty->IsVisible() ); + } + if ( pLabelQuery ) + { + pLabelQuery->SetVisible( m_bRefreshing == false && pLabelQuery->IsVisible() ); + } + if ( pLabelRetrieving ) + { + pLabelRetrieving->SetVisible( m_bRefreshing ); + } + } + + virtual void Reset() + { + CSelectPlayerDialog::Reset(); + m_iNumFriends = 0; + if ( m_bRefreshing == false ) + { + RequestFriendsFromGC(); + } + } + + virtual void SetupSelectFriends() + { + m_PlayerInfoList.Purge(); + + if ( steamapicontext && steamapicontext->SteamFriends() ) + { + // Get our game info so we can use that to test if our friends are connected to the same game as us + FriendGameInfo_t myGameInfo; + CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID(); + steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo ); + + int iFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); + if ( m_iNumFriends != iFriends ) + { + RequestFriendsFromGC(); + } + else + { + m_PlayerInfoList = m_FriendsWhoOwnTF2; + } + } + + UpdatePlayerList(); + } + + virtual void OnSelectPlayer( const CSteamID &steamID ) + { + GCSDK::CProtoBufMsg<CMsgTFFreeTrialChooseMostHelpfulFriend> msg( k_EMsgGCFreeTrial_ChooseMostHelpfulFriend ); + msg.Body().set_account_id_friend( steamID.GetAccountID() ); + GCClientSystem()->BSendMessage( msg ); + } + + void OnTF2FriendsReceived( GCSDK::CProtoBufMsg<CMsgTFRequestTF2FriendsResponse> &msg ) + { + // populate the list of friends who own TF2 + m_bRefreshing = false; + m_FriendsWhoOwnTF2.Purge(); + for ( int i = 0; i < msg.Body().account_ids_size(); ++i ) + { + uint32 unAccountID = msg.Body().account_ids( i ); + FOR_EACH_VEC( m_EntireFriendsList, j ) + { + partner_info_t &info = m_EntireFriendsList[j]; + if ( info.m_steamID.GetAccountID() == unAccountID ) + { + int idx = m_FriendsWhoOwnTF2.AddToTail(); + partner_info_t &infoCopy = m_FriendsWhoOwnTF2[idx]; + infoCopy = info; + break; + } + } + } + + // update UI + if ( m_iCurrentState == SPDS_SELECTING_FROM_FRIENDS ) + { + m_PlayerInfoList = m_FriendsWhoOwnTF2; + UpdatePlayerList(); + } + } + +protected: + virtual const char *GetResFile() { return "resource/ui/SelectMostHelpfulFriendDialog.res"; } + + void RequestFriendsFromGC() + { + // send a message to the GC requesting that it validate which friends own TF2 + m_bRefreshing = true; + m_EntireFriendsList.Purge(); + m_FriendsWhoOwnTF2.Purge(); + + if ( steamapicontext && steamapicontext->SteamFriends() ) + { + // Get our game info so we can use that to test if our friends are connected to the same game as us + FriendGameInfo_t myGameInfo; + CSteamID mySteamID = steamapicontext->SteamUser()->GetSteamID(); + steamapicontext->SteamFriends()->GetFriendGamePlayed( mySteamID, &myGameInfo ); + + m_iNumFriends = steamapicontext->SteamFriends()->GetFriendCount( k_EFriendFlagImmediate ); + if ( m_iNumFriends > 0 ) + { + GCSDK::CProtoBufMsg<CMsgTFRequestTF2Friends> msg( k_EMsgGCRequestTF2Friends ); + for ( int i = 0; i < m_iNumFriends; i++ ) + { + CSteamID friendSteamID = steamapicontext->SteamFriends()->GetFriendByIndex( i, k_EFriendFlagImmediate ); + + const char *pszName = steamapicontext->SteamFriends()->GetFriendPersonaName( friendSteamID ); + int idx = m_EntireFriendsList.AddToTail(); + partner_info_t &info = m_EntireFriendsList[idx]; + info.m_steamID = friendSteamID; + info.m_name = pszName; + + msg.Body().add_account_ids( friendSteamID.GetAccountID() ); + } + GCClientSystem()->BSendMessage( msg ); + } + else + { + m_bRefreshing = false; + } + } + } + + // data + bool m_bRefreshing; + int m_iNumFriends; + CUtlVector<partner_info_t> m_EntireFriendsList; + CUtlVector<partner_info_t> m_FriendsWhoOwnTF2; +}; + +static vgui::DHANDLE<CSelectMostHelpfulFriendDialog> g_hSelectMostHelpfulFriendDialog; + +/** + * Notification that the player should choose their most helpful friend. + */ +class CSelectHelpfulFriendNotification : public CEconNotification +{ +public: + CSelectHelpfulFriendNotification() {} + + virtual void Accept() + { + OpenSelectMostHelpfulFriendDialog( NULL ); + MarkForDeletion(); + } + + virtual void Decline() + { + MarkForDeletion(); + } + + virtual EType NotificationType() { return eType_AcceptDecline; } + + void Trigger() + { + OpenSelectMostHelpfulFriendDialog( NULL ); + MarkForDeletion(); + } + + static bool RemoveOtherNotifications( CEconNotification *pNotification ) + { + return dynamic_cast< CSelectHelpfulFriendNotification* >( pNotification ) != NULL; + } + +}; + +class CWasThankedBySomeoneNotification : public CEconNotification +{ +public: + CWasThankedBySomeoneNotification( const CSteamID& steamID ) + { + SetText( "#TF_Trial_Alert_ThankedBySomeone" ); + SetLifetime( 30.0f ); + + { + extern void GetPlayerNameBySteamID( const CSteamID &steamID, OUT_Z_CAP(maxLenInChars) char *pDestBuffer, int maxLenInChars ); + + wchar_t wszPlayerName[ MAX_PLAYER_NAME_LENGTH ]; + char szPlayerName[ MAX_PLAYER_NAME_LENGTH ]; + GetPlayerNameBySteamID( steamID, szPlayerName, sizeof( szPlayerName ) ); + g_pVGuiLocalize->ConvertANSIToUnicode( szPlayerName, wszPlayerName, sizeof( wszPlayerName ) ); + AddStringToken( "thanker", wszPlayerName ); + } + } + + static bool RemoveOtherNotifications( CEconNotification *pNotification ) + { + return dynamic_cast< CWasThankedBySomeoneNotification* >( pNotification ) != NULL; + } +}; + +#ifdef _DEBUG +CON_COMMAND( cl_free_trial_select_friend, "Bring up dialog to select most helpful friend" ) +{ + OpenSelectMostHelpfulFriendDialog( NULL ); +} + +CON_COMMAND( cl_thanks_test, "Tests the thanked ui notification." ) +{ + if ( steamapicontext == NULL || steamapicontext->SteamUser() == NULL ) + return; + + CSteamID steamID = steamapicontext->SteamUser()->GetSteamID(); + NotificationQueue_Add( new CWasThankedBySomeoneNotification( steamID ) ); +} +#endif + +class CGCRequestTF2FriendsResponse : public GCSDK::CGCClientJob +{ +public: + CGCRequestTF2FriendsResponse( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} + + virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) + { + GCSDK::CProtoBufMsg<CMsgTFRequestTF2FriendsResponse> msg( pNetPacket ); + if ( g_hSelectMostHelpfulFriendDialog.Get() ) + { + g_hSelectMostHelpfulFriendDialog->OnTF2FriendsReceived( msg ); + } + return true; + } +}; +GC_REG_JOB( GCSDK::CGCClient, CGCRequestTF2FriendsResponse, "CGCRequestTF2FriendsResponse", k_EMsgGCRequestTF2FriendsResponse, GCSDK::k_EServerTypeGCClient ); + +class CGCThankedBySomeone : public GCSDK::CGCClientJob +{ +public: + CGCThankedBySomeone( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} + + virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) + { + GCSDK::CProtoBufMsg<CMsgTFThankedBySomeone> msg( pNetPacket ); + NotificationQueue_Add( new CWasThankedBySomeoneNotification( CSteamID( msg.Body().thanker_steam_id() ) ) ); + return true; + } +}; +GC_REG_JOB( GCSDK::CGCClient, CGCThankedBySomeone, "CGCThankedBySomeone", k_EMsgGCFreeTrial_ThankedBySomeone, GCSDK::k_EServerTypeGCClient ); + +class CGCThankedSomeone : public GCSDK::CGCClientJob +{ +public: + CGCThankedSomeone( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} + + virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) + { + ShowMessageBox( "#TF_Trial_ThankSuccess_Title", "#TF_Trial_ThankSuccess_Text", "#GameUI_OK" ); + return true; + } +}; +GC_REG_JOB( GCSDK::CGCClient, CGCThankedSomeone, "CGCThankedSomeone", k_EMsgGCFreeTrial_ThankedSomeone, GCSDK::k_EServerTypeGCClient ); + +class CGCFreeTrialConvertedToPremium : public GCSDK::CGCClientJob +{ +public: + CGCFreeTrialConvertedToPremium( GCSDK::CGCClient *pClient ) : GCSDK::CGCClientJob( pClient ) {} + + virtual bool BYieldingRunGCJob( GCSDK::IMsgNetPacket *pNetPacket ) + { + ShowMessageBox( "#TF_Trial_Converted_Title", "#TF_Trial_Converted_Text", "#GameUI_OK" ); + return true; + } +}; +GC_REG_JOB( GCSDK::CGCClient, CGCFreeTrialConvertedToPremium, "CGCFreeTrialConvertedToPremium", k_EMsgGCFreeTrial_ConvertedToPremium, GCSDK::k_EServerTypeGCClient ); + + +//----------------------------------------------------------------------------- +// External API + +#if _DEBUG +ConVar tf_forcetrialaccount( "tf_forcetrialaccount", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); +#endif + +#ifdef STAGING_ONLY +ConVar tf_thank_a_friend_enabled( "tf_thank_a_friend_enabled", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); +#endif // STAGING_ONLY + +bool IsFreeTrialAccount() +{ +#if _DEBUG + if ( tf_forcetrialaccount.GetBool() ) + return true; +#endif + + if ( InventoryManager() && TFInventoryManager()->GetLocalTFInventory() && TFInventoryManager()->GetLocalTFInventory()->GetSOC() ) + { + CEconGameAccountClient *pGameAccountClient = TFInventoryManager()->GetLocalTFInventory()->GetSOC()->GetSingleton<CEconGameAccountClient>(); + if ( pGameAccountClient ) + return pGameAccountClient->Obj().trial_account(); + } + return false; +} + +bool NeedsToChooseMostHelpfulFriend() +{ +#ifdef STAGING_ONLY + if ( tf_thank_a_friend_enabled.GetBool() ) +#endif // STAGING_ONLY + { + if ( InventoryManager() && TFInventoryManager()->GetLocalTFInventory() && TFInventoryManager()->GetLocalTFInventory()->GetSOC() ) + { + CEconGameAccountClient *pGameAccountClient = TFInventoryManager()->GetLocalTFInventory()->GetSOC()->GetSingleton<CEconGameAccountClient>(); + if ( pGameAccountClient ) + { + return !pGameAccountClient->Obj().trial_account() + && pGameAccountClient->Obj().need_to_choose_most_helpful_friend(); + } + } + } + return false; +} + +void NotifyNeedsToChooseMostHelpfulFriend() +{ + // remove duplicates + NotificationQueue_Remove( &CSelectHelpfulFriendNotification::RemoveOtherNotifications ); + // add new notification + CSelectHelpfulFriendNotification *pNotification = new CSelectHelpfulFriendNotification(); + pNotification->SetText( "#TF_Trial_Alert_SelectFriend" ); + pNotification->SetLifetime( 120.0f ); + NotificationQueue_Add( pNotification ); +} + +CSelectPlayerDialog *OpenSelectMostHelpfulFriendDialog( vgui::Panel *pParent ) +{ + if (!g_hSelectMostHelpfulFriendDialog.Get()) + { + g_hSelectMostHelpfulFriendDialog = vgui::SETUP_PANEL( new CSelectMostHelpfulFriendDialog( pParent ) ); + } + g_hSelectMostHelpfulFriendDialog->InvalidateLayout( false, true ); + g_hSelectMostHelpfulFriendDialog->Reset(); + g_hSelectMostHelpfulFriendDialog->SetVisible( true ); + g_hSelectMostHelpfulFriendDialog->MakePopup(); + g_hSelectMostHelpfulFriendDialog->MoveToFront(); + g_hSelectMostHelpfulFriendDialog->SetKeyBoardInputEnabled(true); + g_hSelectMostHelpfulFriendDialog->SetMouseInputEnabled(true); + TFModalStack()->PushModal( g_hSelectMostHelpfulFriendDialog ); + + return g_hSelectMostHelpfulFriendDialog; +} + |