local Rayfield = loadstring(game:HttpGet("https://sirius.menu/rayfield"))() -- Services local HttpService = game:GetService("HttpService") local TeleportService = game:GetService("TeleportService") local Players = game:GetService("Players") local LocalPlayer = Players.LocalPlayer -- Core Variables local PlaceId = game.PlaceId local scannedServers, joinedHistory = {}, {} local lastServer, AutoScanRunning = nil, false local delayPerScan, serverLimit = 0.1, 200 local lastError = "No errors yet." -- Analytics Variables local totalScanned, totalScanTime, bestPingEver, serversJoined = 0, 0, math.huge, 0 -- UI local Window = Rayfield:CreateWindow({ Name = "Server Scanner", LoadingTitle = "Initializing...", ConfigurationSaving = { Enabled = true, FolderName = "ServerScanner", FileName = "settings" } }) local MainTab = Window:CreateTab("Scanner", nil) local SettingsTab = Window:CreateTab("Settings", nil) -- Analytics Paragraph local analyticsSection = MainTab:CreateParagraph({ Title = "Analytics", Content = "Total Scanned: 0\nAvg Scan Time: 0s\nBest Ping: N/A\nServers Joined: 0" }) -- Scan Status local statusParagraph = MainTab:CreateParagraph({ Title = "Status", Content = "Idle..." }) -- Analytics Updater local function UpdateAnalytics(scanCount, scanTime, bestPing) totalScanned += scanCount totalScanTime += scanTime if bestPing < bestPingEver then bestPingEver = bestPing end analyticsSection:Set({ Title = "Anylytics", Content = string.format( "Total Scanned: %d\nAvg Scan Time: %.2fs\nBest Ping: %dms\nServers Joined: %d", totalScanned, totalScanTime / math.max(1, serversJoined + 1), bestPingEver == math.huge and 0 or bestPingEver, serversJoined ) }) end -- Fetch Server List local function FetchServers(cursor) local url = ("https://games.roblox.com/v1/games/%s/servers/Public?sortOrder=2&limit=100"):format(PlaceId) if cursor then url ..= "&cursor=" .. cursor end local success, response = pcall(function() return game:HttpGet(url) end) if not success or not response then lastError = "[FetchServers] HTTP failed: " .. tostring(response) return {data={}, nextPageCursor=nil} end local successDecode, data = pcall(function() return HttpService:JSONDecode(response) end) if not successDecode then lastError = "[FetchServers] JSON Decode failed." end return (successDecode and data) or {data={}, nextPageCursor=nil} end -- Scan Servers local function ScanServers() local cursor, bestServer, bestPing, scanned = nil, nil, math.huge, 0 local start = os.clock() statusParagraph:Set({Title = "Status", Content = "Scanning servers..."}) local success, err = pcall(function() repeat local page = FetchServers(cursor) for _, server in ipairs(page.data or {}) do if typeof(server) == "table" and server.id and server.playing and server.maxPlayers then if server.playing < server.maxPlayers and not scannedServers[server.id] and not table.find(joinedHistory, server.id) then scannedServers[server.id] = true scanned += 1 local ping = math.abs(server.ping or 0) if ping < bestPing then bestServer = server bestPing = ping end end end task.wait(delayPerScan) end cursor = page.nextPageCursor until not cursor or scanned >= serverLimit end) if not success then lastError = "[ScanServers] Runtime error: " .. tostring(err) end local duration = os.clock() - start statusParagraph:Set({Title = "Status", Content = "Scan Complete."}) UpdateAnalytics(scanned, duration, bestPing) return bestServer end -- Smart Join Function local function SmartJoin(server) if not server or not server.id or server.id == lastServer then return end lastServer = server.id table.insert(joinedHistory, server.id) serversJoined += 1 UpdateAnalytics(0, 0, math.abs(server.ping or 0)) statusParagraph:Set({Title = "Status", Content = "Joining server: " .. tostring(server.id)}) TeleportService:TeleportToPlaceInstance(PlaceId, server.id, LocalPlayer) end -- Auto Scan Toggle MainTab:CreateToggle({ Name = "Auto Scan & Join", CurrentValue = false, Callback = function(Value) AutoScanRunning = Value if Value then task.spawn(function() while AutoScanRunning do local best = ScanServers() if best then SmartJoin(best) end task.wait(5) end end) end end, }) -- Manual Button MainTab:CreateButton({ Name = "Manual Scan + Teleport", Callback = function() local best = ScanServers() if best then SmartJoin(best) else Rayfield:Notify({ Title = "No Server Found", Content = "Couldn't find a suitable server." }) end end }) MainTab:CreateParagraph({ Title = "Smart Scanner", Content = "This tool scans for fast, low-ping, available servers and remembers previously joined ones." }) MainTab:CreateButton({ Name = "Copy Last Error/Warning", Callback = function() setclipboard(lastError) Rayfield:Notify({ Title = "Copied!", Content = "The last error/warning has been copied to your clipboard." }) end }) -- Settings: Server Limit Slider SettingsTab:CreateSlider({ Name = "Max Servers to Scan", Range = {50, 500}, Increment = 25, CurrentValue = serverLimit, Callback = function(Value) serverLimit = Value end }) -- Settings: Delay Per Scan SettingsTab:CreateSlider({ Name = "Delay Per Server (sec)", Range = {0.01, 0.2}, Increment = 0.01, CurrentValue = delayPerScan, Callback = function(Value) delayPerScan = Value end }) SettingsTab:CreateParagraph({ Title = "Performance Tip", Content = "Lower delay = faster scans, but may cause lag. Adjust based on your device performance." })