local j=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local c=j:WaitForChild("\077\111\100\117\108\101\115")local L=require(c.src.utils.Logger)local b=require(c.src.ApiSpec)local f={}f.prototype={}f.__index=f.prototype f.AllPlayers=newproxy(true)function f.create(c)assert(typeof(c)=="\116\097\098\108\101")local L={}setmetatable(L,f)local E=Instance.new("\070\111\108\100\101\114")E.Name="\069\118\101\110\116\115"for j,L in pairs(b.fromClient)do local b=Instance.new("\082\101\109\111\116\101\069\118\101\110\116")b.Name="\102\114\111\109\067\108\105\101\110\116-"..j b.Parent=E local f=c[j]if f==nil then error(("\078\101\101\100 \116\111 \105\109\112\108\101\109\101\110\116 \115\101\114\118\101\114 \104\097\110\100\108\101\114 \102\111\114 \037\113"):format(j),2)end b.OnServerEvent:Connect(function(j,...)assert(typeof(j)=="\073\110\115\116\097\110\099\101"and j:IsA("\080\108\097\121\101\114"))L.arguments(...)f(j,...)end)end for j,c in pairs(b.fromServer)do local b=Instance.new("\082\101\109\111\116\101\069\118\101\110\116")b.Name="\102\114\111\109\083\101\114\118\101\114-"..j b.Parent=E L[j]=function(j,L,...)c.arguments(...)if L==f.AllPlayers then b:FireAllClients(...)else assert(typeof(L)=="\073\110\115\116\097\110\099\101"and L:IsA("\080\108\097\121\101\114"))b:FireClient(L,...)end end end for j in pairs(c)do if b.fromClient[j]==nil then error(("\073\110\118\097\108\105\100 \104\097\110\100\108\101\114 \037\113 \115\112\101\099\105\102\105\101\100\033"):format(j),2)end end E.Parent=j L.remotes=E return L end function f.prototype.destroy(j)j.remotes:Destroy()end return f
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Modules = ReplicatedStorage:WaitForChild('Modules')
local logger = require(Modules.src.utils.Logger)

local ApiSpec = require(Modules.src.ApiSpec)

local ServerApi = {}
ServerApi.prototype = {}
ServerApi.__index = ServerApi.prototype

ServerApi.AllPlayers = newproxy(true)

function ServerApi.create(handlers)
	assert(typeof(handlers) == 'table')

	local self = {}

	setmetatable(self, ServerApi)

	local remotes = Instance.new('Folder')
	remotes.Name = 'Events'

	for name, endpoint in pairs(ApiSpec.fromClient) do
		local remote = Instance.new('RemoteEvent')
		remote.Name = 'fromClient-' .. name
		remote.Parent = remotes

		local handler = handlers[name]

		if handler == nil then
			error(('Need to implement server handler for %q'):format(name), 2)
		end

		remote.OnServerEvent:Connect(function(player, ...)
			assert(typeof(player) == 'Instance' and player:IsA('Player'))

			endpoint.arguments(...)

			handler(player, ...)
		end)
	end

	for name, endpoint in pairs(ApiSpec.fromServer) do
		local remote = Instance.new('RemoteEvent')
		remote.Name = 'fromServer-' .. name
		remote.Parent = remotes

		self[name] = function(_, player, ...)
			endpoint.arguments(...)

			if player == ServerApi.AllPlayers then
				remote:FireAllClients(...)
			else
				assert(typeof(player) == 'Instance' and player:IsA('Player'))

				remote:FireClient(player, ...)
			end
		end
	end

	for name in pairs(handlers) do
		if ApiSpec.fromClient[name] == nil then
			error(('Invalid handler %q specified!'):format(name), 2)
		end
	end

	remotes.Parent = ReplicatedStorage
	self.remotes = remotes

	return self
end

function ServerApi.prototype:destroy()
	self.remotes:Destroy()
end

return ServerApi