• Need help with basic anti-cheat
    2 replies, posted
I wanted to make a simple anti-cheat that just perma-bans users who have certain cvars that vary from what the servers have. I get excessive lag and server crash while using this script and I can't figure out what's wrong with it. [lua] local BannedCVars = { "sv_cheats", "sv_allowcslua", "mat_fullbright", "mat_proxy", "mat_wireframe", "host_timescale", } local first = true local function RefreshCVars() for k, v in pairs(BannedCVars) do BannedCVars[k] = GetConVar(v) if first then cvars.AddChangeCallback( BannedCVars[k]:GetName(), RefreshCVars() ) end end if first then first = false end end RefreshCVars() local function GetCheatCVar() for k, v in pairs(player.GetAll()) do v:SendLua( [[ local LBannedCVars = ]] .. BannedCVars .. [[ local GetConVarNumber = GetConVarNumber for k,v in pairs(LBannedCVars) do if GetConVarNumber( v:GetName() ) ~= v:GetString() then RunConsoleCommand( "banmeimafag", v:GetName() ) end end ]] ) end end timer.Create('GetCheatCVars',5,0, GetCheatCVar) concommand.Add('banmeimafag', function( ply, convar ) ply:Ban( 0, "AntiCheat: Recieved unsynced cvar ( " .. convar .. " )" ) RunConsoleCommand( "ulx", "banid", ply:SteamID() , 0, "AntiCheat: Recieved unsynced cvar ( " .. convar .. " )" ) RunConsoleCommand( "writeid" ) end) [/lua]
1. SendLua should NEVER be used. 2. Never include a function inside itself. 3. A table is NOT a string. You can't use "<string> .. <table>". That's not how it works. A client and a server don't have the same values, so you have to send the tables data back and forth. 4. Never trust the client .. 90% are blocking GetConVarNumber. 1. Learn the net library: [url]http://wiki.garrysmod.com/page/Net_Library_Usage[/url] 3. You can convert a table to a string and back using: [url]http://wiki.garrysmod.com/page/util/TableToJSON[/url]. But don't do it every 5 seconds .. do it once. 4. There are plenty of anticheats and scripts that helps (Best those that aren't public) .. the best way to fight the hackers are admins.
Okay, I haven't tested this yet because I haven't had any victims or crashes yet.. but I wrote it in the net library like I should have the first time. SERVERSIDE CODE: [lua] util.AddNetworkString( "ValidateCVars" ) util.AddNetworkString( "CheckServerVars" ) local BannedCVars = { "sv_cheats", "sv_allowcslua", "mat_fullbright", "mat_proxy", "mat_wireframe", "host_timescale", } local first = true local function RefreshCVars() for k, v in pairs(BannedCVars) do BannedCVars[k] = GetConVar(v) if first then cvars.AddChangeCallback( BannedCVars[k]:GetName(), RefreshCVars() ) end end if first then first = false end end RefreshCVars() local function SendBannedCVars(ply) for k, var in pairs(BannedCVars) do net.Start("ValidateCVars") net.WriteTable( { VarName = var:GetName(), VarString = var:GetString() } ) net.Send(ply) end end net.Receive( "CheckServerVars", function(l, ply) SendBannedCVars(ply) end ) local function ValidateCVar(ply, ServerValue, ClientValue) if GetConVar(ServerValue):GetString() ~= (ClientValue or "") then ply:Ban( 0, "AntiCheat: Recieved unsynced cvar ( " .. convar .. " )" ) RunConsoleCommand( "ulx", "banid", ply:SteamID() , 1, "AntiCheat: Recieved unsynced cvar ( " .. convar .. " )" ) RunConsoleCommand( "writeid" ) end end net.Receive( "ValidateCVars", function(len, ply) ValidateCVar(ply, net.ReadTable().ServerValue, net.ReadTable().ClientValue) end ) [/lua] CLIENTSIDE CODE: [lua] local function CheckCVars() net.Start("CheckServerVars") net.WriteBit() net.SendToServer() end timer.Simple(5, CheckCVars) local function ValidateCVar(ServerValue, ClientValue) net.Send("ValidateCVars") net.WriteTable({ServerValue = ServerValue, ClientValue = ClientValue}) net.SendToServer() end local function RefreshCVar(CVar, OldVal, NewVal) timer.Simple(1, function() -- Wait 1 incase server changed its var too. ValidateCVar(CVar, NewVal) end) end local BannedCVars = { } net.Receive( "ValidateCVars", function() local ConVar = GetConVar(net.ReadTable().VarName) local Value = (ConVar ~= nil and ConVar:GetString() or "0") BannedCVars[ConVar] = Value cvars.AddChangeCallback(net.ReadTable().VarName, RefreshCVar) if Value ~= net.ReadTable().VarString then ValidateCVar(net.ReadTable().VarString, Value) end end ) [/lua]
Sorry, you need to Log In to post a reply to this thread.