I’m making a tool that requires a cooldown to be used again after used the first time, and I am wondering if this would be exploit proof.
local cooldown = game:GetService("ReplicatedStorage").Remotes.CheckCooldown:InvokeServer()
So I have a value inside the player called “Cooldown” and I’m invoking a RemoteFunction to return that value to the client. I think this is the way you should be doing it. But then again I heard that exploiters can also modify the code that is available to them? (Idk if that is true, but if it is, is there a way that I can store this Cooldown without the exploiter seeing it?)
This should be exploit-proof since the value can not be changed by the user server-side(unless you have a method on the server that can be called that does so).
One thing that might be exploitable is how you check if the cooldown is “granted”. If the local script asks the server for a value the user might as well just change that value to instead not call the server and be 0.0001.
From my understand an exploiter can modify all the client-side data and scripts because it’s available to them. The server scripts are safe from modification but could be called or used with malicious intent. I sometimes create a localscript with malicious code that tries to modify, delete or create data and see how well my code manages to protect the data and the players.
They can just prevent the :InvokeServer request from going through. All ROBLOX objects (userdatas) have a metatable with a __namecall metamethod. This metamethod is fired when you index a userdata using the method syntax.
Normally the metatable is locked but because they’re exploiting they likely have engineered a way to bypass the __metatable metamethod.
They could check the name of the method, or type of the object that the method is being called on and return a nil statement, or something else.
local objectMetatable = ... --// they some how unlock the metatable, probably using `debug.getmetatable`; https://pgl.yoyo.org/luai/i/debug.getmetatable
local oldNamecall = objectMetatable.__namecall
function objectMetatable:__namecall(...)
if self.Name == "CoolDown" then return end
return oldNamecall(self, ...)
end
A better method would to be when a player requests to do an action, you on the server check if the time since their last action is greater than some amount and if it is then continue their action, if not then ignore their request.
NO! this code does NOT avoid any exploiters, it just sends an unnecessary signal, the “Cooldown” value you have under the player is replicated automatically, when you change it on the server it changes for the client too, so it’s better off checking it directly from client, as for exploitability, you can’t do much client side, an exploiter can modify the “local” cooldown no matter which way you use it on client, so the best use is to have the cooldown server-side, or have it client AND server side, so even if the client one is modified and the exploiter swings the weapon 1000 times a second on their client, the server will only count the swing done every 1 second (or whatever cooldown you do).