summaryrefslogtreecommitdiff
path: root/tracker/AdminServer/GamePanelInfo.cpp
blob: 44ff791d39c93e95752458f696eb1d27ac1b6802 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
//========= 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();
}