[ARCHIVED] RemoteEventManager

Hey there :grinning_face_with_smiling_eyes:, here to share another utility module in a similar style to my ConnectionController module. This time, it’s a RemoteEvent wrapper that adds some bandwidth optimisations and a block list. It also organises RemoteEvents in a folder that appear upon running so they don’t clutter your explorer!

Here’s a quick overview of the functions:

Main Functions
  • addEvent("name") puts a RemoteEvent into the folder within the module, with the chosen name. The function also returns the RemoteEvent instance.

  • removeEvent("name") destroys the named RemoteEvent.

  • addListener("name", function) runs the function when the named RemoteEvent is fired and automatically determines whether it’s the server or the client.

  • removeListener("name") disconnects the named RemoteEvent but doesn’t destroy it, meaning it can be reused.

  • fireEvent("name", plr, ...) fires the named RemoteEvent, passing on the defined parameters. Automatically determines whether it’s the server or the client. If it’s the client, plr is treated as a normal parameter due to the Player who fired the server passing on natively.

  • fireAllClients("name", ...) fires server → all clients, passing on the defined parameters.

  • blockClient(Player, toggle) doesn’t stop the client from firing RemoteEvents, but causes the server to reject their requests. If toggle is true, the client will be blocked and visa versa.

Once again, I hope you find this asset useful for organising your game’s backend :video_game:, here’s the module (make sure to put it in ReplicatedStorage):

RemoteEventManager Code
--!strict
local runService = game:GetService("RunService")
local eventFolder = script:WaitForChild("Events")

local client = runService:IsClient()
local server = runService:IsServer()

type Function = (any) -> any?

local eventConns = {}
local blockList = {}

return {
	addEvent = function(name : string): RemoteEvent
		assert(server, "This Function can only be used on the Server")
		assert(eventFolder:FindFirstChild(name) == nil, "There is already a RemoteEvent with the Name: "..name)
		
		local event = Instance.new("RemoteEvent")
		event.Name = name
		event.Parent = eventFolder
		
		return event
	end,
	
	removeEvent = function(name : string)
		assert(server, "This Function can only be used on the Server")
		assert(eventFolder:FindFirstChild(name) ~= nil, "There is no RemoteEvent with the Name: "..name)
		
		eventConns[name] = nil
		eventFolder:FindFirstChild(name):Destroy()
	end,
	
	fireEvent = function(name : string, plr : Instance, ... : any?)
		assert(eventFolder:FindFirstChild(name) ~= nil, "There is no RemoteEvent with the Name: "..name)
		
		local event = eventFolder:FindFirstChild(name)
		local params = table.pack(...)
		
		if server then
			event:FireClient(plr, params)
		else
			table.insert(params, 1, plr)
			event:FireServer(params)
		end
	end,
	
	fireAllClients = function(name : string, ... : any?)
		assert(server, "This Function can only be used on the Server")
		assert(eventFolder:FindFirstChild(name) ~= nil, "There is no RemoteEvent with the Name: "..name)

		local event = eventFolder:FindFirstChild(name)
		local params = table.pack(...)

		event:FireAllClients(params)
	end,
	
	addListener = function(name : string, func : Function)
		assert(eventFolder:FindFirstChild(name) ~= nil, "There is no RemoteEvent with the Name: "..name)
		
		local event = eventFolder:WaitForChild(name)
		local signal = if client then event.OnClientEvent else event.OnServerEvent

		local conn = signal:Connect(function(...)
			local params = table.pack(...)
			
			local plrCheck = typeof(params[1]) == "Instance" and params[1]:IsA("Player")
			if plrCheck and blockList[params[1].Name] then warn(params[1], "is blocked from firing RemoteEvents") return end

			func(table.unpack(params))
		end)
		
		eventConns[name] = conn
	end,
	
	removeListener = function(name : string)
		assert(eventFolder:FindFirstChild(name) ~= nil, "There is no RemoteEvent with the Name: "..name)
		
		eventConns[name]:Disconnect()
		eventConns[name] = nil
	end,
	
	blockClient = function(plr : Instance, toggle : boolean?)
		assert(server, "This Function can only be used on the Server")
		
		if toggle then
			blockList[plr.Name] = plr
		else
			blockList[plr.Name] = nil
		end
	end
}

--[[
Made by M_dgettMann (shadowflame63)

Example of adding/removing a RemoteEvent to/from the RemoteEvents folder:
	Module.addEvent("AnExample") -- Adds a RemoteEvent called 'AnExample' into the folder, and returns the RemoteEvent
	Module.removeEvent("AnExample") -- Removes the 'AnExample' RemoteEvent from the folder
	
Example usage of listeners for a named RemoteEvent:
	Module.addListener("AnExample", function() end) -- Runs the function with passed parameters when 'AnExample' is fired, automatically decides whether it's the server or client
	Module.removeListener("AnExample") -- Disconnects the listener for 'AnExample', but the RemoteEvent isn't destroyed and can be reused

Example of firing a named RemoteEvent:
	Module.fireEvent("AnExample", 123, "string") -- Fires named remote passing on the defined parameters, automatically decides whether it's the server or client
	Module.fireAllClients("AnExample", 123, "string") -- Fires server -> all clients, passing on the defined parameters

Example of blocking a client from firing RemoteEvents with effect:
	Module.blockClient(Player, true) -- The client can still fire events, but the server rejects their requests
]]
--[[
Made by M_dgettMann (shadowflame63)

Example of adding/removing a RemoteEvent to/from the RemoteEvents folder:
	Module.addEvent("AnExample") -- Adds a RemoteEvent called 'AnExample' into the folder, and returns the RemoteEvent
	Module.removeEvent("AnExample") -- Removes the 'AnExample' RemoteEvent from the folder
	
Example usage of listeners for a named RemoteEvent:
	Module.addListener("AnExample", function() end) -- Runs the function with passed parameters when 'AnExample' is fired, automatically decides whether it's the server or client
	Module.removeListener("AnExample") -- Disconnects the listener for 'AnExample', but the RemoteEvent isn't destroyed and can be reused

Example of firing a named RemoteEvent:
	Module.fireServer("AnExample", 123, "string") -- Fires client -> server, passing on the defined parameters
	Module.fireClient("AnExample", Player, 123, "string") -- Fires server -> client, passing on the defined parameters
	Module.fireAllClients("AnExample", 123, "string") -- Fires server -> all clients, passing on the defined parameters

Example of blocking a client from firing RemoteEvents with effect:
	Module.blockClient(Player, true) -- The client can still fire events, but the server rejects their requests
]]
Module Model

RemoteEventManager - Roblox

Edit: Fixed the functionality of the optimiser() function, made the blockClient() toggle make more sense and merged the fireClient() and fireServer() functions.

Note: Removed the BandwidthOptimiser module as it wasn’t functioning properly.

This module is outdated and no longer supported.

5 Likes

This doesn’t make sense to me. It’s saying BlockPlayer(Yes) will unblock the player, which doesn’t make sense at all.

1 Like

One thing I did for my custom networking module was remove the need for a fire server and client method. The function can easily be simplified into a single :Fire() and the function know which one to use contextually.

2 Likes

Very good point, I may do that then seeing as listeners already do the same

Sorry, I was just following the same format as the Disable property. I can switch it around if you wish

Setting something’s Disabled property to true will disable it, but for this it’s like setting Disabled to true will enable it. I don’t get what you mean.

1 Like