· 8 years ago · Mar 29, 2018, 08:54 PM
1
2--Converted with ttyyuu12345's model to script plugin v4
3function sandbox(var,func)
4 local env = getfenv(func)
5 local newenv = setmetatable({},{
6 __index = function(self,k)
7 if k=="script" then
8 return var
9 else
10 return env[k]
11 end
12 end,
13 })
14 setfenv(func,newenv)
15 return func
16end
17cors = {}
18mas = Instance.new("Model",game:GetService("Lighting"))
19BoolValue0 = Instance.new("BoolValue")
20Folder1 = Instance.new("Folder")
21BoolValue2 = Instance.new("BoolValue")
22Folder3 = Instance.new("Folder")
23BoolValue4 = Instance.new("BoolValue")
24Folder5 = Instance.new("Folder")
25BoolValue6 = Instance.new("BoolValue")
26Folder7 = Instance.new("Folder")
27Folder8 = Instance.new("Folder")
28BoolValue9 = Instance.new("BoolValue")
29Folder10 = Instance.new("Folder")
30BoolValue11 = Instance.new("BoolValue")
31Script12 = Instance.new("Script")
32LocalScript13 = Instance.new("LocalScript")
33LocalScript14 = Instance.new("LocalScript")
34BoolValue6.Name = "InsertDefaultModules"
35BoolValue6.Parent = Folder5
36BoolValue6.Value = true
37Folder10.Name = "CommandModules"
38Folder10.Parent = Folder7
39BoolValue11.Name = "InsertDefaultModules"
40BoolValue11.Parent = Folder10
41BoolValue11.Value = true
42Folder8.Name = "MessageCreatorModules"
43Folder8.Parent = Folder7
44BoolValue9.Name = "InsertDefaultModules"
45BoolValue9.Parent = Folder8
46BoolValue9.Value = true
47Folder5.Name = "ChatModules"
48Folder5.Parent = mas
49BoolValue6.Name = "InsertDefaultModules"
50BoolValue6.Parent = Folder5
51BoolValue6.Value = true
52Folder7.Name = "ClientChatModules"
53Folder7.Parent = mas
54Folder8.Name = "MessageCreatorModules"
55Folder8.Parent = Folder7
56BoolValue9.Name = "InsertDefaultModules"
57BoolValue9.Parent = Folder8
58BoolValue9.Value = true
59Folder10.Name = "CommandModules"
60Folder10.Parent = Folder7
61BoolValue11.Name = "InsertDefaultModules"
62BoolValue11.Parent = Folder10
63BoolValue11.Value = true
64Script12.Name = "ChatServiceRunner"
65Script12.Parent = mas
66table.insert(cors,sandbox(Script12,function()
67-- // FileName: ChatServiceRunner.lua
68-- // Written by: Xsitsu
69-- // Description: Main script to initialize ChatService and run ChatModules.
70
71local EventFolderName = "DefaultChatSystemChatEvents"
72local EventFolderParent = game:GetService("ReplicatedStorage")
73local modulesFolder = script
74
75local PlayersService = game:GetService("Players")
76local RunService = game:GetService("RunService")
77local Chat = game:GetService("Chat")
78
79local ChatService = require(modulesFolder:WaitForChild("ChatService"))
80
81local ReplicatedModules = Chat:WaitForChild("ClientChatModules")
82local ChatSettings = require(ReplicatedModules:WaitForChild("ChatSettings"))
83
84local ChatLocalization = nil
85pcall(function() ChatLocalization = require(Chat.ClientChatModules.ChatLocalization) end)
86if ChatLocalization == nil then ChatLocalization = { Get = function(key,default) return default end } end
87
88local useEvents = {}
89
90local EventFolder = EventFolderParent:FindFirstChild(EventFolderName)
91if (not EventFolder) then
92 EventFolder = Instance.new("Folder")
93 EventFolder.Name = EventFolderName
94 EventFolder.Archivable = false
95 EventFolder.Parent = EventFolderParent
96end
97
98--// No-opt connect Server>Client RemoteEvents to ensure they cannot be called
99--// to fill the remote event queue.
100local function emptyFunction()
101 --intentially empty
102end
103
104local function GetObjectWithNameAndType(parentObject, objectName, objectType)
105 for _, child in pairs(parentObject:GetChildren()) do
106 if (child:IsA(objectType) and child.Name == objectName) then
107 return child
108 end
109 end
110
111 return nil
112end
113
114local function CreateIfDoesntExist(parentObject, objectName, objectType)
115 local obj = GetObjectWithNameAndType(parentObject, objectName, objectType)
116 if (not obj) then
117 obj = Instance.new(objectType)
118 obj.Name = objectName
119 obj.Parent = parentObject
120 end
121 useEvents[objectName] = obj
122
123 return obj
124end
125
126--// All remote events will have a no-opt OnServerEvent connecdted on construction
127local function CreateEventIfItDoesntExist(parentObject, objectName)
128 local obj = CreateIfDoesntExist(parentObject, objectName, "RemoteEvent")
129 obj.OnServerEvent:Connect(emptyFunction)
130 return obj
131end
132
133CreateEventIfItDoesntExist(EventFolder, "OnNewMessage")
134CreateEventIfItDoesntExist(EventFolder, "OnMessageDoneFiltering")
135CreateEventIfItDoesntExist(EventFolder, "OnNewSystemMessage")
136CreateEventIfItDoesntExist(EventFolder, "OnChannelJoined")
137CreateEventIfItDoesntExist(EventFolder, "OnChannelLeft")
138CreateEventIfItDoesntExist(EventFolder, "OnMuted")
139CreateEventIfItDoesntExist(EventFolder, "OnUnmuted")
140CreateEventIfItDoesntExist(EventFolder, "OnMainChannelSet")
141CreateEventIfItDoesntExist(EventFolder, "ChannelNameColorUpdated")
142
143CreateEventIfItDoesntExist(EventFolder, "SayMessageRequest")
144CreateEventIfItDoesntExist(EventFolder, "SetBlockedUserIdsRequest")
145CreateIfDoesntExist(EventFolder, "GetInitDataRequest", "RemoteFunction")
146CreateIfDoesntExist(EventFolder, "MutePlayerRequest", "RemoteFunction")
147CreateIfDoesntExist(EventFolder, "UnMutePlayerRequest", "RemoteFunction")
148
149EventFolder = useEvents
150
151local function CreatePlayerSpeakerObject(playerObj)
152 --// If a developer already created a speaker object with the
153 --// name of a player and then a player joins and tries to
154 --// take that name, we first need to remove the old speaker object
155 local speaker = ChatService:GetSpeaker(playerObj.Name)
156 if (speaker) then
157 ChatService:RemoveSpeaker(playerObj.Name)
158 end
159
160 speaker = ChatService:InternalAddSpeakerWithPlayerObject(playerObj.Name, playerObj, false)
161
162 for _, channel in pairs(ChatService:GetAutoJoinChannelList()) do
163 speaker:JoinChannel(channel.Name)
164 end
165
166 speaker.ReceivedUnfilteredMessage:connect(function(messageObj, channel)
167 EventFolder.OnNewMessage:FireClient(playerObj, messageObj, channel)
168 end)
169
170 speaker.MessageDoneFiltering:connect(function(messageObj, channel)
171 EventFolder.OnMessageDoneFiltering:FireClient(playerObj, messageObj, channel)
172 end)
173
174 speaker.ReceivedSystemMessage:connect(function(messageObj, channel)
175 EventFolder.OnNewSystemMessage:FireClient(playerObj, messageObj, channel)
176 end)
177
178 speaker.ChannelJoined:connect(function(channel, welcomeMessage)
179 local log = nil
180 local channelNameColor = nil
181
182 local channelObject = ChatService:GetChannel(channel)
183 if (channelObject) then
184 log = channelObject:GetHistoryLogForSpeaker(speaker)
185 channelNameColor = channelObject.ChannelNameColor
186 end
187 EventFolder.OnChannelJoined:FireClient(playerObj, channel, welcomeMessage, log, channelNameColor)
188 end)
189
190 speaker.ChannelLeft:connect(function(channel)
191 EventFolder.OnChannelLeft:FireClient(playerObj, channel)
192 end)
193
194 speaker.Muted:connect(function(channel, reason, length)
195 EventFolder.OnMuted:FireClient(playerObj, channel, reason, length)
196 end)
197
198 speaker.Unmuted:connect(function(channel)
199 EventFolder.OnUnmuted:FireClient(playerObj, channel)
200 end)
201
202 speaker.MainChannelSet:connect(function(channel)
203 EventFolder.OnMainChannelSet:FireClient(playerObj, channel)
204 end)
205
206 speaker.ChannelNameColorUpdated:connect(function(channelName, channelNameColor)
207 EventFolder.ChannelNameColorUpdated:FireClient(playerObj, channelName, channelNameColor)
208 end)
209
210 ChatService:InternalFireSpeakerAdded(speaker.Name)
211end
212
213EventFolder.SayMessageRequest.OnServerEvent:connect(function(playerObj, message, channel)
214 if type(message) ~= "string" then
215 return
216 end
217 if type(channel) ~= "string" then
218 return
219 end
220
221 local speaker = ChatService:GetSpeaker(playerObj.Name)
222 if (speaker) then
223 return speaker:SayMessage(message, channel)
224 end
225
226 return nil
227end)
228
229EventFolder.MutePlayerRequest.OnServerInvoke = function(playerObj, muteSpeakerName)
230 if type(muteSpeakerName) ~= "string" then
231 return
232 end
233
234 local speaker = ChatService:GetSpeaker(playerObj.Name)
235 if speaker then
236 local muteSpeaker = ChatService:GetSpeaker(muteSpeakerName)
237 if muteSpeaker then
238 speaker:AddMutedSpeaker(muteSpeaker.Name)
239 return true
240 end
241 end
242 return false
243end
244
245EventFolder.UnMutePlayerRequest.OnServerInvoke = function(playerObj, unmuteSpeakerName)
246 if type(unmuteSpeakerName) ~= "string" then
247 return
248 end
249
250 local speaker = ChatService:GetSpeaker(playerObj.Name)
251 if speaker then
252 local unmuteSpeaker = ChatService:GetSpeaker(unmuteSpeakerName)
253 if unmuteSpeaker then
254 speaker:RemoveMutedSpeaker(unmuteSpeaker.Name)
255 return true
256 end
257 end
258 return false
259end
260
261-- Map storing Player -> Blocked user Ids.
262local BlockedUserIdsMap = {}
263
264PlayersService.PlayerAdded:connect(function(newPlayer)
265 for player, blockedUsers in pairs(BlockedUserIdsMap) do
266 local speaker = ChatService:GetSpeaker(player.Name)
267 if speaker then
268 for i = 1, #blockedUsers do
269 local blockedUserId = blockedUsers[i]
270 if blockedUserId == newPlayer.UserId then
271 speaker:AddMutedSpeaker(newPlayer.Name)
272 end
273 end
274 end
275 end
276end)
277
278PlayersService.PlayerRemoving:connect(function(removingPlayer)
279 BlockedUserIdsMap[removingPlayer] = nil
280end)
281
282EventFolder.SetBlockedUserIdsRequest.OnServerEvent:connect(function(player, blockedUserIdsList)
283 if type(blockedUserIdsList) ~= "table" then
284 return
285 end
286
287 BlockedUserIdsMap[player] = blockedUserIdsList
288 local speaker = ChatService:GetSpeaker(player.Name)
289 if speaker then
290 for i = 1, #blockedUserIdsList do
291 if type(blockedUserIdsList[i]) == "number" then
292 local blockedPlayer = PlayersService:GetPlayerByUserId(blockedUserIdsList[i])
293 if blockedPlayer then
294 speaker:AddMutedSpeaker(blockedPlayer.Name)
295 end
296 end
297 end
298 end
299end)
300
301EventFolder.GetInitDataRequest.OnServerInvoke = (function(playerObj)
302 local speaker = ChatService:GetSpeaker(playerObj.Name)
303 if not (speaker and speaker:GetPlayer()) then
304 CreatePlayerSpeakerObject(playerObj)
305 speaker = ChatService:GetSpeaker(playerObj.Name)
306 end
307
308 local data = {}
309 data.Channels = {}
310 data.SpeakerExtraData = {}
311
312 for _, channelName in pairs(speaker:GetChannelList()) do
313 local channelObj = ChatService:GetChannel(channelName)
314 if (channelObj) then
315 local channelData =
316 {
317 channelName,
318 channelObj:GetWelcomeMessageForSpeaker(speaker),
319 channelObj:GetHistoryLogForSpeaker(speaker),
320 channelObj.ChannelNameColor,
321 }
322
323 table.insert(data.Channels, channelData)
324 end
325 end
326
327 for _, oSpeakerName in pairs(ChatService:GetSpeakerList()) do
328 local oSpeaker = ChatService:GetSpeaker(oSpeakerName)
329 data.SpeakerExtraData[oSpeakerName] = oSpeaker.ExtraData
330 end
331
332 return data
333end)
334
335local function DoJoinCommand(speakerName, channelName, fromChannelName)
336 local speaker = ChatService:GetSpeaker(speakerName)
337 local channel = ChatService:GetChannel(channelName)
338
339 if (speaker) then
340 if (channel) then
341 if (channel.Joinable) then
342 if (not speaker:IsInChannel(channel.Name)) then
343 speaker:JoinChannel(channel.Name)
344 else
345 speaker:SetMainChannel(channel.Name)
346 speaker:SendSystemMessage(
347 string.gsub(
348 ChatLocalization:Get(
349 "GameChat_SwitchChannel_NowInChannel",
350 string.format("You are now chatting in channel: '%s'", channel.Name)
351 ),
352 "{RBX_NAME}",channel.Name),
353 channel.Name
354 )
355 end
356 else
357 speaker:SendSystemMessage(
358 string.gsub(
359 ChatLocalization:Get(
360 "GameChat_ChatServiceRunner_YouCannotJoinChannel",
361 ("You cannot join channel '" .. channelName .. "'.")
362 ),
363 "{RBX_NAME}",channelName),
364 fromChannelName
365 )
366 end
367 else
368 speaker:SendSystemMessage(
369 string.gsub(
370 ChatLocalization:Get(
371 "GameChat_ChatServiceRunner_ChannelDoesNotExist",
372 ("Channel '" .. channelName .. "' does not exist.")
373 ),
374 "{RBX_NAME}",channelName),
375 fromChannelName
376 )
377 end
378 end
379end
380
381local function DoLeaveCommand(speakerName, channelName, fromChannelName)
382 local speaker = ChatService:GetSpeaker(speakerName)
383 local channel = ChatService:GetChannel(channelName)
384
385 if (speaker) then
386 if (speaker:IsInChannel(channelName)) then
387 if (channel.Leavable) then
388 speaker:LeaveChannel(channel.Name)
389 speaker:SendSystemMessage(
390 string.gsub(
391 ChatLocalization:Get(
392 "GameChat_ChatService_YouHaveLeftChannel",
393 string.format("You have left channel '%s'", channelName)
394 ),
395 "{RBX_NAME}",channel.Name),
396 "System"
397 )
398 else
399 speaker:SendSystemMessage(
400 string.gsub(
401 ChatLocalization:Get(
402 "GameChat_ChatServiceRunner_YouCannotLeaveChannel",
403 ("You cannot leave channel '" .. channelName .. "'.")
404 ),
405 "{RBX_NAME}",channelName),
406 fromChannelName
407 )
408 end
409 else
410 speaker:SendSystemMessage(
411 string.gsub(
412 ChatLocalization:Get(
413 "GameChat_ChatServiceRunner_YouAreNotInChannel",
414 ("You are not in channel '" .. channelName .. "'.")
415 ),
416 "{RBX_NAME}",channelName),
417 fromChannelName
418 )
419 end
420 end
421end
422
423ChatService:RegisterProcessCommandsFunction("default_commands", function(fromSpeaker, message, channel)
424 if (string.sub(message, 1, 6):lower() == "/join ") then
425 DoJoinCommand(fromSpeaker, string.sub(message, 7), channel)
426 return true
427 elseif (string.sub(message, 1, 3):lower() == "/j ") then
428 DoJoinCommand(fromSpeaker, string.sub(message, 4), channel)
429 return true
430
431 elseif (string.sub(message, 1, 7):lower() == "/leave ") then
432 DoLeaveCommand(fromSpeaker, string.sub(message, 8), channel)
433 return true
434 elseif (string.sub(message, 1, 3):lower() == "/l ") then
435 DoLeaveCommand(fromSpeaker, string.sub(message, 4), channel)
436 return true
437
438 elseif (string.sub(message, 1, 3) == "/e " or string.sub(message, 1, 7) == "/emote ") then
439 -- Just don't show these in the chatlog. The animation script listens on these.
440 return true
441
442 end
443
444 return false
445end)
446
447if ChatSettings.GeneralChannelName and ChatSettings.GeneralChannelName ~= "" then
448 local allChannel = ChatService:AddChannel(ChatSettings.GeneralChannelName)
449
450 allChannel.Leavable = false
451 allChannel.AutoJoin = true
452
453 allChannel:RegisterGetWelcomeMessageFunction(function(speaker)
454 if RunService:IsStudio() then
455 return nil
456 end
457 local player = speaker:GetPlayer()
458 if player then
459 local success, canChat = pcall(function()
460 return Chat:CanUserChatAsync(player.UserId)
461 end)
462 if success and not canChat then
463 return ""
464 end
465 end
466 end)
467end
468
469local systemChannel = ChatService:AddChannel("System")
470systemChannel.Leavable = false
471systemChannel.AutoJoin = true
472systemChannel.WelcomeMessage = ChatLocalization:Get(
473 "GameChat_ChatServiceRunner_SystemChannelWelcomeMessage", "This channel is for system and game notifications."
474)
475
476systemChannel.SpeakerJoined:connect(function(speakerName)
477 systemChannel:MuteSpeaker(speakerName)
478end)
479
480
481local function TryRunModule(module)
482 if module:IsA("ModuleScript") then
483 local ret = require(module)
484 if (type(ret) == "function") then
485 ret(ChatService)
486 end
487 end
488end
489
490local modules = Chat:WaitForChild("ChatModules")
491modules.ChildAdded:connect(function(child)
492 local success, returnval = pcall(TryRunModule, child)
493 if not success and returnval then
494 print("Error running module " ..child.Name.. ": " ..returnval)
495 end
496end)
497
498for _, module in pairs(modules:GetChildren()) do
499 local success, returnval = pcall(TryRunModule, module)
500 if not success and returnval then
501 print("Error running module " ..module.Name.. ": " ..returnval)
502 end
503end
504
505PlayersService.PlayerRemoving:connect(function(playerObj)
506 if (ChatService:GetSpeaker(playerObj.Name)) then
507 ChatService:RemoveSpeaker(playerObj.Name)
508 end
509end)
510
511end))
512LocalScript13.Name = "BubbleChat"
513LocalScript13.Parent = mas
514table.insert(cors,sandbox(LocalScript13,function()
515--[[
516 // FileName: BubbleChat.lua
517 // Written by: jeditkacheff, TheGamer101
518 // Description: Code for rendering bubble chat
519]]
520
521--[[ SERVICES ]]
522local PlayersService = game:GetService('Players')
523local ReplicatedStorage = game:GetService("ReplicatedStorage")
524local ChatService = game:GetService("Chat")
525local TextService = game:GetService("TextService")
526--[[ END OF SERVICES ]]
527
528local LocalPlayer = PlayersService.LocalPlayer
529while LocalPlayer == nil do
530 PlayersService.ChildAdded:wait()
531 LocalPlayer = PlayersService.LocalPlayer
532end
533
534local PlayerGui = LocalPlayer:WaitForChild("PlayerGui")
535
536local okShouldClipInGameChat, valueShouldClipInGameChat = pcall(function() return UserSettings():IsUserFeatureEnabled("UserShouldClipInGameChat") end)
537local shouldClipInGameChat = okShouldClipInGameChat and valueShouldClipInGameChat
538
539--[[ SCRIPT VARIABLES ]]
540local CHAT_BUBBLE_FONT = Enum.Font.SourceSans
541local CHAT_BUBBLE_FONT_SIZE = Enum.FontSize.Size24 -- if you change CHAT_BUBBLE_FONT_SIZE_INT please change this to match
542local CHAT_BUBBLE_FONT_SIZE_INT = 24 -- if you change CHAT_BUBBLE_FONT_SIZE please change this to match
543local CHAT_BUBBLE_LINE_HEIGHT = CHAT_BUBBLE_FONT_SIZE_INT + 10
544local CHAT_BUBBLE_TAIL_HEIGHT = 14
545local CHAT_BUBBLE_WIDTH_PADDING = 30
546local CHAT_BUBBLE_FADE_SPEED = 1.5
547
548local BILLBOARD_MAX_WIDTH = 400
549local BILLBOARD_MAX_HEIGHT = 250 --This limits the number of bubble chats that you see above characters
550
551local ELIPSES = "..."
552local MaxChatMessageLength = 128 -- max chat message length, including null terminator and elipses.
553local MaxChatMessageLengthExclusive = MaxChatMessageLength - string.len(ELIPSES) - 1
554
555local NEAR_BUBBLE_DISTANCE = 65 --previously 45
556local MAX_BUBBLE_DISTANCE = 100 --previously 80
557
558--[[ END OF SCRIPT VARIABLES ]]
559
560
561-- [[ SCRIPT ENUMS ]]
562local BubbleColor = { WHITE = "dub",
563 BLUE = "blu",
564 GREEN = "gre",
565 RED = "red" }
566
567--[[ END OF SCRIPT ENUMS ]]
568
569-- This screenGui exists so that the billboardGui is not deleted when the PlayerGui is reset.
570local BubbleChatScreenGui = Instance.new("ScreenGui")
571BubbleChatScreenGui.Name = "BubbleChat"
572BubbleChatScreenGui.ResetOnSpawn = false
573BubbleChatScreenGui.Parent = PlayerGui
574
575--[[ FUNCTIONS ]]
576
577local function lerpLength(msg, min, max)
578 return min + (max-min) * math.min(string.len(msg)/75.0, 1.0)
579end
580
581local function createFifo()
582 local this = {}
583 this.data = {}
584
585 local emptyEvent = Instance.new("BindableEvent")
586 this.Emptied = emptyEvent.Event
587
588 function this:Size()
589 return #this.data
590 end
591
592 function this:Empty()
593 return this:Size() <= 0
594 end
595
596 function this:PopFront()
597 table.remove(this.data, 1)
598 if this:Empty() then emptyEvent:Fire() end
599 end
600
601 function this:Front()
602 return this.data[1]
603 end
604
605 function this:Get(index)
606 return this.data[index]
607 end
608
609 function this:PushBack(value)
610 table.insert(this.data, value)
611 end
612
613 function this:GetData()
614 return this.data
615 end
616
617 return this
618end
619
620local function createCharacterChats()
621 local this = {}
622
623 this.Fifo = createFifo()
624 this.BillboardGui = nil
625
626 return this
627end
628
629local function createMap()
630 local this = {}
631 this.data = {}
632 local count = 0
633
634 function this:Size()
635 return count
636 end
637
638 function this:Erase(key)
639 if this.data[key] then count = count - 1 end
640 this.data[key] = nil
641 end
642
643 function this:Set(key, value)
644 this.data[key] = value
645 if value then count = count + 1 end
646 end
647
648 function this:Get(key)
649 if not key then return end
650 if not this.data[key] then
651 this.data[key] = createCharacterChats()
652 local emptiedCon = nil
653 emptiedCon = this.data[key].Fifo.Emptied:connect(function()
654 emptiedCon:disconnect()
655 this:Erase(key)
656 end)
657 end
658 return this.data[key]
659 end
660
661 function this:GetData()
662 return this.data
663 end
664
665 return this
666end
667
668local function createChatLine(message, bubbleColor, isLocalPlayer)
669 local this = {}
670
671 function this:ComputeBubbleLifetime(msg, isSelf)
672 if isSelf then
673 return lerpLength(msg,8,15)
674 else
675 return lerpLength(msg,12,20)
676 end
677 end
678
679 this.Origin = nil
680 this.RenderBubble = nil
681 this.Message = message
682 this.BubbleDieDelay = this:ComputeBubbleLifetime(message, isLocalPlayer)
683 this.BubbleColor = bubbleColor
684 this.IsLocalPlayer = isLocalPlayer
685
686 return this
687end
688
689local function createPlayerChatLine(player, message, isLocalPlayer)
690 local this = createChatLine(message, BubbleColor.WHITE, isLocalPlayer)
691
692 if player then
693 this.User = player.Name
694 this.Origin = player.Character
695 end
696
697 return this
698end
699
700local function createGameChatLine(origin, message, isLocalPlayer, bubbleColor)
701 local this = createChatLine(message, bubbleColor, isLocalPlayer)
702 this.Origin = origin
703
704 return this
705end
706
707function createChatBubbleMain(filePrefix, sliceRect)
708 local chatBubbleMain = Instance.new("ImageLabel")
709 chatBubbleMain.Name = "ChatBubble"
710 chatBubbleMain.ScaleType = Enum.ScaleType.Slice
711 chatBubbleMain.SliceCenter = sliceRect
712 chatBubbleMain.Image = "rbxasset://textures/" .. tostring(filePrefix) .. ".png"
713 chatBubbleMain.BackgroundTransparency = 1
714 chatBubbleMain.BorderSizePixel = 0
715 chatBubbleMain.Size = UDim2.new(1.0, 0, 1.0, 0)
716 chatBubbleMain.Position = UDim2.new(0,0,0,0)
717
718 return chatBubbleMain
719end
720
721function createChatBubbleTail(position, size)
722 local chatBubbleTail = Instance.new("ImageLabel")
723 chatBubbleTail.Name = "ChatBubbleTail"
724 chatBubbleTail.Image = "rbxasset://textures/ui/dialog_tail.png"
725 chatBubbleTail.BackgroundTransparency = 1
726 chatBubbleTail.BorderSizePixel = 0
727 chatBubbleTail.Position = position
728 chatBubbleTail.Size = size
729
730 return chatBubbleTail
731end
732
733function createChatBubbleWithTail(filePrefix, position, size, sliceRect)
734 local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
735
736 local chatBubbleTail = createChatBubbleTail(position, size)
737 chatBubbleTail.Parent = chatBubbleMain
738
739 return chatBubbleMain
740end
741
742function createScaledChatBubbleWithTail(filePrefix, frameScaleSize, position, sliceRect)
743 local chatBubbleMain = createChatBubbleMain(filePrefix, sliceRect)
744
745 local frame = Instance.new("Frame")
746 frame.Name = "ChatBubbleTailFrame"
747 frame.BackgroundTransparency = 1
748 frame.SizeConstraint = Enum.SizeConstraint.RelativeXX
749 frame.Position = UDim2.new(0.5, 0, 1, 0)
750 frame.Size = UDim2.new(frameScaleSize, 0, frameScaleSize, 0)
751 frame.Parent = chatBubbleMain
752
753 local chatBubbleTail = createChatBubbleTail(position, UDim2.new(1,0,0.5,0))
754 chatBubbleTail.Parent = frame
755
756 return chatBubbleMain
757end
758
759function createChatImposter(filePrefix, dotDotDot, yOffset)
760 local result = Instance.new("ImageLabel")
761 result.Name = "DialogPlaceholder"
762 result.Image = "rbxasset://textures/" .. tostring(filePrefix) .. ".png"
763 result.BackgroundTransparency = 1
764 result.BorderSizePixel = 0
765 result.Position = UDim2.new(0, 0, -1.25, 0)
766 result.Size = UDim2.new(1, 0, 1, 0)
767
768 local image = Instance.new("ImageLabel")
769 image.Name = "DotDotDot"
770 image.Image = "rbxasset://textures/" .. tostring(dotDotDot) .. ".png"
771 image.BackgroundTransparency = 1
772 image.BorderSizePixel = 0
773 image.Position = UDim2.new(0.001, 0, yOffset, 0)
774 image.Size = UDim2.new(1, 0, 0.7, 0)
775 image.Parent = result
776
777 return result
778end
779
780
781local this = {}
782this.ChatBubble = {}
783this.ChatBubbleWithTail = {}
784this.ScalingChatBubbleWithTail = {}
785this.CharacterSortedMsg = createMap()
786
787-- init chat bubble tables
788local function initChatBubbleType(chatBubbleType, fileName, imposterFileName, isInset, sliceRect)
789 this.ChatBubble[chatBubbleType] = createChatBubbleMain(fileName, sliceRect)
790 this.ChatBubbleWithTail[chatBubbleType] = createChatBubbleWithTail(fileName, UDim2.new(0.5, -CHAT_BUBBLE_TAIL_HEIGHT, 1, isInset and -1 or 0), UDim2.new(0, 30, 0, CHAT_BUBBLE_TAIL_HEIGHT), sliceRect)
791 this.ScalingChatBubbleWithTail[chatBubbleType] = createScaledChatBubbleWithTail(fileName, 0.5, UDim2.new(-0.5, 0, 0, isInset and -1 or 0), sliceRect)
792end
793
794initChatBubbleType(BubbleColor.WHITE, "ui/dialog_white", "ui/chatBubble_white_notify_bkg", false, Rect.new(5,5,15,15))
795initChatBubbleType(BubbleColor.BLUE, "ui/dialog_blue", "ui/chatBubble_blue_notify_bkg", true, Rect.new(7,7,33,33))
796initChatBubbleType(BubbleColor.RED, "ui/dialog_red", "ui/chatBubble_red_notify_bkg", true, Rect.new(7,7,33,33))
797initChatBubbleType(BubbleColor.GREEN, "ui/dialog_green", "ui/chatBubble_green_notify_bkg", true, Rect.new(7,7,33,33))
798
799function this:SanitizeChatLine(msg)
800 if string.len(msg) > MaxChatMessageLengthExclusive then
801 return string.sub(msg, 1, MaxChatMessageLengthExclusive + string.len(ELIPSES))
802 else
803 return msg
804 end
805end
806
807local function createBillboardInstance(adornee)
808 local billboardGui = Instance.new("BillboardGui")
809 billboardGui.Adornee = adornee
810 billboardGui.Size = UDim2.new(0,BILLBOARD_MAX_WIDTH,0,BILLBOARD_MAX_HEIGHT)
811 billboardGui.StudsOffset = Vector3.new(0, 1.5, 2)
812 billboardGui.Parent = BubbleChatScreenGui
813
814 local billboardFrame = Instance.new("Frame")
815 billboardFrame.Name = "BillboardFrame"
816 billboardFrame.Size = UDim2.new(1,0,1,0)
817 billboardFrame.Position = UDim2.new(0,0,-0.5,0)
818 billboardFrame.BackgroundTransparency = 1
819 billboardFrame.Parent = billboardGui
820
821 local billboardChildRemovedCon = nil
822 billboardChildRemovedCon = billboardFrame.ChildRemoved:connect(function()
823 if #billboardFrame:GetChildren() <= 1 then
824 billboardChildRemovedCon:disconnect()
825 billboardGui:Destroy()
826 end
827 end)
828
829 this:CreateSmallTalkBubble(BubbleColor.WHITE).Parent = billboardFrame
830
831 return billboardGui
832end
833
834function this:CreateBillboardGuiHelper(instance, onlyCharacter)
835 if instance and not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
836 if not onlyCharacter then
837 if instance:IsA("BasePart") then
838 -- Create a new billboardGui object attached to this player
839 local billboardGui = createBillboardInstance(instance)
840 this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
841 return
842 end
843 end
844
845 if instance:IsA("Model") then
846 local head = instance:FindFirstChild("Head")
847 if head and head:IsA("BasePart") then
848 -- Create a new billboardGui object attached to this player
849 local billboardGui = createBillboardInstance(head)
850 this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
851 end
852 end
853 end
854end
855
856local function distanceToBubbleOrigin(origin)
857 if not origin then return 100000 end
858
859 return (origin.Position - game.Workspace.CurrentCamera.CoordinateFrame.p).magnitude
860end
861
862local function isPartOfLocalPlayer(adornee)
863 if adornee and PlayersService.LocalPlayer.Character then
864 return adornee:IsDescendantOf(PlayersService.LocalPlayer.Character)
865 end
866end
867
868function this:SetBillboardLODNear(billboardGui)
869 local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
870 billboardGui.Size = UDim2.new(0, BILLBOARD_MAX_WIDTH, 0, BILLBOARD_MAX_HEIGHT)
871 billboardGui.StudsOffset = Vector3.new(0, isLocalPlayer and 1.5 or 2.5, isLocalPlayer and 2 or 0.1)
872 billboardGui.Enabled = true
873 local billChildren = billboardGui.BillboardFrame:GetChildren()
874 for i = 1, #billChildren do
875 billChildren[i].Visible = true
876 end
877 billboardGui.BillboardFrame.SmallTalkBubble.Visible = false
878end
879
880function this:SetBillboardLODDistant(billboardGui)
881 local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
882 billboardGui.Size = UDim2.new(4,0,3,0)
883 billboardGui.StudsOffset = Vector3.new(0, 3, isLocalPlayer and 2 or 0.1)
884 billboardGui.Enabled = true
885 local billChildren = billboardGui.BillboardFrame:GetChildren()
886 for i = 1, #billChildren do
887 billChildren[i].Visible = false
888 end
889 billboardGui.BillboardFrame.SmallTalkBubble.Visible = true
890end
891
892function this:SetBillboardLODVeryFar(billboardGui)
893 billboardGui.Enabled = false
894end
895
896function this:SetBillboardGuiLOD(billboardGui, origin)
897 if not origin then return end
898
899 if origin:IsA("Model") then
900 local head = origin:FindFirstChild("Head")
901 if not head then origin = origin.PrimaryPart
902 else origin = head end
903 end
904
905 local bubbleDistance = distanceToBubbleOrigin(origin)
906
907 if bubbleDistance < NEAR_BUBBLE_DISTANCE then
908 this:SetBillboardLODNear(billboardGui)
909 elseif bubbleDistance >= NEAR_BUBBLE_DISTANCE and bubbleDistance < MAX_BUBBLE_DISTANCE then
910 this:SetBillboardLODDistant(billboardGui)
911 else
912 this:SetBillboardLODVeryFar(billboardGui)
913 end
914end
915
916function this:CameraCFrameChanged()
917 for index, value in pairs(this.CharacterSortedMsg:GetData()) do
918 local playerBillboardGui = value["BillboardGui"]
919 if playerBillboardGui then this:SetBillboardGuiLOD(playerBillboardGui, index) end
920 end
921end
922
923function this:CreateBubbleText(message)
924 local bubbleText = Instance.new("TextLabel")
925 bubbleText.Name = "BubbleText"
926 bubbleText.BackgroundTransparency = 1
927 bubbleText.Position = UDim2.new(0,CHAT_BUBBLE_WIDTH_PADDING/2,0,0)
928 bubbleText.Size = UDim2.new(1,-CHAT_BUBBLE_WIDTH_PADDING,1,0)
929 bubbleText.Font = CHAT_BUBBLE_FONT
930 if shouldClipInGameChat then
931 bubbleText.ClipsDescendants = true
932 end
933 bubbleText.TextWrapped = true
934 bubbleText.FontSize = CHAT_BUBBLE_FONT_SIZE
935 bubbleText.Text = message
936 bubbleText.Visible = false
937
938 return bubbleText
939end
940
941function this:CreateSmallTalkBubble(chatBubbleType)
942 local smallTalkBubble = this.ScalingChatBubbleWithTail[chatBubbleType]:Clone()
943 smallTalkBubble.Name = "SmallTalkBubble"
944 smallTalkBubble.AnchorPoint = Vector2.new(0, 0.5)
945 smallTalkBubble.Position = UDim2.new(0,0,0.5,0)
946 smallTalkBubble.Visible = false
947 local text = this:CreateBubbleText("...")
948 text.TextScaled = true
949 text.TextWrapped = false
950 text.Visible = true
951 text.Parent = smallTalkBubble
952
953 return smallTalkBubble
954end
955
956function this:UpdateChatLinesForOrigin(origin, currentBubbleYPos)
957 local bubbleQueue = this.CharacterSortedMsg:Get(origin).Fifo
958 local bubbleQueueSize = bubbleQueue:Size()
959 local bubbleQueueData = bubbleQueue:GetData()
960 if #bubbleQueueData <= 1 then return end
961
962 for index = (#bubbleQueueData - 1), 1, -1 do
963 local value = bubbleQueueData[index]
964 local bubble = value.RenderBubble
965 if not bubble then return end
966 local bubblePos = bubbleQueueSize - index + 1
967
968 if bubblePos > 1 then
969 local tail = bubble:FindFirstChild("ChatBubbleTail")
970 if tail then tail:Destroy() end
971 local bubbleText = bubble:FindFirstChild("BubbleText")
972 if bubbleText then bubbleText.TextTransparency = 0.5 end
973 end
974
975 local udimValue = UDim2.new( bubble.Position.X.Scale, bubble.Position.X.Offset,
976 1, currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT )
977 bubble:TweenPosition(udimValue, Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.1, true)
978 currentBubbleYPos = currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT
979 end
980end
981
982function this:DestroyBubble(bubbleQueue, bubbleToDestroy)
983 if not bubbleQueue then return end
984 if bubbleQueue:Empty() then return end
985
986 local bubble = bubbleQueue:Front().RenderBubble
987 if not bubble then
988 bubbleQueue:PopFront()
989 return
990 end
991
992 spawn(function()
993 while bubbleQueue:Front().RenderBubble ~= bubbleToDestroy do
994 wait()
995 end
996
997 bubble = bubbleQueue:Front().RenderBubble
998
999 local timeBetween = 0
1000 local bubbleText = bubble:FindFirstChild("BubbleText")
1001 local bubbleTail = bubble:FindFirstChild("ChatBubbleTail")
1002
1003 while bubble and bubble.ImageTransparency < 1 do
1004 timeBetween = wait()
1005 if bubble then
1006 local fadeAmount = timeBetween * CHAT_BUBBLE_FADE_SPEED
1007 bubble.ImageTransparency = bubble.ImageTransparency + fadeAmount
1008 if bubbleText then bubbleText.TextTransparency = bubbleText.TextTransparency + fadeAmount end
1009 if bubbleTail then bubbleTail.ImageTransparency = bubbleTail.ImageTransparency + fadeAmount end
1010 end
1011 end
1012
1013 if bubble then
1014 bubble:Destroy()
1015 bubbleQueue:PopFront()
1016 end
1017 end)
1018end
1019
1020function this:CreateChatLineRender(instance, line, onlyCharacter, fifo)
1021 if not instance then return end
1022
1023 if not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
1024 this:CreateBillboardGuiHelper(instance, onlyCharacter)
1025 end
1026
1027 local billboardGui = this.CharacterSortedMsg:Get(instance)["BillboardGui"]
1028 if billboardGui then
1029 local chatBubbleRender = this.ChatBubbleWithTail[line.BubbleColor]:Clone()
1030 chatBubbleRender.Visible = false
1031 local bubbleText = this:CreateBubbleText(line.Message)
1032
1033 bubbleText.Parent = chatBubbleRender
1034 chatBubbleRender.Parent = billboardGui.BillboardFrame
1035
1036 line.RenderBubble = chatBubbleRender
1037
1038 local currentTextBounds = TextService:GetTextSize(
1039 bubbleText.Text, CHAT_BUBBLE_FONT_SIZE_INT, CHAT_BUBBLE_FONT,
1040 Vector2.new(BILLBOARD_MAX_WIDTH, BILLBOARD_MAX_HEIGHT))
1041 local bubbleWidthScale = math.max((currentTextBounds.X + CHAT_BUBBLE_WIDTH_PADDING)/BILLBOARD_MAX_WIDTH, 0.1)
1042 local numOflines = (currentTextBounds.Y/CHAT_BUBBLE_FONT_SIZE_INT)
1043
1044 -- prep chat bubble for tween
1045 chatBubbleRender.Size = UDim2.new(0,0,0,0)
1046 chatBubbleRender.Position = UDim2.new(0.5,0,1,0)
1047
1048 local newChatBubbleOffsetSizeY = numOflines * CHAT_BUBBLE_LINE_HEIGHT
1049
1050 chatBubbleRender:TweenSizeAndPosition(UDim2.new(bubbleWidthScale, 0, 0, newChatBubbleOffsetSizeY),
1051 UDim2.new( (1-bubbleWidthScale)/2, 0, 1, -newChatBubbleOffsetSizeY),
1052 Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true,
1053 function() bubbleText.Visible = true end)
1054
1055 -- todo: remove when over max bubbles
1056 this:SetBillboardGuiLOD(billboardGui, line.Origin)
1057 this:UpdateChatLinesForOrigin(line.Origin, -newChatBubbleOffsetSizeY)
1058
1059 delay(line.BubbleDieDelay, function()
1060 this:DestroyBubble(fifo, chatBubbleRender)
1061 end)
1062 end
1063end
1064
1065function this:OnPlayerChatMessage(sourcePlayer, message, targetPlayer)
1066 if not this:BubbleChatEnabled() then return end
1067
1068 local localPlayer = PlayersService.LocalPlayer
1069 local fromOthers = localPlayer ~= nil and sourcePlayer ~= localPlayer
1070
1071 local safeMessage = this:SanitizeChatLine(message)
1072
1073 local line = createPlayerChatLine(sourcePlayer, safeMessage, not fromOthers)
1074
1075 if sourcePlayer and line.Origin then
1076 local fifo = this.CharacterSortedMsg:Get(line.Origin).Fifo
1077 fifo:PushBack(line)
1078 --Game chat (badges) won't show up here
1079 this:CreateChatLineRender(sourcePlayer.Character, line, true, fifo)
1080 end
1081end
1082
1083function this:OnGameChatMessage(origin, message, color)
1084 local localPlayer = PlayersService.LocalPlayer
1085 local fromOthers = localPlayer ~= nil and (localPlayer.Character ~= origin)
1086
1087 local bubbleColor = BubbleColor.WHITE
1088
1089 if color == Enum.ChatColor.Blue then bubbleColor = BubbleColor.BLUE
1090 elseif color == Enum.ChatColor.Green then bubbleColor = BubbleColor.GREEN
1091 elseif color == Enum.ChatColor.Red then bubbleColor = BubbleColor.RED end
1092
1093 local safeMessage = this:SanitizeChatLine(message)
1094 local line = createGameChatLine(origin, safeMessage, not fromOthers, bubbleColor)
1095
1096 this.CharacterSortedMsg:Get(line.Origin).Fifo:PushBack(line)
1097 this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo)
1098end
1099
1100function this:BubbleChatEnabled()
1101 local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
1102 if clientChatModules then
1103 local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
1104 if chatSettings then
1105 local chatSettings = require(chatSettings)
1106 if chatSettings.BubbleChatEnabled ~= nil then
1107 return chatSettings.BubbleChatEnabled
1108 end
1109 end
1110 end
1111 return PlayersService.BubbleChat
1112end
1113
1114function this:ShowOwnFilteredMessage()
1115 local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
1116 if clientChatModules then
1117 local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
1118 if chatSettings then
1119 chatSettings = require(chatSettings)
1120 return chatSettings.ShowUserOwnFilteredMessage
1121 end
1122 end
1123 return false
1124end
1125
1126function findPlayer(playerName)
1127 for i,v in pairs(PlayersService:GetPlayers()) do
1128 if v.Name == playerName then
1129 return v
1130 end
1131 end
1132end
1133
1134ChatService.Chatted:connect(function(origin, message, color) this:OnGameChatMessage(origin, message, color) end)
1135
1136local cameraChangedCon = nil
1137if game.Workspace.CurrentCamera then
1138 cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
1139end
1140
1141game.Workspace.Changed:connect(function(prop)
1142 if prop == "CurrentCamera" then
1143 if cameraChangedCon then cameraChangedCon:disconnect() end
1144 if game.Workspace.CurrentCamera then
1145 cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
1146 end
1147 end
1148end)
1149
1150
1151local AllowedMessageTypes = nil
1152
1153function getAllowedMessageTypes()
1154 if AllowedMessageTypes then
1155 return AllowedMessageTypes
1156 end
1157 local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
1158 if clientChatModules then
1159 local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
1160 if chatSettings then
1161 chatSettings = require(chatSettings)
1162 if chatSettings.BubbleChatMessageTypes then
1163 AllowedMessageTypes = chatSettings.BubbleChatMessageTypes
1164 return AllowedMessageTypes
1165 end
1166 end
1167 local chatConstants = clientChatModules:FindFirstChild("ChatConstants")
1168 if chatConstants then
1169 chatConstants = require(chatConstants)
1170 AllowedMessageTypes = {chatConstants.MessageTypeDefault, chatConstants.MessageTypeWhisper}
1171 end
1172 return AllowedMessageTypes
1173 end
1174 return {"Message", "Whisper"}
1175end
1176
1177function checkAllowedMessageType(messageData)
1178 local allowedMessageTypes = getAllowedMessageTypes()
1179 for i = 1, #allowedMessageTypes do
1180 if allowedMessageTypes[i] == messageData.MessageType then
1181 return true
1182 end
1183 end
1184 return false
1185end
1186
1187local ChatEvents = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents")
1188local OnMessageDoneFiltering = ChatEvents:WaitForChild("OnMessageDoneFiltering")
1189local OnNewMessage = ChatEvents:WaitForChild("OnNewMessage")
1190
1191OnNewMessage.OnClientEvent:connect(function(messageData, channelName)
1192 if not checkAllowedMessageType(messageData) then
1193 return
1194 end
1195
1196 local sender = findPlayer(messageData.FromSpeaker)
1197 if not sender then
1198 return
1199 end
1200
1201 if not messageData.IsFiltered or messageData.FromSpeaker == LocalPlayer.Name then
1202 if messageData.FromSpeaker ~= LocalPlayer.Name or this:ShowOwnFilteredMessage() then
1203 return
1204 end
1205 end
1206
1207 this:OnPlayerChatMessage(sender, messageData.Message, nil)
1208end)
1209
1210OnMessageDoneFiltering.OnClientEvent:connect(function(messageData, channelName)
1211 if not checkAllowedMessageType(messageData) then
1212 return
1213 end
1214
1215 local sender = findPlayer(messageData.FromSpeaker)
1216 if not sender then
1217 return
1218 end
1219
1220 if messageData.FromSpeaker == LocalPlayer.Name and not this:ShowOwnFilteredMessage() then
1221 return
1222 end
1223
1224 this:OnPlayerChatMessage(sender, messageData.Message, nil)
1225end)
1226
1227end))
1228LocalScript14.Name = "ChatScript"
1229LocalScript14.Parent = mas
1230table.insert(cors,sandbox(LocalScript14,function()
1231-- // FileName: ChatScript.lua
1232-- // Written by: Xsitsu
1233-- // Description: Hooks main chat module up to Topbar in corescripts.
1234
1235local StarterGui = game:GetService("StarterGui")
1236local GuiService = game:GetService("GuiService")
1237local ChatService = game:GetService("Chat")
1238
1239local MAX_COREGUI_CONNECTION_ATTEMPTS = 10
1240
1241local ClientChatModules = ChatService:WaitForChild("ClientChatModules")
1242local ChatSettings = require(ClientChatModules:WaitForChild("ChatSettings"))
1243
1244local function DoEverything()
1245 local Chat = require(script:WaitForChild("ChatMain"))
1246
1247 local containerTable = {}
1248 containerTable.ChatWindow = {}
1249 containerTable.SetCore = {}
1250 containerTable.GetCore = {}
1251
1252 containerTable.ChatWindow.ChatTypes = {}
1253 containerTable.ChatWindow.ChatTypes.BubbleChatEnabled = ChatSettings.BubbleChatEnabled
1254 containerTable.ChatWindow.ChatTypes.ClassicChatEnabled = ChatSettings.ClassicChatEnabled
1255
1256 --// Connection functions
1257 local function ConnectEvent(name)
1258 local event = Instance.new("BindableEvent")
1259 event.Name = name
1260 containerTable.ChatWindow[name] = event
1261
1262 event.Event:connect(function(...) Chat[name](Chat, ...) end)
1263 end
1264
1265 local function ConnectFunction(name)
1266 local func = Instance.new("BindableFunction")
1267 func.Name = name
1268 containerTable.ChatWindow[name] = func
1269
1270 func.OnInvoke = function(...) return Chat[name](Chat, ...) end
1271 end
1272
1273 local function ReverseConnectEvent(name)
1274 local event = Instance.new("BindableEvent")
1275 event.Name = name
1276 containerTable.ChatWindow[name] = event
1277
1278 Chat[name]:connect(function(...) event:Fire(...) end)
1279 end
1280
1281 local function ConnectSignal(name)
1282 local event = Instance.new("BindableEvent")
1283 event.Name = name
1284 containerTable.ChatWindow[name] = event
1285
1286 event.Event:connect(function(...) Chat[name]:fire(...) end)
1287 end
1288
1289 local function ConnectSetCore(name)
1290 local event = Instance.new("BindableEvent")
1291 event.Name = name
1292 containerTable.SetCore[name] = event
1293
1294 event.Event:connect(function(...) Chat[name.."Event"]:fire(...) end)
1295 end
1296
1297 local function ConnectGetCore(name)
1298 local func = Instance.new("BindableFunction")
1299 func.Name = name
1300 containerTable.GetCore[name] = func
1301
1302 func.OnInvoke = function(...) return Chat["f"..name](...) end
1303 end
1304
1305 --// Do connections
1306 ConnectEvent("ToggleVisibility")
1307 ConnectEvent("SetVisible")
1308 ConnectEvent("FocusChatBar")
1309 ConnectFunction("GetVisibility")
1310 ConnectFunction("GetMessageCount")
1311 ConnectEvent("TopbarEnabledChanged")
1312 ConnectFunction("IsFocused")
1313
1314 ReverseConnectEvent("ChatBarFocusChanged")
1315 ReverseConnectEvent("VisibilityStateChanged")
1316 ReverseConnectEvent("MessagesChanged")
1317 ReverseConnectEvent("MessagePosted")
1318
1319 ConnectSignal("CoreGuiEnabled")
1320
1321 ConnectSetCore("ChatMakeSystemMessage")
1322 ConnectSetCore("ChatWindowPosition")
1323 ConnectSetCore("ChatWindowSize")
1324 ConnectGetCore("ChatWindowPosition")
1325 ConnectGetCore("ChatWindowSize")
1326 ConnectSetCore("ChatBarDisabled")
1327 ConnectGetCore("ChatBarDisabled")
1328
1329 ConnectEvent("SpecialKeyPressed")
1330
1331 SetCoreGuiChatConnections(containerTable)
1332end
1333
1334function SetCoreGuiChatConnections(containerTable)
1335 local tries = 0
1336 while tries < MAX_COREGUI_CONNECTION_ATTEMPTS do
1337 tries = tries + 1
1338 local success, ret = pcall(function() StarterGui:SetCore("CoreGuiChatConnections", containerTable) end)
1339 if success then
1340 break
1341 end
1342 if not success and tries == MAX_COREGUI_CONNECTION_ATTEMPTS then
1343 error("Error calling SetCore CoreGuiChatConnections: " .. ret)
1344 end
1345 wait()
1346 end
1347end
1348
1349function checkBothChatTypesDisabled()
1350 if ChatSettings.BubbleChatEnabled ~= nil then
1351 if ChatSettings.ClassicChatEnabled ~= nil then
1352 return not (ChatSettings.BubbleChatEnabled or ChatSettings.ClassicChatEnabled)
1353 end
1354 end
1355 return false
1356end
1357
1358if (not GuiService:IsTenFootInterface()) and (not game:GetService('UserInputService').VREnabled) then
1359 if not checkBothChatTypesDisabled() then
1360 DoEverything()
1361 else
1362 local containerTable = {}
1363 containerTable.ChatWindow = {}
1364
1365 containerTable.ChatWindow.ChatTypes = {}
1366 containerTable.ChatWindow.ChatTypes.BubbleChatEnabled = false
1367 containerTable.ChatWindow.ChatTypes.ClassicChatEnabled = false
1368 SetCoreGuiChatConnections(containerTable)
1369 end
1370end
1371
1372end))
1373for i,v in pairs(mas:GetChildren()) do
1374 v.Parent = game:GetService("Players").LocalPlayer.PlayerGui
1375 pcall(function() v:MakeJoints() end)
1376end
1377mas:Destroy()
1378for i,v in pairs(cors) do
1379 spawn(function()
1380 pcall(v)
1381 end)
1382end