Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- export type Remote = {
- Name: string,
- RemoteEvent: RemoteEvent,
- OnClientEvent: RBXScriptSignal,
- OnServerEvent: RBXScriptSignal,
- Events: Dictionary,
- FireAllClients: () -> (),
- FireClient: (Player) -> (),
- FireServer: () -> (),
- Wait: (Player?, string) -> (),
- RemoteFunction: RemoteFunction,
- -- OnClientInvoke = RemoteFunction.OnClientInvoke,
- -- OnServerInvoke = RemoteFunction.OnServerInvoke,
- Functions: Dictionary,
- InvokeClient: (Player) -> (),
- InvokeServer: () -> (),
- Connection: RBXScriptConnection?,
- }
- local RunService = game:GetService("RunService")
- local RemoteAdded = Instance.new("BindableEvent")
- local Remotes = {}
- local function makeRemoteEvent(name: string): RemoteEvent
- local RemoteEvent = Instance.new("RemoteEvent")
- RemoteEvent.Name = name .. ".RE"
- return RemoteEvent
- end
- local function makeRemoteFunction(name: string): RemoteFunction
- local RemoteFunction = Instance.new("RemoteFunction")
- RemoteFunction.Name = name .. ".RF"
- return RemoteFunction
- end
- function Remotes.create(name: string): Remote
- if RunService:IsServer() then
- if not Remotes[name] then
- local RemoteEvent = makeRemoteEvent(name)
- local RemoteFunction = makeRemoteFunction(name)
- local Remote = {
- Name = name,
- RemoteEvent = RemoteEvent,
- OnServerEvent = RemoteEvent.OnServerEvent,
- Events = {},
- FireAllClients = function(...)
- RemoteEvent:FireAllClients(...)
- end,
- FireClient = function(player: Player, ...)
- RemoteEvent:FireClient(player, ...)
- end,
- Wait = function(player: Player?, event: string): string
- local result = table.pack(RemoteEvent.OnServerEvent:Wait())
- if player then
- if result[1] == player and result[2] == event then
- return unpack(result, 3)
- end
- else
- if result[2] == event then
- return unpack(result, 3)
- end
- end
- end,
- RemoteFunction = RemoteFunction,
- Functions = {},
- InvokeClient = function(player: Player, ...): any
- return RemoteFunction:InvokeClient(player, ...)
- end,
- }
- local functions = Remote.Functions
- function RemoteFunction.OnServerInvoke(player: Player, instruction: string, ...): any
- local callback = functions[instruction]
- if callback then
- local errorMessage, stacktrace
- local results = table.pack(xpcall(callback, function(err)
- errorMessage = err
- stacktrace = debug.traceback()
- end, player, ...))
- if not results[1] then
- error(string.format(
- "Error Message: %s.\nFrom Instruction %q with RemoteFunction %q from Player %q\nStack trace:%s",
- tostring(errorMessage),
- tostring(instruction),
- tostring(name),
- tostring(player),
- tostring(stacktrace)
- ))
- end
- return unpack(results, 2)
- else
- warn(instruction, "is an Invalid Function for", name, "RemoteFunction")
- end
- end
- Remotes[name] = Remote
- RemoteEvent.Parent = script
- RemoteFunction.Parent = script
- script:SetAttribute(name, true)
- RemoteAdded:Fire()
- else
- warn("RemoteEvent", name, "already exists use Remotes.get instead")
- end
- return Remotes[name]
- else
- error("Can NOT call Remotes.create from Client")
- end
- end
- function Remotes.get(name: string): Remote
- script:WaitForChild(name .. ".RE")
- script:WaitForChild(name .. ".RF")
- while not Remotes[name] do
- RemoteAdded.Event:Wait()
- end
- return Remotes[name]
- end
- local function setEvents(Remote: Remote, newInstructions: Dictionary)
- local events = Remote.Events
- for instruction: string, callback in pairs(newInstructions) do
- events[instruction] = callback
- end
- end
- function Remotes.handleEvents(Remote: Remote, newInstructions: Dictionary)
- setEvents(Remote, newInstructions)
- if not Remote.Connection then
- local events = Remote.Events
- if RunService:IsClient() then
- Remote.Connection = Remote.OnClientEvent:Connect(function(instruction: string, ...)
- local callback = events[instruction]
- if callback then
- local errorMessage, stacktrace
- local success = xpcall(callback, function(err)
- errorMessage = err
- stacktrace = debug.traceback()
- end, ...)
- if not success then
- error(string.format(
- "Error Message: %s.\nFrom Instruction %q with RemoteEvent %q\nStack trace:%s",
- tostring(errorMessage),
- tostring(instruction),
- tostring(Remote.Name),
- tostring(stacktrace)
- ))
- end
- else
- warn(instruction, "is an Invalid Event for", Remote.Name, " a Client RemoteEvent")
- end
- end)
- elseif RunService:IsServer() then
- Remote.Connection = Remote.OnServerEvent:Connect(function(player: Player, instruction: string, ...)
- local callback = events[instruction]
- if callback then
- local errorMessage, stacktrace
- local success = xpcall(callback, function(err)
- errorMessage = err
- stacktrace = debug.traceback()
- end, player, ...)
- if not success then
- error(string.format(
- "Error Message: %s.\nFrom Instruction %q with RemoteEvent %q from Player %q\nStack trace:%s",
- tostring(errorMessage),
- tostring(instruction),
- tostring(Remote.Name),
- tostring(player),
- tostring(stacktrace)
- ))
- end
- else
- warn(instruction, "is an Invalid Event for", Remote.Name, "a Server RemoteEvent from Player", player)
- end
- end)
- end
- end
- end
- local function setFunctions(Remote: Remote, newInstructions: Dictionary)
- local functions = Remote.Functions
- for instruction: string, callback in pairs(newInstructions) do
- functions[instruction] = callback
- end
- end
- function Remotes.handleFunctions(Remote: Remote, newInstructions: Dictionary)
- setFunctions(Remote, newInstructions)
- end
- if RunService:IsClient() then
- local function _Create(name: string)
- local RemoteEvent = script:WaitForChild(name .. ".RE")
- local RemoteFunction = script:WaitForChild(name .. ".RF")
- local Remote = {
- Name = name,
- RemoteEvent = RemoteEvent,
- OnClientEvent = RemoteEvent.OnClientEvent,
- Events = {},
- FireServer = function(...)
- RemoteEvent:FireServer(...)
- end,
- Wait = function(event: string): string
- local result = table.pack(RemoteEvent.OnClientEvent:Wait())
- if result[1] == event then
- return unpack(result, 2)
- end
- end,
- RemoteFunction = RemoteFunction,
- Functions = {},
- InvokeServer = function(...): any
- return RemoteFunction:InvokeServer(...)
- end,
- }
- local functions = Remote.Functions
- function RemoteFunction.OnClientInvoke(instruction: string, ...): any
- local callback = functions[instruction]
- if callback then
- local errorMessage, stacktrace
- local results = table.pack(xpcall(callback, function(err)
- errorMessage = err
- stacktrace = debug.traceback()
- end, ...))
- if not results[1] then
- error(string.format(
- "Error Message: %s.\nFrom Instruction %q with RemoteFunction %q\nStack trace:%s",
- tostring(errorMessage),
- tostring(instruction),
- tostring(name),
- tostring(stacktrace)
- ))
- end
- return unpack(results, 2)
- else
- warn(instruction, "is an Invalid Function for", name, "RemoteFunction")
- end
- end
- Remotes[name] = Remote
- RemoteAdded:Fire()
- end
- script.AttributeChanged:Connect(_Create)
- for name: string, _ in pairs(script:GetAttributes()) do
- _Create(name)
- end
- end
- return Remotes
Add Comment
Please, Sign In to add comment