Exploit Prevention (Version 1)

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.

When an instance is destroyed all connections on that instance are disconnected, and most of the instance’s memory is freed.

@ThoseNamesAreGood
The second example does not use more (or necessarily less) memory than the first, and additionally, either is technically correct although I would prefer the first since its a bit more readable.

@dollychun
I also believe this article is kind of misleading in some places, a lot of this stuff is not ideal or necessarily accurate, and a lot of it can be interpreted wrong. For example, the CheckTeleport function checks if the player has moved more than 140 studs in a second. This doesn’t really effectively detect teleportation, or speed, or no clip, or whatever.

“Use an anti exploit…” doesn’t really help the issue of explaining how to prevent noclipping. This is basically just like saying “fix the issue to fix the issue”

The last section on remotes is definitely accurate, but, option #3 would be easily circumvented, and option #2 is not really a solution to the problem. Option #1 is better, but, you should also check if the money bag exists otherwise, you allow them to fire it when its being removed.

You should be doing checks on Heartbeat, not in a wait() loop since Heartbeat is synchronized with physics. Additionally, you shouldn’t just stick in an arbitrary value if you want your code to accurately detect these sorts of exploits, you should do a little math to determine how far is realistic using, for example Velocity.Magnitude. I go over this in my topic (who @LexiDog5 linked, thanks :smile:).

2 Likes

That’s just not true and pretty much the only difference between while wait() do .... end and while true do .... wait() end is that the code in .... runs before the wait in the while true do loop.

while wait() do runs the wait immediately before code executes,
and while true do wait() [code] end does the same, and while true do [code] wait() end has the difference that the wait happens immediately after the code runs, so the only differences will be in the first and last iteration.

Generally, while wait() do I personally dislike because its a bit harder to understand/read (in some cases), and its a little misleading, but, I mean, its not terrible.

Both are perfectly viable options, I have no real complaints for either to be fair.

If you have a rate limiter on a client-sided script, even if the player spammed manually or with an autoclicker, it would limit that rate in which a player sends a remote event. If it was an exploiter, they would be accessing that remote via an exploit that’s ran directly in Roblox’s VM which would not be affected by the rate limiter.

So, with this, the server side would know this unusual spam traffic is from an exploiter’s client and would never result in false positives due to rate limiting a regular player via a script in the client.