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.