-- -- nion Chat by mac0 v14.5 | Fixed Message Send Handler local Players = game:GetService("Players") local TweenSvc = game:GetService("TweenService") local UIS = game:GetService("UserInputService") local ContentProvider = game:GetService("ContentProvider") local HttpSvc = game:GetService("HttpService") local TeleportService = game:GetService("TeleportService") local RunService = game:GetService("RunService") local Player = Players.LocalPlayer local PlayerGui = Player:WaitForChild("PlayerGui") -- تنظيف الواجهة القديمة if PlayerGui:FindFirstChild("nionchatgui") then PlayerGui.nionchatgui:Destroy() end -- ============================================================ -- FIREBASE REALTIME DATABASE SYNC CONFIGURATION -- ============================================================ local FIREBASE_URL = "https://psychoontop-chat-mkx-default-rtdb.firebaseio.com/" local lastProcessedKey = "" local initialFetchDone = false -- Executor-Safe Universal HTTP Request Wrapper local function makeHttpRequest(options) local req = (syn and syn.request) or http_request or request or (http and http.request) if req then local success, response = pcall(req, options) if success then return response end end return nil end -- ============================================================ -- CORE FUNCTIONS & CONFIGS -- ============================================================ local function make(class, props) local o = Instance.new(class) for k, v in pairs(props) do o[k] = v end return o end local C = { WIN = Color3.fromRGB(30, 30, 36), BG2 = Color3.fromRGB(38, 38, 46), BG3 = Color3.fromRGB(50, 50, 60), TABBAR = Color3.fromRGB(20, 20, 25), INPUT = Color3.fromRGB(28, 28, 35), BLUE = Color3.fromRGB(30, 120, 255), WINOUT = Color3.fromRGB(58, 58, 76), SYSBG = Color3.fromRGB(70, 56, 8), SYSTXT = Color3.fromRGB(255, 208, 35), WHITE = Color3.fromRGB(255, 255, 255), GRAY = Color3.fromRGB(135, 135, 152), ME = Color3.fromRGB(42, 42, 54), THEM = Color3.fromRGB(42, 42, 54), RED = Color3.fromRGB(200, 48, 48), GREEN = Color3.fromRGB(28, 185, 82), GOLD = Color3.fromRGB(255, 215, 0), } local ClientProfileData = { DisplayName = Player.DisplayName, Bio = "" } local CREATORS = { ["mac0"] = true, ["itgagagag011"] = true } local ScriptBans = {} local MutedPlayers = { All = false } -- ============================================================ -- INITIALIZATION -- ============================================================ local Gui = make("ScreenGui",{Name="nionchatgui",ResetOnSpawn=false,ZIndexBehavior=Enum.ZIndexBehavior.Sibling,IgnoreGuiInset=true}) if ScriptBans[Player.Name] then Player:Kick("\n[nion Chat by mac0]\nYou are banned from using this script environment.") return end Gui.Parent = PlayerGui -- Helper Functions local function corner(p,r) local c=Instance.new("UICorner") c.CornerRadius=UDim.new(0,r or 8) c.Parent=p end local function stroke(p,col,t) local s=Instance.new("UIStroke") s.Color=col or Color3.fromRGB(55,55,70) s.Thickness=t or 1 s.Parent=p end local function ll(p,dir,sp) local l=Instance.new("UIListLayout") l.FillDirection=dir or Enum.FillDirection.Vertical l.SortOrder=Enum.SortOrder.LayoutOrder l.Padding=UDim.new(0,sp or 4) l.Parent=p end local function tw(o,t,pr) if not o then return end local tweener = TweenSvc:Create(o, TweenInfo.new(t, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), pr) pcall(function() tweener:Play() end) end local function getTime() local t=os.date("*t") return string.format("%02d:%02d",t.hour,t.min) end local DM_STORE={} local function dmKey(a,b) local t={a,b} table.sort(t) return t[1].."__"..t[2] end local function saveConvo(key) local ok,enc=pcall(function() return HttpSvc:JSONEncode(DM_STORE[key] or {}) end) if ok then pcall(function() PlayerGui:SetAttribute("XD_"..key,enc) end) end end local function loadConvo(key) if DM_STORE[key] then return DM_STORE[key] end local raw=PlayerGui:GetAttribute("XD_"..key) if raw then local ok,dec=pcall(function() return HttpSvc:JSONDecode(raw) end) if ok and dec then DM_STORE[key]=dec return dec end end DM_STORE[key]={} return {} end local function appendDM(key,msg) if not DM_STORE[key] then loadConvo(key) end table.insert(DM_STORE[key],msg) if #DM_STORE[key]>200 then local trim={} for i=#DM_STORE[key]-199,#DM_STORE[key] do table.insert(trim,DM_STORE[key][i]) end DM_STORE[key]=trim end saveConvo(key) end -- STATE & GLOBAL VARIABLES local dmTarget = nil local dmContacts = {} local currentTab = "SERVER" local MsgScroll, CvScrl local switchTab, addDMContact -- ============================================================ -- MAIN UI SHELL WINDOW -- ============================================================ local Win=make("Frame",{ Name="NionChatWin", Size=UDim2.new(0,520,0,420), Position=UDim2.new(0.5,-260,0.5,-210), BackgroundColor3=C.WIN, BackgroundTransparency=0.28, Visible=false, ZIndex=500, Parent=Gui }) corner(Win,16) stroke(Win,C.WINOUT,1.5) local XBtn=make("TextButton",{ Size=UDim2.new(0,24,0,24), Position=UDim2.new(1,-30,0,10), BackgroundColor3=C.RED, Text="✖", TextColor3=C.WHITE, TextSize=13, Font=Enum.Font.GothamBold, ZIndex=502, Parent=Win }) corner(XBtn,7) local TabBar=make("Frame",{ Size=UDim2.new(1,0,0,44), BackgroundColor3=C.TABBAR, BackgroundTransparency=0.15, ZIndex=501, Parent=Win }) corner(TabBar,16) local TabScroll=make("ScrollingFrame",{ Size=UDim2.new(1,-34,1,0), BackgroundTransparency=1, ScrollBarThickness=0, AutomaticCanvasSize=Enum.AutomaticSize.X, ZIndex=502, Parent=TabBar }) ll(TabScroll,Enum.FillDirection.Horizontal,0) local TABS={{name="SERVER",icon="🌐"},{name="GALLERY",icon="🖼"},{name="PROFILE",icon="⚙️"},{name="DMs",icon="💬"}} local tabBtns={} for i,t in ipairs(TABS) do local btn=make("TextButton",{ Size=UDim2.new(0,84,1,0), BackgroundTransparency=1, Text=t.icon.." "..t.name, TextSize=10, Font=Enum.Font.GothamBold, TextColor3=C.GRAY, ZIndex=503, LayoutOrder=i, Parent=TabScroll }) local ul=make("Frame",{ Size=UDim2.new(0,50,0,2), Position=UDim2.new(0.5,-25,1,-2), BackgroundColor3=C.BLUE, BackgroundTransparency=1, ZIndex=503, Parent=btn }) tabBtns[t.name]={b=btn,ul=ul} end local Content=make("Frame",{ Size=UDim2.new(1,0,1,-44), Position=UDim2.new(0,0,0,44), BackgroundTransparency=1, ClipsDescendants=true, ZIndex=501, Parent=Win }) -- SERVER PAGE local SrvPage=make("Frame",{ Size=UDim2.new(1,0,1,0), BackgroundTransparency=1, ZIndex=501, Parent=Content }) MsgScroll=make("ScrollingFrame",{ Size=UDim2.new(1,-6,1,-56), Position=UDim2.new(0,3,0,3), BackgroundTransparency=1, ScrollBarThickness=2, ScrollBarImageColor3=C.BLUE, AutomaticCanvasSize=Enum.AutomaticSize.Y, ZIndex=502, Parent=SrvPage }) ll(MsgScroll,Enum.FillDirection.Vertical,5) local IBar=make("Frame",{ Size=UDim2.new(1,-10,0,48), Position=UDim2.new(0,5,1,-52), BackgroundColor3=C.INPUT, BackgroundTransparency=0.1, ZIndex=503, Parent=SrvPage }) corner(IBar,24) stroke(IBar,Color3.fromRGB(58,58,76),1) local CInput=make("TextBox",{ Size=UDim2.new(1,-150,1,-8), Position=UDim2.new(0,14,0,4), BackgroundTransparency=1, PlaceholderText="Message nion Chat...", PlaceholderColor3=C.GRAY, Text="", TextColor3=C.WHITE, TextSize=13, Font=Enum.Font.Gotham, TextXAlignment=Enum.TextXAlignment.Left, ClearTextOnFocus=false, ZIndex=504, Parent=IBar }) local VoiceBtn=make("TextButton",{ Size=UDim2.new(0,32,0,32), Position=UDim2.new(1,-145,0.5,-16), BackgroundTransparency=1, Text="🎙️", TextSize=20, ZIndex=504, Parent=IBar }) local SBtn=make("TextButton",{ Size=UDim2.new(0,40,0,40), Position=UDim2.new(1,-46,0.5,-20), BackgroundColor3=C.BLUE, Text="↑", TextColor3=C.WHITE, TextSize=24, Font=Enum.Font.GothamBold, ZIndex=504, Parent=IBar }) corner(SBtn,20) -- ============================================================ -- VOICE ENGINE & AUDIO DISPLAY -- ============================================================ local function addAudioMsg(parentScroll, sender, soundId, overrideDisplayName) if ScriptBans[sender] or MutedPlayers.All or MutedPlayers[sender] then return end local pObj = Players:FindFirstChild(sender) local uid = pObj and pObj.UserId or 0 local currentDisplayName = overrideDisplayName or (sender == Player.Name and ClientProfileData.DisplayName or (pObj and pObj.DisplayName or sender)) local wrap = make("Frame", { Size = UDim2.new(1, -4, 0, 50), BackgroundTransparency = 1, ZIndex = 520, Parent = parentScroll }) local av = make("ImageButton", { Size = UDim2.new(0, 36, 0, 36), BackgroundColor3 = C.BG3, Image = "https://www.roblox.com/headshot-thumbnail/image?userId=" .. uid .. "&width=100&height=100&format=png", ZIndex = 521, Parent = wrap }) corner(av, 18) local bub = make("Frame", { Size = UDim2.new(0, 230, 0, 44), Position = UDim2.new(0, 44, 0, 0), BackgroundColor3 = (sender == Player.Name) and C.ME or C.THEM, BackgroundTransparency = 0.08, ZIndex = 521, Parent = wrap }) corner(bub, 10) local playBtn = make("TextButton", { Size = UDim2.new(0, 32, 0, 32), Position = UDim2.new(0, 6, 0.5, -16), BackgroundColor3 = C.BLUE, Text = "▶", TextColor3 = C.WHITE, TextSize = 14, Font = Enum.Font.GothamBold, ZIndex = 522, Parent = bub }) corner(playBtn, 16) local titleLbl = make("TextLabel", { Size = UDim2.new(1, -50, 0, 18), Position = UDim2.new(0, 44, 0, 4), BackgroundTransparency = 1, Text = "🎙️ " .. currentDisplayName, TextColor3 = C.WHITE, TextSize = 11, Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 522, Parent = bub }) local subLbl = make("TextLabel", { Size = UDim2.new(1, -50, 0, 14), Position = UDim2.new(0, 44, 0, 22), BackgroundTransparency = 1, Text = "انقر للاستماع للصوت", TextColor3 = C.GRAY, TextSize = 10, Font = Enum.Font.Gotham, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 522, Parent = bub }) local soundInstance = Instance.new("Sound") soundInstance.SoundId = string.find(soundId, "rbxassetid://") and soundId or ("rbxassetid://" .. soundId) soundInstance.Parent = bub local isPlaying = false playBtn.MouseButton1Click:Connect(function() if not isPlaying then soundInstance:Play() isPlaying = true playBtn.Text = "⏸" playBtn.BackgroundColor3 = C.RED subLbl.Text = "جاري التشغيل..." else soundInstance:Stop() isPlaying = false playBtn.Text = "▶" playBtn.BackgroundColor3 = C.BLUE subLbl.Text = "متوقف مؤقتاً" end end) soundInstance.Ended:Connect(function() isPlaying = false playBtn.Text = "▶" playBtn.BackgroundColor3 = C.BLUE subLbl.Text = "انقر للاستماع للصوت" end) task.delay(0.05, function() if parentScroll then parentScroll.CanvasPosition = Vector2.new(0, parentScroll.AbsoluteCanvasSize.Y) end end) end -- ============================================================ -- CHAT DISPLAY & SENDING LOGIC -- ============================================================ local function broadcastPayload(sender, text, isImg, imgUrl) if FIREBASE_URL == "" then return end task.spawn(function() local data = { sender = sender, displayName = ClientProfileData.DisplayName, text = text, isImg = isImg, imgUrl = imgUrl or "", timestamp = os.time() } local success, json = pcall(function() return HttpSvc:JSONEncode(data) end) if success then makeHttpRequest({ Url = FIREBASE_URL .. "global_chat.json", Method = "POST", Headers = { ["Content-Type"] = "application/json" }, Body = json }) end end) end local function addSys(text) local f=make("Frame",{ Size=UDim2.new(1,-4,0,42), BackgroundColor3=C.SYSBG, BackgroundTransparency=0.1, ZIndex=503, Parent=MsgScroll }) corner(f,8) stroke(f,Color3.fromRGB(115,90,10)) make("TextLabel",{ Size=UDim2.new(1,-14,1,0), Position=UDim2.new(0,7,0,0), BackgroundTransparency=1, Text="⚠ [SYSTEM] : "..text, TextColor3=C.SYSTXT, TextSize=12, Font=Enum.Font.GothamBold, TextWrapped=true, TextXAlignment=Enum.TextXAlignment.Left, ZIndex=504, Parent=f }) end local function addMsg(sender,text,isImg,imgUrl,overrideDisplayName) if ScriptBans[sender] or MutedPlayers.All or MutedPlayers[sender] then return end local pObj=Players:FindFirstChild(sender) local uid=pObj and pObj.UserId or 0 local currentDisplayName = overrideDisplayName or (sender == Player.Name and ClientProfileData.DisplayName or (pObj and pObj.DisplayName or sender)) local wrap=make("Frame",{ Size=UDim2.new(1,-4,0,0), AutomaticSize=Enum.AutomaticSize.Y, BackgroundTransparency=1, ZIndex=503, Parent=MsgScroll }) ll(wrap, Enum.FillDirection.Horizontal, 10) local av=make("ImageButton",{ Size=UDim2.new(0,36,0,36), BackgroundColor3=C.BG3, Image="https://www.roblox.com/headshot-thumbnail/image?userId="..uid.."&width=100&height=100&format=png", ZIndex=504, Parent=wrap }) corner(av,18) local bub=make("Frame",{ Size=UDim2.new(0.82, -46, 0, 0), AutomaticSize=Enum.AutomaticSize.Y, BackgroundColor3=(sender==Player.Name) and C.ME or C.THEM, BackgroundTransparency=0.08, ZIndex=504, Parent=wrap }) corner(bub,12) local lbl=make("TextLabel",{ Size=UDim2.new(1,-16,0,0), AutomaticSize=Enum.AutomaticSize.Y, Position=UDim2.new(0,8,0,6), BackgroundTransparency=1, Text=""..currentDisplayName..": "..text, RichText=true, TextColor3=C.WHITE, TextSize=13, Font=Enum.Font.Gotham, TextWrapped=true, TextXAlignment=Enum.TextXAlignment.Left, ZIndex=505, Parent=bub }) task.delay(0.05, function() MsgScroll.CanvasPosition = Vector2.new(0, MsgScroll.AbsoluteCanvasSize.Y) end) end -- دالة معالجة الإرسال local function sendMessage() local text = CInput.Text if text == "" or string.gsub(text, "%s+", "") == "" then return end addMsg(Player.Name, text, false, nil) broadcastPayload(Player.Name, text, false, nil) CInput.Text = "" end -- ربط زر الإرسال ورابط الضغط على Enter SBtn.MouseButton1Click:Connect(sendMessage) CInput.FocusLost:Connect(function(enterPressed) if enterPressed then sendMessage() end end) -- VOICE PANEL local VoiceRecorderFrame = make("Frame", { Size = UDim2.new(1, -10, 0, 75), Position = UDim2.new(0, 5, 1, -135), BackgroundColor3 = C.BG2, Visible = false, ZIndex = 530, Parent = SrvPage }) corner(VoiceRecorderFrame, 10) stroke(VoiceRecorderFrame, Color3.fromRGB(60, 60, 85), 1.5) make("TextLabel", { Size = UDim2.new(1, -10, 0, 18), Position = UDim2.new(0, 8, 0, 4), BackgroundTransparency = 1, Text = "🎙️ معاينة وإرسال ملاحظة صوتية", TextColor3 = C.WHITE, TextSize = 11, Font = Enum.Font.GothamBold, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 531, Parent = VoiceRecorderFrame }) local AudioIdInput = make("TextBox", { Size = UDim2.new(0.48, -10, 0, 32), Position = UDim2.new(0, 8, 0, 30), BackgroundColor3 = C.INPUT, PlaceholderText = "ID الصوت (مثال: 9043887091)", PlaceholderColor3 = C.GRAY, Text = "", TextColor3 = C.WHITE, TextSize = 11, Font = Enum.Font.Gotham, ClearTextOnFocus = false, ZIndex = 531, Parent = VoiceRecorderFrame }) corner(AudioIdInput, 6) local SendVoiceBtn = make("TextButton", { Size = UDim2.new(0.26, -10, 0, 32), Position = UDim2.new(0.74, 2, 0, 30), BackgroundColor3 = C.BLUE, Text = "إرسال 🚀", TextColor3 = C.WHITE, TextSize = 11, Font = Enum.Font.GothamBold, ZIndex = 531, Parent = VoiceRecorderFrame }) corner(SendVoiceBtn, 6) SendVoiceBtn.MouseButton1Click:Connect(function() local rawId = AudioIdInput.Text if rawId == "" then return end local soundId = string.find(rawId, "rbxassetid://") and rawId or ("rbxassetid://" .. rawId) addAudioMsg(MsgScroll, Player.Name, soundId) broadcastPayload(Player.Name, "[VOICE]:" .. soundId, false, nil) AudioIdInput.Text = "" VoiceRecorderFrame.Visible = false end) VoiceBtn.MouseButton1Click:Connect(function() VoiceRecorderFrame.Visible = not VoiceRecorderFrame.Visible end) -- DMs PAGE local DMPage=make("Frame",{ Size=UDim2.new(1,0,1,0), BackgroundTransparency=1, Visible=false, ZIndex=501, Parent=Content }) -- DATABASE POLLING LOOP task.spawn(function() while task.wait(1.5) do if FIREBASE_URL ~= "" then local response = makeHttpRequest({ Url = FIREBASE_URL .. "global_chat.json?orderBy=\"$key\"&limitToLast=10", Method = "GET" }) if response and response.StatusCode == 200 then local ok, data = pcall(function() return HttpSvc:JSONEncode(response.Body) end) if ok and type(data) == "table" then local sortedPackets = {} for key, packet in pairs(data) do table.insert(sortedPackets, { key = key, val = packet }) end table.sort(sortedPackets, function(a, b) return a.key < b.key end) for _, entry in ipairs(sortedPackets) do if entry.key > lastProcessedKey then lastProcessedKey = entry.key if initialFetchDone and entry.val.sender ~= Player.Name then if entry.val.text:sub(1,8) == "[VOICE]:" then addAudioMsg(MsgScroll, entry.val.sender, entry.val.text:sub(9), entry.val.displayName) else addMsg(entry.val.sender, entry.val.text, entry.val.isImg, entry.val.imgUrl, entry.val.displayName) end end end end initialFetchDone = true end end end end end) -- TAB SWITCHER & INITIALIZATION local pages={SERVER=SrvPage,GALLERY=DMPage,PROFILE=DMPage,DMs=DMPage} function switchTab(name) currentTab=name for n,t in pairs(tabBtns) do tw(t.b,0.1,{TextColor3=(n==name) and C.WHITE or C.GRAY}) end end for name,t in pairs(tabBtns) do t.b.MouseButton1Click:Connect(function() switchTab(name) end) end XBtn.MouseButton1Click:Connect(function() Win.Visible=false end) Win.Visible = true addSys("👋 WELCOME TO NION CHAT (by mac0)!")