initial
This commit is contained in:
338
game/client/cstrike15/Scaleform/HUD/sfhud_autodisconnect.cpp
Normal file
338
game/client/cstrike15/Scaleform/HUD/sfhud_autodisconnect.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Displays HUD element to show we are having connectivity trouble
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_element_helper.h"
|
||||
#include "scaleformui/scaleformui.h"
|
||||
#include "sfhud_autodisconnect.h"
|
||||
#include "hud_macros.h"
|
||||
#include "view.h"
|
||||
|
||||
#include "inetchannelinfo.h"
|
||||
|
||||
#include "c_cs_playerresource.h"
|
||||
#include "c_cs_player.h"
|
||||
#include "cs_gamerules.h"
|
||||
#include "cs_client_gamestats.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
DECLARE_HUDELEMENT( SFHudAutodisconnect );
|
||||
|
||||
SFUI_BEGIN_GAME_API_DEF
|
||||
SFUI_END_GAME_API_DEF( SFHudAutodisconnect, Autodisconnect );
|
||||
|
||||
SFHudAutodisconnect::SFHudAutodisconnect( const char *value ) : SFHudFlashInterface( value ),
|
||||
m_sfuiControlBg( NULL ), m_sfuiControlTopLabel( NULL ), m_sfuiControlBottomLabel( NULL ), m_sfuiControlTimerLabel( NULL ), m_sfuiControlTimerIcon( NULL )
|
||||
{
|
||||
// This HUD element should never be hidden, so do not call SetHiddenBits
|
||||
}
|
||||
|
||||
SFHudAutodisconnect::~SFHudAutodisconnect()
|
||||
{
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::ShowPanel( bool bShow )
|
||||
{
|
||||
if ( m_FlashAPI )
|
||||
{
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
if ( bShow )
|
||||
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "ShowPanel", NULL, 0 );
|
||||
else
|
||||
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "HidePanel", NULL, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConVar cl_connection_trouble_show( "cl_connection_trouble_show", "0", FCVAR_RELEASE, "Show connection trouble HUD warnings" );
|
||||
DEVELOPMENT_ONLY_CONVAR( cl_connection_trouble_force, 0 );
|
||||
static bool Helper_ShouldInformPlayerAboutConnectionLossChoke()
|
||||
{
|
||||
static ConVarRef cl_connection_trouble_info( "cl_connection_trouble_info" );
|
||||
if ( !cl_connection_trouble_info.IsValid() )
|
||||
return false;
|
||||
|
||||
// No error - nothing to show
|
||||
if ( !cl_connection_trouble_info.GetString()[ 0 ] )
|
||||
return false;
|
||||
|
||||
// Not a transient error - always show
|
||||
if ( cl_connection_trouble_info.GetString()[ 0 ] != '@' )
|
||||
return true;
|
||||
|
||||
// UI debugging feature
|
||||
if ( cl_connection_trouble_force.GetInt() == 1 ) // Allow to always show for testing
|
||||
return true;
|
||||
|
||||
// Don't care when playing demos or GOTV or on listen server
|
||||
if ( g_bEngineIsHLTV || engine->IsClientLocalToActiveServer() )
|
||||
return false;
|
||||
|
||||
// Not when loading
|
||||
if ( engine->IsDrawingLoadingImage() )
|
||||
return false;
|
||||
|
||||
// No local player - don't show
|
||||
C_CSPlayer *pLocalPlayer = C_CSPlayer::GetLocalCSPlayer();
|
||||
if ( !pLocalPlayer )
|
||||
return false;
|
||||
|
||||
// Show only when on active team
|
||||
switch ( pLocalPlayer->GetTeamNumber() )
|
||||
{
|
||||
case TEAM_TERRORIST:
|
||||
case TEAM_CT:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !pLocalPlayer->IsAlive() )
|
||||
return false;
|
||||
|
||||
// Need game rules
|
||||
if ( !CSGameRules() )
|
||||
return false;
|
||||
|
||||
// If the round is already won, then don't show warnings (things will start resetting and cause a spike)
|
||||
if ( CSGameRules()->IsRoundOver() )
|
||||
return false;
|
||||
|
||||
// Don't show warnings during freeze period or warmup (that's when players are joining)
|
||||
if ( CSGameRules()->IsFreezePeriod() || CSGameRules()->IsWarmupPeriod() )
|
||||
return false;
|
||||
|
||||
// Don't show warning for 3 seconds after freezetime ended (need to accumulate choke/loss)
|
||||
if ( gpGlobals->curtime < CSGameRules()->GetRoundStartTime() + 3.0f )
|
||||
return false;
|
||||
|
||||
// Don't show warnings if local player just spawned or respawned (AR / DM / etc.)
|
||||
if ( pLocalPlayer->m_flLastSpawnTimeIndex > gpGlobals->curtime - 3.0f )
|
||||
return false;
|
||||
|
||||
//
|
||||
// OGS recording
|
||||
//
|
||||
static double s_dTimeLastOgsRecordWritten = 0;
|
||||
static double s_dTimeTrackingPeakStarted = 0;
|
||||
static float s_flTrackedPeakValue = 0;
|
||||
static CSClientCsgoGameEventType_t s_chTypeTrackingPeak = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
|
||||
double dTimeNow = Plat_FloatTime();
|
||||
if ( dTimeNow > s_dTimeLastOgsRecordWritten + 60 )
|
||||
{
|
||||
bool bRecordNow = false;
|
||||
CSClientCsgoGameEventType_t chType = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
|
||||
float flCurrentValue = 0;
|
||||
if ( INetChannelInfo *pChannelInfo = engine->GetNetChannelInfo() )
|
||||
{
|
||||
float flPacketLoss = pChannelInfo->GetAvgLoss( FLOW_INCOMING );
|
||||
float flPacketChoke = pChannelInfo->GetAvgChoke( FLOW_INCOMING );
|
||||
if ( flPacketLoss > 0 )
|
||||
{
|
||||
chType = k_CSClientCsgoGameEventType_ConnectionProblem_Loss;
|
||||
flCurrentValue = flPacketLoss;
|
||||
}
|
||||
else if ( flPacketChoke > 0 )
|
||||
{
|
||||
chType = k_CSClientCsgoGameEventType_ConnectionProblem_Choke;
|
||||
flCurrentValue = flPacketChoke;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( chType != s_chTypeTrackingPeak ) || ( dTimeNow > s_dTimeTrackingPeakStarted + 0.75 ) )
|
||||
{ // Start tracking this problem type (or weren't tracking for some time?)
|
||||
s_chTypeTrackingPeak = chType;
|
||||
s_dTimeTrackingPeakStarted = dTimeNow;
|
||||
s_flTrackedPeakValue = 0;
|
||||
}
|
||||
else if ( dTimeNow > s_dTimeTrackingPeakStarted + 0.25 )
|
||||
{ // Have been tracking for 0.25 seconds: time to record
|
||||
bRecordNow = true;
|
||||
}
|
||||
|
||||
// Track max value over the period
|
||||
s_flTrackedPeakValue = MAX( s_flTrackedPeakValue, flCurrentValue );
|
||||
|
||||
if ( bRecordNow )
|
||||
{
|
||||
s_dTimeLastOgsRecordWritten = dTimeNow;
|
||||
uint64 ullData = int(s_flTrackedPeakValue * 1000);
|
||||
g_CSClientGameStats.AddClientCSGOGameEvent( chType, pLocalPlayer->GetAbsOrigin(), pLocalPlayer->EyeAngles(), ullData );
|
||||
DevMsg( "%s (peak at %.1f%%)\n", cl_connection_trouble_info.GetString(), s_flTrackedPeakValue*100 );
|
||||
|
||||
// Reset the data
|
||||
s_chTypeTrackingPeak = k_CSClientCsgoGameEventType_ConnectionProblem_Generic;
|
||||
s_flTrackedPeakValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !cl_connection_trouble_show.GetBool() ) // Allow to always hide transient errors (data collection only)
|
||||
return false;
|
||||
|
||||
// Does not hide with the rest of the HUD
|
||||
return true;
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::ProcessInput( void )
|
||||
{
|
||||
static ConVarRef cl_connection_trouble_info( "cl_connection_trouble_info" );
|
||||
if ( FlashAPIIsValid() && m_bActive && cl_connection_trouble_info.IsValid() && cl_connection_trouble_info.GetString()[0] )
|
||||
{
|
||||
//
|
||||
// See cl_main.cpp CL_Move
|
||||
// bool hasProblem = cl.m_NetChannel->IsTimingOut() && !demoplayer->IsPlayingBack() && cl.IsActive();
|
||||
//
|
||||
|
||||
// Check for disconnect?
|
||||
float TimeoutValue = -1.0f, Percentage = -1.0f;
|
||||
|
||||
if ( 1 == sscanf( cl_connection_trouble_info.GetString(), "disconnect(%f)", &TimeoutValue ) )
|
||||
{
|
||||
if ( TimeoutValue < 0 )
|
||||
TimeoutValue = 0;
|
||||
|
||||
char cTimerStr[ 128 ];
|
||||
V_snprintf( cTimerStr, sizeof(cTimerStr), "%02d:%02d", Floor2Int( TimeoutValue / 60.f ), ( Floor2Int(TimeoutValue) % 60 ) );
|
||||
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_HEADER" );
|
||||
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlBottomLabel, "#SFUI_CONNWARNING_BODY" );
|
||||
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTimerLabel, cTimerStr );
|
||||
|
||||
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, true );
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
|
||||
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, true );
|
||||
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, true );
|
||||
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, true );
|
||||
}
|
||||
}
|
||||
else if ( 2 == sscanf( cl_connection_trouble_info.GetString(), "@%f:loss(%f)", &TimeoutValue, &Percentage ) )
|
||||
{
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_Bandwidth_PacketLoss" );
|
||||
|
||||
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
|
||||
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
|
||||
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
|
||||
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
|
||||
}
|
||||
}
|
||||
else if ( 2 == sscanf( cl_connection_trouble_info.GetString(), "@%f:choke(%f)", &TimeoutValue, &Percentage ) )
|
||||
{
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_Bandwidth_Choking" );
|
||||
|
||||
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
|
||||
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
|
||||
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
|
||||
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetText( m_sfuiControlTopLabel, "#SFUI_CONNWARNING_HEADER" );
|
||||
|
||||
if ( m_sfuiControlBg ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBg, false );
|
||||
if ( m_sfuiControlTopLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTopLabel, true );
|
||||
if ( m_sfuiControlBottomLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlBottomLabel, false );
|
||||
if ( m_sfuiControlTimerLabel ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerLabel, false );
|
||||
if ( m_sfuiControlTimerIcon ) m_pScaleformUI->Value_SetVisible( m_sfuiControlTimerIcon, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::FlashReady( void )
|
||||
{
|
||||
// Grab a pointer to the timeout text box
|
||||
if ( SFVALUE panelRoot = m_pScaleformUI->Value_GetMember( m_FlashAPI, "Panel" ) )
|
||||
{
|
||||
if ( SFVALUE panelAnim = m_pScaleformUI->Value_GetMember( panelRoot, "PanelAnim" ) )
|
||||
{
|
||||
m_sfuiControlBg = m_pScaleformUI->Value_GetMember( panelAnim, "AutoDisconnectBg" );
|
||||
|
||||
if ( SFVALUE text = m_pScaleformUI->Value_GetMember( panelAnim, "Text" ) )
|
||||
{
|
||||
m_sfuiControlTopLabel = m_pScaleformUI->Value_GetMember( text, "AutoDisconnectText1" );
|
||||
m_sfuiControlBottomLabel = m_pScaleformUI->Value_GetMember( text, "AutoDisconnectText2" );
|
||||
m_sfuiControlTimerLabel = m_pScaleformUI->Value_GetMember( text, "TimerText" );
|
||||
m_sfuiControlTimerIcon = m_pScaleformUI->Value_GetMember( text, "TimerIcon" );
|
||||
|
||||
SafeReleaseSFVALUE( text );
|
||||
}
|
||||
|
||||
SafeReleaseSFVALUE( panelAnim );
|
||||
}
|
||||
|
||||
SafeReleaseSFVALUE( panelRoot );
|
||||
}
|
||||
}
|
||||
|
||||
bool SFHudAutodisconnect::PreUnloadFlash( void )
|
||||
{
|
||||
SafeReleaseSFVALUE( m_sfuiControlBg );
|
||||
SafeReleaseSFVALUE( m_sfuiControlTopLabel );
|
||||
SafeReleaseSFVALUE( m_sfuiControlBottomLabel );
|
||||
SafeReleaseSFVALUE( m_sfuiControlTimerLabel );
|
||||
SafeReleaseSFVALUE( m_sfuiControlTimerIcon );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::LevelInit( void )
|
||||
{
|
||||
if ( !FlashAPIIsValid() )
|
||||
{
|
||||
// We assume we are offline-only for splitscreen multiplayer, so we allow this to be displayed in the split screen slot like
|
||||
// the rest of the HUD is. If we support splitscreen online down the road, this should be moved into the fullscreen slot.
|
||||
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudAutodisconnect, this, Autodisconnect );
|
||||
}
|
||||
|
||||
// When initially loaded, hide any previous message
|
||||
ShowPanel( false );
|
||||
m_bActive = false;
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::LevelShutdown( void )
|
||||
{
|
||||
if ( FlashAPIIsValid() )
|
||||
{
|
||||
RemoveFlashElement();
|
||||
}
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::Reset( void )
|
||||
{
|
||||
ShowPanel( false );
|
||||
}
|
||||
|
||||
bool SFHudAutodisconnect::ShouldDraw( void )
|
||||
{
|
||||
return Helper_ShouldInformPlayerAboutConnectionLossChoke();
|
||||
}
|
||||
|
||||
void SFHudAutodisconnect::SetActive( bool bActive )
|
||||
{
|
||||
if ( m_bActive != bActive )
|
||||
{
|
||||
ShowPanel( bActive );
|
||||
}
|
||||
|
||||
CHudElement::SetActive( bActive );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user