Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
11 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "winsock.h" // this BUGGER defines PropertySheet to PropertySheetA ....
#undef PropertySheet
#include "tokenline.h"
#include "GamePanelInfo.h"
//#include "Info.h"
#include "IRunGameEngine.h"
#include "DialogCvarChange.h"
#include "DialogAddBan.h"
#include "BudgetPanelContainer.h"
#include <vgui/ISystem.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <KeyValues.h>
#include <vgui/Cursor.h>
#include <vgui/ILocalize.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/QueryBox.h>
#include <vgui_controls/Image.h>
#include <vgui_controls/ImagePanel.h>
#include "tier0/icommandline.h"
#include <proto_oob.h>
#include <netadr.h>
using namespace vgui;
static const long RETRY_TIME = 10000; // refresh server every 10 seconds
static const long MAP_CHANGE_TIME = 20000; // refresh 20 seconds after a map change
static const long RESTART_TIME = 60000; // refresh 60 seconds after a "_restart"
#include "IManageServer.h"
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CGamePanelInfo::CGamePanelInfo(vgui::Panel *parent, const char *name, const char *mod) : Frame(parent, name)
{
SetSize(560, 420);
SetMinimumSize(560, 420);
m_bRemoteServer = false;
m_bShuttingDown = false;
// Create an Animating Image Panel
m_pAnimImagePanel = new AnimatingImagePanel(this, "AnAnimatingImagePanel");
// Each image file is named ss1, ss2, ss3... ss20, one image for each frame of the animation.
// This loads the 20 images in to the Animation class.
m_pAnimImagePanel->LoadAnimation("resource\\steam\\g", 12);
//!! animation temporarily disabled until UI pass done
//m_pAnimImagePanel->StartAnimation();
m_pAnimImagePanel->SetVisible(false);
// the main container for the various sub panels
m_pDetailsSheet = new PropertySheet(this, "Panels");
// the sub panels
m_pPlayerListPanel = new CPlayerPanel(this, "Player List");
m_pBanListPanel = new CBanPanel(this, "Ban List");
m_pServerLogPanel = new CRawLogPanel(this, "ServerLog");
// chat panel disabled until we get the parsing done
// m_pServerChatPanel = new CChatPanel(this, "ChatPanel");
m_pServerConfigPanel = new CServerConfigPanel(this, "ServerConfigPanel", mod);
m_pGraphsPanel = new CGraphPanel(this,"GraphsPanel");
m_pServerInfoPanel = new CServerInfoPanel(this, "ServerInfo");
if ( CommandLine()->CheckParm( "-BudgetPanel" ) )
m_pBudgetPanel = new CBudgetPanelContainer( this, "BudgetPanel" );
else
m_pBudgetPanel = NULL;
m_pServerInfoPanel->AddActionSignalTarget(this);
m_pDetailsSheet->AddPage(m_pServerInfoPanel,"#Game_Main_Settings");
m_pDetailsSheet->AddPage(m_pServerConfigPanel,"#Game_Configure");
m_pDetailsSheet->AddPage(m_pGraphsPanel,"#Game_Server_Statistics");
m_pDetailsSheet->AddPage(m_pPlayerListPanel,"#Game_Current_Players");
m_pDetailsSheet->AddPage(m_pBanListPanel,"#Game_Bans");
if ( m_pBudgetPanel )
m_pDetailsSheet->AddPage(m_pBudgetPanel,"#Game_Budgets");
// chat panel disabled until we get the parsing done
// m_pDetailsSheet->AddPage(m_pServerChatPanel,"#Game_Chat");
m_pDetailsSheet->AddPage(m_pServerLogPanel,"#Game_Console");
// let us be ticked every frame
ivgui()->AddTickSignal(this->GetVPanel());
LoadControlSettingsAndUserConfig("Admin\\DialogGamePanelInfo.res");
SetNewTitle(false, name);
SetVisible(true);
MoveToCenterOfScreen();
RequestFocus();
MoveToFront();
//!! hack, force the server info panel to refresh fast
// because the info it receives while loading the server is wrong
PostMessage(m_pServerInfoPanel, new KeyValues("ResetData"), 0.1f);
}
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CGamePanelInfo::~CGamePanelInfo()
{
}
//-----------------------------------------------------------------------------
// Purpose: Sets the title of the dialog
//-----------------------------------------------------------------------------
void CGamePanelInfo::SetNewTitle(bool connectionFailed, const char *additional_text)
{
const char *localized_title = "#Game_RemoteTitle";
if (!m_bRemoteServer)
{
localized_title = "Game_LocalTitle";
}
else if (connectionFailed)
{
localized_title = "#Game_RemoteTitle_Failed";
}
wchar_t serverName[256];
g_pVGuiLocalize->ConvertANSIToUnicode(additional_text, serverName, sizeof(serverName));
wchar_t title[256];
g_pVGuiLocalize->ConstructString(title, sizeof(title), g_pVGuiLocalize->Find(localized_title), 1, serverName);
SetTitle(title, true);
}
//-----------------------------------------------------------------------------
// Purpose: Updates the title
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnUpdateTitle()
{
SetNewTitle(false, m_pServerInfoPanel->GetHostname());
Repaint();
}
//-----------------------------------------------------------------------------
// Purpose: data accessor
//-----------------------------------------------------------------------------
void CGamePanelInfo::SetAsRemoteServer(bool remote)
{
m_bRemoteServer = remote;
}
//-----------------------------------------------------------------------------
// Purpose: Relayouts the data
//-----------------------------------------------------------------------------
void CGamePanelInfo::PerformLayout()
{
BaseClass::PerformLayout();
}
//-----------------------------------------------------------------------------
// Purpose: Called every frame, handles resending network messages
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnTick()
{
// service the server I/O queue
RemoteServer().ProcessServerResponse();
}
//-----------------------------------------------------------------------------
// Purpose: handles button responses
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnCommand(const char *command)
{
if (!stricmp(command, "stop2"))
{
RemoteServer().SendCommand("quit");
m_bShuttingDown = true;
Close();
}
else
{
BaseClass::OnCommand(command);
}
}
//-----------------------------------------------------------------------------
// Purpose: produces a dialog asking a player to enter a new ban
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnStop()
{
QueryBox *box = new QueryBox("#Game_Stop_Server_Title", "#Game_Restart_Server");
box->AddActionSignalTarget(this);
box->SetOKButtonText("#Game_Stop_Server");
box->SetOKCommand(new KeyValues("Command", "command", "stop2"));
box->ShowWindow();
}
//-----------------------------------------------------------------------------
// Purpose: displays the help page
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnHelp()
{
system()->ShellExecute("open", "Admin\\Admin.html");
}
//-----------------------------------------------------------------------------
// Purpose: Does any processing needed before closing the dialog
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnClose()
{
if (m_bRemoteServer || m_bShuttingDown)
{
BaseClass::OnClose();
return;
}
// closing the window will kill the local server, notify user
OnStop();
}
//-----------------------------------------------------------------------------
// Purpose: allow the build mode editor to edit the current sub panel
//-----------------------------------------------------------------------------
void CGamePanelInfo::ActivateBuildMode()
{
// BaseClass::ActivateBuildMode();
// return;
// no subpanel, no build mode
EditablePanel *pg = dynamic_cast<EditablePanel *>(m_pDetailsSheet->GetActivePage());
if (pg)
{
pg->ActivateBuildMode();
}
}
//-----------------------------------------------------------------------------
// Purpose: Writes text to the console
//-----------------------------------------------------------------------------
void CGamePanelInfo::AddToConsole(const char *msg)
{
if (m_pServerLogPanel)
{
// hack, look for restart message
if (*msg == 3 && !strncmp(msg + 1, "MasterRequestRestart", strlen("MasterRequestRestart")))
{
OnMasterRequestRestart();
}
else if (*msg == 3 && !strncmp(msg + 1, "MasterOutOfDate", strlen("MasterOutOfDate")))
{
const char *details = strstr( msg, "MasterOutOfDate" );
if ( details )
{
OnMasterOutOfDate(details + strlen("MasterOutOfDate"));
}
}
else
{
// nothing special, just print
m_pServerLogPanel->DoInsertString(msg);
}
}
}
void CGamePanelInfo::OnMasterOutOfDate( const char *msg)
{
#if !defined(_DEBUG)
// open a dialog informing user that they need to restart the server
if (!m_hOutOfDateQueryBox.Get())
{
char *fullmsg = (char *) _alloca( strlen(msg) + strlen( "\n\nDo you wish to shutdown now?\n") + 1 );
_snprintf( fullmsg, strlen(msg) + strlen( "\n\nDo you wish to shutdown now?\n") + 1 , "%s\n\nDo you wish to shutdown now?\n", msg );
m_hOutOfDateQueryBox = new QueryBox("Server restart pending", fullmsg);
m_hOutOfDateQueryBox->AddActionSignalTarget(this);
m_hOutOfDateQueryBox->SetOKCommand(new KeyValues("RestartServer"));
m_hOutOfDateQueryBox->ShowWindow();
}
else
{
// reshow the existing window
m_hOutOfDateQueryBox->Activate();
}
#endif // !defined(_DEBUG)
}
//-----------------------------------------------------------------------------
// Purpose: Called when master server has requested the dedicated server restart
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnMasterRequestRestart()
{
#if !defined(_DEBUG)
// open a dialog informing user that they need to restart the server
if (!m_hRestartQueryBox.Get())
{
m_hRestartQueryBox = new QueryBox("Server restart needed", "Your server is out of date, and will not be listed\non the master server until you restart.\n\nDo you wish to shutdown now?\n");
m_hRestartQueryBox->AddActionSignalTarget(this);
m_hRestartQueryBox->SetOKCommand(new KeyValues("RestartServer"));
m_hRestartQueryBox->ShowWindow();
}
else
{
// reshow the existing window
m_hRestartQueryBox->Activate();
}
#endif // !defined(_DEBUG)
}
//-----------------------------------------------------------------------------
// Purpose: Restarts the server
//-----------------------------------------------------------------------------
void CGamePanelInfo::OnRestartServer()
{
//!! mark us as needing restart
//!! this doesn't work yet, just shut us down
// shut us down
RemoteServer().SendCommand("quit");
m_bShuttingDown = true;
Close();
}