I have been working on a chat GUI recently, but every time the OnServerEvent event fired for a remote event in ReplicatedStorage, it ran the connected function multiple times. Here's the code:

--Local script
local main = script.Parent:WaitForChild("Main")
local container = main:WaitForChild("Container")
local chatbox = main:WaitForChild("ChatBoxContainer"):WaitForChild("ChatBox")
local sendbutton = main:WaitForChild("SendButton")
local chatev = game.ReplicatedStorage:WaitForChild("Chat")
local serverchatev = game.ReplicatedStorage:WaitForChild("Chat")
local adminchatev = game.ReplicatedStorage:WaitForChild("Chat")
local chats = {}

local function isadmin()
	return game.Players.LocalPlayer.Name == "AppleBLOXIAN" or game.Players.LocalPlayer.Name == "BlizzardBOY390"
end

local function calculatesize(text)
	local chat = Instance.new("TextLabel")
	chat.BackgroundTransparency = 1
	chat.Size = UDim2.new(1,0,0,25)
	chat.Font = Enum.Font.SourceSans
	chat.Text = text
	chat.TextSize = 25
	chat.TextXAlignment = Enum.TextXAlignment.Left
	chat.TextYAlignment = Enum.TextYAlignment.Top
	if chat.TextBounds.X > 494 then
		chat.Size = chat.Size + UDim2.new(0,0,0,(chat.TextBounds.X/494)*25)
	end
	return chat.Size
end

local function focuslost(e)
	if e then
		if isadmin() then
			adminchatev:FireServer(game.Players.LocalPlayer.Name,chatbox.Text)
			chatbox.Text = 'Press "/" or click here to chat'
		else
			chatev:FireServer(game.Players.LocalPlayer.Name,chatbox.Text)
			chatbox.Text = 'Press "/" or click here to chat'
		end
	end
end

local function onClick()
	if isadmin() then
		adminchatev:FireServer(game.Players.LocalPlayer.Name,chatbox.Text)
		chatbox.Text = 'Press "/" or click here to chat'
	else
		chatev:FireServer(game.Players.LocalPlayer.Name,chatbox.Text)
		chatbox.Text = 'Press "/" or click here to chat'
	end
end

local function makechat(plrname,msg)
	local chat = Instance.new("TextLabel")
	chat.BackgroundTransparency = 1
	chat.Size = calculatesize(plrname..": "..msg)
	chat.Font = Enum.Font.SourceSans
	chat.Text = plrname..": "..msg
	chat.TextSize = 25
	chat.TextXAlignment = Enum.TextXAlignment.Left
	chat.TextYAlignment = Enum.TextYAlignment.Top
	chat.Position = (function()
		if #chats == 0 then
			return UDim2.new(0,0,0,0)
		else
			return chats[#chats].Position + UDim2.new(0,0,0,chats[#chats].Size.Y.Offset)
		end
	end)()
	chat.Parent = container
	container.CanvasSize = container.CanvasSize + UDim2.new(0,0,0,chat.Size.Y.Offset)
	container.CanvasPosition = container.CanvasPosition + Vector2.new(0,chat.Size.Y.Offset)
	chats[#chats+1] = chat
end

chatbox.FocusLost:connect(focuslost)
sendbutton.MouseButton1Click:connect(onClick)
chatev.OnClientEvent:connect(makechat)
adminchatev.OnClientEvent:connect(makechat)
serverchatev.OnClientEvent:connect(makechat)

game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat,false)

--Server script
local chatev = game.ReplicatedStorage:WaitForChild("Chat")
local serverchatev = game.ReplicatedStorage:WaitForChild("Chat")
local adminchatev = game.ReplicatedStorage:WaitForChild("Chat")

chatev.OnServerEvent:connect(function(plr,plrname,msg)
	msg = game:GetService("Chat"):FilterStringForBroadcast(msg,plr)
	chatev:FireAllClients(plrname,msg)
end)

adminchatev.OnServerEvent:connect(function(plr,plrname,msg)
	adminchatev:FireAllClients(plrname,msg)
end)

game.Players.PlayerAdded:connect(function(plr)
	serverchatev:FireServer("Server",plr.Name.." has joined the game.")
end)

game.Players.PlayerRemoving:connect(function(plr)
	serverchatev:FireServer("Server",plr.Name.." has left the game.")
end)

1 comment

0

You could pass a unique id as an argument to the remote, and store it on the server. You can then make sure there are no duplicates by iterating through the array of stored id's. You should only let entries in the array last as long as the message appears on your chat ui; the array could become quite large and inconvenient to iterate through.