--[[
All-in-One Chat Translator (Incoming Fix)
- Added Backup API (GTX) for reliable incoming translation
- Fixed issues where incoming text wouldn't translate
]]
-- Wait for the game to be fully loaded.
if not game:IsLoaded() then game.Loaded:Wait() end
repeat task.wait(.06) until game:GetService("Players").LocalPlayer
-- Services
local Http = game:GetService("HttpService")
local Players = game:GetService("Players")
local TCS = game:GetService("TextChatService")
local CoreGui = game:GetService("CoreGui")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local LP = Players.LocalPlayer
-- Translator State
local isTranslatorActive = false
local isJumbleActive = false
-- CONFIG: This is the language other people's messages turn into for YOU.
local yourLanguage = "en"
local targetLanguage = nil
-- UI Data (Untouched)
local languageCategories = {
{
Name = "Global & Constructed",
Languages = {
["English (USA/UK)"] = "en", ["Esperanto (Global)"] = "eo", ["Latin (Global)"] = "la"
}
},
{
Name = "African Languages",
Languages = {
["Afrikaans"] = "af", ["Amharic"] = "am", ["Hausa"] = "ha", ["Igbo"] = "ig", ["Malagasy"] = "mg",
["Sesotho"] = "st", ["Shona"] = "sn", ["Somali"] = "so", ["Swahili"] = "sw", ["Xhosa"] = "xh",
["Yoruba"] = "yo", ["Zulu"] = "zu"
}
},
{
Name = "Asian Languages",
Languages = {
["Armenian"] = "hy", ["Azerbaijani"] = "az", ["Bengali"] = "bn", ["Burmese"] = "my", ["Chinese"] = "zh-cn",
["Georgian"] = "ka", ["Gujarati"] = "gu", ["Hindi"] = "hi", ["Hmong"] = "hmn", ["Indonesian"] = "id",
["Japanese"] = "ja", ["Javanese"] = "jw", ["Kannada"] = "kn", ["Kazakh"] = "kk", ["Khmer"] = "km",
["Korean"] = "ko", ["Kurdish"] = "ku", ["Kyrgyz"] = "ky", ["Lao"] = "lo", ["Malay"] = "ms",
["Malayalam"] = "ml", ["Marathi"] = "mr", ["Mongolian"] = "mn", ["Nepali"] = "ne", ["Pashto"] = "ps",
["Punjabi"] = "pa", ["Sindhi"] = "sd", ["Sinhala"] = "si", ["Sundanese"] = "su", ["Tajik"] = "tg",
["Tamil"] = "ta", ["Telugu"] = "te", ["Thai"] = "th", ["Urdu"] = "ur", ["Uzbek"] = "uz", ["Vietnamese"] = "vi"
}
},
{
Name = "European Languages",
Languages = {
["Albanian"] = "sq", ["Basque"] = "eu", ["Belarusian"] = "be", ["Bosnian"] = "bs", ["Bulgarian"] = "bg",
["Catalan"] = "ca", ["Corsican"] = "co", ["Croatian"] = "hr", ["Czech"] = "cs", ["Danish"] = "da",
["Dutch"] = "nl", ["Estonian"] = "et", ["Finnish"] = "fi", ["French"] = "fr", ["Frisian"] = "fy",
["Galician"] = "gl", ["German"] = "de", ["Greek"] = "el", ["Hungarian"] = "hu", ["Icelandic"] = "is",
["Irish"] = "ga", ["Italian"] = "it", ["Latvian"] = "lv", ["Lithuanian"] = "lt", ["Luxembourgish"] = "lb",
["Macedonian"] = "mk", ["Maltese"] = "mt", ["Norwegian"] = "no", ["Polish"] = "pl", ["Portuguese"] = "pt",
["Romanian"] = "ro", ["Russian"] = "ru", ["Scots Gaelic"] = "gd", ["Serbian"] = "sr", ["Slovak"] = "sk",
["Slovenian"] = "sl", ["Spanish"] = "es", ["Swedish"] = "sv", ["Ukrainian"] = "uk", ["Welsh"] = "cy"
}
},
{
Name = "Middle Eastern",
Languages = {
["Arabic"] = "ar", ["Hebrew"] = "iw", ["Persian"] = "fa", ["Turkish"] = "tr", ["Yiddish"] = "yi"
}
},
{
Name = "North & Central American",
Languages = { ["Haitian Creole"] = "ht" }
},
{
Name = "Oceanian Languages",
Languages = {
["Cebuano"] = "ceb", ["Filipino"] = "tl", ["Hawaiian"] = "haw", ["Maori"] = "mi", ["Samoan"] = "sm"
}
}
}
local languages = {}
local langCodesArray = {}
for _, categoryData in ipairs(languageCategories) do
for langName, langCode in pairs(categoryData.Languages) do
languages[langName] = langCode
table.insert(langCodesArray, langCode)
end
end
--region Translation API
local gv
local function req(opt)
local fn = (syn and syn.request) or (http and http.request) or http_request or request
if fn then return fn(opt) end
return Http:RequestAsync(opt)
end
local function consent(body)
local t = {}
for tag in body:gmatch('') do
local k, v = tag:match('')
t[k] = v
end
gv = t.v or ""
end
local function got(url, method, body)
method = method or "GET"
local res = req({Url = url, Method = method, Headers = {cookie = "CONSENT=YES+" .. (gv or "")}, Body = body})
local b = res.Body or res.body or ""
if type(b) ~= "string" then b = tostring(b) end
if b:match("https://consent.google.com/s") then
consent(b)
res = req({Url = url, Method = "GET", Headers = {cookie = "CONSENT=YES+" .. (gv or "")}})
end
return res
end
local function q(data)
local s = ""
for k, v in pairs(data) do
if type(v) == "table" then
for _, vv in pairs(v) do s ..= "&" .. Http:UrlEncode(k) .. "=" .. Http:UrlEncode(vv) end
else
s ..= "&" .. Http:UrlEncode(k) .. "=" .. Http:UrlEncode(v)
end
end
return s:sub(2)
end
local jE = function(x) return Http:JSONEncode(x) end
local jD = function(x) return Http:JSONDecode(x) end
local rpc = "MkEWBc"
local root = "https://translate.google.com/"
local exec = "https://translate.google.com/_/TranslateWebserverUi/data/batchexecute"
local fsid, bl, rid = nil, nil, math.random(1000, 9999)
-- Initialize tokens in background
task.spawn(function()
local b = (got(root).Body or "")
fsid = b:match('"FdrFJe":"(.-)"')
bl = b:match('"cfb2h":"(.-)"')
end)
-- The Backup API (GTX) - Used if the main one fails
local function translateBackup(text, target, source)
source = source or "auto"
local url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl="..source.."&tl="..target.."&dt=t&q="..Http:UrlEncode(text)
local res = req({Url = url, Method = "GET"})
local success, response = pcall(function()
return jD(res.Body or res.body)
end)
if success and response and response[1] then
local combinedText = ""
-- Recombine sentences
for _, section in ipairs(response[1]) do
if section[1] then combinedText = combinedText .. section[1] end
end
return combinedText, response[3] -- Text, DetectedLang
end
return nil, nil
end
local function translateInfo(txt, tgt, src)
rid += 10000
src = src or "auto"
-- Try Main Method
if fsid and bl then
local data = {{txt, src, tgt, true}, {nil}}
local freq = {{{rpc, jE(data), nil, "generic"}}}
local url = exec .. "?" .. q{rpcids = rpc, ["f.sid"] = fsid, bl = bl, hl = "en", _reqID = rid - 10000, rt = "c"}
local body = q{["f.req"] = jE(freq)}
local res = got(url, "POST", body)
local ok, out = pcall(function()
local arr = jD((res.Body or ""):match("%[.-%]\n"))
return jD(arr[1][3])
end)
if ok and out and out[2] and out[2][1] and out[2][1][1] and out[2][1][1][6] then
local t = out[2][1][1][6][1][1]
local l = out[3]
if t then return t, l end
end
end
-- Fallback to Backup Method
return translateBackup(txt, tgt, src)
end
-- Simplified wrapper for just text
local function translate(txt, tgt, src)
local t, _ = translateInfo(txt, tgt, src)
return t
end
--endregion
--region Chat Helper Functions
local chatVersion = "Legacy"
if TCS.ChatVersion == Enum.ChatVersion.TextChatService then
chatVersion = "TCS"
end
local function sys(msg)
if chatVersion == "TCS" then
local chans = TCS:WaitForChild("TextChannels", 5)
if chans then
local c = chans:FindFirstChild("RBXGeneral") or chans:FindFirstChild("RBXSystem")
if c and c.DisplaySystemMessage then
c:DisplaySystemMessage(msg)
end
end
else
pcall(function()
StarterGui:SetCore("ChatMakeSystemMessage", {
Text = msg,
Color = Color3.fromRGB(100, 255, 100), -- Greenish for visibility
Font = Enum.Font.SourceSansBold,
FontSize = Enum.FontSize.Size18
})
end)
end
end
local function sendChat(text)
task.spawn(function()
if chatVersion == "TCS" then
local chan = TCS.TextChannels:FindFirstChild("RBXGeneral") or TCS.TextChannels:FindFirstChild("General")
if chan then chan:SendAsync(text) end
else
local remote = ReplicatedStorage:FindFirstChild("DefaultChatSystemChatEvents")
if remote then
local say = remote:FindFirstChild("SayMessageRequest")
if say then say:FireServer(text, "All") end
end
end
end)
end
local function handleOutgoing(rawMessage)
if not rawMessage or rawMessage == "" then return end
if rawMessage:sub(1, 1) == "/" then
sendChat(rawMessage)
return
end
if isJumbleActive then
local words = {}
for word in rawMessage:gmatch("%S+") do table.insert(words, word) end
local translatedWords = {}
for _, word in ipairs(words) do
local randomLangCode = langCodesArray[math.random(#langCodesArray)]
local translatedWord = translate(word, randomLangCode, "auto") or word
table.insert(translatedWords, translatedWord)
end
sendChat(table.concat(translatedWords, " "))
elseif isTranslatorActive and targetLanguage then
local translatedText = translate(rawMessage, targetLanguage, "auto") or rawMessage
sendChat(translatedText)
else
sendChat(rawMessage)
end
end
--endregion
--region UI Creation (Untouched)
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "TranslatorUI"
if syn and syn.protect_gui then syn.protect_gui(screenGui) end
screenGui.Parent = CoreGui
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
local mainFrame = Instance.new("Frame")
mainFrame.Name = "MainFrame"
mainFrame.Parent = screenGui
mainFrame.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
mainFrame.BorderColor3 = Color3.fromRGB(80, 80, 80)
mainFrame.BorderSizePixel = 1
mainFrame.Position = UDim2.new(0, 20, 0, 20)
mainFrame.Size = UDim2.new(0, 280, 0, 30)
mainFrame.ClipsDescendants = true
mainFrame.Active = true
mainFrame.Draggable = true
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Parent = mainFrame
titleLabel.BackgroundTransparency = 1
titleLabel.Position = UDim2.new(0, 10, 0, 0)
titleLabel.Size = UDim2.new(0, 100, 0, 30)
titleLabel.Font = Enum.Font.SourceSansBold
titleLabel.Text = "Translator"
titleLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
titleLabel.TextSize = 16
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
local toggleButton = Instance.new("TextButton")
toggleButton.Name = "ToggleButton"
toggleButton.Parent = mainFrame
toggleButton.BackgroundColor3 = Color3.fromRGB(55, 55, 55)
toggleButton.Size = UDim2.new(0, 25, 0, 20)
toggleButton.Position = UDim2.new(1, -30, 0.5, -10)
toggleButton.Font = Enum.Font.SourceSansBold
toggleButton.Text = "[+]"
toggleButton.TextColor3 = Color3.fromRGB(200, 200, 200)
toggleButton.TextSize = 16
toggleButton.ZIndex = 2
local scrollFrame = Instance.new("ScrollingFrame")
scrollFrame.Name = "ScrollFrame"
scrollFrame.Parent = mainFrame
scrollFrame.BackgroundTransparency = 1
scrollFrame.Position = UDim2.new(0, 0, 0, 30)
scrollFrame.Size = UDim2.new(1, 0, 1, -30)
scrollFrame.Visible = false
scrollFrame.ZIndex = 1
scrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y
scrollFrame.ScrollBarImageColor3 = Color3.fromRGB(120, 120, 120)
scrollFrame.ScrollBarThickness = 6
scrollFrame.BorderSizePixel = 0
local listLayout = Instance.new("UIListLayout")
listLayout.Parent = scrollFrame
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 5)
local controlFrame = Instance.new("Frame")
controlFrame.Name = "ControlFrame"
controlFrame.Parent = scrollFrame
controlFrame.BackgroundTransparency = 1
controlFrame.Size = UDim2.new(1, 0, 0, 30)
controlFrame.AutomaticSize = Enum.AutomaticSize.Y
controlFrame.LayoutOrder = 1
local controlGrid = Instance.new("UIGridLayout")
controlGrid.Parent = controlFrame
controlGrid.CellPadding = UDim2.new(0, 5, 0, 5)
controlGrid.CellSize = UDim2.new(0, 85, 0, 25)
controlGrid.StartCorner = Enum.StartCorner.TopLeft
controlGrid.HorizontalAlignment = Enum.HorizontalAlignment.Center
controlGrid.SortOrder = Enum.SortOrder.LayoutOrder
local stopButton = Instance.new("TextButton")
stopButton.Name = "StopButton"
stopButton.Parent = controlFrame
stopButton.BackgroundColor3 = Color3.fromRGB(150, 40, 40)
stopButton.BorderColor3 = Color3.fromRGB(80, 80, 80)
stopButton.Font = Enum.Font.SourceSansBold
stopButton.Text = "Stop"
stopButton.TextColor3 = Color3.fromRGB(255, 255, 255)
stopButton.TextSize = 14
stopButton.LayoutOrder = 1
local jumbleButton = Instance.new("TextButton")
jumbleButton.Name = "JumbleButton"
jumbleButton.Parent = controlFrame
jumbleButton.BackgroundColor3 = Color3.fromRGB(120, 60, 180)
jumbleButton.BorderColor3 = Color3.fromRGB(80, 80, 80)
jumbleButton.Font = Enum.Font.SourceSansBold
jumbleButton.Text = "Jumble"
jumbleButton.TextColor3 = Color3.fromRGB(255, 255, 255)
jumbleButton.TextSize = 14
jumbleButton.LayoutOrder = 2
local searchBoxFrame = Instance.new("Frame")
searchBoxFrame.Name = "SearchBoxFrame"
searchBoxFrame.Parent = scrollFrame
searchBoxFrame.BackgroundTransparency = 1
searchBoxFrame.Size = UDim2.new(1, -10, 0, 25)
searchBoxFrame.Position = UDim2.new(0, 5, 0, 0)
searchBoxFrame.LayoutOrder = 2
local searchBoxLabel = Instance.new("TextLabel")
searchBoxLabel.Name = "SearchLabel"
searchBoxLabel.Parent = searchBoxFrame
searchBoxLabel.BackgroundTransparency = 1
searchBoxLabel.Size = UDim2.new(0, 60, 1, 0)
searchBoxLabel.Font = Enum.Font.SourceSans
searchBoxLabel.Text = "Search: "
searchBoxLabel.TextColor3 = Color3.fromRGB(200, 200, 200)
searchBoxLabel.TextSize = 14
searchBoxLabel.TextXAlignment = Enum.TextXAlignment.Left
local searchBox = Instance.new("TextBox")
searchBox.Name = "SearchBox"
searchBox.Parent = searchBoxFrame
searchBox.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
searchBox.BorderColor3 = Color3.fromRGB(80, 80, 80)
searchBox.Position = UDim2.new(0, 60, 0, 0)
searchBox.Size = UDim2.new(1, -65, 1, 0)
searchBox.Font = Enum.Font.SourceSans
searchBox.Text = ""
searchBox.TextColor3 = Color3.fromRGB(240, 240, 240)
searchBox.TextSize = 14
searchBox.PlaceholderText = "Type to filter..."
searchBox.PlaceholderColor3 = Color3.fromRGB(150, 150, 150)
searchBox.ClearTextOnFocus = false
local langButtons = {}
local categoryElements = {}
local categoryLayoutOrder = 3
for _, categoryData in ipairs(languageCategories) do
local headerLabel = Instance.new("TextLabel")
headerLabel.Name = categoryData.Name .. "Header"
headerLabel.Parent = scrollFrame
headerLabel.BackgroundTransparency = 1
headerLabel.Size = UDim2.new(1, -10, 0, 20)
headerLabel.Position = UDim2.new(0, 5, 0, 0)
headerLabel.Font = Enum.Font.SourceSansBold
headerLabel.Text = categoryData.Name
headerLabel.TextColor3 = Color3.fromRGB(255, 255, 255)
headerLabel.TextSize = 16
headerLabel.TextXAlignment = Enum.TextXAlignment.Left
headerLabel.LayoutOrder = categoryLayoutOrder
categoryLayoutOrder += 1
local buttonContainer = Instance.new("Frame")
buttonContainer.Name = categoryData.Name .. "Container"
buttonContainer.Parent = scrollFrame
buttonContainer.BackgroundTransparency = 1
buttonContainer.Size = UDim2.new(1, 0, 0, 50)
buttonContainer.AutomaticSize = Enum.AutomaticSize.Y
buttonContainer.LayoutOrder = categoryLayoutOrder
categoryLayoutOrder += 1
local gridLayout = Instance.new("UIGridLayout")
gridLayout.Parent = buttonContainer
gridLayout.CellPadding = UDim2.new(0, 5, 0, 5)
gridLayout.CellSize = UDim2.new(0, 85, 0, 25)
gridLayout.StartCorner = Enum.StartCorner.TopLeft
gridLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
gridLayout.SortOrder = Enum.SortOrder.Name
local sortedLangNames = {}
for langName in pairs(categoryData.Languages) do
table.insert(sortedLangNames, langName)
end
table.sort(sortedLangNames)
local categoryButtons = {}
for _, langName in ipairs(sortedLangNames) do
local button = Instance.new("TextButton")
button.Name = langName
button.Parent = buttonContainer
button.BackgroundColor3 = Color3.fromRGB(55, 55, 55)
button.BorderColor3 = Color3.fromRGB(80, 80, 80)
button.Font = Enum.Font.SourceSans
button.Text = langName
button.TextColor3 = Color3.fromRGB(255, 255, 255)
button.TextSize = 12
langButtons[langName] = button
categoryButtons[langName] = button
end
table.insert(categoryElements, {
header = headerLabel,
container = buttonContainer,
buttons = categoryButtons
})
end
local function updateFilter(searchText)
local searchTextLower = string.lower(searchText)
if searchTextLower == "" then
for _, category in ipairs(categoryElements) do
category.header.Visible = true
category.container.Visible = true
for _, button in pairs(category.buttons) do button.Visible = true end
end
return
end
for _, category in ipairs(categoryElements) do
local anyButtonVisible = false
for langName, button in pairs(category.buttons) do
local langNameLower = string.lower(langName)
if string.find(langNameLower, searchTextLower) then
button.Visible = true; anyButtonVisible = true
else
button.Visible = false
end
end
category.header.Visible = anyButtonVisible
category.container.Visible = anyButtonVisible
end
end
local isExpanded = false
toggleButton.MouseButton1Click:Connect(function()
isExpanded = not isExpanded
scrollFrame.Visible = isExpanded
if isExpanded then
toggleButton.Text = "[-]"
mainFrame.Size = UDim2.new(0, 280, 0, 300)
searchBox.Text = ""
updateFilter("")
else
toggleButton.Text = "[+]"
mainFrame.Size = UDim2.new(0, 280, 0, 30)
end
end)
local function resetButtonColors()
for _, button in pairs(langButtons) do button.BackgroundColor3 = Color3.fromRGB(55, 55, 55) end
stopButton.BackgroundColor3 = Color3.fromRGB(150, 40, 40)
jumbleButton.BackgroundColor3 = Color3.fromRGB(120, 60, 180)
end
for langName, button in pairs(langButtons) do
button.MouseButton1Click:Connect(function()
resetButtonColors()
button.BackgroundColor3 = Color3.fromRGB(70, 115, 190)
isTranslatorActive = true; isJumbleActive = false
targetLanguage = languages[langName]
sys("[TR] Translator enabled. Language set to " .. langName .. ".")
end)
end
stopButton.MouseButton1Click:Connect(function()
resetButtonColors()
isTranslatorActive = false; isJumbleActive = false
targetLanguage = nil
sys("[TR] Auto-translation DISABLED.")
end)
jumbleButton.MouseButton1Click:Connect(function()
resetButtonColors()
jumbleButton.BackgroundColor3 = Color3.fromRGB(160, 90, 220)
isTranslatorActive = false; isJumbleActive = true
targetLanguage = nil
sys("[TR] Jumble mode ENABLED. Have fun!")
end)
searchBox.Changed:Connect(function() updateFilter(searchBox.Text) end)
--endregion
--region Main Logic
local function hookChatBox()
local box = nil
if LP:FindFirstChild("PlayerGui") and LP.PlayerGui:FindFirstChild("Chat") then
box = LP.PlayerGui.Chat:FindFirstChild("ChatBar", true)
end
if not box and CoreGui:FindFirstChild("ExperienceChat") then
for _, v in pairs(CoreGui.ExperienceChat:GetDescendants()) do
if v:IsA("TextBox") and v.Parent and v.Parent.Name == "TextBoxContainer" then
box = v; break
end
end
end
if box then
local connections = getconnections(box.FocusLost)
box.FocusLost:Connect(function(enter)
if enter then
local msg = box.Text
if (isTranslatorActive or isJumbleActive) and msg ~= "" and msg:sub(1,1) ~= "/" then
box.Text = ""
task.spawn(function() handleOutgoing(msg) end)
end
end
end)
sys("[TR] Chat Hooked Successfully.")
end
end
-- Incoming Chat Handling (Updated with threading & fallback)
if chatVersion == "TCS" then
TCS.MessageReceived:Connect(function(msg)
if not msg.TextSource then return end
if msg.TextSource.UserId == LP.UserId then return end -- Don't translate self
task.spawn(function()
local text, detectedLang = translateInfo(msg.Text, yourLanguage, "auto")
-- Comparison logic: Ignore if translation is identical or nil
if text and text ~= "" and string.lower(text) ~= string.lower(msg.Text) then
local langTag = detectedLang and detectedLang ~= "" and detectedLang:upper() or "UNK"
sys("(" .. langTag .. ") " .. msg.PrefixText .. ": " .. text)
end
end)
end)
else
local chatEvents = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents", 5)
if chatEvents then
chatEvents.OnMessageDoneFiltering.OnClientEvent:Connect(function(data)
task.spawn(function()
local speaker = data.FromSpeaker
local message = data.Message
if speaker ~= LP.Name then
local text, detectedLang = translateInfo(message, yourLanguage, "auto")
if text and text ~= "" and string.lower(text) ~= string.lower(message) then
local langTag = detectedLang and detectedLang ~= "" and detectedLang:upper() or "UNK"
sys("(" .. langTag .. ") [" .. speaker .. "]: " .. text)
end
end
end)
end)
end
end
task.wait(1)
hookChatBox()
LP.CharacterAdded:Connect(function() task.wait(1); hookChatBox() end)
--MEME