I know that exploiters can read local scripts in client. I’ve been recently being worried for exploiters because I heard they can edit the local scripts itself, and they don’t need to make a separate script.
If that is true, can’t they just not remove :FireServer()? Because I’m sending the combo value to the server by firing a remote event to make cooldowns. If their able to remove it then the cooldown would be non-existent. This would be an issue for me making an anti-cheat because I’m relearning scripting.
Mhm. They CAN modify the local scripts, and can do anything a local script can do, plus more!
Consider implementing a cooldown on the server side, such that even if the client removes the cooldown then it doesn’t have a major impact.
Nothing you can do about it client-side. Secure your remotes by validating variables to operate conditions and use some sort of a network module to make it miserable for exploiters to crack.
The cooldown and hitbox should be made at server.
Even if the combat is animation based, you can start a coroutine to check if the speed of the animation changes while it is playing. You can also use AdjustSpeed(1);
You can make a a StateMachine folder in the character, with a BooleanValue to check players attack debounce.
Even if an exploiter, changes the BoolValue’s value,
the value on the server is that what matters. His animation would play, but the server-sided hitbox will not be spawned.
Hitboxes being server-sided are a bad idea, since with fast moves, the client attacking Will hit on their screen but miss on the server. Games use a favor-the-client or favor-the-shooter approach. Easiest way to do this is send a remote with info then to verify it. The next best thing is a lag comp solution which requires rewriting Roblox code.
You can still use the remote. Validate it though, so if there is no response from that remote on the server in for example, a hit function, kick the exploiter, or just deny the exploiters hit.
Example
remote.OnServerEvent:Connect(function(plr, args)
local check = CompareCooldownLeft(args.Action)
if check then
args.Action.CooldownTick = tick()
end
end
local function Hit(plr, args)
if not args.Action.CooldownTick then plr:Kick()
--rest of the function
end
An exploiter cannot exploit this because there is nothing to be exploited. It checks the data between two points in time. That’s it. They can change the args of the remote, but the server decides if the cooldown should stand. By firing the remote with different args, they’re basically just executing intended game code from an executor, minus the perks of cool client-side effects.
By sending a remote to check cooldowns and verifying, there’s literally no way an exploiter can exploit that. Where is the vulnerability? It’s the same as connecting a remote-event for like jumping to a fireserver().
There’s no important args to be secured. You send the action, server compares it with server-sided data.
In a case like this, you don’t create data on the client that the server needs to trust and use.
I don’t recommend kicking in these instances unless you have a really high degree of certainty.
Latency, bugs, or other things can cause false positives if the client ends up in a state where it thinks it can send a request, only to then get kicked.
Yeah, I would deny the hit or just add some leniency to the cool down.
But, in this case, it’s checking if the cooldown data hasn’t been received yet. Afaik, remotes go out of their way to be sent in an orderly manner.
If the remote for the cooldown could get sent, so could the one for the hit, no matter how tight the margin. Still would add like a 0.1 second leniency though