-- I love danny, We Love danny local Net = { Log = {}, Block = {}, Exclude = {}, Paused = false, Selected = nil, Rows = {} } local CGUI = game:GetService("CoreGui") local TS = game:GetService("TweenService") local UIS = game:GetService("UserInputService") local HS = game:GetService("HttpService") local DIR = "Photon" local oldGet = game.HttpGet local oldPost = game.HttpPostAsync local oldReq = request or (syn and syn.request) or (http and http.request) local function Create(cls, props) local inst = Instance.new(cls) for k, v in pairs(props) do inst[k] = v end return inst end local function matches(pool, url) for _, pattern in ipairs(pool) do if string.find(url, pattern, 1, true) then return true end end return false end local function keyFor(entry) return (entry.method or "GET") .. "|" .. entry.url end local function buildSnippet(entry) local lines = {} if entry.kind == "request" then table.insert(lines, "request({") table.insert(lines, string.format(" Url = %q,", entry.url)) table.insert(lines, string.format(" Method = %q,", entry.method or "GET")) if entry.headers and next(entry.headers) then table.insert(lines, " Headers = {") for k, v in pairs(entry.headers) do table.insert(lines, string.format(" [%q] = %q,", k, tostring(v))) end table.insert(lines, " },") end if entry.body and entry.body ~= "" then table.insert(lines, string.format(" Body = %q,", entry.body)) end table.insert(lines, "})") elseif entry.kind == "httpget" then table.insert(lines, string.format("game:HttpGet(%q)", entry.url)) elseif entry.kind == "httppost" then table.insert(lines, string.format("game:HttpPostAsync(%q, %q, %q)", entry.url, entry.body or "", entry.contentType or "application/json")) end return table.concat(lines, "\n") end print("Danny's too cool man") local function wrap(fn, kind) return function(...) local args = {...} local url = type(args[1]) == "table" and args[1].Url or args[1] or "" if Net.Block and matches(Net.Block, url) then if kind == "request" then return {Success = false, StatusCode = 0, StatusMessage = "blocked", Body = ""} end return "" end if Net.Paused or (Net.Exclude and matches(Net.Exclude, url)) then return fn(...) end local entry = { kind = kind, url = url, method = (type(args[1]) == "table" and args[1].Method) or "GET", headers = type(args[1]) == "table" and args[1].Headers or nil, body = (type(args[1]) == "table" and args[1].Body) or args[2], contentType = args[3], time = os.clock(), } entry.snippet = buildSnippet(entry) if Net.OnCapture then Net.OnCapture(entry) end return fn(...) end end if oldReq then hookfunction(oldReq, wrap(oldReq, "request")) end if oldGet then hookfunction(game.HttpGet, wrap(oldGet, "httpget")) end if oldPost then hookfunction(game.HttpPostAsync, wrap(oldPost, "httppost")) end local screen = Create("ScreenGui", {Name = "PhotonSpy", ResetOnSpawn = false, IgnoreGuiInset = true, Parent = CGUI}) local root = Create("Frame", { Size = UDim2.new(0, 660, 0, 440), Position = UDim2.new(0.5, -330, 0.5, -220), BackgroundColor3 = Color3.fromRGB(19, 19, 23), BorderSizePixel = 0, ClipsDescendants = true, Parent = screen }) Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = root}) local outline = Create("UIStroke", {Color = Color3.fromRGB(45, 45, 52), Thickness = 1, Parent = root}) local titleBar = Create("TextButton", { AutoButtonColor = false, Text = "", Size = UDim2.new(1, 0, 0, 38), BackgroundColor3 = Color3.fromRGB(14, 14, 17), BorderSizePixel = 0, Parent = root }) Create("UICorner", {CornerRadius = UDim.new(0, 10), Parent = titleBar}) local titleBarFix = Create("Frame", {Size = UDim2.new(1, 0, 0, 10), Position = UDim2.new(0, 0, 1, -10), BackgroundColor3 = Color3.fromRGB(14, 14, 17), BorderSizePixel = 0, ZIndex = 0, Parent = titleBar}) local dot = Create("Frame", {Size = UDim2.new(0, 8, 0, 8), Position = UDim2.new(0, 14, 0.5, -4), BackgroundColor3 = Color3.fromRGB(90, 200, 130), Parent = titleBar}) Create("UICorner", {CornerRadius = UDim.new(1, 0), Parent = dot}) local title = Create("TextLabel", {BackgroundTransparency = 1, Position = UDim2.new(0, 30, 0, 0), Size = UDim2.new(1, -140, 1, 0), Font = Enum.Font.GothamBold, TextSize = 14, TextColor3 = Color3.fromRGB(235, 235, 240), TextXAlignment = Enum.TextXAlignment.Left, Text = "Photon Spy", Parent = titleBar}) local countLabel = Create("TextLabel", {BackgroundTransparency = 1, Position = UDim2.new(1, -136, 0, 0), Size = UDim2.new(0, 56, 1, 0), Font = Enum.Font.GothamMedium, TextSize = 12, TextColor3 = Color3.fromRGB(120, 125, 135), TextXAlignment = Enum.TextXAlignment.Right, Text = "0 reqs", Parent = titleBar}) local function makeTitleBtn(text, x) local btn = Create("TextButton", { Size = UDim2.new(0, 26, 0, 26), Position = UDim2.new(1, x, 0, 6), BackgroundColor3 = Color3.fromRGB(36, 36, 41), Text = text, TextColor3 = Color3.fromRGB(210, 210, 215), Font = Enum.Font.GothamBold, TextSize = 15, AutoButtonColor = false, Parent = titleBar }) Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = btn}) btn.MouseEnter:Connect(function() TS:Create(btn, TweenInfo.new(0.1), {BackgroundColor3 = text == "×" and Color3.fromRGB(180, 60, 60) or Color3.fromRGB(60, 60, 68)}):Play() end) btn.MouseLeave:Connect(function() TS:Create(btn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(36, 36, 41)}):Play() end) return btn end local closeBtn = makeTitleBtn("×", -34) local minimizeBtn = makeTitleBtn("–", -64) closeBtn.MouseButton1Click:Connect(function() screen.Enabled = false end) local expandedHeight, minimized = 440, false minimizeBtn.MouseButton1Click:Connect(function() minimized = not minimized TS:Create(root, TweenInfo.new(0.15, Enum.EasingStyle.Quad), { Size = minimized and UDim2.new(0, 660, 0, 38) or UDim2.new(0, 660, 0, expandedHeight) }):Play() minimizeBtn.Text = minimized and "+" or "–" end) local dragging, dragStart, startPos, dragMoved titleBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true dragMoved = false dragStart = input.Position startPos = root.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) UIS.InputChanged:Connect(function(input) if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then local delta = input.Position - dragStart if math.abs(delta.X) > 3 or math.abs(delta.Y) > 3 then dragMoved = true end root.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) local function setPaused(state) Net.Paused = state local check = state titleBar.BackgroundColor3 = check and Color3.fromRGB(60, 18, 18) or Color3.fromRGB(14, 14, 17) titleBarFix.BackgroundColor3 = check and Color3.fromRGB(60, 18, 18) or Color3.fromRGB(14, 14, 17) title.TextColor3 = check and Color3.fromRGB(255, 180, 180) or Color3.fromRGB(235, 235, 240) title.Text = check and "Photon Spy (Paused)" or "Photon Spy" dot.BackgroundColor3 = check and Color3.fromRGB(210, 70, 70) or Color3.fromRGB(90, 200, 130) end titleBar.MouseButton1Click:Connect(function() if not dragMoved then setPaused(not Net.Paused) end end) local listWrap = Create("Frame", {Position = UDim2.new(0, 10, 0, 48), Size = UDim2.new(1, -20, 1, -96), BackgroundColor3 = Color3.fromRGB(13, 13, 16), BorderSizePixel = 0, Parent = root}) Create("UICorner", {CornerRadius = UDim.new(0, 8), Parent = listWrap}) local list = Create("ScrollingFrame", {Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3, ScrollBarImageColor3 = Color3.fromRGB(70, 70, 78), CanvasSize = UDim2.new(0, 0, 0, 0), AutomaticCanvasSize = Enum.AutomaticSize.Y, Parent = listWrap}) Create("UIPadding", {PaddingTop = UDim.new(0, 6), PaddingLeft = UDim.new(0, 6), PaddingRight = UDim.new(0, 6), PaddingBottom = UDim.new(0, 6), Parent = list}) local layout = Create("UIListLayout", {Padding = UDim.new(0, 4), SortOrder = Enum.SortOrder.LayoutOrder, Parent = list}) local emptyLabel = Create("TextLabel", {BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 40), Font = Enum.Font.Gotham, TextSize = 13, TextColor3 = Color3.fromRGB(90, 90, 98), Text = "waiting for requests...", LayoutOrder = 9999, Parent = list}) local toolbar = Create("Frame", {Position = UDim2.new(0, 10, 1, -40), Size = UDim2.new(1, -20, 0, 30), BackgroundTransparency = 1, Parent = root}) local leftButtons = Create("Frame", {Size = UDim2.new(1, -240, 1, 0), Position = UDim2.new(0, 0, 0, 0), BackgroundTransparency = 1, Parent = toolbar}) Create("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder, Parent = leftButtons}) local rightButtons = Create("Frame", {Size = UDim2.new(0, 220, 1, 0), Position = UDim2.new(1, -220, 0, 0), BackgroundTransparency = 1, Parent = toolbar}) Create("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, HorizontalAlignment = Enum.HorizontalAlignment.Right, Padding = UDim.new(0, 6), SortOrder = Enum.SortOrder.LayoutOrder, Parent = rightButtons}) local configInput = Create("TextBox", { Size = UDim2.new(0, 110, 1, 0), BackgroundColor3 = Color3.fromRGB(28, 28, 33), TextColor3 = Color3.fromRGB(235, 235, 240), PlaceholderColor3 = Color3.fromRGB(100, 100, 108), Font = Enum.Font.GothamMedium, TextSize = 12, Text = "", PlaceholderText = "Config name...", ClearTextOnFocus = false, LayoutOrder = 1, Parent = rightButtons }) Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = configInput}) Create("UIStroke", {Color = Color3.fromRGB(45, 45, 52), Thickness = 1, Parent = configInput}) local function makeToolBtn(parent, text, color, layoutOrder) local btn = Create("TextButton", { Size = UDim2.new(0, 0, 1, 0), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = color, TextColor3 = Color3.fromRGB(232, 232, 238), Font = Enum.Font.GothamMedium, TextSize = 12, Text = " " .. text .. " ", AutoButtonColor = false, LayoutOrder = layoutOrder or 0, Parent = parent }) Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = btn}) btn.MouseEnter:Connect(function() TS:Create(btn, TweenInfo.new(0.1), {BackgroundColor3 = color:Lerp(Color3.new(1, 1, 1), 0.12)}):Play() end) btn.MouseLeave:Connect(function() TS:Create(btn, TweenInfo.new(0.1), {BackgroundColor3 = color}):Play() end) return btn end local excludeBtn = makeToolBtn(leftButtons, "Exclude", Color3.fromRGB(40, 40, 46), 1) local blockBtn = makeToolBtn(leftButtons, "Block", Color3.fromRGB(95, 45, 50), 2) local copyBtn = makeToolBtn(leftButtons, "Copy Code", Color3.fromRGB(35, 48, 68), 3) local clearBtn = makeToolBtn(leftButtons, "Clear", Color3.fromRGB(40, 40, 46), 4) local clearBlockedBtn = makeToolBtn(leftButtons, "Clear Blocked", Color3.fromRGB(40, 40, 46), 5) local clearExcludedBtn = makeToolBtn(leftButtons, "Clear Excluded", Color3.fromRGB(40, 40, 46), 6) local saveBtn = makeToolBtn(rightButtons, "Save", Color3.fromRGB(40, 70, 50), 2) local importBtn = makeToolBtn(rightButtons, "Import", Color3.fromRGB(50, 60, 80), 3) local statusLabel = Create("TextLabel", {BackgroundTransparency = 1, Size = UDim2.new(0, 0, 1, 0), AutomaticSize = Enum.AutomaticSize.X, Font = Enum.Font.Code, TextSize = 11, TextColor3 = Color3.fromRGB(130, 130, 138), Text = "", LayoutOrder = 7, Parent = leftButtons}) local function flashStatus(text) statusLabel.Text = text statusLabel.TextColor3 = Color3.fromRGB(160, 220, 170) task.delay(2, function() if statusLabel.Text == text then statusLabel.Text = "" end end) end local function getConfigPath() local name = configInput.Text:gsub("[%/%%?%*%.%\"%>%<|%:]", "") if name == "" then name = "config" end return DIR .. "/" .. name .. ".json" end local function clearSelection() if Net.Selected then local oldKey = keyFor(Net.Selected) local oldRowData = Net.Rows[oldKey] if oldRowData and oldRowData.row then local stroke = oldRowData.row:FindFirstChild("SelectionStroke") if stroke then stroke:Destroy() end oldRowData.stroke = nil end end Net.Selected = nil end local methodColors = { GET = Color3.fromRGB(45, 90, 65), POST = Color3.fromRGB(40, 70, 100), PUT = Color3.fromRGB(95, 80, 35), PATCH = Color3.fromRGB(95, 80, 35), DELETE = Color3.fromRGB(100, 45, 50), } local function selectRow(row, entry) clearSelection() Net.Selected = entry local key = keyFor(entry) local rowData = Net.Rows[key] if rowData and rowData.row then local s = Create("UIStroke", { Name = "SelectionStroke", Color = Color3.fromRGB(120, 160, 230), Thickness = 1.5, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, Parent = rowData.row }) rowData.stroke = s end end local function makeRow(entry) local method = (entry.method or "GET"):upper() local row = Create("TextButton", { AutoButtonColor = false, Text = "", Size = UDim2.new(1, 0, 0, 50), BackgroundColor3 = Color3.fromRGB(22, 22, 27), BorderSizePixel = 0, LayoutOrder = -math.floor(entry.time * 1000), Parent = list }) Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = row}) Create("UIPadding", {PaddingLeft = UDim.new(0, 8), PaddingRight = UDim.new(0, 8), PaddingTop = UDim.new(0, 6), Parent = row}) local methodTag = Create("TextLabel", {Size = UDim2.new(0, 52, 0, 20), BackgroundColor3 = methodColors[method] or Color3.fromRGB(60, 60, 68), TextColor3 = Color3.fromRGB(225, 235, 230), Font = Enum.Font.GothamBold, TextSize = 11, Text = method, Parent = row}) Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = methodTag}) local urlLabel = Create("TextLabel", {Size = UDim2.new(1, -118, 0, 20), Position = UDim2.new(0, 60, 0, 0), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(215, 215, 220), Font = Enum.Font.Code, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, Text = entry.url, Parent = row}) local countTag = Create("TextLabel", {Size = UDim2.new(0, 46, 0, 20), Position = UDim2.new(1, -46, 0, 0), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(150, 155, 165), Font = Enum.Font.GothamMedium, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Right, Text = "x1", Parent = row}) local subLabel = Create("TextLabel", {Size = UDim2.new(1, 0, 0, 16), Position = UDim2.new(0, 60, 0, 22), BackgroundTransparency = 1, TextColor3 = Color3.fromRGB(120, 120, 128), Font = Enum.Font.Code, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, Text = entry.body and ("body: " .. tostring(entry.body):sub(1, 90)) or "no body", Parent = row}) row.MouseButton1Click:Connect(function() if Net.Selected and keyFor(Net.Selected) == keyFor(entry) then clearSelection() else selectRow(row, entry) end end) emptyLabel.Visible = false return row, countTag end Net.OnCapture = function(entry) local key = keyFor(entry) local existing = Net.Rows[key] if existing then existing.count = existing.count + 1 existing.entry = entry existing.countTag.Text = "x" .. existing.count existing.row.LayoutOrder = -math.floor(entry.time * 1000) if Net.Selected and keyFor(Net.Selected) == key then Net.Selected = entry local currentStroke = existing.row:FindFirstChild("SelectionStroke") if not currentStroke then Create("UIStroke", { Name = "SelectionStroke", Color = Color3.fromRGB(120, 160, 230), Thickness = 1.5, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, Parent = existing.row }) end end else local row, countTag = makeRow(entry) Net.Rows[key] = {row = row, countTag = countTag, count = 1, entry = entry, stroke = nil} if Net.Selected and keyFor(Net.Selected) == key then selectRow(row, entry) end end table.insert(Net.Log, 1, entry) if #Net.Log > 400 then table.remove(Net.Log) end countLabel.Text = #Net.Log .. " reqs" end excludeBtn.MouseButton1Click:Connect(function() if not Net.Selected then flashStatus("select a request first") return end local pattern = Net.Selected.url table.insert(Net.Exclude, pattern) local key = keyFor(Net.Selected) local row = Net.Rows[key] if row then row.row:Destroy() Net.Rows[key] = nil end clearSelection() flashStatus("excluded " .. pattern) end) blockBtn.MouseButton1Click:Connect(function() if not Net.Selected then flashStatus("select a request first") return end local pattern = Net.Selected.url table.insert(Net.Block, pattern) clearSelection() flashStatus("blocked " .. pattern) end) copyBtn.MouseButton1Click:Connect(function() if not Net.Selected then flashStatus("select a request first") return end local cb = setclipboard or toclipboard if cb then cb(Net.Selected.snippet) end flashStatus("copied snippet") end) clearBtn.MouseButton1Click:Connect(function() for _, data in pairs(Net.Rows) do data.row:Destroy() end Net.Rows = {} Net.Log = {} clearSelection() emptyLabel.Visible = true countLabel.Text = "0 reqs" flashStatus("cleared log") end) clearBlockedBtn.MouseButton1Click:Connect(function() Net.Block = {} flashStatus("unblocked everything") end) clearExcludedBtn.MouseButton1Click:Connect(function() Net.Exclude = {} flashStatus("unexcluded everything") end) saveBtn.MouseButton1Click:Connect(function() if not isfolder(DIR) then makefolder(DIR) end local path = getConfigPath() local fileName = path:match("([^/]+)$") writefile(path, HS:JSONEncode({Block = Net.Block, Exclude = Net.Exclude})) flashStatus("saved " .. fileName) end) importBtn.MouseButton1Click:Connect(function() local path = getConfigPath() local fileName = path:match("([^/]+)$") if not isfile(path) then flashStatus(fileName .. " not found") return end local ok, decoded = pcall(function() return HS:JSONDecode(readfile(path)) end) if ok and decoded then Net.Block = decoded.Block or {} Net.Exclude = decoded.Exclude or {} flashStatus("imported " .. fileName) else flashStatus("failed to parse config") end end) getgenv().PhotonSpy = Net