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.

274 lines
7.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #ifdef _WIN32
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdarg.h>
  17. #include <windows.h>
  18. // base vgui interfaces
  19. #include <vgui/vgui.h>
  20. #include <vgui_controls/Panel.h>
  21. #include <vgui/IVGui.h>
  22. #include <vgui/ISurface.h>
  23. #include <vgui/Cursor.h>
  24. #include <vgui_controls/ProgressBox.h>
  25. #include "filesystem.h"
  26. #include "IAdminServer.h"
  27. #include "MainPanel.h"
  28. #include <imanageserver.h>
  29. #include "ivguimodule.h"
  30. #include <vgui/IVGui.h>
  31. // memdbgon must be the last include file in a .cpp file!!!
  32. #include "tier0/memdbgon.h"
  33. using namespace vgui;
  34. static CMainPanel *s_InternetDlg = NULL;
  35. CSysModule *g_hAdminServerModule = NULL;
  36. extern IAdminServer *g_pAdminServer;
  37. char *gpszCvars = NULL;
  38. void Sys_Sleep_Old( int msec );
  39. extern BOOL gbAppHasBeenTerminated; // used to signal the server thread
  40. //-----------------------------------------------------------------------------
  41. // Purpose: Constructor
  42. //-----------------------------------------------------------------------------
  43. CMainPanel::CMainPanel( ) : Panel(NULL, "CMainPanel")
  44. {
  45. SetPaintBackgroundEnabled( false );
  46. SetFgColor( Color( 0,0,0,0 ) );
  47. m_bStarting = false;
  48. m_flPreviousSteamProgress = 0.0f;
  49. m_pGameServer= NULL;
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Purpose: Destructor
  53. //-----------------------------------------------------------------------------
  54. CMainPanel::~CMainPanel()
  55. {
  56. if (gpszCvars)
  57. {
  58. free(gpszCvars);
  59. }
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Called once to set up
  63. //-----------------------------------------------------------------------------
  64. void CMainPanel::Initialize( )
  65. {
  66. s_InternetDlg = this;
  67. m_pGameServer = NULL;
  68. m_bStarted = false;
  69. m_bIsInConfig = true;
  70. m_bClosing = false;
  71. m_pProgressBox = NULL;
  72. m_hShutdown = NULL;
  73. MoveToFront();
  74. m_pConfigPage = new CCreateMultiplayerGameServerPage(this, "Config");
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. //-----------------------------------------------------------------------------
  79. void CMainPanel::Open( void )
  80. {
  81. m_pConfigPage->SetVisible(true);
  82. m_pConfigPage->MoveToFront();
  83. }
  84. //-----------------------------------------------------------------------------
  85. // Purpose:
  86. //-----------------------------------------------------------------------------
  87. void CMainPanel::OnClose()
  88. {
  89. DoStop();
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: returns a pointer to a static instance of this dialog
  93. //-----------------------------------------------------------------------------
  94. CMainPanel *CMainPanel::GetInstance()
  95. {
  96. return s_InternetDlg;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Changes to the console page and starts up the actual server
  100. //-----------------------------------------------------------------------------
  101. void CMainPanel::StartServer(const char *cvars)
  102. {
  103. surface()->SetCursor(dc_hourglass);
  104. m_pConfigPage->GetServer(s1);
  105. // hide the config page and close it
  106. m_pConfigPage->SetVisible(false);
  107. m_pConfigPage->Close();
  108. gpszCvars = strdup(cvars);
  109. // show the basic progress box immediately
  110. m_pProgressBox = new ProgressBox("#Start_Server_Loading_Title", "#Server_UpdatingSteamResources", "Starting dedicated server...");
  111. m_pProgressBox->SetCancelButtonVisible(true);
  112. m_pProgressBox->ShowWindow();
  113. // make sure we have all the steam content for this mod
  114. char reslist[_MAX_PATH];
  115. _snprintf(reslist, sizeof(reslist), "reslists/%s/preload.lst", m_pConfigPage->GetGameName());
  116. m_hResourceWaitHandle = g_pFullFileSystem->WaitForResources(reslist);
  117. if (!m_hResourceWaitHandle)
  118. {
  119. Assert( 0 );
  120. }
  121. m_pProgressBox->SetCancelButtonEnabled(false);
  122. m_hShutdown = CreateEvent( NULL, TRUE, FALSE, NULL );
  123. ivgui()->AddTickSignal(GetVPanel());
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose: lets us delay the loading of the management screen until the server has started
  127. //-----------------------------------------------------------------------------
  128. void CMainPanel::OnTick()
  129. {
  130. if (m_hResourceWaitHandle)
  131. {
  132. // see if we've been cancelled
  133. if (!m_pProgressBox.Get() || !m_pProgressBox->IsVisible())
  134. {
  135. // cancel out
  136. g_pFullFileSystem->CancelWaitForResources(m_hResourceWaitHandle);
  137. m_hResourceWaitHandle = NULL;
  138. DoStop();
  139. return;
  140. }
  141. // update resource waiting
  142. bool complete;
  143. float progress;
  144. if (g_pFullFileSystem->GetWaitForResourcesProgress(m_hResourceWaitHandle, &progress, &complete))
  145. {
  146. vgui::ivgui()->DPrintf2( "progress %.2f %s\n", progress, complete ? "not complete" : "complete" );
  147. // don't set the progress if we've jumped straight from 0 to 100% complete
  148. if (!(progress == 1.0f && m_flPreviousSteamProgress == 0.0f))
  149. {
  150. m_pProgressBox->SetProgress(progress);
  151. m_flPreviousSteamProgress = progress;
  152. }
  153. }
  154. // This is here because without it, the dedicated server will consume a lot of CPU and it will slow Steam down
  155. // so much that it'll download at 64k instead of 6M.
  156. Sleep( 200 );
  157. // see if we're done
  158. if (complete)
  159. {
  160. m_hResourceWaitHandle = NULL;
  161. m_bStarting = true;
  162. m_bIsInConfig = false;
  163. // at this stage in the process the user can no longer cancel
  164. m_pProgressBox->SetCancelButtonEnabled(false);
  165. }
  166. }
  167. if (m_bStarting) // if we are actively launching the app
  168. {
  169. static int count = 0;
  170. if (WAIT_OBJECT_0 == WaitForSingleObject(m_hShutdown, 10) || count > 5000)
  171. {
  172. if (!m_bStarted)
  173. {
  174. serveritem_t server;
  175. m_pConfigPage->GetServer(server);
  176. ManageServerUIHandle_t managePage = g_pAdminServer->OpenManageServerDialog(server.name, server.gameDir);
  177. m_pGameServer = g_pAdminServer->GetManageServerInterface(managePage);
  178. m_bStarted = true;
  179. if (m_pProgressBox)
  180. {
  181. m_pProgressBox->Close();
  182. m_pProgressBox = NULL;
  183. }
  184. }
  185. else // must be stopping the server
  186. {
  187. DoStop();
  188. }
  189. surface()->SetCursor(dc_user);
  190. m_bStarting = false;
  191. ResetEvent(m_hShutdown);
  192. }
  193. else
  194. {
  195. count++;
  196. }
  197. }
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Purpose: stops VGUI and kills any progress dialog we may have been displaying
  201. //-----------------------------------------------------------------------------
  202. void CMainPanel::DoStop()
  203. {
  204. surface()->SetCursor(dc_user);
  205. m_bStarted = false;
  206. m_bClosing = true;
  207. if (m_pProgressBox)
  208. {
  209. m_pProgressBox->Close();
  210. m_pProgressBox = NULL;
  211. }
  212. ivgui()->Stop();
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Purpose: Pushes text into the console
  216. //-----------------------------------------------------------------------------
  217. void CMainPanel::AddConsoleText(const char *msg)
  218. {
  219. if (m_pGameServer)
  220. {
  221. m_pGameServer->AddToConsole(msg);
  222. }
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Purpose: Message map
  226. //-----------------------------------------------------------------------------
  227. MessageMapItem_t CMainPanel::m_MessageMap[] =
  228. {
  229. MAP_MESSAGE( CMainPanel, "Quit", OnClose ),
  230. };
  231. IMPLEMENT_PANELMAP(CMainPanel, BaseClass);
  232. #endif // _WIN32