-- FINAL Compact Chat Spy – EVERYTHING FIXED (Typewriter, Settings, Hashtags) local Players = game:GetService("Players") local TextChatService = game:GetService("TextChatService") local gui = Instance.new("ScreenGui") gui.Name = "ChatSpyFinal" gui.ResetOnSpawn = false gui.DisplayOrder = 999 gui.Parent = game:GetService("CoreGui") local mainFrame = Instance.new("Frame") mainFrame.Size = UDim2.new(0, 320, 0, 260) mainFrame.Position = UDim2.new(0, 10, 0, 10) mainFrame.BackgroundColor3 = Color3.fromRGB(20, 20, 20) mainFrame.BorderSizePixel = 3 mainFrame.BorderColor3 = Color3.fromRGB(255, 0, 255) mainFrame.Parent = gui -- Title Bar local titleBar = Instance.new("Frame") titleBar.Size = UDim2.new(1, 0, 0, 40) titleBar.BackgroundColor3 = Color3.fromRGB(150, 0, 255) titleBar.Parent = mainFrame local titleLabel = Instance.new("TextLabel") titleLabel.Size = UDim2.new(1, -80, 1, 0) titleLabel.BackgroundTransparency = 1 titleLabel.Text = "🔥 SPY LOADED 🔥" titleLabel.TextColor3 = Color3.new(1, 1, 1) titleLabel.Font = Enum.Font.GothamBold titleLabel.TextSize = 18 titleLabel.TextXAlignment = Enum.TextXAlignment.Left titleLabel.Position = UDim2.new(0, 10, 0, 0) titleLabel.Parent = titleBar task.spawn(function() for i = 1, 5 do titleBar.BackgroundColor3 = Color3.fromRGB(255, 0, 255) task.wait(0.3) titleBar.BackgroundColor3 = Color3.fromRGB(150, 0, 255) task.wait(0.3) end titleLabel.Text = "🔍 Chat Spy" end) local closeBtn = Instance.new("TextButton") closeBtn.Size = UDim2.new(0, 35, 0, 35) closeBtn.Position = UDim2.new(1, -40, 0, 2.5) closeBtn.BackgroundColor3 = Color3.fromRGB(200, 0, 0) closeBtn.Text = "X" closeBtn.TextColor3 = Color3.new(1, 1, 1) closeBtn.Parent = titleBar closeBtn.MouseButton1Click:Connect(function() gui:Destroy() end) -- Draggable local dragging = false local dragStart, startPos titleBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = mainFrame.Position end end) titleBar.InputChanged:Connect(function(input) if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then local delta = input.Position - dragStart mainFrame.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) game:GetService("UserInputService").InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end end) -- Tabs local tabFrame = Instance.new("Frame") tabFrame.Size = UDim2.new(1, 0, 0, 35) tabFrame.Position = UDim2.new(0, 0, 0, 40) tabFrame.BackgroundColor3 = Color3.fromRGB(35, 35, 35) tabFrame.Parent = mainFrame local logTab = Instance.new("TextButton") logTab.Size = UDim2.new(0.5, 0, 1, 0) logTab.Text = "Log" logTab.BackgroundColor3 = Color3.fromRGB(120, 0, 240) logTab.TextColor3 = Color3.new(1,1,1) logTab.Font = Enum.Font.GothamBold logTab.TextSize = 16 logTab.Parent = tabFrame local settingsTab = Instance.new("TextButton") settingsTab.Size = UDim2.new(0.5, 0, 1, 0) settingsTab.Position = UDim2.new(0.5, 0, 0, 0) settingsTab.Text = "Settings" settingsTab.BackgroundColor3 = Color3.fromRGB(60, 60, 60) settingsTab.TextColor3 = Color3.new(1,1,1) settingsTab.Font = Enum.Font.GothamBold settingsTab.TextSize = 16 settingsTab.Parent = tabFrame -- Log Frame local logFrame = Instance.new("ScrollingFrame") logFrame.Size = UDim2.new(1, -10, 1, -85) logFrame.Position = UDim2.new(0, 5, 0, 80) logFrame.BackgroundTransparency = 1 logFrame.ScrollBarThickness = 6 logFrame.Visible = true logFrame.Parent = mainFrame local logLayout = Instance.new("UIListLayout") logLayout.Padding = UDim.new(0, 4) logLayout.Parent = logFrame -- Settings Scroll local settingsScroll = Instance.new("ScrollingFrame") settingsScroll.Size = UDim2.new(1, -10, 1, -85) settingsScroll.Position = UDim2.new(0, 5, 0, 80) settingsScroll.BackgroundTransparency = 1 settingsScroll.ScrollBarThickness = 6 settingsScroll.Visible = false settingsScroll.Parent = mainFrame local settingsLayout = Instance.new("UIListLayout") settingsLayout.Padding = UDim.new(0, 10) settingsLayout.Parent = settingsScroll -- Settings Variables local msgColor = Color3.new(1, 1, 1) local tabActive = Color3.fromRGB(120, 0, 240) local typewriter = false local autoScroll = true local unfiltered = false -- Color Picker Function local function makePicker(name, default, callback) local frame = Instance.new("Frame") frame.Size = UDim2.new(1, 0, 0, 120) frame.BackgroundColor3 = Color3.fromRGB(45, 45, 55) frame.Parent = settingsScroll local title = Instance.new("TextLabel") title.Size = UDim2.new(1, 0, 0, 25) title.BackgroundTransparency = 1 title.Text = name title.TextColor3 = Color3.new(1,1,1) title.Font = Enum.Font.GothamBold title.TextSize = 15 title.TextXAlignment = Enum.TextXAlignment.Left title.Position = UDim2.new(0, 8, 0, 0) title.Parent = frame local preview = Instance.new("Frame") preview.Size = UDim2.new(0, 60, 0, 60) preview.Position = UDim2.new(1, -70, 0, 25) preview.BackgroundColor3 = default preview.BorderSizePixel = 2 preview.BorderColor3 = Color3.new(1,1,1) preview.Parent = frame local r, g, b = math.floor(default.R*255), math.floor(default.G*255), math.floor(default.B*255) local function box(ch, y) local tb = Instance.new("TextBox") tb.Size = UDim2.new(0, 45, 0, 25) tb.Position = UDim2.new(0, 8, 0, 30 + y) tb.BackgroundColor3 = Color3.fromRGB(70,70,80) tb.Text = tostring(ch == 1 and r or ch == 2 and g or b) tb.TextColor3 = Color3.new(1,1,1) tb.Parent = frame tb.FocusLost:Connect(function() local v = math.clamp(tonumber(tb.Text) or 0, 0, 255) tb.Text = v if ch == 1 then r = v elseif ch == 2 then g = v else b = v end local newC = Color3.fromRGB(r, g, b) preview.BackgroundColor3 = newC callback(newC) if name == "Active Tab Color" then tabActive = newC if logFrame.Visible then logTab.BackgroundColor3 = newC else settingsTab.BackgroundColor3 = newC end end end) end box(1, 0) box(2, 30) box(3, 60) end makePicker("Text Color", msgColor, function(c) msgColor = c end) makePicker("Active Tab Color", tabActive, function(c) tabActive = c end) -- Toggles local typeBtn = Instance.new("TextButton") typeBtn.Size = UDim2.new(1, 0, 0, 40) typeBtn.BackgroundColor3 = Color3.fromRGB(60, 60, 70) typeBtn.Text = "Typewriter: OFF" typeBtn.TextColor3 = Color3.new(1,1,1) typeBtn.Font = Enum.Font.GothamBold typeBtn.TextSize = 16 typeBtn.Parent = settingsScroll typeBtn.MouseButton1Click:Connect(function() typewriter = not typewriter typeBtn.Text = "Typewriter: " .. (typewriter and "ON" or "OFF") end) local scrollBtn = Instance.new("TextButton") scrollBtn.Size = UDim2.new(1, 0, 0, 40) scrollBtn.BackgroundColor3 = Color3.fromRGB(60, 60, 70) scrollBtn.Text = "Auto-Scroll: ON" scrollBtn.TextColor3 = Color3.new(1,1,1) scrollBtn.Font = Enum.Font.GothamBold scrollBtn.TextSize = 16 scrollBtn.Parent = settingsScroll scrollBtn.MouseButton1Click:Connect(function() autoScroll = not autoScroll scrollBtn.Text = "Auto-Scroll: " .. (autoScroll and "ON" or "OFF") end) local filterBtn = Instance.new("TextButton") filterBtn.Size = UDim2.new(1, 0, 0, 40) filterBtn.BackgroundColor3 = Color3.fromRGB(80, 40, 40) filterBtn.Text = "Unfiltered Mode: OFF" filterBtn.TextColor3 = Color3.new(1,1,1) filterBtn.Font = Enum.Font.GothamBold filterBtn.TextSize = 16 filterBtn.Parent = settingsScroll filterBtn.MouseButton1Click:Connect(function() unfiltered = not unfiltered filterBtn.Text = "Unfiltered Mode: " .. (unfiltered and "ON" or "OFF") filterBtn.BackgroundColor3 = unfiltered and Color3.fromRGB(150, 50, 50) or Color3.fromRGB(80, 40, 40) end) settingsLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() settingsScroll.CanvasSize = UDim2.new(0, 0, 0, settingsLayout.AbsoluteContentSize.Y + 10) end) -- Tab Switch logTab.MouseButton1Click:Connect(function() logFrame.Visible = true settingsScroll.Visible = false logTab.BackgroundColor3 = tabActive settingsTab.BackgroundColor3 = Color3.fromRGB(60,60,60) end) settingsTab.MouseButton1Click:Connect(function() logFrame.Visible = false settingsScroll.Visible = true settingsTab.BackgroundColor3 = tabActive logTab.BackgroundColor3 = Color3.fromRGB(60,60,60) end) -- Name Color local function getNameColor(id) local p = Players:GetPlayerByUserId(id) if p and p.Team then return p.Team.TeamColor.Color end local cols = {Color3.fromRGB(253,41,67), Color3.fromRGB(1,162,255), Color3.fromRGB(2,184,87), Color3.fromRGB(217,133,252)} return cols[(id % #cols) + 1] end -- Add Message – Typewriter FIXED (no broken tags) local function add(chName, msg) local src = msg.TextSource if not src then return end local name = Players:GetPlayerByUserId(src.UserId) and Players:GetPlayerByUserId(src.UserId).DisplayName or "Unknown" local rawText = msg.Text or "" local displayText = unfiltered and rawText or (msg.PrefixText or rawText) local time = os.date("%H:%M") local kind = chName:find("Whisper") and "[WHISPER]" or chName:find("Team") and "[TEAM]" or "[PUBLIC]" local team = Players:GetPlayerByUserId(src.UserId) and Players:GetPlayerByUserId(src.UserId).Team and " ("..Players:GetPlayerByUserId(src.UserId).Team.Name..")" or "" local col = getNameColor(src.UserId) local hex = "#" .. col:ToHex() local formatted = displayText:gsub("(#%w+)", "%1") local full = string.format("[%s] %s %s%s: %s", time, kind, hex, name, team, formatted) local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 0, 0) label.BackgroundTransparency = 1 label.TextColor3 = msgColor label.TextSize = 13 label.Font = Enum.Font.Gotham label.TextXAlignment = Enum.TextXAlignment.Left label.TextWrapped = true label.RichText = true label.AutomaticSize = Enum.AutomaticSize.Y label.Parent = logFrame local pad = Instance.new("UIPadding", label) pad.PaddingLeft = UDim.new(0, 6) if typewriter then label.Text = "" local i = 1 while i <= #full do local startTag = full:find("<", i) if startTag then label.Text = label.Text .. full:sub(i, startTag - 1) local endTag = full:find(">", startTag) if endTag then label.Text = label.Text .. full:sub(startTag, endTag) i = endTag + 1 else break end else label.Text = label.Text .. full:sub(i) break end task.wait(0.02) end else label.Text = full end if autoScroll then logFrame.CanvasPosition = Vector2.new(0, logFrame.AbsoluteCanvasSize.Y) end end -- Connect local function connectChannel(ch) if ch:IsA("TextChannel") then ch.MessageReceived:Connect(function(m) add(ch.Name, m) end) end end for _, ch in TextChatService.TextChannels:GetChildren() do connectChannel(ch) end TextChatService.TextChannels.ChildAdded:Connect(connectChannel) TextChatService.OnIncomingMessage:Connect(function(m) if m.TextSource then add("Unknown", m) end end) logLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() logFrame.CanvasSize = UDim2.new(0, 0, 0, logLayout.AbsoluteContentSize.Y + 10) if autoScroll then logFrame.CanvasPosition = Vector2.new(0, logFrame.AbsoluteCanvasSize.Y) end end) print("FINAL Chat Spy – Everything fixed: Typewriter, Settings, Hashtags, Unfiltered 👀🔥")