debug.setmemorycategory("Test")
local remote = script.RemoteFunction
--LocalScript's old code (spammable if you want to attempt breaking the script) is:
--script.Parent:WaitForChild("RemoteFunction"):InvokeServer("Random")
local function runNetwork(Player,signal,invokeData)
if Player then
if signal then
signal.OnServerInvoke = nil
Player:LoadCharacter()
task.wait() -- this wait is necessary for garbage collection
signal:Destroy() signal = nil
runNetwork(Player)
else
signal = remote:Clone()
local scrip = signal.LocalScript
scrip.Parent = Player.PlayerGui
signal.Parent = Player.PlayerGui
local connection = Player.AncestryChanged:Once(function() if not Player or Player and not Player.Parent then warn("Player exit") signal.OnServerInvoke = nil task.wait() -- this wait is necessary for garbage collection
signal:Destroy() signal = nil end end)
signal.OnServerInvoke = function(Player,...) scrip:Destroy() connection:Disconnect() runNetwork(Player,signal,...) print("activated") end
end
end
end
game.Players.PlayerAdded:Connect(function(Player)
runNetwork(Player)
end)
Intended to make stress free networking the easiest…
ServerScriptService contains the localscript, which you can modify to spam just about any comms to the remote.
How would this prevent that, and what memory leak does this fix?
Why? You can just check who’s the sending player, this doesn’t stop exploiters from spamming it.
I don’t think you quite understand how garbage collection and connections work, and please don’t inline a bunch of code (that makes it pretty hard to read).
The memory leak being fixed is part of how fast the remote is deleting, immediately setting OnServerInvoke to nil and customizing the iteration’s cooldown. The intended behavior is to prevent hooks from happening by hiding or deleting the instance, comparatively, it’s always vulnerable to :InvokeServer().
the leak is here:
signal.OnServerInvoke = nil
Player:LoadCharacter()
task.wait() -- this wait is necessary for garbage collection,
-- removing it presents extreme memory usage perceptually leaking over a long period of time, even if it may not entirely be a leak
signal:Destroy() signal = nil
runNetwork(Player)
What hook are you preventing? That callback is on the server.
Hiding Instances also doesn’t prevent exploiters from tampering with them, they have several methods to get them.
Additionally, what do you mean by “this wait is necessary for garbage collection”? Values are marked for GC when they go out of scope.
when InvokeServer() calls, the RemoteFunction.OnServerInvoke is immediately set to nil, but it doesn’t always clean it all up in one heartbeat. A hacker can spam it fast enough to invoke within the same iteration it is set to nil, where it gets entirely deleted instead, that gets prevented.
The purpose of PlayerGui is to keep the remote private, only the server should be able to access a PlayerGui folder, but not other players.
remove the garbage collector task.wait() and check F9, server memory, search “test”, compare the bar graphs!
If a RemoteFunction is in ReplicatedStorage, any player can Invoke it. Sanity checks are simple, but the function is always going to call without delay if we don’t actually remove the Instance. Without anything to Invoke, there’s 0 potential for programmatical spam and reassured, no callback runs 2x
MAINLY, the remote deletes after ANY invocation, any hacker can send 1 message and screw it up.
in reducing code, i opted to utilize how replication is handled client - server
What delay, and what’s the problem with the simple “return if something isn’t what we expect”?
You might think you’ve reduced “programmatical spam”, but really you’ve just complicated RemoteFunctions unnecessarily, increasing memory usage and making your code less efficient.
…Why?
There’s a reason why things are standardized, why not just add them to a cooldown table? It avoids needing to create remotes for every single player, setting callbacks over and over, and janky garbage collection.
Im intending to scale the code up into a network module that handles more things, mostly for crucial network interactions that should work with single inputs. (like wanting to press the spawn button 1 time and it just works, practically disregarding how laggy you are completely)
RemoteEvents don’t yield automatically, and im straight up trying to avoid them completely
Recursive networking is the goal, idk. Only 1 replication happens on the client, 1 replication giving them an event listener that only they can communicate with, without tampering. This is especially good at a simple task like a spawn button that is practically unhackable, also easy to obtain
Remote Functions are not the best idea for networking. It takes a round trip for you to get the data you are looking for which is suboptimal, this means you experience twice the latency that you would normally experience if you are trying to do game state syncing (call takes one trip to arrive at the server, response comes one trip later). You would do this with remote events or unreliable remote events instead (data is sent every tick, you recieve the latest data after one trip).
Remote functions are generally to be reserved for asynchronous behaviors, such as completing or verifying a purchase, or interacting with a server-side system in a scenario where minor latency is not particularly a point of a concern, so in any case where they have the opportunity to be “spammed” it shouldn’t happen unless someone is doing something such as auto-clicking the “Buy” button in a store.
This does exactly what a RemoteEvent would normally do, but the behavior favors waiting for the client network to be ok, send the packet, and continue.
A situation where 1 click needs to register on server, without a miss
Roblox uses RakNet, which is already reliable networking.
Unless you explicitly use UnreliableRemoteEvents, all events are reliable, and packet loss isn’t an issue.