//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Menu responsible for allowing players to join a game // // $Revision: $ // $NoKeywords: $ //===========================================================================// #include "menumanager.h" #include "basemenu.h" #include "vgui_controls/listpanel.h" #include "vgui_controls/textentry.h" #include "vgui_controls/button.h" #include "networkmessages.h" #include "networkmanager.h" #include "tier1/KeyValues.h" //----------------------------------------------------------------------------- // Constructor, destructor //----------------------------------------------------------------------------- class CJoinGameMenu : public CBaseMenu, public INetworkMessageListener { DECLARE_CLASS_SIMPLE( CJoinGameMenu, CBaseMenu ); public: CJoinGameMenu( vgui::Panel *pParent, const char *pPanelName ); virtual ~CJoinGameMenu(); // Called when a particular network message occurs virtual void OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage ); virtual void OnCommand( const char *pCommand ); MESSAGE_FUNC( OnTextNewLine, "TextNewLine" ); private: vgui::ListPanel *m_pPlayerList; vgui::TextEntry *m_pChatLog; vgui::TextEntry *m_pServerName; vgui::TextEntry *m_pServerPort; vgui::TextEntry *m_pChatEntry; vgui::TextEntry *m_pPlayerName; vgui::Button *m_pJoinGame; bool m_bJoiningGame; }; //----------------------------------------------------------------------------- // Hooks the menu into the menu manager //----------------------------------------------------------------------------- REGISTER_MENU( "JoinGameMenu", CJoinGameMenu ); //----------------------------------------------------------------------------- // Sort by player name //----------------------------------------------------------------------------- static int __cdecl PlayerNameSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 ) { const char *string1 = item1.kv->GetString("player"); const char *string2 = item2.kv->GetString("player"); return stricmp( string1, string2 ); } //----------------------------------------------------------------------------- // Constructor, destructor //----------------------------------------------------------------------------- CJoinGameMenu::CJoinGameMenu( vgui::Panel *pParent, const char *pPanelName ) : BaseClass( pParent, pPanelName ) { m_pPlayerList = new vgui::ListPanel( this, "PlayerList" ); m_pPlayerList->AddColumnHeader( 0, "color", "Color", 52, 0 ); m_pPlayerList->AddColumnHeader( 1, "player", "Player Name", 128, 0 ); m_pPlayerList->SetSelectIndividualCells( false ); m_pPlayerList->SetEmptyListText( "No Players" ); m_pPlayerList->SetDragEnabled( false ); m_pPlayerList->AddActionSignalTarget( this ); m_pPlayerList->SetSortFunc( 0, PlayerNameSortFunc ); m_pPlayerList->SetSortFunc( 1, PlayerNameSortFunc ); m_pPlayerList->SetSortColumn( 1 ); m_pServerName = new vgui::TextEntry( this, "ServerName" ); m_pServerPort = new vgui::TextEntry( this, "ServerPort" ); char pInitialPort[16]; Q_snprintf( pInitialPort, sizeof(pInitialPort), "%d", NETWORKSYSTEM_DEFAULT_SERVER_PORT ); m_pServerPort->SetText( pInitialPort ); m_pPlayerName = new vgui::TextEntry( this, "PlayerName" ); m_pPlayerName->SetMultiline( false ); m_pChatLog = new vgui::TextEntry( this, "ChatLog" ); m_pChatLog->SetMultiline( true ); m_pChatLog->SetVerticalScrollbar( true ); m_pChatEntry = new vgui::TextEntry( this, "ChatEntry" ); m_pChatEntry->AddActionSignalTarget( this ); m_pChatEntry->SetMultiline( false ); m_pChatEntry->SendNewLine( true ); m_pJoinGame = new vgui::Button( this, "JoinGame", "Join Game", this ); LoadControlSettings( "resource/joingamemenu.res", "GAME" ); m_pPlayerName->SetText( "Unnamed" ); m_pChatEntry->SetEnabled( false ); if ( !g_pNetworkManager->StartClient() ) { m_pJoinGame->SetEnabled( false ); return; } g_pNetworkManager->AddListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this ); } CJoinGameMenu::~CJoinGameMenu() { g_pNetworkManager->RemoveListener( NETWORK_MESSAGE_SERVER_TO_CLIENT, LEGION_NETMESSAGE_GROUP, CHAT_MESSAGE, this ); } //----------------------------------------------------------------------------- // Called when a particular network message occurs //----------------------------------------------------------------------------- void CJoinGameMenu::OnNetworkMessage( NetworkMessageRoute_t route, INetworkMessage *pNetworkMessage ) { CNetworkMessage_Chat *pChatMsg = static_cast( pNetworkMessage ); m_pChatLog->InsertString( pChatMsg->m_Message.Get() ); m_pChatLog->InsertChar( '\n' ); } //----------------------------------------------------------------------------- // Called when the enter key is hit in the chat entry window //----------------------------------------------------------------------------- void CJoinGameMenu::OnTextNewLine() { CNetworkMessage_Chat msg; int nLen = m_pChatEntry->GetTextLength(); if ( nLen > 0 ) { char *pText = (char*)_alloca( (nLen+1) * sizeof(char) ); m_pChatEntry->GetText( pText, nLen+1 ); m_pChatEntry->SetText( "" ); int nLenName = m_pPlayerName->GetTextLength(); char *pName = (char*)_alloca( (nLenName+8) * sizeof(char) ); if ( nLenName == 0 ) { nLenName = 7; Q_strcpy( pName, "unnamed" ); } else { m_pPlayerName->GetText( pName, nLenName+1 ); } int nTotalLen = nLen + nLenName; msg.m_Message.SetLength( nTotalLen + 3 ); Q_snprintf( msg.m_Message.Get(), nTotalLen+3, "[%s] %s", pName, pText ); g_pNetworkManager->PostClientToServerMessage( &msg ); } } //----------------------------------------------------------------------------- // Called when the enter key is hit in the chat entry window //----------------------------------------------------------------------------- void CJoinGameMenu::OnCommand( const char *pCommand ) { if ( !Q_stricmp( pCommand, "Cancel" ) ) { g_pNetworkManager->ShutdownClient(); g_pMenuManager->PopMenu(); return; } if ( !Q_stricmp( pCommand, "JoinGame" ) ) { if ( !m_bJoiningGame ) { g_pNetworkManager->DisconnectClientFromServer(); m_pChatEntry->SetEnabled( false ); m_pChatEntry->SetText( "" ); m_bJoiningGame = true; m_pJoinGame->SetText( "Join Game" ); } else { int nLen = m_pServerName->GetTextLength(); char *pServer = (char*)_alloca( (nLen+1) * sizeof(char) ); m_pServerName->GetText( pServer, nLen+1 ); char pPort[32]; m_pServerPort->GetText( pPort, sizeof(pPort) ); if ( g_pNetworkManager->ConnectClientToServer( pServer, atoi( pPort ) ) ) { m_pChatEntry->SetEnabled( true ); m_bJoiningGame = false; m_pJoinGame->SetText( "Leave Game" ); } } return; } BaseClass::OnCommand( pCommand ); }