So i’ve made a script for a medkit for my game, and it’s all on client and can be easily manipulated by exploiters im aware and i want to prevent from exploits
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Tool = script.Parent
local Debounce = false
function Activated()
if Debounce then
return
end
Debounce = true
local Character = Player.Character
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid and Humanoid.Health > 0 then
Humanoid.Health = Humanoid.MaxHealth - 1
Tool:Destroy()
end
Debounce = false
end
Tool.Activated:Connect(Activated)
A decent way would be you to use remotes in this case.
Like this
local Players = game:GetService("Players")
local Remote = game.ReplicatedStorage.Remote
local Player = Players.LocalPlayer
local Tool = script.Parent
local Debounce = false
function Activated()
if Debounce then return end
Debounce = true
Remote:FireServer()
task.wait(.1) -- Just to avoid remote spam
Debounce = false
end
Tool.Activated:Connect(Activated)
Server
local Remote = game.ReplicatedStorage.Remote
local serverDebounce = {}
Remote.OnServerEvent:Connect(function(plr)
if serverDebounce[plr] then return end
serverDebounce[plr] = true
local Character = plr.Character
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid and Humanoid.Health > 0 then
Humanoid.Health = Humanoid.MaxHealth - 1
Tool:Destroy()
end
task.wait(1) -- Cooldown
serverDebounce[plr] = false
end)
This isn’t really a good way to do this but it will be useful for now, dont forget to whenever the player disconnects his table index gets removed, so your game wont store useless data.
Just like what @netheround said, it doesn’t have a sanity check (aka protection) to check if it’s the player that’s holding the tool, or an exploiter firing remote from someone holding the tool.
I’d recommend adding a sanity check to make sure that it’s the player that’s holding the tool and not anyone else.
Im thinking of one, before firing the remote should i just check if the player has the tool i dont really know what should i do, i’ve aleardy thought about this
To check the player, you need to have a variable containing the player using the tool, so if the server script is inside the tool, you can do:
Remote.OnServerEvent:Connect(function(plr)
local character = script:FindFirstAncestorWhichIsA("Model")
if plr.Character == character then
-- Heal code here.
end
end)
If you don’t know what is :FindFirstAncestor(), it’s basically the opposite of :FindFirstChild(), like its looking for the parent.
Yeah you’re both totally right, but as i said it wasn’t the best way to do it, but for now on an early testing phase would help a lot, i dont know what type of game he is doing nor if it is actually a game and not a project, but you’re right about sanity checks i just dont added it in there because i dont really know too if Netheround had any knowledge about it, making sanity checks would prob confuse him more
If it can’t find the ancestor which is a “Model”, it’ll return nil, and Backpack is not inside of any ancestors classified as “Model”. That way, you have both things in one for checking the right player and checking if the tool is equipped.
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Tool = script.Parent
local Mouse = Player:GetMouse()
Tool.Equipped:Connect(function()
Mouse.Icon = "http://www.roblox.com/asset/?id=32801669"
end)
Tool.Activated:Connect(function()
Mouse.Icon = ""
end)
Server code:
local Players = game:GetService("Players")
local Tool = script.Parent
local Player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Debounce = false
function Activated()
if Debounce then
return
end
Debounce = true
if Humanoid and Humanoid.Health > 0 then
Humanoid.Health = Humanoid.MaxHealth - 1
Tool:Destroy()
end
Debounce = false
end
Tool.Activated:Connect(Activated)