Exploit Prevention (Version 1)

Or just add a client-sided debounce since you don’t often want people to spam stuff.

2 Likes

The only thing that you need to check on server is if the player did meet the requirements. In this case is if player is close enough. You should also consider not to use ClickDetector on client unless it’s attached to object that was created by the client.

Like @LexiDog5 said, id based checking is pointless and easily bypass-able, don’t waste time on doing that, it does only 2 things, which is consuming your time and network usage.

Checking if the event was spammed is pointless too, as player could’ve lagged while clicking on around 10 money bags, which would cause false positives, don’t do that either.

So conclusion is, use Script instead, money bags are usually collect-able by all players.

local MoneyBag = script.Parent -- your money bag
local ClickDetector = Instance.new("ClickDetector", MoneyBag) -- a new click detector
ClickDetector.MouseClick:Connect(function(Player) -- listen for clicks on money bag
	Player.leaderstats.Money.Value += 100 -- add 100 money to the player
	MoneyBag:Destroy() -- remove the money bag
end)

And another reason why you should not make money bags client sided, is that they can be easily teleported to the player, and server would think that player is close enough to the money bag. So exploiter could just easily teleport all client sided money bags to himself and get money for all of them.

If you want to have good protection against exploiting and you want only a certain player to see the money bag. Hide the bag and prevent click detection on other clients, this will still make money bag seem non-existing to other players while server will have full control over the money bag while keeping exploiters away, as they can’t do anything server sided. And also mind checking if the player that clicked was the one that was allowed to.

If you will not use the click connection than disconnect it bc it takes memory

It won’t take the memory as the ClickDetector gets destroyed, and the connection does too. Correct me if I am wrong.

No, it doesn’t disconnect the event that was already connected and fire

I am pretty sure that connections get disconnected automatically once the object gets destroyed.

Yes, as long as you actually use :Destroy().

Don’t use delay() or wait() in your code, it’s considered code smell / bad practice. Instead, you can do a throttled RunService.Stepped loop:

local Step = game:GetService("RunService").Stepped

local function throttle(n, func)
    local iterations = 0
    return function(...)
        iterations += 1

        if iterations >= n then
            iterations = 0
            func(...)
        end
    end
end

local connection
connection = Step:Connect(throttle(20, function(total, delta)
    -- once player leaves, make sure to do connection:Disconnect()
end))

This way, you also have access to the time between each frames. (I chose Stepped because it fires before the physics happens each frame. However, you can replace it with Heartbeat if you want.)

2 Likes

Yes, since ClickDetector is child of MoneyBag, all children of MoneyBag will be destroyed as well the connections that were made. So that concludes this misunderstanding here.

No…
It doesn’t gets disconnected once it gets destroyed


check output…

Because the script is still running, and why we are still arguing about this?

Because I am right, and it has nothing to do with the script wth, you don’t know anything clearly
Putting it inside will print the same.
image

local con
con = workspace.Part.Touched:Connect(function()

	workspace.Part:Destroy()
	print(con,type(con))
end)

Please don’t say that I don’t know anything. Don’t mention my knowledge. You are not me, so you don’t know what I know and what I don’t know.

I’ve asked @Legoracer, and he had agreed. I am not sure why it still printing it, but I am sure that the connection is still removed at some point.

This isn’t proving anything.

That is not correct, the connection does get disconnected.

local con
con = workspace.Part.Touched:Connect(function()

	workspace.Part:Destroy()
	print(con.Connected) -- false
end)
5 Likes

No I am sure it doesnt disconnects

1 Like

Why are you still arguing?
3 people are telling you that what you saying isn’t correct. Read some posts and rethink your argument. I won’t continue arguing with you.

im not arguing I am just saying that it doesnt gets disconnect

Case and point.


Instance:Destroy disconnects all connections.

6 Likes

The reason that you printing the connection still shows something is because of how Lua’s GC works. Destroy() does disconnect the connection but the actual connection object will not be collected until it has no references (which in the case you showed will happen AFTER the bound function finishes executing).

2 Likes

Im pretty sure its:

while true do
    wait()
end
while wait() do
       
end

Im pretty sure that uses up a lot more memory instead of while true do.