I looked some stuff up, and I think you should check out these resources:
-
This forum post helped me understand how to do sanity checks inside of scripts.
-
This YouTube video showed me what exploits are capable of, and exactly what to watch out for.
-
This Wikipedia article talks about defensive programming as a whole, and dives deep into the common practices and strategies most developers use to prevent exploiters.
In this case, sanity checks are necessary to secure the remote event, and the more parameters you add, the better security you will have against exploiters. In our case (and many others) we can use our current setting to our advantage. Think about it:
Firstly, a customer enters. Then, when buying items, the customer is usually in front of the cashier.
It’s no surprise that both of these can be passed as arguments from the client, but the real deal comes from the server too. Our next iteration can go something like this:
LocalScript
local player = game.Players.LocalPlayer
local shopRange = (player.Character.HumanoidRootPart.Position - game:GetService(“Workspace”).ShopPart.Position).Magnitude -- Change accordingly
local shopCheck = player.Character:FindFirstChild(“InShop”) -- Change accordingly
if shopRange <= 8 and shopCheck then
if cashAmount.Value > 0 then
cashValueChanged:FireServer()
else
print("Invalid Transaction")
return end
end
ServerScript
local cashValueChanged = game.ReplicatedStorage.cashValueChanged
cashValueChanged.OnServerEvent:Connect(function(player)
local shopRange = (player.Character.HumanoidRootPart.Position - game:GetService(“Workspace”).ShopPart.Position).Magnitude -- Change accordingly
local shopCheck = player.Character:FindFirstChild(“InShop”) -- Change accordingly
if shopRange <= 8 and shopCheck then
player.cashFolder[currencyName].Value = player.cashFolder[currencyName].Value - 10
end)
else
print(“Malicious behavior detected.”)
-- This wouldn’t fire unless an exploiter bypassed the LocalScript first.
end
This won’t prevent ALL exploits, because it isn’t possible. This only makes it so that exploiters can’t spend their money outside of the shop, which in this situation prevents all exploits. Cool.
With that being said, there is no happy go lucky, all around, easy peasy way to prevent exploits. I thought there was, but looking stuff up had me realize it wasn’t what I originally thought. We learn and we grow I guess.
Basically, just think about what you want the average player to do inside your functionality, and make unnecessary boundaries to make sure exploiters have a harder time breaking it. And don’t trust the client, because exploiters have full control over everything client-side.
I hope this helps!