Facepunch / garrysmod-issues

Garry's Mod issue tracker
147 stars 56 forks source link

Lua created replicated cvars don't trigger change callbacks on the client #3740

Open Lexicality opened 5 years ago

Lexicality commented 5 years ago

Details

(I've read #3503, but I think this is different.) I have a replicated cvar that is replicating fine, but isn't triggering any change callbacks when it does.

Steps to reproduce

CreateConVar("cvar_repl_test", 1, FCVAR_REPLICATED + FCVAR_ARCHIVE);
if CLIENT then
    cvars.AddChangeCallback("cvar_repl_test", function(...) print("CLIENT", ...) end, "test");
else
    cvars.AddChangeCallback("cvar_repl_test", function(...) print("SERVER", ...) end, "test");
end
] cvar_repl_test 2
SERVER  cvar_repl_test  1   2
] lua_run print(GetConVarString("cvar_repl_test"))
> print(GetConVarString("cvar_repl_test"))...
2
] lua_run_cl print(GetConVarString("cvar_repl_test"))
2
] lua_run_cl PrintTable(cvars.GetConVarCallbacks("cvar_repl_test"))
1:
        1   =   function: 0x42b01728
        2   =   test
LeQuackers commented 3 years ago

I'm not sure about the current implementation but using g_pCVar->InstallGlobalChangeCallback would probably fix this.

brandonsturgeon commented 1 year ago

When I run this on x86-64 server (linux) and x86-64 client (windows), I get:

[Server] SERVER cvar_repl_test  1   newvalue

[STEAM_0:0:21170873 (Phatso)] CLIENT    cvar_repl_test  1   newvalue

Seems to work, not sure if that's only on x86-64, though

Grocel commented 1 year ago

I can confirm this not working on the main branch.

Vuthakral commented 1 year ago

Just coming in with some actual evidence that this issue is in fact still an issue. Comment above claims it does not work on main (unsurprising), but I am testing this on x86-64 gmod_03_12033

edit: Here is my workaround for this issue. Just net message it into your table of cached convars to force-update it on the client.

It should be noted this is not a full problem solver as it still opens the potential for cheaters to make their game think something is allowed that shouldn't be, or vice versa. A proper fix for this issue is greatly needed, and my workaround should not be used for anything which could be abused by cheaters.

-- server lua in an autorun somewhere
util.AddNetworkString("SyncCustomServerVar")
---------
-- in your cvar.AddChangeCallback
if SERVER then
    net.Start("SyncCustomServerVar")
    net.WriteString(namearg)
    net.WriteFloat(newarg)
    net.Broadcast()
end
---------
-- client lua in an autorun somewhere
net.Receive("SyncCustomServerVar", function()
    MyTable[net.ReadString()] = net.ReadFloat()
end)
Grocel commented 1 year ago

You could also readout the cvar in a think hook (polling) and trigger a hook/function manually when a change is detected. No need for extra networking.