Source SDK

Source SDK

KumBaYa Aug 4, 2017 @ 2:34pm
Retrieving a cvar value in the server (MP)
Hi there! I'm trying to get cvars value from the server side (not a plugin). ATM I use engine->StartQueryCvarValue like that ('cl_playermodel' just for an example):

int nQueryResult = (int)engine->StartQueryCvarValue(pPlayer->edict(), "cl_playermodel");

I'm trying to catch the result on CServerGameDLL::OnQueryCvarValueFinished that declared as:

virtual void OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue);

But! I get negative values (that means the engine consider it as a query from a server) and... nothing happens. No errors, no values got.

Can somebody explain me how I can get convar values from the server code? Thanks a lot for any help!
Last edited by KumBaYa; Aug 4, 2017 @ 2:36pm
< >
Showing 1-13 of 13 comments
GreenMelon Aug 8, 2017 @ 1:44pm 
If you want to get a value of a ConVar you can type the name of it and do .GetFloat() or .GetBool(), .GetInt().
KumBaYa Aug 8, 2017 @ 4:32pm 
Tnx, but I think you don't understand me clearly. I want to o get convar values of a client. Read the code that I've written
Last edited by KumBaYa; Aug 8, 2017 @ 4:33pm
GreenMelon Aug 11, 2017 @ 8:11am 
I dont really understand what you want to do. ConVar values are got with the methot that I specified.
KumBaYa Aug 11, 2017 @ 12:13pm 
That's pretty easy to understand.

https://developer.valvesoftware.com/wiki/Querying_ConVars_from_Server_Plugins

I want to do the same but only in SERVER code:

https://developer.valvesoftware.com/wiki/Querying_ConVars_from_Server_DLL

But I can not. I'm looking for solution/workaround of this issue. My CServerGameDLL::OnQueryCvarValueFinished member does not call and I don't know why.
Last edited by KumBaYa; Aug 11, 2017 @ 12:14pm
KumBaYa Aug 11, 2017 @ 12:16pm 
UPD: I mean, I want to get convars of a client, like the mat_wireframe, but I need to do it on server side.
GreenMelon Aug 15, 2017 @ 3:28pm 
Well, maybe you can somehow do it another way, like sending a client message to the server with the convar value. I havent worked with convar querys from the server so its all I can recommend at the time. (Like for example how the client sends his mouse position and button input information to the server.)
KumBaYa Aug 15, 2017 @ 4:21pm 
I cannot change client code, because it's hl2dm =( So no way... Any other ideas? We need more coders in that forum =)
Spirrwell Aug 19, 2017 @ 10:32am 
engine->GetClientConVarValue()?
KumBaYa Aug 19, 2017 @ 1:57pm 
Originally posted by Spirrwell:
engine->GetClientConVarValue()?

Please, have a look at starting post again. I need to catch values of convars like mat_wireframe, but using engine->StartQueryCvarValue method. The point is in that I cannot use GetClientConVarValue to getting mat_wireframe value, only StartQueryCvarValue.
Last edited by KumBaYa; Aug 19, 2017 @ 1:57pm
Spirrwell Aug 19, 2017 @ 6:18pm 
Well you never said anything about that function so I figured I'd suggest it. Seems that GetClientConVar doesn't work for engine owned variables.

But anyway, I tested out OnQueryCvarValueFinished() myself, and it's definitely not getting called from StartQueryCvarValue().

I even tried doing while ( true ) {} just to see if I could lock the game, because it's sometimes possible that Warning() and Msg() calls just flat out don't work for some odd reason. Nothing. Game continues like nothing happened.

So my only guess is that it's an engine bug and the ony way you'd be able to get the value is by modifying the client code.
Last edited by Spirrwell; Aug 19, 2017 @ 6:34pm
KumBaYa Aug 20, 2017 @ 11:04am 
Yes, that's very odd. It seems the engine ignores querying cvars from a server. I think I can reach the goal only using a server plugin. Okay, thank you anyway, you tried to help me.
Adrián Aug 21, 2017 @ 7:21am 
Hello,

I have coded some tests.

I found out engine->GetClientConVarValue() only returns the value for convars declared on Client, and marked with flag FCVAR_USERINFO. This is because convars with this flag are sent through the network with a StringTable ("userinfo") when client connects or value changes.

On the other hand, I tried few engine->StartQueryCvarValue() calls without luck.

You should use first method, since it does not use network on each call unlike second. Instead, it retrieves the convar values from the mentioned StringTable. By the way, some examples of userinfo convars whose value you can retrieve are: cl_playermodel, cl_language.

Test code for you:

CON_COMMAND(get_convar_userinfo, "Outputs the value of a convar from executing player. Query from UserInfo") { const char *pszConvarName = args.Arg(1); if (pszConvarName[0] == '\0') { Msg("Format: get_convar <convarname>\n"); return; } CBasePlayer *pPlayer = UTIL_GetCommandClient(); if (pPlayer != NULL) { char msg[221]; Q_snprintf(msg, sizeof msg, "Value of convar %s: %s", pszConvarName, engine->GetClientConVarValue(pPlayer->entindex(), pszConvarName)); ClientPrint(pPlayer, HUD_PRINTTALK, msg); } } CON_COMMAND(get_convar_client, "Outputs the value of a convar from executing player. Query from client-side") { const char *pszConvarName = args.Arg(1); if (pszConvarName[0] == '\0') { Msg("Format: get_convar <convarname>\n"); return; } CBasePlayer *pPlayer = UTIL_GetCommandClient(); if (pPlayer != NULL) { engine->StartQueryCvarValue(pPlayer->edict(), pszConvarName); } } void CServerGameDLL::OnQueryCvarValueFinished( QueryCvarCookie_t iCookie, edict_t *pPlayerEntity, EQueryCvarValueStatus eStatus, const char *pCvarName, const char *pCvarValue ) { CBasePlayer *pBasePlayer = ToBasePlayer(pPlayerEntity->GetUnknown()->GetBaseEntity()); char msg[221]; Q_snprintf(msg, sizeof msg, "Value of convar %s: %s", pCvarName, engine->GetClientConVarValue(pBasePlayer->entindex(), pCvarName)); ClientPrint(pBasePlayer, HUD_PRINTTALK, msg); }

As a side note, there is a GitHub repo containing old leaked SourceEngine2007 codebase. This helps a lot to learn about specific flows or even allow you to send netmessages with a bit of buffer hacks. For instance, here you can check what engine->GetClientConvarValue() does:

https://github.com/LestaD/SourceEngine2007/blob/43a5c90a5ada1e69ca044595383be67f40b33c61/se2007/engine/vengineserver_impl.cpp#L1255

I hope it helps. Regards.
Last edited by Adrián; Aug 21, 2017 @ 7:22am
niar Apr 23, 2019 @ 11:57am 
Originally posted by Adrián:
Hello,
I found out engine->GetClientConVarValue() only returns the value for convars declared on Client, and marked with flag FCVAR_USERINFO. This is because convars with this flag are sent through the network with a StringTable ("userinfo") when client connects or value changes.

Thanks from the future, I was scratching my head as to why a FCVAR_USERINFO flagged ConVar would not propagate its value change to server through GetClientConVarValue (it kept returning default value); turned out it indeed needed to be declared only on clientside code to work.
< >
Showing 1-13 of 13 comments
Per page: 1530 50