-- 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)