RuizuKun_Dev

Remotes.lua

May 26th, 2021 (edited)
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.42 KB | None | 0 0
  1. export type Remote = {
  2.     Name: string,
  3.  
  4.     RemoteEvent: RemoteEvent,
  5.     OnClientEvent: RBXScriptSignal,
  6.     OnServerEvent: RBXScriptSignal,
  7.     Events: Dictionary,
  8.     FireAllClients: () -> (),
  9.     FireClient: (Player) -> (),
  10.     FireServer: () -> (),
  11.  
  12.     Wait: (Player?, string) -> (),
  13.  
  14.     RemoteFunction: RemoteFunction,
  15.     -- OnClientInvoke = RemoteFunction.OnClientInvoke,
  16.     -- OnServerInvoke = RemoteFunction.OnServerInvoke,
  17.     Functions: Dictionary,
  18.     InvokeClient: (Player) -> (),
  19.     InvokeServer: () -> (),
  20.  
  21.     Connection: RBXScriptConnection?,
  22. }
  23.  
  24. local RunService = game:GetService("RunService")
  25.  
  26. local RemoteAdded = Instance.new("BindableEvent")
  27.  
  28. local Remotes = {}
  29.  
  30. local function makeRemoteEvent(name: string): RemoteEvent
  31.     local RemoteEvent = Instance.new("RemoteEvent")
  32.     RemoteEvent.Name = name .. ".RE"
  33.     return RemoteEvent
  34. end
  35.  
  36. local function makeRemoteFunction(name: string): RemoteFunction
  37.     local RemoteFunction = Instance.new("RemoteFunction")
  38.     RemoteFunction.Name = name .. ".RF"
  39.     return RemoteFunction
  40. end
  41.  
  42. function Remotes.create(name: string): Remote
  43.     if RunService:IsServer() then
  44.         if not Remotes[name] then
  45.             local RemoteEvent = makeRemoteEvent(name)
  46.  
  47.             local RemoteFunction = makeRemoteFunction(name)
  48.  
  49.             local Remote = {
  50.                 Name = name,
  51.  
  52.                 RemoteEvent = RemoteEvent,
  53.                 OnServerEvent = RemoteEvent.OnServerEvent,
  54.                 Events = {},
  55.                 FireAllClients = function(...)
  56.                     RemoteEvent:FireAllClients(...)
  57.                 end,
  58.                 FireClient = function(player: Player, ...)
  59.                     RemoteEvent:FireClient(player, ...)
  60.                 end,
  61.  
  62.                 Wait = function(player: Player?, event: string): string
  63.                     local result = table.pack(RemoteEvent.OnServerEvent:Wait())
  64.                     if player then
  65.                         if result[1] == player and result[2] == event then
  66.                             return unpack(result, 3)
  67.                         end
  68.                     else
  69.                         if result[2] == event then
  70.                             return unpack(result, 3)
  71.                         end
  72.                     end
  73.                 end,
  74.  
  75.                 RemoteFunction = RemoteFunction,
  76.                 Functions = {},
  77.                 InvokeClient = function(player: Player, ...): any
  78.                     return RemoteFunction:InvokeClient(player, ...)
  79.                 end,
  80.             }
  81.  
  82.             local functions = Remote.Functions
  83.             function RemoteFunction.OnServerInvoke(player: Player, instruction: string, ...): any
  84.                 local callback = functions[instruction]
  85.                 if callback then
  86.                     local errorMessage, stacktrace
  87.                     local results = table.pack(xpcall(callback, function(err)
  88.                         errorMessage = err
  89.                         stacktrace = debug.traceback()
  90.                     end, player, ...))
  91.                     if not results[1] then
  92.                         error(string.format(
  93.                             "Error Message: %s.\nFrom Instruction %q with RemoteFunction %q from Player %q\nStack trace:%s",
  94.                             tostring(errorMessage),
  95.                             tostring(instruction),
  96.                             tostring(name),
  97.                             tostring(player),
  98.                             tostring(stacktrace)
  99.                         ))
  100.                     end
  101.                     return unpack(results, 2)
  102.                 else
  103.                     warn(instruction, "is an Invalid Function for", name, "RemoteFunction")
  104.                 end
  105.             end
  106.  
  107.             Remotes[name] = Remote
  108.  
  109.             RemoteEvent.Parent = script
  110.             RemoteFunction.Parent = script
  111.  
  112.             script:SetAttribute(name, true)
  113.  
  114.             RemoteAdded:Fire()
  115.         else
  116.             warn("RemoteEvent", name, "already exists use Remotes.get instead")
  117.         end
  118.         return Remotes[name]
  119.     else
  120.         error("Can NOT call Remotes.create from Client")
  121.     end
  122. end
  123.  
  124. function Remotes.get(name: string): Remote
  125.     script:WaitForChild(name .. ".RE")
  126.     script:WaitForChild(name .. ".RF")
  127.     while not Remotes[name] do
  128.         RemoteAdded.Event:Wait()
  129.     end
  130.     return Remotes[name]
  131. end
  132.  
  133. local function setEvents(Remote: Remote, newInstructions: Dictionary)
  134.     local events = Remote.Events
  135.  
  136.     for instruction: string, callback in pairs(newInstructions) do
  137.         events[instruction] = callback
  138.     end
  139. end
  140.  
  141. function Remotes.handleEvents(Remote: Remote, newInstructions: Dictionary)
  142.     setEvents(Remote, newInstructions)
  143.     if not Remote.Connection then
  144.         local events = Remote.Events
  145.         if RunService:IsClient() then
  146.             Remote.Connection = Remote.OnClientEvent:Connect(function(instruction: string, ...)
  147.                 local callback = events[instruction]
  148.                 if callback then
  149.                     local errorMessage, stacktrace
  150.                     local success = xpcall(callback, function(err)
  151.                         errorMessage = err
  152.                         stacktrace = debug.traceback()
  153.                     end, ...)
  154.                     if not success then
  155.                         error(string.format(
  156.                             "Error Message: %s.\nFrom Instruction %q with RemoteEvent %q\nStack trace:%s",
  157.                             tostring(errorMessage),
  158.                             tostring(instruction),
  159.                             tostring(Remote.Name),
  160.                             tostring(stacktrace)
  161.                         ))
  162.                     end
  163.                 else
  164.                     warn(instruction, "is an Invalid Event for", Remote.Name, " a Client RemoteEvent")
  165.                 end
  166.             end)
  167.         elseif RunService:IsServer() then
  168.             Remote.Connection = Remote.OnServerEvent:Connect(function(player: Player, instruction: string, ...)
  169.                 local callback = events[instruction]
  170.                 if callback then
  171.                     local errorMessage, stacktrace
  172.                     local success = xpcall(callback, function(err)
  173.                         errorMessage = err
  174.                         stacktrace = debug.traceback()
  175.                     end, player, ...)
  176.                     if not success then
  177.                         error(string.format(
  178.                             "Error Message: %s.\nFrom Instruction %q with RemoteEvent %q from Player %q\nStack trace:%s",
  179.                             tostring(errorMessage),
  180.                             tostring(instruction),
  181.                             tostring(Remote.Name),
  182.                             tostring(player),
  183.                             tostring(stacktrace)
  184.                         ))
  185.                     end
  186.                 else
  187.                     warn(instruction, "is an Invalid Event for", Remote.Name, "a Server RemoteEvent from Player", player)
  188.                 end
  189.             end)
  190.         end
  191.     end
  192. end
  193.  
  194. local function setFunctions(Remote: Remote, newInstructions: Dictionary)
  195.     local functions = Remote.Functions
  196.  
  197.     for instruction: string, callback in pairs(newInstructions) do
  198.         functions[instruction] = callback
  199.     end
  200. end
  201.  
  202. function Remotes.handleFunctions(Remote: Remote, newInstructions: Dictionary)
  203.     setFunctions(Remote, newInstructions)
  204. end
  205.  
  206. if RunService:IsClient() then
  207.     local function _Create(name: string)
  208.         local RemoteEvent = script:WaitForChild(name .. ".RE")
  209.  
  210.         local RemoteFunction = script:WaitForChild(name .. ".RF")
  211.  
  212.         local Remote = {
  213.             Name = name,
  214.  
  215.             RemoteEvent = RemoteEvent,
  216.             OnClientEvent = RemoteEvent.OnClientEvent,
  217.             Events = {},
  218.             FireServer = function(...)
  219.                 RemoteEvent:FireServer(...)
  220.             end,
  221.  
  222.             Wait = function(event: string): string
  223.                 local result = table.pack(RemoteEvent.OnClientEvent:Wait())
  224.                 if result[1] == event then
  225.                     return unpack(result, 2)
  226.                 end
  227.             end,
  228.  
  229.             RemoteFunction = RemoteFunction,
  230.             Functions = {},
  231.             InvokeServer = function(...): any
  232.                 return RemoteFunction:InvokeServer(...)
  233.             end,
  234.         }
  235.  
  236.         local functions = Remote.Functions
  237.         function RemoteFunction.OnClientInvoke(instruction: string, ...): any
  238.             local callback = functions[instruction]
  239.             if callback then
  240.                 local errorMessage, stacktrace
  241.                 local results = table.pack(xpcall(callback, function(err)
  242.                     errorMessage = err
  243.                     stacktrace = debug.traceback()
  244.                 end, ...))
  245.                 if not results[1] then
  246.                     error(string.format(
  247.                         "Error Message: %s.\nFrom Instruction %q with RemoteFunction %q\nStack trace:%s",
  248.                         tostring(errorMessage),
  249.                         tostring(instruction),
  250.                         tostring(name),
  251.                         tostring(stacktrace)
  252.                     ))
  253.                 end
  254.                 return unpack(results, 2)
  255.             else
  256.                 warn(instruction, "is an Invalid Function for", name, "RemoteFunction")
  257.             end
  258.         end
  259.  
  260.         Remotes[name] = Remote
  261.  
  262.         RemoteAdded:Fire()
  263.     end
  264.     script.AttributeChanged:Connect(_Create)
  265.  
  266.     for name: string, _ in pairs(script:GetAttributes()) do
  267.         _Create(name)
  268.     end
  269. end
  270.  
  271. return Remotes
Add Comment
Please, Sign In to add comment