local s={}PlayersService.PlayerAdded:connect(function(k)for s,r in pairs(s)do local z=ChatService:GetSpeaker(s.Name)if z then for s=1,#r,1 do local t=r[s]if t==k.UserId then z:AddMutedSpeaker(k.Name)end end end end end)PlayersService.PlayerRemoving:connect(function(k)s[k]=nil end)EventFolder.SetBlockedUserIdsRequest.OnServerEvent:connect(function(k,r)s[k]=r local z=ChatService:GetSpeaker(k.Name)if z then for s=1,#r,1 do local k=PlayersService:GetPlayerByUserId(r[s])if k then z:AddMutedSpeaker(k.Name)end end end end)EventFolder.GetInitDataRequest.OnServerInvoke=function(s)local k=ChatService:GetSpeaker(s.Name)if not(k and k:GetPlayer())then CreatePlayerSpeakerObject(s)k=ChatService:GetSpeaker(s.Name)end local r={}r.Channels={}r.SpeakerExtraData={}for s,z in pairs(k:GetChannelList())do local t=ChatService:GetChannel(z)if t then local s={z,t.WelcomeMessage;t:GetHistoryLogForSpeaker(k),t.ChannelNameColor}table.insert(r.Channels,s)end end for s,k in pairs(ChatService:GetSpeakerList())do local z=ChatService:GetSpeaker(k)r.SpeakerExtraData[k]=z.ExtraData end return r end local function k(s,k,r)local z=ChatService:GetSpeaker(s)local t=ChatService:GetChannel(k)if z then if t then if t.Joinable then if not z:IsInChannel(t.Name)then z:JoinChannel(t.Name)else z:SetMainChannel(t.Name)z:SendSystemMessage(string.format("\089\111\117 \097\114\101 \110\111\119 \099\104\097\116\116\105\110\103 \105\110 \099\104\097\110\110\101\108\058 \'\037\115\'",t.Name),t.Name)end else z:SendSystemMessage("\089\111\117 \099\097\110\110\111\116 \106\111\105\110 \099\104\097\110\110\101\108 \'"..(k.."\'\046"),r)end else z:SendSystemMessage("\067\104\097\110\110\101\108 \'"..(k.."\' \100\111\101\115 \110\111\116 \101\120\105\115\116\046"),r)end end end local function r(s,k,r)local z=ChatService:GetSpeaker(s)local t=ChatService:GetChannel(k)if z then if z:IsInChannel(k)then if t.Leavable then z:LeaveChannel(t.Name)z:SendSystemMessage(string.format("\089\111\117 \104\097\118\101 \108\101\102\116 \099\104\097\110\110\101\108 \'\037\115\'",t.Name),"\083\121\115\116\101\109")else z:SendSystemMessage("\089\111\117 \099\097\110\110\111\116 \108\101\097\118\101 \099\104\097\110\110\101\108 \'"..(k.."\'\046"),r)end else z:SendSystemMessage("\089\111\117 \097\114\101 \110\111\116 \105\110 \099\104\097\110\110\101\108 \'"..(k.."\'\046"),r)end end end ChatService:RegisterProcessCommandsFunction("\100\101\102\097\117\108\116\095\099\111\109\109\097\110\100\115",function(s,z,t)if(string.sub(z,1,6)):lower()=="\047\106\111\105\110 "then k(s,string.sub(z,7),t)return true elseif(string.sub(z,1,3)):lower()=="\047\106 "then k(s,string.sub(z,4),t)return true elseif(string.sub(z,1,7)):lower()=="\047\108\101\097\118\101 "then r(s,string.sub(z,8),t)return true elseif(string.sub(z,1,3)):lower()=="\047\108 "then r(s,string.sub(z,4),t)return true elseif string.sub(z,1,3)=="\047\101 "or string.sub(z,1,7)=="\047\101\109\111\116\101 "then return true end return false end)local z=ChatService:AddChannel("\065\108\108")local t=ChatService:AddChannel("\083\121\115\116\101\109")z.Leavable=false z.AutoJoin=true t.Leavable=false t.AutoJoin=true t.WelcomeMessage="\084\104\105\115 \099\104\097\110\110\101\108 \105\115 \102\111\114 \115\121\115\116\101\109 \097\110\100 \103\097\109\101 \110\111\116\105\102\105\099\097\116\105\111\110\115\046"t.SpeakerJoined:connect(function(s)t:MuteSpeaker(s)end)local function w(s)if s:IsA("\077\111\100\117\108\101\083\099\114\105\112\116")then local k=require(s)if type(k)=="\102\117\110\099\116\105\111\110"then k(ChatService)end end end local T=(game:GetService("\067\104\097\116")):WaitForChild("\067\104\097\116\077\111\100\117\108\101\115")T.ChildAdded:connect(function(s)local k,r=pcall(w,s)if not k and r then print("\069\114\114\111\114 \114\117\110\110\105\110\103 \109\111\100\117\108\101 "..(s.Name..("\058 "..r)))end end)for s,k in pairs(T:GetChildren())do local r,z=pcall(w,k)if not r and z then print("\069\114\114\111\114 \114\117\110\110\105\110\103 \109\111\100\117\108\101 "..(k.Name..("\058 "..z)))end end local d=game:GetService("\080\108\097\121\101\114\115")d.PlayerRemoving:connect(function(s)if ChatService:GetSpeaker(s.Name)then ChatService:RemoveSpeaker(s.Name)end end)

local BlockedUserIdsMap = {}

PlayersService.PlayerAdded:connect(function(newPlayer)
	for player, blockedUsers in pairs(BlockedUserIdsMap) do
		local speaker = ChatService:GetSpeaker(player.Name)
		if speaker then
			for i = 1, #blockedUsers do
				local blockedUserId = blockedUsers[i]
				if blockedUserId == newPlayer.UserId then
					speaker:AddMutedSpeaker(newPlayer.Name)
				end
			end
		end
	end
end)

PlayersService.PlayerRemoving:connect(function(removingPlayer)
	BlockedUserIdsMap[removingPlayer] = nil
end)

EventFolder.SetBlockedUserIdsRequest.OnServerEvent:connect(function(player, blockedUserIdsList)
	BlockedUserIdsMap[player] = blockedUserIdsList
	local speaker = ChatService:GetSpeaker(player.Name)
	if speaker then
		for i = 1, #blockedUserIdsList do
			local blockedPlayer = PlayersService:GetPlayerByUserId(blockedUserIdsList[i])
			if blockedPlayer then
				speaker:AddMutedSpeaker(blockedPlayer.Name)
			end
		end
	end
end)

EventFolder.GetInitDataRequest.OnServerInvoke = (function(playerObj)
	local speaker = ChatService:GetSpeaker(playerObj.Name)
	if not (speaker and speaker:GetPlayer()) then
		CreatePlayerSpeakerObject(playerObj)
		speaker = ChatService:GetSpeaker(playerObj.Name)
	end

	local data = {}
	data.Channels = {}
	data.SpeakerExtraData = {}

	for i, channelName in pairs(speaker:GetChannelList()) do
		local channelObj = ChatService:GetChannel(channelName)
		if (channelObj) then
			local channelData =
			{
				channelName,
				channelObj.WelcomeMessage,
				channelObj:GetHistoryLogForSpeaker(speaker),
				channelObj.ChannelNameColor,
			}

			table.insert(data.Channels, channelData)
		end
	end

	for i, oSpeakerName in pairs(ChatService:GetSpeakerList()) do
		local oSpeaker = ChatService:GetSpeaker(oSpeakerName)
		data.SpeakerExtraData[oSpeakerName] = oSpeaker.ExtraData
	end

	return data
end)

local function DoJoinCommand(speakerName, channelName, fromChannelName)
	local speaker = ChatService:GetSpeaker(speakerName)
	local channel = ChatService:GetChannel(channelName)

	if (speaker) then
		if (channel) then
			if (channel.Joinable) then
				if (not speaker:IsInChannel(channel.Name)) then
					speaker:JoinChannel(channel.Name)
				else
					speaker:SetMainChannel(channel.Name)
					speaker:SendSystemMessage(string.format("You are now chatting in channel: '%s'", channel.Name), channel.Name)
				end
			else
				speaker:SendSystemMessage("You cannot join channel '" .. channelName .. "'.", fromChannelName)
			end
		else
			speaker:SendSystemMessage("Channel '" .. channelName .. "' does not exist.", fromChannelName)
		end
	end
end

local function DoLeaveCommand(speakerName, channelName, fromChannelName)
	local speaker = ChatService:GetSpeaker(speakerName)
	local channel = ChatService:GetChannel(channelName)

	if (speaker) then
		if (speaker:IsInChannel(channelName)) then
			if (channel.Leavable) then
				speaker:LeaveChannel(channel.Name)
				speaker:SendSystemMessage(string.format("You have left channel '%s'", channel.Name), "System")
			else
				speaker:SendSystemMessage("You cannot leave channel '" .. channelName .. "'.", fromChannelName)
			end
		else
			speaker:SendSystemMessage("You are not in channel '" .. channelName .. "'.", fromChannelName)
		end
	end
end

ChatService:RegisterProcessCommandsFunction("default_commands", function(fromSpeaker, message, channel)
	if (string.sub(message, 1, 6):lower() == "/join ") then
		DoJoinCommand(fromSpeaker, string.sub(message, 7), channel)
		return true
	elseif (string.sub(message, 1, 3):lower() == "/j ") then
		DoJoinCommand(fromSpeaker, string.sub(message, 4), channel)
		return true

	elseif (string.sub(message, 1, 7):lower() == "/leave ") then
		DoLeaveCommand(fromSpeaker, string.sub(message, 8), channel)
		return true
	elseif (string.sub(message, 1, 3):lower() == "/l ") then
		DoLeaveCommand(fromSpeaker, string.sub(message, 4), channel)
		return true

	elseif (string.sub(message, 1, 3) == "/e " or string.sub(message, 1, 7) == "/emote ") then
		-- Just don't show these in the chatlog. The animation script listens on these.
		return true

	end

	return false
end)


local allChannel = ChatService:AddChannel("All")
local systemChannel = ChatService:AddChannel("System")

allChannel.Leavable = false
allChannel.AutoJoin = true

systemChannel.Leavable = false
systemChannel.AutoJoin = true
systemChannel.WelcomeMessage = "This channel is for system and game notifications."

systemChannel.SpeakerJoined:connect(function(speakerName)
	systemChannel:MuteSpeaker(speakerName)
end)


local function TryRunModule(module)
	if module:IsA("ModuleScript") then
		local ret = require(module)
		if (type(ret) == "function") then
			ret(ChatService)
		end
	end
end

local modules = game:GetService("Chat"):WaitForChild("ChatModules")
modules.ChildAdded:connect(function(child)
	local success, returnval = pcall(TryRunModule, child)
	if not success and returnval then
		print("Error running module " ..child.Name.. ": " ..returnval)
	end
end)

for i, module in pairs(modules:GetChildren()) do
	local success, returnval = pcall(TryRunModule, module)
	if not success and returnval then
		print("Error running module " ..module.Name.. ": " ..returnval)
	end
end

local Players = game:GetService("Players")
Players.PlayerRemoving:connect(function(playerObj)
	if (ChatService:GetSpeaker(playerObj.Name)) then
		ChatService:RemoveSpeaker(playerObj.Name)
	end
end)
