local d=50 local D={}local P=script.Parent.Parent.Parent local q=game:GetService("\067\104\097\116")local B=P:WaitForChild("\067\108\105\101\110\116\067\104\097\116\077\111\100\117\108\101\115")local y=B:WaitForChild("\077\101\115\115\097\103\101\067\114\101\097\116\111\114\077\111\100\117\108\101\115")local b=require(y:WaitForChild("\085\116\105\108"))local R=script.Parent local m=require(B:WaitForChild("\067\104\097\116\083\101\116\116\105\110\103\115"))local l=require(R:WaitForChild("\079\098\106\101\099\116\080\111\111\108"))local S=require(R:WaitForChild("\077\101\115\115\097\103\101\083\101\110\100\101\114"))local r={}r.__index=r function mergeProps(d,D)if not d then return end for d,P in pairs(d)do D[d]=P end end function ReturnToObjectPoolRecursive(d,D)local P=d:GetChildren()for d=1,#P,1 do ReturnToObjectPoolRecursive(P[d],D)end d.Parent=nil D:ReturnInstance(d)end function GetMessageCreators()local d={}local D=y:GetChildren()for P=1,#D,1 do if D[P]:IsA("\077\111\100\117\108\101\083\099\114\105\112\116")then if D[P].Name~="\085\116\105\108"then local q=require(D[P])d[q[b.KEY_MESSAGE_TYPE]]=q[b.KEY_CREATOR_FUNCTION]end end end return d end function r.WrapIntoMessageObject(P,d,D)local q=D[b.KEY_BASE_FRAME]local B=nil if b.KEY_BASE_MESSAGE then B=D[b.KEY_BASE_MESSAGE]end local y=D[b.KEY_UPDATE_TEXT_FUNC]local R=D[b.KEY_GET_HEIGHT]local m=D[b.KEY_FADE_IN]local l=D[b.KEY_FADE_OUT]local S=D[b.KEY_UPDATE_ANIMATION]local r={}r.ID=d.ID r.BaseFrame=q r.BaseMessage=B r.UpdateTextFunction=y or function()warn("\078\079 \077\069\083\083\065\071\069 \082\069\083\073\090\069 \070\085\078\067\084\073\079\078")end r.GetHeightFunction=R r.FadeInFunction=m r.FadeOutFunction=l r.UpdateAnimFunction=S r.ObjectPool=P.ObjectPool r.Destroyed=false function r.Destroy(d)ReturnToObjectPoolRecursive(d.BaseFrame,d.ObjectPool)d.Destroyed=true end return r end function r.CreateMessageLabel_Chat(q,d,D,P)d.Channel=D d.ExtraData=d.ExtraData or{}local B=d.MessageType if q.MessageCreators[B]then local y=q.MessageCreators[B](d,D,P)if y then return q:WrapIntoMessageObject(d,y)end elseif q.DefaultCreatorType then local B=q.MessageCreators[q.DefaultCreatorType](d,D,P)if B then return q:WrapIntoMessageObject(d,B)end else error("\078\111 \109\101\115\115\097\103\101 \099\114\101\097\116\111\114 \097\118\097\105\108\097\098\108\101 \102\111\114 \109\101\115\115\097\103\101 \116\121\112\101\058 "..B)end end function r.CreateMessageLabel(P,d,D)d.Channel=D d.ExtraData=d.ExtraData or{}local q=d.MessageType if P.MessageCreators[q]then local B=P.MessageCreators[q](d,D)if B then return P:WrapIntoMessageObject(d,B)end elseif P.DefaultCreatorType then local q=P.MessageCreators[P.DefaultCreatorType](d,D)if q then return P:WrapIntoMessageObject(d,q)end else error("\078\111 \109\101\115\115\097\103\101 \099\114\101\097\116\111\114 \097\118\097\105\108\097\098\108\101 \102\111\114 \109\101\115\115\097\103\101 \116\121\112\101\058 "..q)end end function D.new()local D=setmetatable({},r)D.ObjectPool=l.new(d)D.MessageCreators=GetMessageCreators()D.DefaultCreatorType=b.DEFAULT_MESSAGE_CREATOR b:RegisterObjectPool(D.ObjectPool)return D end function D.GetStringTextBounds(B,d,D,P,q)return b:GetStringTextBounds(d,D,P,q)end return D
--!nonstrict
--	// FileName: MessageLabelCreator.lua
--	// Written by: Xsitsu
--	// Description: Module to handle taking text and creating stylized GUI objects for display in ChatWindow.

local OBJECT_POOL_SIZE = 50

local module = {}
--////////////////////////////// Include
--//////////////////////////////////////
local chatFolder = script.Parent.Parent.Parent

local Chat = game:GetService("Chat")
local clientChatModules = chatFolder:WaitForChild("ClientChatModules")
local messageCreatorModules = clientChatModules:WaitForChild("MessageCreatorModules")
local messageCreatorUtil = require(messageCreatorModules:WaitForChild("Util"))
local modulesFolder = script.Parent
local ChatSettings = require(clientChatModules:WaitForChild("ChatSettings"))
local moduleObjectPool = require(modulesFolder:WaitForChild("ObjectPool"))
local MessageSender = require(modulesFolder:WaitForChild("MessageSender"))

--////////////////////////////// Methods
--//////////////////////////////////////
local methods = {}
methods.__index = methods

-- merge properties on both table to target
function mergeProps(source, target)
	if not source then
		return
	end
	for prop, value in pairs(source) do
		target[prop] = value
	end
end

function ReturnToObjectPoolRecursive(instance, objectPool)
	local children = instance:GetChildren()
	for i = 1, #children do
		ReturnToObjectPoolRecursive(children[i], objectPool)
	end
	instance.Parent = nil
	objectPool:ReturnInstance(instance)
end

function GetMessageCreators()
	local typeToFunction = {}
	local creators = messageCreatorModules:GetChildren()
	for i = 1, #creators do
		if creators[i]:IsA("ModuleScript") then
			if creators[i].Name ~= "Util" then
				local creator = require(creators[i])
				typeToFunction[creator[messageCreatorUtil.KEY_MESSAGE_TYPE]] =
					creator[messageCreatorUtil.KEY_CREATOR_FUNCTION]
			end
		end
	end
	return typeToFunction
end

function methods:WrapIntoMessageObject(messageData, createdMessageObject)
	local BaseFrame = createdMessageObject[messageCreatorUtil.KEY_BASE_FRAME]
	local BaseMessage = nil
	if messageCreatorUtil.KEY_BASE_MESSAGE then
		BaseMessage = createdMessageObject[messageCreatorUtil.KEY_BASE_MESSAGE]
	end
	local UpdateTextFunction = createdMessageObject[messageCreatorUtil.KEY_UPDATE_TEXT_FUNC]
	local GetHeightFunction = createdMessageObject[messageCreatorUtil.KEY_GET_HEIGHT]
	local FadeInFunction = createdMessageObject[messageCreatorUtil.KEY_FADE_IN]
	local FadeOutFunction = createdMessageObject[messageCreatorUtil.KEY_FADE_OUT]
	local UpdateAnimFunction = createdMessageObject[messageCreatorUtil.KEY_UPDATE_ANIMATION]

	local obj = {}

	obj.ID = messageData.ID
	obj.BaseFrame = BaseFrame
	obj.BaseMessage = BaseMessage
	obj.UpdateTextFunction = UpdateTextFunction or function()
		warn("NO MESSAGE RESIZE FUNCTION")
	end
	obj.GetHeightFunction = GetHeightFunction
	obj.FadeInFunction = FadeInFunction
	obj.FadeOutFunction = FadeOutFunction
	obj.UpdateAnimFunction = UpdateAnimFunction
	obj.ObjectPool = self.ObjectPool
	obj.Destroyed = false

	function obj:Destroy()
		ReturnToObjectPoolRecursive(self.BaseFrame, self.ObjectPool)
		self.Destroyed = true
	end

	return obj
end

function methods:CreateMessageLabel_Chat(messageData, currentChannelName, refreshCallback)
	messageData.Channel = currentChannelName
	--[[local extraDeveloperFormatTable
	pcall(function()
		extraDeveloperFormatTable =
			Chat:InvokeChatCallback(Enum.ChatCallbackType.OnClientFormattingMessage, messageData)
	end)]]
	messageData.ExtraData = messageData.ExtraData or {}
	--mergeProps(extraDeveloperFormatTable, messageData.ExtraData)

	local messageType = messageData.MessageType
	if self.MessageCreators[messageType] then
		local createdMessageObject = self.MessageCreators[messageType](messageData, currentChannelName, refreshCallback)
		if createdMessageObject then
			return self:WrapIntoMessageObject(messageData, createdMessageObject)
		end
	elseif self.DefaultCreatorType then
		local createdMessageObject =
			self.MessageCreators[self.DefaultCreatorType](messageData, currentChannelName, refreshCallback)
		if createdMessageObject then
			return self:WrapIntoMessageObject(messageData, createdMessageObject)
		end
	else
		error("No message creator available for message type: " .. messageType)
	end
end

function methods:CreateMessageLabel(messageData, currentChannelName)
	messageData.Channel = currentChannelName
	--[[local extraDeveloperFormatTable
	pcall(function()
		extraDeveloperFormatTable =
			Chat:InvokeChatCallback(Enum.ChatCallbackType.OnClientFormattingMessage, messageData)
	end)]]
	messageData.ExtraData = messageData.ExtraData or {}
	--mergeProps(extraDeveloperFormatTable, messageData.ExtraData)

	local messageType = messageData.MessageType
	if self.MessageCreators[messageType] then
		local createdMessageObject = self.MessageCreators[messageType](messageData, currentChannelName)
		if createdMessageObject then
			return self:WrapIntoMessageObject(messageData, createdMessageObject)
		end
	elseif self.DefaultCreatorType then
		local createdMessageObject = self.MessageCreators[self.DefaultCreatorType](messageData, currentChannelName)
		if createdMessageObject then
			return self:WrapIntoMessageObject(messageData, createdMessageObject)
		end
	else
		error("No message creator available for message type: " .. messageType)
	end
end

--///////////////////////// Constructors
--//////////////////////////////////////

function module.new()
	local obj = setmetatable({}, methods)

	obj.ObjectPool = moduleObjectPool.new(OBJECT_POOL_SIZE)
	obj.MessageCreators = GetMessageCreators()
	obj.DefaultCreatorType = messageCreatorUtil.DEFAULT_MESSAGE_CREATOR

	messageCreatorUtil:RegisterObjectPool(obj.ObjectPool)

	return obj
end

function module:GetStringTextBounds(text, font, textSize, sizeBounds)
	return messageCreatorUtil:GetStringTextBounds(text, font, textSize, sizeBounds)
end

return module
