local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local TextChatService = game:GetService("TextChatService") local CoreGui = game:GetService("CoreGui") local env = (getgenv and getgenv()) or _G env.__ChatBlocker = env.__ChatBlocker or { enabled = false, hooked = false } local State = env.__ChatBlocker if State.unload then pcall(State.unload) end local function isLegacyChatRemote(inst) return typeof(inst) == "Instance" and inst.ClassName == "RemoteEvent" and inst.Name == "SayMessageRequest" end local function isTextChannel(inst) return typeof(inst) == "Instance" and inst.ClassName == "TextChannel" end if not State.hooked then State.hooked = true if hookmetamethod and getnamecallmethod then local oldNamecall oldNamecall = hookmetamethod(game, "__namecall", newcclosure(function(self, ...) if State.enabled then local method = getnamecallmethod() if method == "FireServer" and isLegacyChatRemote(self) then return end if method == "SendAsync" and isTextChannel(self) then return end end return oldNamecall(self, ...) end)) else warn("[ChatBlocker] executor has no hookmetamethod, namecall hook will not be installed") end if hookfunction then local function hookMethod(className, methodName, check) pcall(function() local dummy = Instance.new(className) local orig orig = hookfunction(dummy[methodName], newcclosure(function(self, ...) if State.enabled and check(self) then return end return orig(self, ...) end)) dummy:Destroy() end) end hookMethod("RemoteEvent", "FireServer", isLegacyChatRemote) hookMethod("TextChannel", "SendAsync", isTextChannel) end end local function setInputBar(blocked) pcall(function() local cfg = TextChatService:FindFirstChildOfClass("ChatInputBarConfiguration") if not cfg then return end if blocked then if State.prevBar == nil then State.prevBar = cfg.Enabled end cfg.Enabled = false elseif State.prevBar ~= nil then cfg.Enabled = State.prevBar State.prevBar = nil end end) end local function getGuiParent() if gethui then local ok, ui = pcall(gethui) if ok and ui then return ui end end if pcall(function() return CoreGui:GetChildren() end) then return CoreGui end return Players.LocalPlayer:WaitForChild("PlayerGui") end local gui = Instance.new("ScreenGui") gui.Name = "ChatBlockerGui" gui.ResetOnSpawn = false gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling if syn and syn.protect_gui then pcall(syn.protect_gui, gui) end gui.Parent = getGuiParent() local frame = Instance.new("Frame") frame.Name = "Main" frame.Size = UDim2.fromOffset(220, 112) frame.Position = UDim2.new(0.5, -110, 0.3, 0) frame.BackgroundColor3 = Color3.fromRGB(28, 28, 34) frame.BorderSizePixel = 0 frame.Parent = gui Instance.new("UICorner", frame).CornerRadius = UDim.new(0, 8) local title = Instance.new("TextLabel") title.Name = "Title" title.Size = UDim2.new(1, 0, 0, 30) title.BackgroundColor3 = Color3.fromRGB(40, 40, 50) title.BorderSizePixel = 0 title.Text = " Chat Blocker" title.TextXAlignment = Enum.TextXAlignment.Left title.TextColor3 = Color3.fromRGB(235, 235, 240) title.Font = Enum.Font.SourceSansBold title.TextSize = 18 title.Parent = frame Instance.new("UICorner", title).CornerRadius = UDim.new(0, 8) local closeBtn = Instance.new("TextButton") closeBtn.Name = "Close" closeBtn.Size = UDim2.fromOffset(30, 30) closeBtn.Position = UDim2.new(1, -30, 0, 0) closeBtn.BackgroundTransparency = 1 closeBtn.Text = "X" closeBtn.TextColor3 = Color3.fromRGB(230, 90, 90) closeBtn.Font = Enum.Font.SourceSansBold closeBtn.TextSize = 18 closeBtn.Parent = title local toggle = Instance.new("TextButton") toggle.Name = "Toggle" toggle.Size = UDim2.new(1, -24, 0, 40) toggle.Position = UDim2.new(0, 12, 0, 42) toggle.BorderSizePixel = 0 toggle.TextColor3 = Color3.fromRGB(255, 255, 255) toggle.Font = Enum.Font.SourceSansBold toggle.TextSize = 20 toggle.AutoButtonColor = true toggle.Parent = frame Instance.new("UICorner", toggle).CornerRadius = UDim.new(0, 6) local hint = Instance.new("TextLabel") hint.Name = "Hint" hint.Size = UDim2.new(1, -24, 0, 18) hint.Position = UDim2.new(0, 12, 0, 88) hint.BackgroundTransparency = 1 hint.Text = "RShift - hide / show" hint.TextColor3 = Color3.fromRGB(130, 130, 140) hint.Font = Enum.Font.SourceSans hint.TextSize = 14 hint.Parent = frame local function refresh() if State.enabled then toggle.Text = "Chat: BLOCKED" toggle.BackgroundColor3 = Color3.fromRGB(46, 160, 90) else toggle.Text = "Chat: ALLOWED" toggle.BackgroundColor3 = Color3.fromRGB(170, 55, 55) end end local function setBlocked(value) State.enabled = value setInputBar(value) refresh() end local conns = {} local function connect(signal, fn) local c = signal:Connect(fn) table.insert(conns, c) return c end local dragging, dragStart, startPos, dragInput connect(title.InputBegan, function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = frame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) connect(title.InputChanged, function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then dragInput = input end end) connect(UserInputService.InputChanged, function(input) if dragging and input == dragInput then local delta = input.Position - dragStart frame.Position = UDim2.new( startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y ) end end) local function unload() State.enabled = false setInputBar(false) for _, c in ipairs(conns) do pcall(function() c:Disconnect() end) end if gui then gui:Destroy() end State.unload = nil end State.unload = unload connect(toggle.MouseButton1Click, function() setBlocked(not State.enabled) end) connect(closeBtn.MouseButton1Click, unload) connect(UserInputService.InputBegan, function(input, gameProcessed) if gameProcessed then return end if input.KeyCode == Enum.KeyCode.RightShift then frame.Visible = not frame.Visible end end) refresh()