· last year · Jun 16, 2024, 10:35 PM
1--[[
2 Message Translator
3 Made by Aim, updated by cli, Updated by rang#1234
4 Credits to Riptxde for the sending chathook
5--]]
6pcall(function()
7 if not game['Loaded'] then game['Loaded']:Wait() end; repeat wait(.06) until game:GetService('Players').LocalPlayer ~= nil
8 local YourLang = "pt" -- Language code that the messages are going to be translated to
9
10 local googlev = isfile'googlev.txt' and readfile'googlev.txt' or ''
11
12 function googleConsent(Body)
13 local args = {}
14
15 for match in Body:gmatch('<input type="hidden" name=".-" value=".-">') do
16 local k,v = match:match('<input type="hidden" name="(.-)" value="(.-)">')
17 args[k] = v
18 end
19 googlev = args.v
20 writefile('googlev.txt', args.v)
21 end
22
23 local function got(url, Method, Body) -- Basic version of https://www.npmjs.com/package/got using synapse's request API for google websites
24 Method = Method or "GET"
25
26 local res = request({
27 Url = url,
28 Method = Method,
29 Headers = {cookie="CONSENT=YES+"..googlev},
30 Body = Body
31 })
32
33 if res.Body:match('https://consent.google.com/s') then
34 print('consent')
35 googleConsent(res.Body)
36 res = request({
37 Url = url,
38 Method = "GET",
39 Headers = {cookie="CONSENT=YES+"..googlev}
40 })
41 end
42
43 return res
44 end
45
46 local languages = {
47 auto = "Automatic",
48 af = "Afrikaans",
49 sq = "Albanian",
50 am = "Amharic",
51 ar = "Arabic",
52 hy = "Armenian",
53 az = "Azerbaijani",
54 eu = "Basque",
55 be = "Belarusian",
56 bn = "Bengali",
57 bs = "Bosnian",
58 bg = "Bulgarian",
59 ca = "Catalan",
60 ceb = "Cebuano",
61 ny = "Chichewa",
62 ['zh-cn'] = "Chinese Simplified",
63 ['zh-tw'] = "Chinese Traditional",
64 co = "Corsican",
65 hr = "Croatian",
66 cs = "Czech",
67 da = "Danish",
68 nl = "Dutch",
69 en = "English",
70 eo = "Esperanto",
71 et = "Estonian",
72 tl = "Filipino",
73 fi = "Finnish",
74 fr = "French",
75 fy = "Frisian",
76 gl = "Galician",
77 ka = "Georgian",
78 de = "German",
79 el = "Greek",
80 gu = "Gujarati",
81 ht = "Haitian Creole",
82 ha = "Hausa",
83 haw = "Hawaiian",
84 iw = "Hebrew",
85 hi = "Hindi",
86 hmn = "Hmong",
87 hu = "Hungarian",
88 is = "Icelandic",
89 ig = "Igbo",
90 id = "Indonesian",
91 ga = "Irish",
92 it = "Italian",
93 ja = "Japanese",
94 jw = "Javanese",
95 kn = "Kannada",
96 kk = "Kazakh",
97 km = "Khmer",
98 ko = "Korean",
99 ku = "Kurdish (Kurmanji)",
100 ky = "Kyrgyz",
101 lo = "Lao",
102 la = "Latin",
103 lv = "Latvian",
104 lt = "Lithuanian",
105 lb = "Luxembourgish",
106 mk = "Macedonian",
107 mg = "Malagasy",
108 ms = "Malay",
109 ml = "Malayalam",
110 mt = "Maltese",
111 mi = "Maori",
112 mr = "Marathi",
113 mn = "Mongolian",
114 my = "Myanmar (Burmese)",
115 ne = "Nepali",
116 no = "Norwegian",
117 ps = "Pashto",
118 fa = "Persian",
119 pl = "Polish",
120 pt = "Portuguese",
121 pa = "Punjabi",
122 ro = "Romanian",
123 ru = "Russian",
124 sm = "Samoan",
125 gd = "Scots Gaelic",
126 sr = "Serbian",
127 st = "Sesotho",
128 sn = "Shona",
129 sd = "Sindhi",
130 si = "Sinhala",
131 sk = "Slovak",
132 sl = "Slovenian",
133 so = "Somali",
134 es = "Spanish",
135 su = "Sundanese",
136 sw = "Swahili",
137 sv = "Swedish",
138 tg = "Tajik",
139 ta = "Tamil",
140 te = "Telugu",
141 th = "Thai",
142 tr = "Turkish",
143 uk = "Ukrainian",
144 ur = "Urdu",
145 uz = "Uzbek",
146 vi = "Vietnamese",
147 cy = "Welsh",
148 xh = "Xhosa",
149 yi = "Yiddish",
150 yo = "Yoruba",
151 zu = "Zulu"
152 };
153
154 function find(lang)
155 for i,v in pairs(languages) do
156 if i == lang or v == lang then
157 return i
158 end
159 end
160 end
161
162 function isSupported(lang)
163 local key = find(lang)
164 return key and true or false
165 end
166
167 function getISOCode(lang)
168 local key = find(lang)
169 return key
170 end
171
172 function stringifyQuery(dataFields)
173 local data = ""
174 for k, v in pairs(dataFields) do
175 if type(v) == "table" then
176 for _,v in pairs(v) do
177 data = data .. ("&%s=%s"):format(
178 game.HttpService:UrlEncode(k),
179 game.HttpService:UrlEncode(v)
180 )
181 end
182 else
183 data = data .. ("&%s=%s"):format(
184 game.HttpService:UrlEncode(k),
185 game.HttpService:UrlEncode(v)
186 )
187 end
188 end
189 data = data:sub(2)
190 return data
191 end
192
193 local reqid = math.random(1000,9999)
194 local rpcidsTranslate = "MkEWBc"
195 local rootURL = "https://translate.google.com/"
196 local executeURL = "https://translate.google.com/_/TranslateWebserverUi/data/batchexecute"
197 local fsid, bl
198
199 do -- init
200 print('initialize')
201 local InitialReq = got(rootURL)
202 fsid = InitialReq.Body:match('"FdrFJe":"(.-)"')
203 bl = InitialReq.Body:match('"cfb2h":"(.-)"')
204 end
205
206 local HttpService = game:GetService("HttpService")
207 function jsonE(o)
208 return HttpService:JSONEncode(o)
209 end
210 function jsonD(o)
211 return HttpService:JSONDecode(o)
212 end
213
214 function translate(str, to, from)
215 reqid = reqid + 10000
216 from = from and getISOCode(from) or 'auto'
217 to = to and getISOCode(to) or 'en'
218
219 local data = {{str, from, to, true}, {nil}}
220
221 local freq = {
222 {
223 {
224 rpcidsTranslate,
225 jsonE(data),
226 nil,
227 "generic"
228 }
229 }
230 }
231
232 local url = executeURL..'?'..stringifyQuery{rpcids = rpcidsTranslate, ['f.sid'] = fsid, bl = bl, hl="en", _reqid = reqid-10000, rt = 'c'}
233 local body = stringifyQuery{['f.req'] = jsonE(freq)}
234
235 local req = got(url, "POST", body)
236
237 local body = jsonD(req.Body:match'%[.-%]\n')
238 local translationData = jsonD(body[1][3])
239 local result = {
240 text = "",
241 from = {
242 language = "",
243 text = ""
244 },
245 raw = ""
246 }
247 result.raw = translationData
248 result.text = translationData[2][1][1][6][1][1]
249
250 result.from.language = translationData[3]
251 result.from.text = translationData[2][5][1]
252
253 return result
254 end
255
256 local Players = game:GetService("Players")
257 local LP = Players.LocalPlayer
258 local StarterGui = game:GetService('StarterGui')
259 for i=1, 15 do
260 local r = pcall(StarterGui["SetCore"])
261 if r then break end
262 game:GetService('RunService').RenderStepped:wait()
263 end
264 wait()
265
266 local properties = {
267 Color = Color3.new(1,1,0);
268 Font = Enum.Font.SourceSansItalic;
269 TextSize = 16;
270 }
271
272 game:GetService("StarterGui"):SetCore("SendNotification",
273 {
274 Title = "Chat Translator",
275 Text = "Ported to Google Translate",
276 Duration = 3
277 }
278 )
279
280 properties.Text = "[TR] To send messages in a language, say > followed by the target language/language code, e.g.: >ru or >russian. To disable (go back to original language), say >d."
281 StarterGui:SetCore("ChatMakeSystemMessage", properties)
282
283 function translateFrom(message)
284 local translation = translate(message, YourLang)
285
286 local text
287 if translation.from.language ~= YourLang then
288 text = translation.text
289 end
290
291 return {text, translation.from.language}
292 end
293
294 function get(plr, msg)
295 local tab = translateFrom(msg)
296 local translation = tab[1]
297 if translation then
298 properties.Text = "("..tab[2]:upper()..") ".."[".. plr.Name .."]: "..translation
299 StarterGui:SetCore("ChatMakeSystemMessage", properties)
300 end
301 end
302
303 game.ReplicatedStorage.DefaultChatSystemChatEvents.OnMessageDoneFiltering.OnClientEvent:Connect(function(messageData)
304 get(game:GetService("Players")[messageData.FromSpeaker],messageData.Message)
305 end)
306
307 local sendEnabled = false
308 local target = ""
309
310 function translateTo(message, target)
311 target = target:lower()
312 local translation = translate(message, target, "auto")
313
314 return translation.text
315 end
316
317 function disableSend()
318 sendEnabled = false
319 properties.Text = "[TR] Sending Disabled"
320 StarterGui:SetCore("ChatMakeSystemMessage", properties)
321 end
322
323 local CBar, CRemote, Connected = LP['PlayerGui']:WaitForChild('Chat')['Frame'].ChatBarParentFrame['Frame'].BoxFrame['Frame'].ChatBar, game:GetService('ReplicatedStorage').DefaultChatSystemChatEvents['SayMessageRequest'], {}
324
325 local HookChat = function(Bar)
326 coroutine.wrap(function()
327 if not table.find(Connected,Bar) then
328 local Connect = Bar['FocusLost']:Connect(function(Enter)
329 if Enter ~= false and Bar['Text'] ~= '' then
330 local Message = Bar['Text']
331 Bar['Text'] = '';
332 if Message == ">d" then
333 disableSend()
334 elseif Message:sub(1,1) == ">" and not Message:find(" ") then
335 if getISOCode(Message:sub(2)) then
336 sendEnabled = true
337 target = Message:sub(2)
338 else
339 properties.Text = "[TR] Invalid language"
340 StarterGui:SetCore("ChatMakeSystemMessage", properties)
341 end
342 elseif sendEnabled then
343 Message = translateTo(Message, target)
344 if not _G.SecureChat then
345 game:GetService('Players'):Chat(Message);
346 end
347 CRemote:FireServer(Message,'All')
348 else
349 if not _G.SecureChat then
350 game:GetService('Players'):Chat(Message);
351 end
352 CRemote:FireServer(Message,'All')
353 end
354 end
355 end)
356 Connected[#Connected+1] = Bar; Bar['AncestryChanged']:Wait(); Connect:Disconnect()
357 end
358 end)()
359 end
360
361 HookChat(CBar); local BindHook = Instance.new('BindableEvent')
362
363 local MT = getrawmetatable(game); local NC = MT.__namecall; setreadonly(MT, false)
364
365 MT.__namecall = newcclosure(function(...)
366 local Method, Args = getnamecallmethod(), {...}
367 if rawequal(tostring(Args[1]),'ChatBarFocusChanged') and rawequal(Args[2],true) then
368 if LP['PlayerGui']:FindFirstChild('Chat') then
369 BindHook:Fire()
370 end
371 end
372 return NC(...)
373 end)
374
375 BindHook['Event']:Connect(function()
376 CBar = LP['PlayerGui'].Chat['Frame'].ChatBarParentFrame['Frame'].BoxFrame['Frame'].ChatBar
377 HookChat(CBar)
378 end)
379end)