To summarize, I’m creating a fighting game that uses client-sided hitboxes for good responsiveness, and run checks on the server to make sure exploiters don’t abuse this and change cooldowns, range and whatnot. The issue is, when I try to create the server cooldown, it doesn’t stop the actions inside the boolean. The range detection part of it works completely fine. Any suggestions or any other simple way? The data argument in the remote event only contains things like the hitbox position, and combo count by the way. (Included the whole script incase there’s something in the script affecting it.)
local remote = game:GetService('ReplicatedStorage').Remotes.Attacks.Sp.Click
local cooldownTable = {} --//List of server cooldowned players to prevent exploits!
remote.OnServerEvent:Connect(function(player, data, hit)
if (not cooldownTable[player]) and (data.Position - hit.Parent.HumanoidRootPart.Position).magnitude < 7 and not player.Character:FindFirstChild('Stun') then --Preventing cooldown, stun, and range hackers.
table.insert(cooldownTable, player)
delay(.4, function()
cooldownTable[player] = nil
end)
if hit.Parent:FindFirstChild('IFrame') then return end --Return ends
if data.Combo < 4 then
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(2.5)
local stun = Instance.new("BoolValue", hit.Parent)
stun.Name = "Stun"
if data.Combo == 1 then
game.Debris:AddItem(stun, .45)
elseif data.Combo == 2 then
game.Debris:AddItem(stun, .4)
elseif data.Combo > 2 then
game.Debris:AddItem(stun, .35)
end
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .2)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
else
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(5)
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 70
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .4)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
end
end--//CD CHECK END
end)
A debounce would be the correct method. The only thing is that you’re writing and reading using 2 separate “methods” for lack of a better word.
table.insert appends the value to the table giving the value a numerical index.
Indexing a table using brackets indexes the table with an index using an arbitrary type.
So, you’re checking if the debounce is false using the player as an index, but when you actually insert to the table you’re inserting using a numerical index.
So I’ll try breaking it down step by step:
cooldownTable now is {}
in connection:
check if table[player] is falsy (nil or false)
insert player to the table; table now is { [1] = player }
task.delay(.4, set cooldownTable[player] to nil, ultimately nothing changes, table now is still { [1] = player })
So what happens on the next event if the cooldown isn’t over?
in connection:
table now is { [1] = player }
so, check if table[player] is falsy, it is, so condition passes
To fix it, instead of doing table.insert(t, player), do t[player] = true, and then set t[player] to nil after .4 seconds. Or switch out t[player] with table.find(t, player). I think using t[player] = true is faster tho.
I tried doing both methods (table.find(cooldownTable, player), and cooldownTable[Player] = true and it still ended up not working. Pretty weird. Here’s my script at the moment: (Edited the cooldown bit since I discovered a security flaw with it, still works fine)
local remote = game:GetService('ReplicatedStorage').Remotes.Attacks.Sp.Click
local cooldownTable = {} --//List of server cooldowned players to prevent exploits!
remote.OnServerEvent:Connect(function(player, data, hit)
if (not cooldownTable[player]) and (player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-3).Position - hit.Parent.HumanoidRootPart.Position).magnitude < 7 and not player.Character:FindFirstChild('Stun') then --Preventing cooldown, stun, and range hackers.
cooldownTable[player] = true
delay(.4, function()
cooldownTable[player] = nil
end)
if hit.Parent:FindFirstChild('IFrame') then return end --Return ends
if data.Combo < 4 then
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(2.5)
local stun = Instance.new("BoolValue", hit.Parent)
stun.Name = "Stun"
if data.Combo == 1 then
game.Debris:AddItem(stun, .45)
elseif data.Combo == 2 then
game.Debris:AddItem(stun, .4)
elseif data.Combo > 2 then
game.Debris:AddItem(stun, .35)
end
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .2)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
else
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(5)
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 70
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .4)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
end
end--//Exploit Check End
end)
(I also forgot to add that sometimes the server cooldown rarely works, not all the time though. Also possible it’s my hitbox system acting up, which I highly doubt.)
Sorry for late response. It looks ok to me, are you sure it isn’t working? If you have poor internet connection sometimes that can cause synchronization issues on the client, but usually ping remains at a relatively constant rate so that might not be it.
I see you may have a minor issue though but I’m not too sure whether or not that’s causing it (or even if it’s unintended)
I think you might want to wrap these in parentheses (eg (player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-3)).Position
Could you maybe try printing cooldownTable[player] and see? It might be because of your if statement condition but I’m really not too sure.
local remote = game:GetService('ReplicatedStorage').Remotes.Attacks.Sp.Click
local __CS = game:GetService("CollectionService")
remote.OnServerEvent:Connect(function(player, data, hit)
if not __CS:HasTag(player, "__INCOOLDOWN")and (player.Character.HumanoidRootPart.CFrame * CFrame.new(0,0,-3).Position - hit.Parent.HumanoidRootPart.Position).magnitude < 7 and not player.Character:FindFirstChild('Stun') then --Preventing cooldown, stun, and range hackers.
__CS:AddTag(player, "__INCOOLDOWN")
task.delay(0.4,function()
__CS:RemoveTag(player, "__INCOOLDOWN")
end)
if hit.Parent:FindFirstChild('IFrame') then return end --Return ends
if data.Combo < 4 then
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(2.5)
local stun = Instance.new("BoolValue", hit.Parent)
stun.Name = "Stun"
if data.Combo == 1 then
game.Debris:AddItem(stun, .45)
elseif data.Combo == 2 then
game.Debris:AddItem(stun, .4)
elseif data.Combo > 2 then
game.Debris:AddItem(stun, .35)
end
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .2)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
else
if not hit.Parent:FindFirstChild('Blocking') then
hit.Parent.Humanoid:TakeDamage(5)
else
--//Blocking
end
local bv = Instance.new('BodyVelocity', hit.Parent.HumanoidRootPart)
bv.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 70
bv.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv, .4)
local bv2 = Instance.new('BodyVelocity', player.Character.HumanoidRootPart)
bv2.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector * 15
bv2.MaxForce = Vector3.new(99999,99999,99999)
game.Debris:AddItem(bv2, .2)
end
end--//Exploit Check End
end)