From 48d92114e9e0d009fe44b6a1e2d55b3f4460366d Mon Sep 17 00:00:00 2001 From: jhh8 Date: Wed, 10 Dec 2025 14:54:29 +0200 Subject: [PATCH 1/3] cvarlist_rd concommand works on server, preferably need someone to test on client (client compilation doesnt work for me since a year ago, lazy to solve) --- src/game/client/swarm/rd_convar_hacks.cpp | 86 +++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/game/client/swarm/rd_convar_hacks.cpp b/src/game/client/swarm/rd_convar_hacks.cpp index f3db69455..e6f1a8875 100644 --- a/src/game/client/swarm/rd_convar_hacks.cpp +++ b/src/game/client/swarm/rd_convar_hacks.cpp @@ -190,3 +190,89 @@ static class CRD_Convar_Hacks final : public CAutoGameSystem pConVar->SetValue( szNewDefault ); } } s_RD_Convar_Hacks; + + + +static bool ConCommandBaseSortFunc( const ConCommandBase* const &hLeftCMD, const ConCommandBase* const &hRightCMD ) +{ + const char* szLeftCMDName = hLeftCMD->GetName(); + const char* szRightCMDName = hRightCMD->GetName(); + + if ( *szLeftCMDName == '-' || *szLeftCMDName == '+' ) + szLeftCMDName++; + if ( *szRightCMDName == '-' || *szRightCMDName == '+' ) + szRightCMDName++; + + return ( Q_stricmp( szLeftCMDName, szRightCMDName ) < 0 ); +} + +CON_COMMAND( cvarlist_rd, "Prints a list of all cvars, with correct values (unlike normal cvarlist)." ) +{ + ConMsg( "cvar list\n--------------\n" ); + + const ConCommandBase* pCMD; + ICvar::Iterator cvariterator( g_pCVar ); + CUtlRBTree< const ConCommandBase* > cvarsorted( 0, 0, ConCommandBaseSortFunc ); + + for ( cvariterator.SetFirst(); cvariterator.IsValid(); cvariterator.Next() ) + { + pCMD = cvariterator.Get(); + + if ( pCMD->IsFlagSet( FCVAR_HIDDEN ) || pCMD->IsFlagSet( FCVAR_DEVELOPMENTONLY ) ) + continue; + + cvarsorted.Insert( pCMD ); + } + + for ( int i = cvarsorted.FirstInorder(); i != cvarsorted.InvalidIndex(); i = cvarsorted.NextInorder( i ) ) + { + pCMD = cvarsorted[ i ]; + if ( pCMD->IsCommand() ) + { + char tempbuff[512]{}; + ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), "cmd", "", pCMD->GetHelpText() ); + } + else + { + char szFullFlags[128]{}; + + constexpr static const char* s_szFlagDesc[] = + { + "", + "", + "sv", + "cl", + "", + "prot", + "sp", + "a", + "nf", + "user", + "print", + "log", + "numeric", + "rep", + "cheat", + "", + "demo", + "norecord", + }; + + for ( int c = 2; c < ARRAYSIZE( s_szFlagDesc ); ++c ) + { + char szFlag[32]{}; + + if ( pCMD->IsFlagSet( 1<GetName(), dynamic_cast< const ConVar* >( pCMD )->GetString(), szFullFlags, pCMD->GetHelpText() ); + } + } + + ConMsg("--------------\n%3i total convars/concommands\n", cvarsorted.Count() ); +} \ No newline at end of file From 2325335c4411e58ef0a074ceb88576e24b36c6ae Mon Sep 17 00:00:00 2001 From: jhh8 Date: Sun, 14 Dec 2025 11:57:56 +0200 Subject: [PATCH 2/3] default value in cvarlist_rd instead of current --- src/game/client/swarm/rd_convar_hacks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/client/swarm/rd_convar_hacks.cpp b/src/game/client/swarm/rd_convar_hacks.cpp index e6f1a8875..1a8c11d24 100644 --- a/src/game/client/swarm/rd_convar_hacks.cpp +++ b/src/game/client/swarm/rd_convar_hacks.cpp @@ -270,7 +270,7 @@ CON_COMMAND( cvarlist_rd, "Prints a list of all cvars, with correct values (unli } char tempbuff[512]{}; - ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), dynamic_cast< const ConVar* >( pCMD )->GetString(), szFullFlags, pCMD->GetHelpText() ); + ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), static_cast< const ConVar* >( pCMD )->GetDefault(), szFullFlags, pCMD->GetHelpText() ); } } From 0fca825465fcef56408f799574c27ac40c3392b4 Mon Sep 17 00:00:00 2001 From: jhh8 Date: Tue, 16 Dec 2025 12:21:07 +0200 Subject: [PATCH 3/3] cvarlist_rd: add arguments for default/current values and CSV format print, and strip help text --- src/game/client/swarm/rd_convar_hacks.cpp | 182 +++++++++++++++++----- 1 file changed, 144 insertions(+), 38 deletions(-) diff --git a/src/game/client/swarm/rd_convar_hacks.cpp b/src/game/client/swarm/rd_convar_hacks.cpp index 1a8c11d24..00ebc563b 100644 --- a/src/game/client/swarm/rd_convar_hacks.cpp +++ b/src/game/client/swarm/rd_convar_hacks.cpp @@ -193,6 +193,7 @@ static class CRD_Convar_Hacks final : public CAutoGameSystem + static bool ConCommandBaseSortFunc( const ConCommandBase* const &hLeftCMD, const ConCommandBase* const &hRightCMD ) { const char* szLeftCMDName = hLeftCMD->GetName(); @@ -206,9 +207,56 @@ static bool ConCommandBaseSortFunc( const ConCommandBase* const &hLeftCMD, const return ( Q_stricmp( szLeftCMDName, szRightCMDName ) < 0 ); } -CON_COMMAND( cvarlist_rd, "Prints a list of all cvars, with correct values (unlike normal cvarlist)." ) +static char *StripTabsAndReturns( const char *inbuffer, char *outbuffer, int outbufferSize ) +{ + char *out = outbuffer; + const char *i = inbuffer; + char *o = out; + + out[ 0 ] = 0; + + while ( *i && o - out < outbufferSize - 1 ) + { + if ( *i == '\n' || + *i == '\r' || + *i == '\t' ) + { + *o++ = ' '; + i++; + continue; + } + if ( *i == '\"' ) + { + *o++ = '\''; + i++; + continue; + } + + *o++ = *i++; + } + + *o = '\0'; + + return out; +} + +CON_COMMAND( cvarlist_rd, "Prints a list of all cvars, with correct values (unlike normal cvarlist). No argument - current values, arg being 1 - default values, arg being 2 - current values in csv format, arg being 3 - default values in csv format" ) { - ConMsg( "cvar list\n--------------\n" ); + bool bDefault = false; + bool bCSV = false; + int nArgs = args.ArgC(); + if ( nArgs >= 2 ) + { + int nArg1 = atoi( args[1] ); + + bDefault = nArg1 == 1 || nArg1 == 3; + bCSV = nArg1 >= 2; + } + + if ( !bCSV ) + ConMsg( "cvar list\n--------------\n" ); + else + ConMsg( "\"Name\",\"Value\",\"GAMEDLL\",\"CLIENTDLL\",\"PROTECTED\",\"SPONLY\",\"ARCHIVE\",\"NOTIFY\",\"USERINFO\",\"PRINTABLEONLY\",\"UNLOGGED\",\"NEVER_AS_STRING\",\"REPLICATED\",\"CHEAT\",\"SS\",\"DEMO\",\"DONTRECORD\",\"SS_ADDED\",,\"Help Text\"\n" ); const ConCommandBase* pCMD; ICvar::Iterator cvariterator( g_pCVar ); @@ -229,50 +277,108 @@ CON_COMMAND( cvarlist_rd, "Prints a list of all cvars, with correct values (unli pCMD = cvarsorted[ i ]; if ( pCMD->IsCommand() ) { - char tempbuff[512]{}; - ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), "cmd", "", pCMD->GetHelpText() ); + if ( !bCSV ) // unchanged cvarlist console output format + { + char tempbuff[512]{}; + ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), "cmd", "", StripTabsAndReturns( pCMD->GetHelpText(), tempbuff, sizeof( tempbuff ) ) ); + } + else // CSV format + { + char tempbuff[512]{}; + ConMsg( "\"%s\",\"%s\",%s,\"%s\"\n", pCMD->GetName(), "cmd", ",,,,,,,,,,,,,,,,", StripTabsAndReturns( pCMD->GetHelpText(), tempbuff, sizeof( tempbuff ) ) ); + } } - else - { - char szFullFlags[128]{}; + else + { + char szFullFlags[256]{}; - constexpr static const char* s_szFlagDesc[] = + if ( !bCSV ) // unchanged cvarlist console output format { - "", - "", - "sv", - "cl", - "", - "prot", - "sp", - "a", - "nf", - "user", - "print", - "log", - "numeric", - "rep", - "cheat", - "", - "demo", - "norecord", - }; - - for ( int c = 2; c < ARRAYSIZE( s_szFlagDesc ); ++c ) - { - char szFlag[32]{}; + constexpr static const char* s_szFlagDesc[] = + { + "", + "", + "sv", + "cl", + "", + "prot", + "sp", + "a", + "nf", + "user", + "print", + "log", + "numeric", + "rep", + "cheat", + "", + "demo", + "norecord", + }; + + for ( int c = 2; c < ARRAYSIZE( s_szFlagDesc ); ++c ) + { + char szFlag[32]{}; - if ( pCMD->IsFlagSet( 1<IsFlagSet( 1 << c ) && sizeof( s_szFlagDesc[c] ) != sizeof( "" ) ) + { + Q_snprintf( szFlag, sizeof( szFlag ), ", %s", s_szFlagDesc[c] ); + Q_strncat( szFullFlags, szFlag, sizeof( szFullFlags ), COPY_ALL_CHARACTERS ); + } + } + char tempbuff[512]{}; + ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), bDefault ? static_cast< const ConVar* >( pCMD )->GetDefault() : static_cast< const ConVar* >( pCMD )->GetString(), szFullFlags, StripTabsAndReturns( pCMD->GetHelpText(), tempbuff, sizeof(tempbuff) ) ); + } + else // CSV format + { + constexpr static const char* s_szFlagDesc[] = { - Q_snprintf( szFlag, sizeof( szFlag ), ", %s", s_szFlagDesc[c] ); - Q_strncat( szFullFlags, szFlag, sizeof( szFullFlags ), COPY_ALL_CHARACTERS ); + "", + "", + "GAMEDLL", + "CLIENTDLL", + "", + "PROTECTED", + "SPONLY", + "ARCHIVE", + "NOTIFY", + "USERINFO", + "PRINTABLEONLY", + "UNLOGGED", + "NEVER_AS_STRING", + "REPLICATED", + "CHEAT", + "SS", + "DEMO", + "DONTRECORD", + "SS_ADDED", + }; + + for ( int c = 2; c < ARRAYSIZE( s_szFlagDesc ); ++c ) + { + if ( c == 4 ) // FCVAR_HIDDEN, we filter those out anyway + continue; + + char szFlag[32]{}; + + if ( pCMD->IsFlagSet( 1 << c ) && sizeof( s_szFlagDesc[c] ) != sizeof( "" ) ) + { + Q_snprintf( szFlag, sizeof( szFlag ), "\"%s\",", s_szFlagDesc[c] ); + Q_strncat( szFullFlags, szFlag, sizeof( szFullFlags ), COPY_ALL_CHARACTERS ); + } + else + { + Q_snprintf( szFlag, sizeof( szFlag ), "," ); + Q_strncat( szFullFlags, szFlag, sizeof( szFullFlags ), COPY_ALL_CHARACTERS ); + } } + + char tempbuff[512]{}; + ConMsg( "\"%s\",\"%s\",%s,\"%s\"\n", pCMD->GetName(), bDefault ? static_cast< const ConVar* >( pCMD )->GetDefault() : static_cast< const ConVar* >( pCMD )->GetString(), szFullFlags, StripTabsAndReturns( pCMD->GetHelpText(), tempbuff, sizeof(tempbuff) ) ); } - - char tempbuff[512]{}; - ConMsg( "%-40s : %-8s : %-16s : %s\n", pCMD->GetName(), static_cast< const ConVar* >( pCMD )->GetDefault(), szFullFlags, pCMD->GetHelpText() ); } } - ConMsg("--------------\n%3i total convars/concommands\n", cvarsorted.Count() ); + if ( !bCSV ) + ConMsg("--------------\n%3i total convars/concommands\n", cvarsorted.Count() ); } \ No newline at end of file