-- Chat personalizado via WebSocket (Delta) -- Troque a URL abaixo pela do seu servidor (veja servidor.js) local URL = "wss://chat-ws-r8a6.onrender.com" local Players = game:GetService("Players") local HttpService = game:GetService("HttpService") local UIS = game:GetService("UserInputService") local lp = Players.LocalPlayer local parent = (gethui and gethui()) or game:GetService("CoreGui") -- Remove chat antigo se executar de novo if parent:FindFirstChild("WSChat") then parent.WSChat:Destroy() end -- ========== INTERFACE ========== local gui = Instance.new("ScreenGui") gui.Name = "WSChat" gui.ResetOnSpawn = false gui.Parent = parent local main = Instance.new("Frame") main.Size = UDim2.new(0, 300, 0, 230) main.Position = UDim2.new(0, 20, 0.5, -115) main.BackgroundColor3 = Color3.fromRGB(25, 25, 30) main.BorderSizePixel = 0 main.Parent = gui Instance.new("UICorner", main).CornerRadius = UDim.new(0, 8) local top = Instance.new("TextLabel") top.Size = UDim2.new(1, 0, 0, 28) top.BackgroundColor3 = Color3.fromRGB(45, 45, 60) top.BorderSizePixel = 0 top.Text = " Chat WS (arraste aqui)" top.TextColor3 = Color3.new(1, 1, 1) top.TextXAlignment = Enum.TextXAlignment.Left top.Font = Enum.Font.GothamBold top.TextSize = 14 top.Parent = main Instance.new("UICorner", top).CornerRadius = UDim.new(0, 8) local hide = Instance.new("TextButton") hide.Size = UDim2.new(0, 28, 0, 28) hide.Position = UDim2.new(1, -28, 0, 0) hide.BackgroundTransparency = 1 hide.Text = "-" hide.TextColor3 = Color3.new(1, 1, 1) hide.TextSize = 20 hide.Parent = top local box = Instance.new("ScrollingFrame") box.Size = UDim2.new(1, -10, 1, -72) box.Position = UDim2.new(0, 5, 0, 32) box.BackgroundTransparency = 1 box.BorderSizePixel = 0 box.ScrollBarThickness = 4 box.CanvasSize = UDim2.new(0, 0, 0, 0) box.AutomaticCanvasSize = Enum.AutomaticSize.Y box.Parent = main local layout = Instance.new("UIListLayout", box) layout.Padding = UDim.new(0, 2) local input = Instance.new("TextBox") input.Size = UDim2.new(1, -70, 0, 30) input.Position = UDim2.new(0, 5, 1, -35) input.BackgroundColor3 = Color3.fromRGB(40, 40, 50) input.TextColor3 = Color3.new(1, 1, 1) input.PlaceholderText = "Digite sua mensagem..." input.PlaceholderColor3 = Color3.fromRGB(150, 150, 150) input.ClearTextOnFocus = false input.Font = Enum.Font.Gotham input.TextSize = 14 input.Text = "" input.Parent = main Instance.new("UICorner", input).CornerRadius = UDim.new(0, 6) local send = Instance.new("TextButton") send.Size = UDim2.new(0, 55, 0, 30) send.Position = UDim2.new(1, -60, 1, -35) send.BackgroundColor3 = Color3.fromRGB(70, 120, 255) send.Text = "Enviar" send.TextColor3 = Color3.new(1, 1, 1) send.Font = Enum.Font.GothamBold send.TextSize = 14 send.Parent = main Instance.new("UICorner", send).CornerRadius = UDim.new(0, 6) -- ========== ARRASTAR (PC e celular) ========== local dragging, dragStart, startPos top.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then dragging, dragStart, startPos = true, i.Position, main.Position end end) UIS.InputChanged:Connect(function(i) if dragging and (i.UserInputType == Enum.UserInputType.MouseMovement or i.UserInputType == Enum.UserInputType.Touch) then local d = i.Position - dragStart main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y) end end) UIS.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then dragging = false end end) -- Minimizar local minimized = false hide.MouseButton1Click:Connect(function() minimized = not minimized box.Visible = not minimized input.Visible = not minimized send.Visible = not minimized main.Size = minimized and UDim2.new(0, 300, 0, 28) or UDim2.new(0, 300, 0, 230) hide.Text = minimized and "+" or "-" end) -- ========== MENSAGENS ========== local function addMsg(name, text, color) local l = Instance.new("TextLabel") l.Size = UDim2.new(1, -6, 0, 0) l.AutomaticSize = Enum.AutomaticSize.Y l.BackgroundTransparency = 1 l.TextWrapped = true l.RichText = true l.TextXAlignment = Enum.TextXAlignment.Left l.Font = Enum.Font.Gotham l.TextSize = 14 l.TextColor3 = Color3.new(1, 1, 1) local safe = tostring(text):gsub("<", "<"):gsub(">", ">") if name then l.Text = string.format('%s: %s', color or "#6fa8ff", name, safe) else l.Text = '' .. safe .. "" end l.Parent = box task.defer(function() box.CanvasPosition = Vector2.new(0, 99999) end) end -- ========== WEBSOCKET ========== local ws local ok, err = pcall(function() ws = WebSocket.connect(URL) end) if not ok or not ws then addMsg(nil, "Falha ao conectar: " .. tostring(err)) addMsg(nil, "Confira a URL no topo do script.") else addMsg(nil, "Conectado! Pode conversar.") ws.OnMessage:Connect(function(raw) local good, data = pcall(function() return HttpService:JSONDecode(raw) end) if good and type(data) == "table" then addMsg(data.user or "?", data.text or "") else addMsg("?", raw) end end) ws.OnClose:Connect(function() addMsg(nil, "Conexão encerrada.") ws = nil end) end local function sendMsg() local t = input.Text if t == "" or #t > 200 then return end if not ws then addMsg(nil, "Sem conexão.") return end local payload = HttpService:JSONEncode({ user = lp.DisplayName, text = t }) pcall(function() ws:Send(payload) end) input.Text = "" end send.MouseButton1Click:Connect(sendMsg) input.FocusLost:Connect(function(enter) if enter then sendMsg() end end)