Counter Strike : Global Offensive Source Code
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.

479 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdio.h>
  8. #include <time.h>
  9. #include "createmultiplayergamegameplaypage.h"
  10. using namespace vgui;
  11. #include <keyvalues.h>
  12. #include <vgui/ILocalize.h>
  13. #include <vgui_controls/ComboBox.h>
  14. #include <vgui_controls/CheckButton.h>
  15. #include <vgui_controls/Label.h>
  16. #include <vgui_controls/TextEntry.h>
  17. #include "filesystem.h"
  18. #include "panellistpanel.h"
  19. #include "scriptobject.h"
  20. // memdbgon must be the last include file in a .cpp file!!!
  21. #include <tier0/memdbgon.h>
  22. #define OPTIONS_DIR "cfg"
  23. #define DEFAULT_OPTIONS_FILE OPTIONS_DIR "/settings_default.scr"
  24. #define OPTIONS_FILE OPTIONS_DIR "/settings.scr"
  25. //-----------------------------------------------------------------------------
  26. // Purpose: class for loading/saving server config file
  27. //-----------------------------------------------------------------------------
  28. class CServerDescription : public CDescription
  29. {
  30. public:
  31. explicit CServerDescription( CPanelListPanel *panel );
  32. void WriteScriptHeader( FileHandle_t fp );
  33. void WriteFileHeader( FileHandle_t fp );
  34. };
  35. //-----------------------------------------------------------------------------
  36. // Purpose: Constructor
  37. //-----------------------------------------------------------------------------
  38. CCreateMultiplayerGameGameplayPage::CCreateMultiplayerGameGameplayPage(vgui::Panel *parent, const char *name) : PropertyPage(parent, name)
  39. {
  40. m_pOptionsList = new CPanelListPanel(this, "GameOptions");
  41. m_pDescription = new CServerDescription(m_pOptionsList);
  42. m_pDescription->InitFromFile( DEFAULT_OPTIONS_FILE );
  43. m_pDescription->InitFromFile( OPTIONS_FILE );
  44. m_pList = NULL;
  45. LoadControlSettings("Resource/CreateMultiplayerGameGameplayPage.res");
  46. LoadGameOptionsList();
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Destructor
  50. //-----------------------------------------------------------------------------
  51. CCreateMultiplayerGameGameplayPage::~CCreateMultiplayerGameGameplayPage()
  52. {
  53. delete m_pDescription;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Purpose:
  57. //-----------------------------------------------------------------------------
  58. int CCreateMultiplayerGameGameplayPage::GetMaxPlayers()
  59. {
  60. return atoi(GetValue("maxplayers", "32"));
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. const char *CCreateMultiplayerGameGameplayPage::GetPassword()
  66. {
  67. return GetValue("sv_password", "");
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose:
  71. //-----------------------------------------------------------------------------
  72. const char *CCreateMultiplayerGameGameplayPage::GetHostName()
  73. {
  74. return GetValue("hostname", "Half-Life");
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. //-----------------------------------------------------------------------------
  79. const char *CCreateMultiplayerGameGameplayPage::GetValue(const char *cvarName, const char *defaultValue)
  80. {
  81. for (mpcontrol_t *mp = m_pList; mp != NULL; mp = mp->next)
  82. {
  83. Panel *control = mp->pControl;
  84. if (control && !stricmp(mp->GetName(), cvarName))
  85. {
  86. KeyValues *data = new KeyValues("GetText");
  87. static char buf[128];
  88. if (control && control->RequestInfo(data))
  89. {
  90. Q_strncpy(buf, data->GetString("text", defaultValue), sizeof(buf) - 1);
  91. }
  92. else
  93. {
  94. // no value found, copy in default text
  95. Q_strncpy(buf, defaultValue, sizeof(buf) - 1);
  96. }
  97. // ensure null termination of string
  98. buf[sizeof(buf) - 1] = 0;
  99. // free
  100. data->deleteThis();
  101. return buf;
  102. }
  103. }
  104. return defaultValue;
  105. }
  106. //-----------------------------------------------------------------------------
  107. // Purpose: called to get data from the page
  108. //-----------------------------------------------------------------------------
  109. void CCreateMultiplayerGameGameplayPage::OnApplyChanges()
  110. {
  111. // Get the values from the controls
  112. GatherCurrentValues();
  113. // Create the game.cfg file
  114. if ( m_pDescription )
  115. {
  116. FileHandle_t fp;
  117. // Add settings to config.cfg
  118. m_pDescription->WriteToConfig();
  119. // save out in the settings file
  120. g_pFullFileSystem->CreateDirHierarchy( OPTIONS_DIR, "GAME" );
  121. fp = g_pFullFileSystem->Open( OPTIONS_FILE, "wb", "GAME" );
  122. if ( fp )
  123. {
  124. m_pDescription->WriteToScriptFile( fp );
  125. g_pFullFileSystem->Close( fp );
  126. }
  127. }
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose: Creates all the controls in the game options list
  131. //-----------------------------------------------------------------------------
  132. void CCreateMultiplayerGameGameplayPage::LoadGameOptionsList()
  133. {
  134. // destroy any existing controls
  135. mpcontrol_t *p, *n;
  136. p = m_pList;
  137. while ( p )
  138. {
  139. n = p->next;
  140. //
  141. delete p->pControl;
  142. delete p->pPrompt;
  143. delete p;
  144. p = n;
  145. }
  146. m_pList = NULL;
  147. // Go through desciption creating controls
  148. CScriptObject *pObj;
  149. pObj = m_pDescription->pObjList;
  150. mpcontrol_t *pCtrl;
  151. CheckButton *pBox;
  152. TextEntry *pEdit;
  153. ComboBox *pCombo;
  154. CScriptListItem *pListItem;
  155. Panel *objParent = m_pOptionsList;
  156. while ( pObj )
  157. {
  158. if ( pObj->type == O_OBSOLETE )
  159. {
  160. pObj = pObj->pNext;
  161. continue;
  162. }
  163. pCtrl = new mpcontrol_t( objParent, pObj->cvarname );
  164. pCtrl->type = pObj->type;
  165. switch ( pCtrl->type )
  166. {
  167. case O_BOOL:
  168. pBox = new CheckButton( pCtrl, "DescCheckButton", pObj->prompt );
  169. pBox->SetSelected( pObj->fdefValue != 0.0f ? true : false );
  170. pCtrl->pControl = (Panel *)pBox;
  171. break;
  172. case O_STRING:
  173. case O_NUMBER:
  174. pEdit = new TextEntry( pCtrl, "DescEdit");
  175. pEdit->InsertString(pObj->defValue);
  176. pCtrl->pControl = (Panel *)pEdit;
  177. break;
  178. case O_LIST:
  179. pCombo = new ComboBox( pCtrl, "DescEdit", 5, false );
  180. pListItem = pObj->pListItems;
  181. while ( pListItem )
  182. {
  183. pCombo->AddItem(pListItem->szItemText, NULL);
  184. pListItem = pListItem->pNext;
  185. }
  186. pCombo->ActivateItemByRow((int)pObj->fdefValue);
  187. pCtrl->pControl = (Panel *)pCombo;
  188. break;
  189. default:
  190. break;
  191. }
  192. if ( pCtrl->type != O_BOOL )
  193. {
  194. pCtrl->pPrompt = new vgui::Label( pCtrl, "DescLabel", "" );
  195. pCtrl->pPrompt->SetContentAlignment( vgui::Label::a_west );
  196. pCtrl->pPrompt->SetTextInset( 5, 0 );
  197. pCtrl->pPrompt->SetText( pObj->prompt );
  198. }
  199. pCtrl->pScrObj = pObj;
  200. pCtrl->SetSize( 100, 28 );
  201. //pCtrl->SetBorder( scheme()->GetBorder(1, "DepressedButtonBorder") );
  202. m_pOptionsList->AddItem( pCtrl );
  203. // Link it in
  204. if ( !m_pList )
  205. {
  206. m_pList = pCtrl;
  207. pCtrl->next = NULL;
  208. }
  209. else
  210. {
  211. mpcontrol_t *p;
  212. p = m_pList;
  213. while ( p )
  214. {
  215. if ( !p->next )
  216. {
  217. p->next = pCtrl;
  218. pCtrl->next = NULL;
  219. break;
  220. }
  221. p = p->next;
  222. }
  223. }
  224. pObj = pObj->pNext;
  225. }
  226. }
  227. //-----------------------------------------------------------------------------
  228. // Purpose: applies all the values in the page
  229. //-----------------------------------------------------------------------------
  230. void CCreateMultiplayerGameGameplayPage::GatherCurrentValues()
  231. {
  232. if ( !m_pDescription )
  233. return;
  234. // OK
  235. CheckButton *pBox;
  236. TextEntry *pEdit;
  237. ComboBox *pCombo;
  238. mpcontrol_t *pList;
  239. CScriptObject *pObj;
  240. CScriptListItem *pItem;
  241. char szValue[256];
  242. char strValue[256];
  243. wchar_t w_szStrValue[256];
  244. pList = m_pList;
  245. while ( pList )
  246. {
  247. pObj = pList->pScrObj;
  248. if ( !pList->pControl )
  249. {
  250. pObj->SetCurValue( pObj->defValue );
  251. pList = pList->next;
  252. continue;
  253. }
  254. switch ( pObj->type )
  255. {
  256. case O_BOOL:
  257. pBox = (CheckButton *)pList->pControl;
  258. Q_snprintf( szValue, sizeof( szValue ), "%s", pBox->IsSelected() ? "1" : "0" );
  259. break;
  260. case O_NUMBER:
  261. pEdit = ( TextEntry * )pList->pControl;
  262. pEdit->GetText( strValue, sizeof( strValue ) );
  263. Q_snprintf( szValue, sizeof( szValue ), "%s", strValue );
  264. break;
  265. case O_STRING:
  266. pEdit = ( TextEntry * )pList->pControl;
  267. pEdit->GetText( strValue, sizeof( strValue ) );
  268. Q_snprintf( szValue, sizeof( szValue ), "%s", strValue );
  269. break;
  270. case O_LIST:
  271. pCombo = ( ComboBox *)pList->pControl;
  272. pCombo->GetText( w_szStrValue, sizeof( w_szStrValue ) / sizeof( wchar_t ) );
  273. pItem = pObj->pListItems;
  274. while ( pItem )
  275. {
  276. wchar_t *wLocalizedString = NULL;
  277. wchar_t w_szStrTemp[256];
  278. // Localized string?
  279. if ( pItem->szItemText[0] == '#' )
  280. {
  281. wLocalizedString = g_pVGuiLocalize->Find( pItem->szItemText );
  282. }
  283. if ( wLocalizedString )
  284. {
  285. // Copy the string we found into our temp array
  286. V_wcscpy_safe( w_szStrTemp, wLocalizedString );
  287. }
  288. else
  289. {
  290. // Just convert what we have to Unicode
  291. g_pVGuiLocalize->ConvertANSIToUnicode( pItem->szItemText, w_szStrTemp, sizeof( w_szStrTemp ) );
  292. }
  293. if ( _wcsicmp( w_szStrTemp, w_szStrValue ) == 0 )
  294. {
  295. // Found a match!
  296. break;
  297. }
  298. pItem = pItem->pNext;
  299. }
  300. if ( pItem )
  301. {
  302. Q_snprintf( szValue, sizeof( szValue ), "%s", pItem->szValue );
  303. }
  304. else //Couldn't find index
  305. {
  306. Q_snprintf( szValue, sizeof( szValue ), "%s", pObj->defValue );
  307. }
  308. break;
  309. }
  310. // Remove double quotes and % characters
  311. UTIL_StripInvalidCharacters( szValue, sizeof( szValue ) );
  312. Q_strncpy( strValue, szValue, sizeof( strValue ) );
  313. pObj->SetCurValue( strValue );
  314. pList = pList->next;
  315. }
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose: Constructor, load/save server settings object
  319. //-----------------------------------------------------------------------------
  320. CServerDescription::CServerDescription(CPanelListPanel *panel) : CDescription(panel)
  321. {
  322. setHint( "// NOTE: THIS FILE IS AUTOMATICALLY REGENERATED, \r\n"
  323. "//DO NOT EDIT THIS HEADER, YOUR COMMENTS WILL BE LOST IF YOU DO\r\n"
  324. "// Multiplayer options script\r\n"
  325. "//\r\n"
  326. "// Format:\r\n"
  327. "// Version [float]\r\n"
  328. "// Options description followed by \r\n"
  329. "// Options defaults\r\n"
  330. "//\r\n"
  331. "// Option description syntax:\r\n"
  332. "//\r\n"
  333. "// \"cvar\" { \"Prompt\" { type [ type info ] } { default } }\r\n"
  334. "//\r\n"
  335. "// type = \r\n"
  336. "// BOOL (a yes/no toggle)\r\n"
  337. "// STRING\r\n"
  338. "// NUMBER\r\n"
  339. "// LIST\r\n"
  340. "//\r\n"
  341. "// type info:\r\n"
  342. "// BOOL no type info\r\n"
  343. "// NUMBER min max range, use -1 -1 for no limits\r\n"
  344. "// STRING no type info\r\n"
  345. "// LIST "" delimited list of options value pairs\r\n"
  346. "//\r\n"
  347. "//\r\n"
  348. "// default depends on type\r\n"
  349. "// BOOL is \"0\" or \"1\"\r\n"
  350. "// NUMBER is \"value\"\r\n"
  351. "// STRING is \"value\"\r\n"
  352. "// LIST is \"index\", where index \"0\" is the first element of the list\r\n\r\n\r\n" );
  353. setDescription ( "SERVER_OPTIONS" );
  354. }
  355. //-----------------------------------------------------------------------------
  356. // Purpose:
  357. //-----------------------------------------------------------------------------
  358. void CServerDescription::WriteScriptHeader( FileHandle_t fp )
  359. {
  360. char am_pm[] = "AM";
  361. tm newtime;
  362. Plat_GetLocalTime( &newtime );
  363. if( newtime.tm_hour > 12 ) /* Set up extension. */
  364. Q_strncpy( am_pm, "PM", sizeof( am_pm ) );
  365. if( newtime.tm_hour > 12 ) /* Convert from 24-hour */
  366. newtime.tm_hour -= 12; /* to 12-hour clock. */
  367. if( newtime.tm_hour == 0 ) /*Set hour to 12 if midnight. */
  368. newtime.tm_hour = 12;
  369. g_pFullFileSystem->FPrintf( fp, "%s", (char *)getHint() );
  370. char timeString[64];
  371. Plat_GetTimeString( &newtime, timeString, sizeof( timeString ) );
  372. // Write out the comment and Cvar Info:
  373. g_pFullFileSystem->FPrintf( fp, "// Half-Life Server Configuration Layout Script (stores last settings chosen, too)\r\n" );
  374. g_pFullFileSystem->FPrintf( fp, "// File generated: %.19s %s\r\n", timeString, am_pm );
  375. g_pFullFileSystem->FPrintf( fp, "//\r\n//\r\n// Cvar\t-\tSetting\r\n\r\n" );
  376. g_pFullFileSystem->FPrintf( fp, "VERSION %.1f\r\n\r\n", SCRIPT_VERSION );
  377. g_pFullFileSystem->FPrintf( fp, "DESCRIPTION SERVER_OPTIONS\r\n{\r\n" );
  378. }
  379. //-----------------------------------------------------------------------------
  380. // Purpose:
  381. //-----------------------------------------------------------------------------
  382. void CServerDescription::WriteFileHeader( FileHandle_t fp )
  383. {
  384. char am_pm[] = "AM";
  385. tm newtime;
  386. Plat_GetLocalTime( &newtime );
  387. if( newtime.tm_hour > 12 ) /* Set up extension. */
  388. Q_strncpy( am_pm, "PM", sizeof( am_pm ) );
  389. if( newtime.tm_hour > 12 ) /* Convert from 24-hour */
  390. newtime.tm_hour -= 12; /* to 12-hour clock. */
  391. if( newtime.tm_hour == 0 ) /*Set hour to 12 if midnight. */
  392. newtime.tm_hour = 12;
  393. char timeString[64];
  394. Plat_GetTimeString( &newtime, timeString, sizeof( timeString ) );
  395. g_pFullFileSystem->FPrintf( fp, "// Half-Life Server Configuration Settings\r\n" );
  396. g_pFullFileSystem->FPrintf( fp, "// DO NOT EDIT, GENERATED BY HALF-LIFE\r\n" );
  397. g_pFullFileSystem->FPrintf( fp, "// File generated: %.19s %s\r\n", timeString, am_pm );
  398. g_pFullFileSystem->FPrintf( fp, "//\r\n//\r\n// Cvar\t-\tSetting\r\n\r\n" );
  399. }