I made a projectile function which creates the projectile locally then sends it to the server for smooth movement, and if it’s touched, then it fires an event to a server hit script. I’ve added a lot of sanity checks, the only thing that I’m worried about is that exploiters can change the hit argument to make it become everyone in the server. Would this be possible based on my script? If so, how would I prevent this?
CLIENT KNIFE FUNCTION:
local function Knife()
local Knife = Instance.new("Part",game.Workspace)
Knife.CanCollide = false
Knife.Size = Vector3.new(2,2,2)
Knife.CFrame = Player.Character.PrimaryPart.CFrame * CFrame.new(1,1,-3)
local KnifeMesh = Instance.new("SpecialMesh",Knife)
KnifeMesh.MeshType = "FileMesh"
KnifeMesh.MeshId = MeshId
KnifeMesh.TextureId = TextureId
KnifeMesh.Scale = Vector3.new(1,1,1)
local BodyVel = Instance.new("BodyVelocity",Knife)
BodyVel.maxForce = Vector3.new(math.huge,math.huge,math.huge)
game:GetService("Debris"):AddItem(Knife, 10)
BodyVel.Velocity = Player.Character.PrimaryPart.CFrame.lookVector * speed
Knife.Touched:Connect(function(p)
if p.Parent ~= nil and p.Parent:FindFirstChild("Humanoid") and p.Parent ~= Player.Character then
game.ReplicatedStorage.RE:FindFirstChild("Hit"):FireServer(p, throw)
Knife:Destroy()
local S = Instance.new("Sound", p.Parent:FindFirstChild("HumanoidRootPart"))
S.SoundId = "rbxassetid://93706376"
S.PlaybackSpeed = math.random(95,110)/100
S.Volume = 2
S:Play()
game:GetService("Debris"):AddItem(S, 3)
end
end)
end
SERVER DAMAGE RECEIVER:
local Timestamp = tick()
game.ReplicatedStorage.RE:FindFirstChild("Hit").OnServerEvent:Connect(function(player, hit, throw)
if (tick() - Timestamp) < 3 then return end
if hit.Parent:FindFirstChild("Humanoid") then
if hit.Parent ~= player.Character then
if throw then
wait()
hit.Parent:FindFirstChild("Humanoid"):TakeDamage(0.5)
Timestamp = tick()
end
end
end
end)
There’s no check here to make sure the knife was actually near the hit humanoid, so they could just spam the remote with the humanoid they want to damage, albeit spaced out by 3 seconds.
You are also not separating out each timestamp respective to the player who used fired the remote, so if one player hits someone with the knife, then no knife in the entire server will register hits for 3 seconds.
I’m not sure what throw represents here either, can you elaborate?
I would recommend implementing a magnitude check using both the player and hit players humanoidRootPart. This will at least limit the range which they can damage players.
Also since your using .touched they don’t necessarily have to even fire the remote with false information. They could simply loop through every players character and teleport them to their knife (on the client), which would then trigger the touched event.
The easiest thing to do is implement a magnitude check, but if you want even more beefy security you could also cast a ray in front of the player (assuming the swing only deals damage in front). Anything within the ray takes damages, etc.
Yes, the throw is an argument from my animation marker that fires the remote event to create a projectile. This is so that the exploiter cannot cast projectiles if they are not attacking.
The problem is that you’re trusting what the client sends as its throw argument. Having a serverside table shared between that script and the knife remote receiving script would allow you to check the value from the server entirely, which is the only secure way to do it.
Regardless, that is not the biggest problem here for security. You need to find some way to check the knife’s position from the server and run a magnitude check between it and the hit player’s character.