remote spy script -- LocalScript: Full Remote Tester with Scrollable Console + Multiservice + Resizable UI -- Place in StarterGui. Development and debugging only. local Players = game:GetService("Players") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local Lighting = game:GetService("Lighting") local SoundService = game:GetService("SoundService") local StarterGui = game:GetService("StarterGui") local StarterPack = game:GetService("StarterPack") local StarterPlayer = game:GetService("StarterPlayer") remote spy script How to use it? remote spy script local TextChatService = game:GetService("TextChatService") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") -- ========================= -- UTILITY FUNCTIONS -- ========================= -- Trim whitespace remote spy script How to get it? remote spy script local function trim(s) return s:match("^%s*(.-)%s*$") end -- Pretty print tables recursively local function pretty(v, depth) depth = depth or 0 local t = typeof(v) if t == "string" then return '"' .. v .. '"' elseif t == "number" or t == "boolean" or v == nil then return tostring(v) remote spy script How to get it for free? remote spy script elseif t == "table" then if depth > 4 then return "{...}" end local parts = {} for k,val in pairs(v) do table.insert(parts, string.rep(" ", depth+1) .. "["..pretty(k,depth+1).."] = "..pretty(val,depth+1)) end return "{\n"..table.concat(parts,",\n").."\n"..string.rep(" ",depth).."}" else return "<"..t..">" remote spy script How to use it? remote spy script end end -- Parse a single token local function parseToken(tok) tok = trim(tok) if tok == "" then return nil end local s = tok:match('^"(.*)"$') or tok:match("^'(.*)'$") if s then return s end if tok == "true" then return true end remote spy script How to get it for free? remote spy script if tok == "false" then return false end if tok == "nil" then return nil end local n = tonumber(tok) if n then return n end return tok end -- Parse CSV arguments into Lua values local function parseArgs(csv) csv = tostring(csv or "") remote spy script How to dowload it? remote spy script if csv == "" then return {} end local out, cur, inQuotes, quoteChar = {}, "", false, nil for i = 1, #csv do local c = csv:sub(i,i) if (c == '"' or c == "'") and not inQuotes then inQuotes = true quoteChar = c cur ..= c elseif c == quoteChar and inQuotes then inQuotes = false remote spy script How to dowload it? remote spy script quoteChar = nil cur ..= c elseif c == "," and not inQuotes then table.insert(out, parseToken(cur)) cur = "" else cur ..= c end end if cur ~= "" then table.insert(out, parseToken(cur)) end remote spy script How to get it for free? remote spy script return out end -- ========================= -- REMOTE COLLECTION -- ========================= local function safeGetDescendants(parent) local ok, descendants = pcall(function() return parent:GetDescendants() remote spy script How to use it? remote spy script end) return ok and descendants or {} end local function collectRemotes() local remotes = {} local services = { ReplicatedStorage, Players, Workspace, StarterGui, StarterPack, StarterPlayer, playerGui, Lighting, SoundService, ChatService, remote spy script PasteShr remote spy script TextChatService, CoreGui, UserGameSettings, VRService } for _, svc in ipairs(services) do for _, inst in ipairs(safeGetDescendants(svc)) do if inst:IsA("RemoteEvent") or inst:IsA("RemoteFunction") then table.insert(remotes, inst) end end end remote spy script How to get it for free? remote spy script -- Include Backpack remotes if player:FindFirstChild("Backpack") then for _, inst in ipairs(safeGetDescendants(player.Backpack)) do if inst:IsA("RemoteEvent") or inst:IsA("RemoteFunction") then table.insert(remotes, inst) end end end remote spy script How to use it? remote spy script -- Include Character tool remotes if player.Character then for _, inst in ipairs(safeGetDescendants(player.Character)) do if inst:IsA("RemoteEvent") or inst:IsA("RemoteFunction") then table.insert(remotes, inst) end end end -- Include StarterPack items remote spy script How to get it? remote spy script for _, inst in ipairs(safeGetDescendants(StarterPack)) do if inst:IsA("RemoteEvent") or inst:IsA("RemoteFunction") then table.insert(remotes, inst) end end table.sort(remotes, function(a,b) return a:GetFullName() < b:GetFullName() end) return remotes end remote spy script How to get it? remote spy script -- ========================= -- GUI SETUP -- ========================= local screenGui = Instance.new("ScreenGui") screenGui.Name = "RemoteTesterGUI" screenGui.ResetOnSpawn = false screenGui.Parent = playerGui screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling remote spy script How to get it for free? remote spy script local main = Instance.new("Frame") main.Size = UDim2.new(0.45,0,0.6,0) main.Position = UDim2.new(0.5,-260,0.15,0) main.AnchorPoint = Vector2.new(0.5,0) main.BackgroundColor3 = Color3.fromRGB(34,34,34) main.BorderSizePixel = 0 main.Parent = screenGui -- UIScale for optional zooming local uiScale = Instance.new("UIScale") remote spy script How to use it? remote spy script uiScale.Scale = 1 uiScale.Parent = main -- Titlebar local titlebar = Instance.new("Frame") titlebar.Size = UDim2.new(1,0,0,34) titlebar.BackgroundColor3 = Color3.fromRGB(24,24,24) titlebar.BorderSizePixel = 0 titlebar.Parent = main remote spy script How to get it for free? remote spy script local title = Instance.new("TextLabel") title.Size = UDim2.new(0.7,0,1,0) title.Position = UDim2.new(0,8,0,0) title.BackgroundTransparency = 1 title.Text = "ReplicatedStorage Remote Tester + Scrollable Console" title.TextColor3 = Color3.fromRGB(230,230,230) title.Font = Enum.Font.SourceSansSemibold title.TextSize = 14 title.TextXAlignment = Enum.TextXAlignment.Left title.Parent = titlebar remote spy script PasteShr remote spy script local btnClose = Instance.new("TextButton") btnClose.Size = UDim2.new(0,36,0,22) btnClose.Position = UDim2.new(1,-44,0,6) btnClose.Text = "X" btnClose.Parent = titlebar local btnMin = Instance.new("TextButton") btnMin.Size = UDim2.new(0,36,0,22) btnMin.Position = UDim2.new(1,-88,0,6) remote spy script How to dowload it? remote spy script btnMin.Text = "_" btnMin.Parent = titlebar -- Content frame local content = Instance.new("Frame") content.Size = UDim2.new(1,-16,1,-50) content.Position = UDim2.new(0,8,0,40) content.BackgroundTransparency = 1 content.Parent = main remote spy script How to dowload it? remote spy script -- Panels local leftPanel = Instance.new("Frame") leftPanel.Size = UDim2.new(0.55,0,1,0) leftPanel.Position = UDim2.new(0,0,0,0) leftPanel.BackgroundColor3 = Color3.fromRGB(28,28,28) leftPanel.BorderSizePixel = 0 leftPanel.Parent = content local rightPanel = Instance.new("Frame") rightPanel.Size = UDim2.new(0.43,0,1,0) remote spy script How to get it? remote spy script rightPanel.Position = UDim2.new(0.57,0,0,0) rightPanel.BackgroundColor3 = Color3.fromRGB(30,30,30) rightPanel.BorderSizePixel = 0 rightPanel.Parent = content -- Scrollable console local consoleFrame = Instance.new("Frame") consoleFrame.Size = UDim2.new(1,0,0.25,0) consoleFrame.Position = UDim2.new(0,0,0.75,0) consoleFrame.BackgroundColor3 = Color3.fromRGB(20,20,20) remote spy script How to get it? remote spy script consoleFrame.BorderSizePixel = 0 consoleFrame.Parent = main local consoleScroll = Instance.new("ScrollingFrame") consoleScroll.Size = UDim2.new(1,-8,1,-8) consoleScroll.Position = UDim2.new(0,4,0,4) consoleScroll.BackgroundTransparency = 1 consoleScroll.CanvasSize = UDim2.new(0,0,0,0) consoleScroll.ScrollBarThickness = 6 consoleScroll.Parent = consoleFrame remote spy script How to dowload it? remote spy script local consoleLayout = Instance.new("UIListLayout") consoleLayout.Padding = UDim.new(0,2) consoleLayout.Parent = consoleScroll -- ========================= -- LOGGING FUNCTION -- ========================= local function logConsole(msg,isError) remote spy script How to dowload it? remote spy script msg = tostring(msg) local lines = msg:split("\n") for _,line in ipairs(lines) do local label = Instance.new("TextLabel") label.Size = UDim2.new(1,0,0,16) label.BackgroundTransparency = 1 label.Font = Enum.Font.Code label.TextSize = 12 label.TextXAlignment = Enum.TextXAlignment.Left label.Text = os.date("[%H:%M:%S] ") .. line remote spy script PasteShr remote spy script label.TextColor3 = isError and Color3.fromRGB(255,80,80) or Color3.fromRGB(0,255,0) label.Parent = consoleScroll end consoleScroll.CanvasSize = UDim2.new(0,0,0,consoleLayout.AbsoluteContentSize.Y + 4) consoleScroll.CanvasPosition = Vector2.new(0, consoleScroll.CanvasSize.Y.Offset) end -- ========================= -- REMOTES UI -- ========================= remote spy script How to get it? remote spy script local remotesLabel = Instance.new("TextLabel") remotesLabel.Size = UDim2.new(1,0,0,26) remotesLabel.Position = UDim2.new(0,8,0,6) remotesLabel.BackgroundTransparency = 1 remotesLabel.Text = "Remotes in accessible services" remotesLabel.TextColor3 = Color3.fromRGB(220,220,220) remotesLabel.Font = Enum.Font.SourceSansSemibold remotesLabel.TextSize = 14 remotesLabel.TextXAlignment = Enum.TextXAlignment.Left remote spy script How to get it? remote spy script remotesLabel.Parent = leftPanel local refreshBtn = Instance.new("TextButton") refreshBtn.Size = UDim2.new(0,80,0,24) refreshBtn.Position = UDim2.new(1,-88,0,6) refreshBtn.Text = "Refresh" refreshBtn.Parent = leftPanel local remotesList = Instance.new("ScrollingFrame") remotesList.Size = UDim2.new(1,-16,1,-50) remote spy script How to dowload it? remote spy script remotesList.Position = UDim2.new(0,8,0,38) remotesList.CanvasSize = UDim2.new(0,0,0,0) remotesList.ScrollBarThickness = 6 remotesList.BackgroundTransparency = 1 remotesList.Parent = leftPanel local uiListLayout = Instance.new("UIListLayout") uiListLayout.Padding = UDim.new(0,6) uiListLayout.Parent = remotesList remote spy script PasteShr remote spy script local selectedLabel = Instance.new("TextLabel") selectedLabel.Size = UDim2.new(1,-16,0,24) selectedLabel.Position = UDim2.new(0,8,0,8) selectedLabel.BackgroundTransparency = 1 selectedLabel.Text = "Selected: (none)" selectedLabel.TextColor3 = Color3.fromRGB(230,230,230) selectedLabel.Font = Enum.Font.SourceSans selectedLabel.TextSize = 14 selectedLabel.TextXAlignment = Enum.TextXAlignment.Left selectedLabel.Parent = rightPanel remote spy script How to get it for free? remote spy script local argsLabel = Instance.new("TextLabel") argsLabel.Size = UDim2.new(1,-16,0,18) argsLabel.Position = UDim2.new(0,8,0,36) argsLabel.BackgroundTransparency = 1 argsLabel.Text = "Arguments (comma separated)" argsLabel.TextColor3 = Color3.fromRGB(200,200,200) argsLabel.Font = Enum.Font.SourceSans argsLabel.TextSize = 12 argsLabel.TextXAlignment = Enum.TextXAlignment.Left remote spy script PasteShr remote spy script argsLabel.Parent = rightPanel local argsBox = Instance.new("TextBox") argsBox.Size = UDim2.new(1,-16,0,36) argsBox.Position = UDim2.new(0,8,0,56) argsBox.ClearTextOnFocus = false argsBox.PlaceholderText = [["hello",5,true]] argsBox.Text = "" argsBox.Parent = rightPanel remote spy script PasteShr remote spy script local fireButton = Instance.new("TextButton") fireButton.Size = UDim2.new(0,200,0,36) fireButton.Position = UDim2.new(0,8,0,100) fireButton.Text = "Fire / Invoke Selected Remote" fireButton.Parent = rightPanel -- ========================= -- DRAGGING AND RESIZING -- ========================= remote spy script PasteShr remote spy script local dragging, dragStartPos, guiStartPos local resizing, resizeDir, resizeStartPos, resizeStartSize local edgeThreshold = 8 -- Determine which edge/corner is being hovered local function getResizeDirection(mousePos) local absPos = main.AbsolutePosition local absSize = main.AbsoluteSize local rightEdge = absPos.X + absSize.X local bottomEdge = absPos.Y + absSize.Y remote spy script PasteShr remote spy script local nearLeft = math.abs(mousePos.X - absPos.X) <= edgeThreshold local nearRight = math.abs(mousePos.X - rightEdge) <= edgeThreshold local nearTop = math.abs(mousePos.Y - absPos.Y) <= edgeThreshold local nearBottom = math.abs(mousePos.Y - bottomEdge) <= edgeThreshold if nearLeft and nearTop then return "TopLeft" elseif nearRight and nearTop then return "TopRight" elseif nearLeft and nearBottom then return "BottomLeft" elseif nearRight and nearBottom then return "BottomRight" elseif nearLeft then return "Left" remote spy script How to dowload it? remote spy script elseif nearRight then return "Right" elseif nearTop then return "Top" elseif nearBottom then return "Bottom" end return nil end -- Dragging titlebar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then remote spy script How to get it? remote spy script if resizing then return end dragging = true dragStartPos = input.Position guiStartPos = main.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end remote spy script How to dowload it? remote spy script end) UserInputService.InputChanged:Connect(function(input) -- Dragging if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then if resizing then return end local delta = input.Position - dragStartPos main.Position = UDim2.new(guiStartPos.X.Scale, guiStartPos.X.Offset + delta.X, guiStartPos.Y.Scale, guiStartPos.Y.Offset + delta.Y) end remote spy script How to get it? remote spy script -- Resizing if resizing and input.UserInputType == Enum.UserInputType.MouseMovement then local delta = input.Position - resizeStartPos local newSize = resizeStartSize local newPos = main.Position if resizeDir == "Right" or resizeDir == "TopRight" or resizeDir == "BottomRight" then newSize = UDim2.new(0, math.max(240, resizeStartSize.X.Offset + delta.X), 0, newSize.Y.Offset) elseif resizeDir == "Left" or resizeDir == "TopLeft" or resizeDir == "BottomLeft" then remote spy script PasteShr remote spy script local newWidth = math.max(240, resizeStartSize.X.Offset - delta.X) newSize = UDim2.new(0, newWidth, 0, newSize.Y.Offset) newPos = UDim2.new(newPos.X.Scale, newPos.X.Offset + delta.X, newPos.Y.Scale, newPos.Y.Offset) end if resizeDir == "Bottom" or resizeDir == "BottomLeft" or resizeDir == "BottomRight" then newSize = UDim2.new(0, newSize.X.Offset, 0, math.max(180, resizeStartSize.Y.Offset + delta.Y)) elseif resizeDir == "Top" or resizeDir == "TopLeft" or resizeDir == "TopRight" then local newHeight = math.max(180, resizeStartSize.Y.Offset - delta.Y) newSize = UDim2.new(0, newSize.X.Offset, 0, newHeight) remote spy script How to get it for free? remote spy script newPos = UDim2.new(newPos.X.Scale, newPos.X.Offset, newPos.Y.Scale, newPos.Y.Offset + delta.Y) end main.Size = newSize main.Position = newPos end end) main.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then remote spy script How to dowload it? remote spy script local dir = getResizeDirection(input.Position) if dir then resizing = true resizeDir = dir resizeStartPos = input.Position resizeStartSize = main.Size input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then resizing = false resizeDir = nil remote spy script PasteShr remote spy script end end) end end end) -- ========================= -- MINIMIZE / CLOSE -- ========================= remote spy script PasteShr remote spy script btnClose.MouseButton1Click:Connect(function() screenGui:Destroy() end) local minimized = false btnMin.MouseButton1Click:Connect(function() minimized = not minimized content.Visible = not minimized consoleFrame.Visible = not minimized main.Size = minimized and UDim2.new(0,240,0,34) or UDim2.new(0.45,0,0.6,0) end) -- ========================= remote spy script How to get it for free? remote spy script -- REMOTE LIST POPULATION -- ========================= local selectedRemote local function clearList() for _,v in ipairs(remotesList:GetChildren()) do if v:IsA("TextButton") then v:Destroy() end end end remote spy script How to use it? remote spy script local function populate() clearList() local remotes = collectRemotes() logConsole("Loading "..#remotes.." remotes...") spawn(function() -- run asynchronously to avoid freezing the main thread for _,inst in ipairs(remotes) do local btn = Instance.new("TextButton") btn.Size = UDim2.new(1,-8,0,28) btn.BackgroundColor3 = Color3.fromRGB(38,38,38) remote spy script How to get it? remote spy script btn.BorderSizePixel = 0 btn.Text = inst:GetFullName() btn.Font = Enum.Font.SourceSans btn.TextSize = 13 btn.TextColor3 = Color3.fromRGB(230,230,230) btn.Parent = remotesList btn.MouseButton1Click:Connect(function() for _,b in ipairs(remotesList:GetChildren()) do if b:IsA("TextButton") then remote spy script How to dowload it? remote spy script b.BackgroundColor3 = Color3.fromRGB(38,38,38) end end btn.BackgroundColor3 = Color3.fromRGB(60,60,60) selectedRemote = inst selectedLabel.Text = "Selected: " .. inst:GetFullName() end) -- Yield a little to avoid freezing on low-end task.wait(0.05) remote spy script PasteShr remote spy script end remotesList.CanvasSize = UDim2.new(0,0,0,uiListLayout.AbsoluteContentSize.Y + 8) logConsole("Finished loading "..#remotes.." remotes.") end) end refreshBtn.MouseButton1Click:Connect(function() populate() logConsole("Manual refresh triggered.") remote spy script How to dowload it? remote spy script end) ReplicatedStorage.DescendantAdded:Connect(function(d) if d:IsA("RemoteEvent") or d:IsA("RemoteFunction") then populate() end end) ReplicatedStorage.DescendantRemoving:Connect(function(d) if d:IsA("RemoteEvent") or d:IsA("RemoteFunction") then if selectedRemote == d then selectedRemote = nil end populate() end remote spy script How to get it? remote spy script end) -- ========================= -- FIRE REMOTE -- ========================= fireButton.MouseButton1Click:Connect(function() if not selectedRemote then logConsole("No remote selected.",true) return remote spy script How to get it? remote spy script end local args = parseArgs(argsBox.Text) local ok, res = pcall(function() if selectedRemote:IsA("RemoteEvent") then selectedRemote:FireServer(table.unpack(args)) return "Fired RemoteEvent." else local result = selectedRemote:InvokeServer(table.unpack(args)) return "InvokeServer returned: " .. pretty(result) end remote spy script How to dowload it? remote spy script end) if ok then logConsole(res) else logConsole("Error: "..tostring(res),true) end end) -- ========================= -- INITIALIZATION remote spy script How to use it? remote spy script -- ========================= populate() logConsole("Ready.") remote spy script