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.

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