local P=(game:GetService("\082\117\110\083\101\114\118\105\099\101")):IsServer()local p=game:GetService("\080\108\097\121\101\114\115")local W=require(script.Parent.Parent.Ser)local u={}u.__index=u function u.Is(P)return type(P)=="\116\097\098\108\101"and getmetatable(P)==u end function u.new()assert(P,"\082\101\109\111\116\101\083\105\103\110\097\108 \099\097\110 \111\110\108\121 \098\101 \099\114\101\097\116\101\100 \111\110 \116\104\101 \115\101\114\118\101\114")local p=setmetatable({_remote=Instance.new("\082\101\109\111\116\101\069\118\101\110\116")},u)return p end function u.Fire(p,P,...)p._remote:FireClient(P,W.SerializeArgsAndUnpack(...))end function u.FireAll(P,...)P._remote:FireAllClients(W.SerializeArgsAndUnpack(...))end function u.FireExcept(u,P,...)local Y=W.SerializeArgs(...)for p,f in ipairs(p:GetPlayers())do if f~=P then u._remote:FireClient(f,W.UnpackArgs(Y))end end end function u.Wait(P)return P._remote.OnServerEvent:Wait()end function u.Connect(p,P)return p._remote.OnServerEvent:Connect(function(p,...)P(p,W.DeserializeArgsAndUnpack(...))end)end function u.Destroy(P)P._remote:Destroy()P._remote=nil end return u
--[[

	remoteSignal = RemoteSignal.new()

	remoteSignal:Connect(handler: (player: Player, ...args: any) -> void): RBXScriptConnection
	remoteSignal:Fire(player: Player, ...args: any): void
	remoteSignal:FireAll(...args: any): void
	remoteSignal:FireExcept(player: Player, ...args: any): void
	remoteSignal:Wait(): (...any)
	remoteSignal:Destroy(): void

--]]

local IS_SERVER = game:GetService("RunService"):IsServer()

local Players = game:GetService("Players")
local Ser = require(script.Parent.Parent.Ser)

local RemoteSignal = {}
RemoteSignal.__index = RemoteSignal

function RemoteSignal.Is(object)
	return type(object) == "table" and getmetatable(object) == RemoteSignal
end

function RemoteSignal.new()
	assert(IS_SERVER, "RemoteSignal can only be created on the server")
	local self = setmetatable({
		_remote = Instance.new("RemoteEvent"),
	}, RemoteSignal)
	return self
end

function RemoteSignal:Fire(player, ...)
	self._remote:FireClient(player, Ser.SerializeArgsAndUnpack(...))
end

function RemoteSignal:FireAll(...)
	self._remote:FireAllClients(Ser.SerializeArgsAndUnpack(...))
end

function RemoteSignal:FireExcept(player, ...)
	local args = Ser.SerializeArgs(...)
	for _, plr in ipairs(Players:GetPlayers()) do
		if plr ~= player then
			self._remote:FireClient(plr, Ser.UnpackArgs(args))
		end
	end
end

function RemoteSignal:Wait()
	return self._remote.OnServerEvent:Wait()
end

function RemoteSignal:Connect(handler)
	return self._remote.OnServerEvent:Connect(function(player, ...)
		handler(player, Ser.DeserializeArgsAndUnpack(...))
	end)
end

function RemoteSignal:Destroy()
	self._remote:Destroy()
	self._remote = nil
end

return RemoteSignal
