I’m not sure the details about exploiting, but a basic sanity check is checking if the player actually clicked the weapon when the server is fired. For instance;
=== [Client Side] ===
local WasWeaponFired? = false
local Damage = 50
tool.Activated:Connect(function()
WasWeaponFired = true
game.ReplicatedStorage.RemoteEvent:FireServer(WasWeaponFired, Damage)
WasWeaponFired = false
end)
=== [Server Side] ===
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function(player, WasWeaponFired, Damage)
if WasWeaponFired == false then return end
print("Player Clicked Tool!")
end)
Basically if the RemoteEvent was fired without the player activating the tool, don’t allow the function to happen. People put advanced code there as well in replacement of the return such as a ban function if it fires without the tool being clicked 3 times, or a warning system.
Notice how I said a “Basic” Sanity check and “I’m not sure the details about exploiting.”
EDIT: Not knowing about how to exploit doesn’t necessarily mean I have no knowledge of Sanity Checks.
EDIT: Why would I make a complicated system for him to follow here? He should discover how to do that on his own. I was just giving him the basic understanding.
Well, you should treat your client code like it can be modified or changed. I wrote a fairly detailed article on game security in Roblox which goes into way more detail than I do here if you’d like to read it.
Basically think like your client code will always be something that can be changed or rewritten by an exploiter. An exploiter can, for example, call DealDMG:FireServer(character) whenever they want, and, based on your checks above this will just work regardless of whether the person used the sword, if the sword actually hit, or if they’re in range. This isn’t what you want (obviously, that was your question in the first place). Instead, you want to check if it makes sense, in other words, as said above, a sanity check. A simple sanity check for swords is to check the distance between the two players. You can assume that a target (hit) player’s HumanoidRootPart position can’t be further than the length of the sword give or take a couple studs. For example, distance <= swordLength + 2.
Another, very accurate sanity check is to raycast from the base of the sword to the tip of the sword. (I highly recommend using the new workspace:Raycast() function, the existing raycast functions were just deprecated and are harder to use in this scenario).
Similarly, for guns, usually you’ll simulate the collision on the server. If guns in your game were to use raycast, you might have the client ask the server to shoot a bullet. The server then does all of the work. On the client, you might also have a copy of part of that code to show the bullet being shot for them. If guns in your game used physics, you could do the same thing, just have the client ask the server to fire the gun (or start firing the gun if its auto). The server then decides when damage is done (and again the easiest way is a raycast).
Your sanity checks should never be based on information sent over the remote. For example, sending a swordEquipped value over the remote is pointless because an exploiter can again, basically edit your client code or just write their own.
Look when sword activate fire server not dealing damage. Then from server play the animation if there is, and if any player touched the sword while the remote is activated he get damage.