diff --git a/BaseMenu.h b/BaseMenu.h index aa333ab5..3616421d 100644 --- a/BaseMenu.h +++ b/BaseMenu.h @@ -227,6 +227,7 @@ void UI_CloseMenu( void ); // SCR support void UI_LoadScriptConfig( void ); +void UI_SaveScriptConfig( void ); class CMenuEntry { diff --git a/CFGScript.cpp b/CFGScript.cpp index 00f7d290..611fced3 100644 --- a/CFGScript.cpp +++ b/CFGScript.cpp @@ -14,6 +14,7 @@ GNU General Public License for more details. */ +#include #include "extdll_menu.h" #include "BaseMenu.h" #include "enginecallback_menu.h" @@ -300,7 +301,7 @@ scrvardef_t *CSCR_LoadDefaultCVars( const char *scriptfilename, int *count ) // Create a new object if( CSCR_ParseSingleCvar( &state, &var ) ) { - // Cvar_Get( var.name, var.value, var.flags, var.desc ); + EngFuncs::CvarSetString( var.name, var.value ); scrvardef_t *entry = new scrvardef_t; *entry = var; @@ -341,6 +342,136 @@ scrvardef_t *CSCR_LoadDefaultCVars( const char *scriptfilename, int *count ) return list; } +/* +====================== +CSCR_SaveToFile + +Save cvars to script file with specific formatting +====================== +*/ +void CSCR_SaveToFile( const char *filename, const char *description, scrvardef_t *list ) +{ + if( !filename || !list ) return; + + CUtlString buffer; + + // Write current time in header + char timeBuf[64]; + time_t now = time( NULL ); + strftime( timeBuf, sizeof(timeBuf), "%a %b %d %I:%M:%S %p", localtime( &now ) ); + + buffer.AppendFormat( "// NOTE: THIS FILE IS AUTOMATICALLY REGENERATED, \n" ); + buffer.AppendFormat( "//DO NOT EDIT THIS HEADER, YOUR COMMENTS WILL BE LOST IF YOU DO\n" ); + + if( !stricmp( description, "INFO_OPTIONS" ) ) + buffer.AppendFormat( "// User options script\n" ); + else + buffer.AppendFormat( "// Multiplayer options script\n" ); + + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// Format:\n" ); + buffer.AppendFormat( "// Version [float]\n" ); + buffer.AppendFormat( "// Options description followed by \n" ); + buffer.AppendFormat( "// Options defaults\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// Option description syntax:\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// \"cvar\" { \"Prompt\" { type [ type info ] } { default } }\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// type = \n" ); + buffer.AppendFormat( "// BOOL (a yes/no toggle)\n" ); + buffer.AppendFormat( "// STRING\n" ); + buffer.AppendFormat( "// NUMBER\n" ); + buffer.AppendFormat( "// LIST\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// type info:\n" ); + buffer.AppendFormat( "// BOOL no type info\n" ); + buffer.AppendFormat( "// NUMBER min max range, use -1 -1 for no limits\n" ); + buffer.AppendFormat( "// STRING no type info\n" ); + buffer.AppendFormat( "// LIST delimited list of options value pairs\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// default depends on type\n" ); + buffer.AppendFormat( "// BOOL is \"0\" or \"1\"\n" ); + buffer.AppendFormat( "// NUMBER is \"value\"\n" ); + buffer.AppendFormat( "// STRING is \"value\"\n" ); + buffer.AppendFormat( "// LIST is \"index\", where index \"0\" is the first element of the list\n" ); + buffer.AppendFormat( "\n\n" ); + + if( !stricmp( description, "INFO_OPTIONS" ) ) + buffer.AppendFormat( "// Half-Life User Info Configuration Layout Script (stores last settings chosen, too)\n" ); + else + buffer.AppendFormat( "// Half-Life Server Configuration Layout Script (stores last settings chosen, too)\n" ); + + buffer.AppendFormat( "// File generated: %s\n", timeBuf ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "//\n" ); + buffer.AppendFormat( "// Cvar - Setting\n" ); + buffer.AppendFormat( "\n" ); + + buffer.AppendFormat( "VERSION 1.0\n" ); + buffer.AppendFormat( "\n" ); + buffer.AppendFormat( "DESCRIPTION %s\n", description ); + buffer.AppendFormat( "{\n" ); + + for( scrvardef_t *var = list; var; var = var->next ) + { + const char *currentValue = EngFuncs::GetCvarString( var->name ); + + if ( !currentValue ) + currentValue = var->value; + + buffer.AppendFormat( "\t\"%s\"\n", var->name ); + buffer.AppendFormat( "\t{\n" ); + buffer.AppendFormat( "\t\t\"%s\"\n", var->desc ); + + // Type info + buffer.AppendFormat( "\t\t{ " ); + switch( var->type ) + { + case T_BOOL: + buffer.AppendFormat( "BOOL" ); + break; + case T_STRING: + buffer.AppendFormat( "STRING" ); + break; + case T_NUMBER: + buffer.AppendFormat( "NUMBER %g %g", var->number.fMin, var->number.fMax ); + break; + case T_LIST: + buffer.AppendFormat( "\n\t\t\tLIST" ); + for( scrvarlistentry_t *entry = var->list.pEntries; entry; entry = entry->next ) + { + buffer.AppendFormat( "\n\t\t\t\"%s\" \"%g\"", entry->szName, entry->flValue ); + } + break; + default: + break; + } + + if( var->type != T_LIST ) + buffer.AppendFormat( " }" ); + else + buffer.AppendFormat( "\n\t\t}" ); + + buffer.AppendFormat( "\n" ); + + // Value + buffer.AppendFormat( "\t\t{ \"%s\" }\n", currentValue ); + + if( var->flags & CVAR_USERINFO ) + { + buffer.AppendFormat( "\t\tSetInfo\n" ); + } + + buffer.AppendFormat( "\t}\n\n" ); + } + + buffer.AppendFormat( "}\n" ); + + EngFuncs::COM_SaveFile( filename, buffer.Get(), buffer.Length() ); +} + void CSCR_FreeList( scrvardef_t *list ) { scrvardef_t *i = list; diff --git a/CFGScript.h b/CFGScript.h index 99d9dbfc..29ee3460 100644 --- a/CFGScript.h +++ b/CFGScript.h @@ -77,6 +77,7 @@ struct scrvardef_t }; scrvardef_t *CSCR_LoadDefaultCVars( const char *scriptfilename, int *count ); +void CSCR_SaveToFile( const char *filename, const char *description, scrvardef_t *list ); void CSCR_FreeList( scrvardef_t *list ); #endif // CFGSCRIPT_H diff --git a/menus/CreateGame.cpp b/menus/CreateGame.cpp index e57d0620..472b632b 100644 --- a/menus/CreateGame.cpp +++ b/menus/CreateGame.cpp @@ -66,6 +66,7 @@ class CMenuCreateGame : public CMenuFramework CMenuCreateGame() : CMenuFramework("CMenuCreateGame"), mapsListModel( this ) { } static void Begin( CMenuBaseItem *pSelf, void *pExtra ); + void Show() override; void Reload( void ) override; void SaveCvars( void ); @@ -116,12 +117,12 @@ void CMenuCreateGame::Begin( CMenuBaseItem *pSelf, void *pExtra ) EngFuncs::CvarSetValue( "deathmatch", 1.0f ); // start deathmatch as default menu->SaveCvars(); + UI_SaveScriptConfig(); EngFuncs::PlayBackgroundTrack( NULL, NULL ); // all done, start server const char *listenservercfg = EngFuncs::GetCvarString( "lservercfgfile" ); - EngFuncs::WriteServerConfig( listenservercfg ); char cmd[1024]; snprintf( cmd, sizeof( cmd ), "exec %s\n", listenservercfg ); @@ -239,6 +240,9 @@ void CMenuCreateGame::_Init( void ) SET_EVENT_MULTI( maxClients.onCvarGet, { CMenuField *self = (CMenuField*)pSelf; + const char *val = EngFuncs::GetCvarString( self->CvarName() ); + self->SetBuffer( val ); + const char *buf = self->GetBuffer(); int players = atoi( buf ); @@ -281,6 +285,18 @@ void CMenuCreateGame::_VidInit() password.SetRect( 350, 460, 205, 32 ); } +void CMenuCreateGame::Show() +{ + UI_LoadScriptConfig(); + + hostName.UpdateCvar( true ); + maxClients.UpdateCvar( true ); + password.UpdateCvar( true ); + nat.UpdateCvar( true ); + + CMenuBaseWindow::Show(); +} + void CMenuCreateGame::SaveCvars() { hostName.WriteCvar(); diff --git a/menus/dynamic/ScriptMenu.cpp b/menus/dynamic/ScriptMenu.cpp index a5160d89..d36d7831 100644 --- a/menus/dynamic/ScriptMenu.cpp +++ b/menus/dynamic/ScriptMenu.cpp @@ -62,7 +62,8 @@ class CMenuScriptConfig : public CMenuFramework for( int i = m_iPagesIndex, j = 0; j < m_iPagesCount; i++, j++ ) ((CMenuScriptConfigPage*)m_pItems[i])->Save(); - CMenuFramework::SaveAndPopMenu(); + UI_SaveScriptConfig(); + Hide(); } void FlipMenu( void ); @@ -343,6 +344,14 @@ void UI_LoadScriptConfig() menu_useroptions->SetScriptConfig( "user.scr", true ); } +void UI_SaveScriptConfig() +{ + if( menu_serveroptions && menu_serveroptions->m_pVars ) + CSCR_SaveToFile( "settings.scr", "SERVER_OPTIONS", menu_serveroptions->m_pVars ); + if( menu_useroptions && menu_useroptions->m_pVars ) + CSCR_SaveToFile( "user.scr", "INFO_OPTIONS", menu_useroptions->m_pVars ); +} + bool UI_AdvUserOptions_IsAvailable() { return menu_useroptions->m_pVars != NULL;