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/game_controls/vguitextwindow.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/game_controls/vguitextwindow.cpp')
| -rw-r--r-- | game/client/game_controls/vguitextwindow.cpp | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/game/client/game_controls/vguitextwindow.cpp b/game/client/game_controls/vguitextwindow.cpp new file mode 100644 index 0000000..4967d74 --- /dev/null +++ b/game/client/game_controls/vguitextwindow.cpp @@ -0,0 +1,436 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "vguitextwindow.h" +#include <networkstringtabledefs.h> +#include <cdll_client_int.h> +#include <clientmode_shared.h> + +#include <vgui/IScheme.h> +#include <vgui/ILocalize.h> +#include <vgui/ISurface.h> +#include <filesystem.h> +#include <KeyValues.h> +#include <convar.h> +#include <vgui_controls/ImageList.h> + +#include <vgui_controls/TextEntry.h> +#include <vgui_controls/Button.h> + +#include <game/client/iviewport.h> + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +using namespace vgui; +extern INetworkStringTable *g_pStringTableInfoPanel; + +#define TEMP_HTML_FILE "textwindow_temp.html" + +ConVar cl_disablehtmlmotd( "cl_disablehtmlmotd", "0", FCVAR_ARCHIVE, "Disable HTML motds." ); + +//============================================================================= +// HPE_BEGIN: +// [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration +// of options. Passing a command string is dangerous and allowed a server network +// message to run arbitrary commands on the client. +//============================================================================= +CON_COMMAND( showinfo, "Shows a info panel: <type> <title> <message> [<command number>]" ) +{ + if ( !gViewPortInterface ) + return; + + if ( args.ArgC() < 4 ) + return; + + IViewPortPanel * panel = gViewPortInterface->FindPanelByName( PANEL_INFO ); + + if ( panel ) + { + KeyValues *kv = new KeyValues("data"); + kv->SetInt( "type", Q_atoi(args[ 1 ]) ); + kv->SetString( "title", args[ 2 ] ); + kv->SetString( "message", args[ 3 ] ); + + if ( args.ArgC() == 5 ) + kv->SetString( "command", args[ 4 ] ); + + panel->SetData( kv ); + + gViewPortInterface->ShowPanel( panel, true ); + + kv->deleteThis(); + } + else + { + Msg("Couldn't find info panel.\n" ); + } +} +//============================================================================= +// HPE_END +//============================================================================= + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CTextWindow::CTextWindow(IViewPort *pViewPort) : Frame(NULL, PANEL_INFO ) +{ + // initialize dialog + m_pViewPort = pViewPort; + +// SetTitle("", true); + + m_szTitle[0] = '\0'; + m_szMessage[0] = '\0'; + m_szMessageFallback[0] = '\0'; + m_nExitCommand = TEXTWINDOW_CMD_NONE; + m_bShownURL = false; + m_bUnloadOnDismissal = false; + + // load the new scheme early!! + SetScheme("ClientScheme"); + SetMoveable(false); + SetSizeable(false); + SetProportional(true); + + // hide the system buttons + SetTitleBarVisible( false ); + + m_pTextMessage = new TextEntry( this, "TextMessage" ); + m_pHTMLMessage = new CMOTDHTML( this,"HTMLMessage" ); + m_pTitleLabel = new Label( this, "MessageTitle", "Message Title" ); + m_pOK = new Button(this, "ok", "#PropertyDialog_OK"); + + m_pOK->SetCommand("okay"); + m_pTextMessage->SetMultiline( true ); + m_nContentType = TYPE_TEXT; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTextWindow::ApplySchemeSettings( IScheme *pScheme ) +{ + BaseClass::ApplySchemeSettings( pScheme ); + + LoadControlSettings("Resource/UI/TextWindow.res"); + + Reset(); +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +CTextWindow::~CTextWindow() +{ + // remove temp file again + g_pFullFileSystem->RemoveFile( TEMP_HTML_FILE, "DEFAULT_WRITE_PATH" ); +} + +void CTextWindow::Reset( void ) +{ + //============================================================================= + // HPE_BEGIN: + // [Forrest] Replace strange hard-coded default message with hard-coded error message. + //============================================================================= + V_strcpy_safe( m_szTitle, "Error loading info message." ); + V_strcpy_safe( m_szMessage, "" ); + V_strcpy_safe( m_szMessageFallback, "" ); + //============================================================================= + // HPE_END + //============================================================================= + + m_nExitCommand = TEXTWINDOW_CMD_NONE; + m_nContentType = TYPE_TEXT; + m_bShownURL = false; + m_bUnloadOnDismissal = false; + Update(); +} + +void CTextWindow::ShowText( const char *text ) +{ + m_pTextMessage->SetVisible( true ); + m_pTextMessage->SetText( text ); + m_pTextMessage->GotoTextStart(); +} + +void CTextWindow::ShowURL( const char *URL, bool bAllowUserToDisable ) +{ + #ifdef _DEBUG + Msg( "CTextWindow::ShowURL( %s )\n", URL ); + #endif + + ClientModeShared *mode = ( ClientModeShared * )GetClientModeNormal(); + if ( ( bAllowUserToDisable && cl_disablehtmlmotd.GetBool() ) || !mode->IsHTMLInfoPanelAllowed() ) + { + Warning( "Blocking HTML info panel '%s'; Using plaintext instead.\n", URL ); + + // User has disabled HTML TextWindows. Show the fallback as text only. + if ( g_pStringTableInfoPanel ) + { + int index = g_pStringTableInfoPanel->FindStringIndex( "motd_text" ); + if ( index != ::INVALID_STRING_INDEX ) + { + int length = 0; + const char *data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length ); + if ( data && data[0] ) + { + m_pHTMLMessage->SetVisible( false ); + ShowText( data ); + } + } + } + return; + } + + m_pHTMLMessage->SetVisible( true ); + m_pHTMLMessage->OpenURL( URL, NULL ); + m_bShownURL = true; +} + +void CTextWindow::ShowIndex( const char *entry ) +{ + const char *data = NULL; + int length = 0; + + if ( NULL == g_pStringTableInfoPanel ) + return; + + int index = g_pStringTableInfoPanel->FindStringIndex( m_szMessage ); + + if ( index != ::INVALID_STRING_INDEX ) + data = (const char *)g_pStringTableInfoPanel->GetStringUserData( index, &length ); + + if ( !data || !data[0] ) + return; // nothing to show + + // is this a web URL ? + if ( !Q_strncmp( data, "http://", 7 ) || !Q_strncmp( data, "https://", 8 ) ) + { + ShowURL( data ); + return; + } + + // try to figure out if this is HTML or not + if ( data[0] != '<' ) + { + ShowText( data ); + return; + } + + // data is a HTML, we have to write to a file and then load the file + FileHandle_t hFile = g_pFullFileSystem->Open( TEMP_HTML_FILE, "wb", "DEFAULT_WRITE_PATH" ); + + if ( hFile == FILESYSTEM_INVALID_HANDLE ) + return; + + g_pFullFileSystem->Write( data, length, hFile ); + g_pFullFileSystem->Close( hFile ); + + if ( g_pFullFileSystem->Size( TEMP_HTML_FILE ) != (unsigned int)length ) + return; // something went wrong while writing + + ShowFile( TEMP_HTML_FILE ); +} + +void CTextWindow::ShowFile( const char *filename ) +{ + if ( Q_stristr( filename, ".htm" ) || Q_stristr( filename, ".html" ) ) + { + // it's a local HTML file + char localURL[ _MAX_PATH + 7 ]; + Q_strncpy( localURL, "file://", sizeof( localURL ) ); + + char pPathData[ _MAX_PATH ]; + g_pFullFileSystem->GetLocalPath( filename, pPathData, sizeof(pPathData) ); + Q_strncat( localURL, pPathData, sizeof( localURL ), COPY_ALL_CHARACTERS ); + + ShowURL( localURL ); + } + else + { + // read from local text from file + FileHandle_t f = g_pFullFileSystem->Open( m_szMessage, "rb", "GAME" ); + + if ( !f ) + return; + + char buffer[2048]; + + int size = MIN( g_pFullFileSystem->Size( f ), sizeof(buffer)-1 ); // just allow 2KB + + g_pFullFileSystem->Read( buffer, size, f ); + g_pFullFileSystem->Close( f ); + + buffer[size]=0; //terminate string + + ShowText( buffer ); + } +} + +void CTextWindow::Update( void ) +{ + SetTitle( m_szTitle, false ); + + m_pTitleLabel->SetText( m_szTitle ); + + if ( m_pHTMLMessage ) + m_pHTMLMessage->SetVisible( false ); + m_pTextMessage->SetVisible( false ); + + if ( m_nContentType == TYPE_INDEX ) + { + ShowIndex( m_szMessage ); + } + else if ( m_nContentType == TYPE_URL ) + { + if ( !Q_strncmp( m_szMessage, "http://", 7 ) || !Q_strncmp( m_szMessage, "https://", 8 ) || !Q_stricmp( m_szMessage, "about:blank" ) ) + { + ShowURL( m_szMessage ); + } + else + { + // We should have trapped this at a higher level + Assert( !"URL protocol is missing or blocked" ); + } + } + else if ( m_nContentType == TYPE_FILE ) + { + ShowFile( m_szMessage ); + } + else if ( m_nContentType == TYPE_TEXT ) + { + ShowText( m_szMessage ); + } + else + { + DevMsg("CTextWindow::Update: unknown content type %i\n", m_nContentType ); + } +} + +void CTextWindow::OnCommand( const char *command ) +{ + if (!Q_strcmp(command, "okay")) + { + //============================================================================= + // HPE_BEGIN: + // [Forrest] Replaced text window command string with TEXTWINDOW_CMD enumeration + // of options. Passing a command string is dangerous and allowed a server network + // message to run arbitrary commands on the client. + //============================================================================= + const char *pszCommand = NULL; + switch ( m_nExitCommand ) + { + case TEXTWINDOW_CMD_NONE: + break; + + case TEXTWINDOW_CMD_JOINGAME: + pszCommand = "joingame"; + break; + + case TEXTWINDOW_CMD_CHANGETEAM: + pszCommand = "changeteam"; + break; + + case TEXTWINDOW_CMD_IMPULSE101: + pszCommand = "impulse 101"; + break; + + case TEXTWINDOW_CMD_MAPINFO: + pszCommand = "mapinfo"; + break; + + case TEXTWINDOW_CMD_CLOSED_HTMLPAGE: + pszCommand = "closed_htmlpage"; + break; + + case TEXTWINDOW_CMD_CHOOSETEAM: + pszCommand = "chooseteam"; + break; + + default: + DevMsg("CTextWindow::OnCommand: unknown exit command value %i\n", m_nExitCommand ); + break; + } + + if ( pszCommand != NULL ) + { + engine->ClientCmd_Unrestricted( pszCommand ); + } + //============================================================================= + // HPE_END + //============================================================================= + + m_pViewPort->ShowPanel( this, false ); + } + + BaseClass::OnCommand(command); +} + +void CTextWindow::OnKeyCodePressed( vgui::KeyCode code ) +{ + if ( code == KEY_XBUTTON_A || code == KEY_XBUTTON_B || code == STEAMCONTROLLER_A || code == STEAMCONTROLLER_B ) + { + OnCommand( "okay" ); + return; + } + + BaseClass::OnKeyCodePressed(code); +} + +void CTextWindow::SetData(KeyValues *data) +{ + SetData( data->GetInt( "type" ), data->GetString( "title" ), data->GetString( "msg" ), data->GetString( "msg_fallback" ), data->GetInt( "cmd" ), data->GetBool( "unload" ) ); +} + +void CTextWindow::SetData( int type, const char *title, const char *message, const char *message_fallback, int command, bool bUnload ) +{ + Q_strncpy( m_szTitle, title, sizeof( m_szTitle ) ); + Q_strncpy( m_szMessage, message, sizeof( m_szMessage ) ); + Q_strncpy( m_szMessageFallback, message_fallback, sizeof( m_szMessageFallback ) ); + + m_nExitCommand = command; + + m_nContentType = type; + m_bUnloadOnDismissal = bUnload; + + Update(); +} + +void CTextWindow::ShowPanel( bool bShow ) +{ + if ( BaseClass::IsVisible() == bShow ) + return; + + m_pViewPort->ShowBackGround( bShow ); + + if ( bShow ) + { + Activate(); + SetMouseInputEnabled( true ); + } + else + { + SetVisible( false ); + SetMouseInputEnabled( false ); + + if ( m_bUnloadOnDismissal && m_bShownURL && m_pHTMLMessage ) + { + m_pHTMLMessage->OpenURL( "about:blank", NULL ); + m_bShownURL = false; + } + } +} + +bool CTextWindow::CMOTDHTML::OnStartRequest( const char *url, const char *target, const char *pchPostData, bool bIsRedirect ) +{ + if ( Q_strstr( url, "steam://" ) ) + return false; + + return BaseClass::OnStartRequest( url, target, pchPostData, bIsRedirect ); +} |