Old ROBLOX Text Filter (Do not use)

With the push by ROBLOX for all Experiences to use the TextFilter I have found this code inside the ROBLOX core modules, it is only visible during run time and is defined as a class (:slight_smile: function, so I have ported it to a module which you can use to filter your text using the same method as ROBLOX does for filtering a user’s public message. I have removed a line which indexed the message into an array with a key equaling weather or not the message passed. Additionally, I have added the ability to parse the message into sentences and only censor the sentence that does not pass the text filter.

local module = {}
local RunService=game:GetService("RunService")
local Chat=game:GetService("Chat")
local MAX_FILTER_RETRIES=6
local MAX_FILTER_DURATION=4
local FILTER_BACKOFF_INTERVALS={.3,4,.5,.6}
function module.ApplyRobloxFilter(fromPlayerObj, message) --// USES FFLAG
	if (RunService:IsServer() and not RunService:IsStudio()) then
		local filterStartTime = tick()
		local filterRetries = 0	
		while true do
			local success, message = pcall(function()
			return Chat:FilterStringForBroadcast(message, fromPlayerObj)
			end)
			if success then
				return message
			else
				--return nil
				--warn("Error filtering message:", message)
			end
			filterRetries = filterRetries + 1
			if filterRetries > MAX_FILTER_RETRIES or (tick() - filterStartTime) > MAX_FILTER_DURATION then
				return nil
			end
			local backoffInterval = FILTER_BACKOFF_INTERVALS[math.min(#FILTER_BACKOFF_INTERVALS, filterRetries)]
			-- backoffWait = backoffInterval +/- (0 -> backoffInterval)
			local backoffWait = backoffInterval + ((math.random()*2 - 1) * backoffInterval)
			task.wait(backoffWait)
		end
	else
		return message
	end
	return nil
end

local function splitIntoSentences(text)
	local sentences = {}
	for sentence, punct in string.gmatch(text, "([^%.!?]+)([%.!?])") do
		table.insert(sentences, sentence .. punct)
	end
	return sentences
end


function module.filterText(fromPlayerObj, message)
	local filteredMessage = module.ApplyRobloxFilter(fromPlayerObj, message)
	if filteredMessage == nil or filteredMessage~=message then
		-- Text was filtered, separate into sentences and filter again
		local sentences = splitIntoSentences(message)
		local filteredSentences = {}
		for _, sentence in ipairs(sentences) do
			local filteredSentence = module.ApplyRobloxFilter(fromPlayerObj, sentence)
			if filteredSentence then
				table.insert(filteredSentences, filteredSentence)
			end
		end
		return table.concat(filteredSentences, ". ")
	else
		return filteredMessage
	end
end

--local textfilter=require(game.ReplicatedStorage.GlobalSpells.TextFilter)

return module
5 Likes

this is…

oddly mediocre for roblox

5 Likes

My favorite part is this lol. Look at that interesting computation.

2 Likes

Excluding the two other functions, this is the old filtering function of the lua chat system aka the LegacyChat, i recognize it very well. It isn’t being used in the latest version of the chat as it was migrated to use TextChatService’s or TextService’s filtering api

That code uses the deprecated Chat service, and wont be allowed either for messages considered as “chats” past April 30th, due to the requirement that chat messages must go through TextChannels from TextChatService

5 Likes

Is that supposed to delay in increasing intervals if filtering errored? I had some trouble reading this code :sweat_smile:

1 Like