How would i go about protecting this client code?

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)

Thanks

2 Likes

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.

The remote event doesnt have protection at all im not really good in how exploits work but i guess they can fire it and heal themselves up

1 Like

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.

1 Like

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.

2 Likes

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

1 Like

Just check if they have the tool equipped on the server and do the following:

  1. Tool is equipped - expected behavior, heal the player and do the debounce thing
  2. Tool isn’t equipped or the player doesn’t have the tool - ignore the request but rate limit it so it can’t be spammed

To check if a tool is equipped, check if that tool exists under that player’s character, on the server.

The player check I provided already does that.

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.

Is it possible to just create this on the server insteand of doing the remote stuff and then protection

You can try moving the code to a server script and get the player with the following code:

local Player = (Tool.Parent:IsA("Backpack") and Tool.Parent.Parent or Tool.Parent)

But it must run when you know the player has the tool else it will return a false result.

Sorry this didn’t work for you …

I’ve figured this way which works too!

local Player = script:FindFirstAncestorWhichIsA("Player") or game:GetService("Players"):GetPlayerFromCharacter(script.Parent.Parent)
1 Like

I’ve figured out how to do it, thanks to Nyrion.

Client code:

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)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.