mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-13 20:21:06 +00:00
1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user