
Universal Script – Httpspy V2 (remake from Bebomods)
print("Hi! its me ServerDead :D (Or ServerSadzz my username from back in the day...)")
local Options = {
SaveLogs = false,
MaxEntries = 150,
PreviewLimit = 200,
StartPaused = false,
Follow = false,
HookDirect = true,
BlockedURLs = {},
}
do
local user = ({ ... })[1]
if type(user) == "table" then
for k, v in pairs(user) do Options[k] = v end
end
end
local VERSION = "v2.0"
local GAME = game
local genv = (getgenv and getgenv()) or _G
if type(genv.HttpSpy) == "table" and type(genv.HttpSpy.Unload) == "function" then
pcall(genv.HttpSpy.Unload)
end
local cloneref = cloneref or function(x) return x end
local newcc = newcclosure or function(f) return f end
local setclip = setclipboard or toclipboard or (type(Clipboard) == "table" and Clipboard.set) or nil
local Players = cloneref(GAME:GetService("Players"))
local UIS = cloneref(GAME:GetService("UserInputService"))
local CoreGui = cloneref(GAME:GetService("CoreGui"))
local State = {
enabled = not Options.StartPaused,
unloaded = false,
follow = Options.Follow == true,
filter = "",
}
local Blocked, BlockPatterns, ResponseHooks, Proxies = {}, {}, {}, {}
for k, v in pairs(Options.BlockedURLs or {}) do
if type(k) == "number" then Blocked[v] = true else Blocked[k] = v and true or nil end
end
local busy = setmetatable({}, { __mode = "k" })
local Conns = {}
local OnRequest = Instance.new("BindableEvent")
local function fmtNum(n)
local s = tostring(math.floor(n))
local out = string.reverse(string.gsub(string.reverse(s), "(%d%d%d)", "%1,"))
if string.sub(out, 1, 1) == "," then out = string.sub(out, 2) end
return out
end
local function fmtTime(dt)
if dt < 1 then return string.format("%d ms", math.floor(dt * 1000 + 0.5)) end
return string.format("%.2f s", dt)
end
local function clip(s, n)
s = tostring(s)
if #s > n then return string.sub(s, 1, n) .. "..." end
return s
end
local function deepCopy(t, seen)
if type(t) ~= "table" then return t end
seen = seen or {}
if seen[t] then return seen[t] end
local c = {}
seen[t] = c
for k, v in pairs(t) do c[deepCopy(k, seen)] = deepCopy(v, seen) end
return c
end
local function serialize(v, indent, seen)
indent = indent or ""
seen = seen or {}
local tv = type(v)
if tv == "string" then return string.format("%q", v) end
if tv ~= "table" then return tostring(v) end
if seen[v] then return "<cycle>" end
seen[v] = true
local keys = {}
for k in pairs(v) do keys[#keys + 1] = k end
table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
if #keys == 0 then seen[v] = nil return "{}" end
local inner = indent .. " "
local parts = {}
for _, k in ipairs(keys) do
local ks = (type(k) == "string" and string.match(k, "^[%a_][%w_]*$")) and k
or ("[" .. serialize(k, inner, seen) .. "]")
parts[#parts + 1] = inner .. ks .. " = " .. serialize(v[k], inner, seen)
end
seen[v] = nil
return "{\n" .. table.concat(parts, ",\n") .. "\n" .. indent .. "}"
end
local function isBlocked(url)
if Blocked[url] then return true end
for _, p in ipairs(BlockPatterns) do
if string.find(url, p, 1, true) then return true end
end
return false
end
local function guarded(fn, ...)
local th = coroutine.running()
local was = busy[th]
busy[th] = true
local res = table.pack(pcall(fn, ...))
busy[th] = was
return res
end
local function fireOnRequest(data)
pcall(function() OnRequest:Fire(data) end)
end
local logName
if Options.SaveLogs and writefile and appendfile then
logName = string.format("HttpSpy_%d_%s.txt", GAME.PlaceId, os.date("%Y-%m-%d_%H-%M-%S"))
pcall(writefile, logName, "HttpSpy " .. VERSION .. " - " .. os.date("%Y-%m-%d %H:%M:%S") .. "\n\n")
end
local rgb = Color3.fromRGB
local C = {
bg = rgb(15, 15, 19),
panel = rgb(23, 23, 29),
panel2 = rgb(31, 31, 39),
stroke = rgb(44, 44, 54),
strokeHi = rgb(85, 85, 100),
text = rgb(232, 232, 240),
dim = rgb(155, 155, 170),
faint = rgb(105, 105, 120),
accent = rgb(230, 60, 72),
green = rgb(80, 205, 125),
red = rgb(235, 75, 85),
}
local BADGE = {
GET = rgb(85, 155, 255),
POST = rgb(255, 165, 65),
PUT = rgb(175, 115, 255),
PATCH = rgb(175, 115, 255),
DELETE = rgb(235, 75, 85),
OBJ = rgb(90, 205, 205),
WS = rgb(70, 205, 160),
INFO = rgb(140, 140, 155),
}
local function new(class, props, kids)
local o = Instance.new(class)
for k, v in pairs(props or {}) do
if k ~= "Parent" then o[k] = v end
end
for _, c in ipairs(kids or {}) do c.Parent = o end
if props and props.Parent then o.Parent = props.Parent end
return o
end
local function corner(r) return new("UICorner", { CornerRadius = UDim.new(0, r) }) end
local function stroke(col) return new("UIStroke", { Color = col, Thickness = 1, ApplyStrokeMode = Enum.ApplyStrokeMode.Border }) end
local function padding(t, r, b, l)
return new("UIPadding", {
PaddingTop = UDim.new(0, t), PaddingRight = UDim.new(0, r),
PaddingBottom = UDim.new(0, b), PaddingLeft = UDim.new(0, l),
})
end
local function button(props, kids)
local st = stroke(C.stroke)
local base = {
AutoButtonColor = false, BackgroundColor3 = C.panel2, BorderSizePixel = 0,
Font = Enum.Font.GothamMedium, TextSize = 12, TextColor3 = C.text,
}
for k, v in pairs(props) do base[k] = v end
local all = { corner(5), st }
for _, k in ipairs(kids or {}) do all[#all + 1] = k end
local b = new("TextButton", base, all)
b.MouseEnter:Connect(function() st.Color = C.strokeHi end)
b.MouseLeave:Connect(function() st.Color = C.stroke end)
return b
end
local function copyTo(btn, text, idleColor)
local label = btn:GetAttribute("label") or btn.Text
btn:SetAttribute("label", label)
local ok = setclip ~= nil and pcall(setclip, text)
btn.Text = ok and "Copied" or "No clipboard"
btn.TextColor3 = ok and C.green or C.red
task.delay(1.2, function()
if btn.Parent then
btn.Text = label
btn.TextColor3 = idleColor or C.dim
end
end)
end
local Gui = new("ScreenGui", {
Name = "ServerDead_" .. tostring(math.random(100000, 999999)),
ResetOnSpawn = false,
ZIndexBehavior = Enum.ZIndexBehavior.Sibling,
DisplayOrder = 999,
})
if type(syn) == "table" and syn.protect_gui then pcall(syn.protect_gui, Gui) end
if not pcall(function() Gui.Parent = (gethui and gethui()) or CoreGui end) then
Gui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")
end
local Main = new("Frame", {
Size = UDim2.fromOffset(620, 400),
Position = UDim2.new(0.5, -310, 0.5, -200),
BackgroundColor3 = C.bg,
BorderSizePixel = 0,
Parent = Gui,
}, { corner(8), stroke(C.stroke) })
local TitleBar = new("Frame", {
Size = UDim2.new(1, 0, 0, 34),
BackgroundColor3 = C.panel,
BorderSizePixel = 0,
Parent = Main,
}, {
corner(8),
new("Frame", {
Size = UDim2.new(1, 0, 0, 8), Position = UDim2.new(0, 0, 1, -8),
BackgroundColor3 = C.panel, BorderSizePixel = 0,
}),
})
new("TextLabel", {
Size = UDim2.new(0, 70, 1, 0), Position = UDim2.fromOffset(12, 0),
BackgroundTransparency = 1, Text = "HttpSpy", TextColor3 = C.text,
Font = Enum.Font.GothamBold, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left,
Parent = TitleBar,
})
new("TextLabel", {
Size = UDim2.new(0, 60, 1, 0), Position = UDim2.fromOffset(76, 1),
BackgroundTransparency = 1, Text = VERSION, TextColor3 = C.faint,
Font = Enum.Font.Gotham, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left,
Parent = TitleBar,
})
local TitleButtons = new("Frame", {
AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -8, 0.5, 0),
Size = UDim2.fromOffset(0, 22), AutomaticSize = Enum.AutomaticSize.X,
BackgroundTransparency = 1, Parent = TitleBar,
}, {
new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 6),
HorizontalAlignment = Enum.HorizontalAlignment.Right,
VerticalAlignment = Enum.VerticalAlignment.Center,
SortOrder = Enum.SortOrder.LayoutOrder,
}),
})
local StatusBtn = button({ Size = UDim2.fromOffset(96, 22), TextSize = 11, Font = Enum.Font.GothamBold, LayoutOrder = 1, Parent = TitleButtons })
local MinBtn = button({ Size = UDim2.fromOffset(22, 22), Text = "-", TextSize = 14, LayoutOrder = 2, Parent = TitleButtons })
local CloseBtn = button({ Size = UDim2.fromOffset(22, 22), Text = "X", TextSize = 13, TextColor3 = C.red, LayoutOrder = 3, Parent = TitleButtons })
local Toolbar = new("Frame", {
Position = UDim2.fromOffset(0, 34), Size = UDim2.new(1, 0, 0, 38),
BackgroundTransparency = 1, Parent = Main,
})
local FilterBox = new("TextBox", {
Position = UDim2.new(0, 8, 0.5, -12), Size = UDim2.new(1, -262, 0, 24),
BackgroundColor3 = C.panel, BorderSizePixel = 0, ClearTextOnFocus = false,
PlaceholderText = "Filter by URL or method", PlaceholderColor3 = C.faint,
Text = "", TextColor3 = C.text, Font = Enum.Font.Gotham, TextSize = 12,
TextXAlignment = Enum.TextXAlignment.Left, ClipsDescendants = true, Parent = Toolbar,
}, { corner(5), stroke(C.stroke), padding(0, 8, 0, 8) })
local FollowBtn = button({ Position = UDim2.new(1, -246, 0.5, -12), Size = UDim2.fromOffset(80, 24), TextColor3 = C.dim, Parent = Toolbar })
local ClearBtn = button({ Position = UDim2.new(1, -160, 0.5, -12), Size = UDim2.fromOffset(64, 24), Text = "Clear", TextColor3 = C.dim, Parent = Toolbar })
local CountLabel = new("TextLabel", {
Position = UDim2.new(1, -90, 0.5, -12), Size = UDim2.fromOffset(82, 24),
BackgroundTransparency = 1, Text = "0 logs", TextColor3 = C.faint,
Font = Enum.Font.Gotham, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Right,
Parent = Toolbar,
})
local LIST_PAD = 6
local Logs = new("ScrollingFrame", {
Position = UDim2.fromOffset(8, 72), Size = UDim2.new(1, -14, 1, -82),
BackgroundTransparency = 1, BorderSizePixel = 0,
CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.None,
ScrollingDirection = Enum.ScrollingDirection.Y, ScrollBarThickness = 5,
ScrollBarImageColor3 = C.strokeHi, VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar,
Parent = Main,
}, { padding(2, 6, 2, 0) })
local Layout = new("UIListLayout", { Padding = UDim.new(0, LIST_PAD), SortOrder = Enum.SortOrder.LayoutOrder, Parent = Logs })
local EmptyLabel = new("TextLabel", {
Position = UDim2.fromOffset(8, 72), Size = UDim2.new(1, -16, 1, -82),
BackgroundTransparency = 1, Text = "No requests yet", TextColor3 = C.faint,
Font = Enum.Font.Gotham, TextSize = 13, Parent = Main,
})
local NewPill = button({
AnchorPoint = Vector2.new(0.5, 1), Position = UDim2.new(0.5, 0, 1, -16),
Size = UDim2.fromOffset(0, 24), AutomaticSize = Enum.AutomaticSize.X,
BackgroundColor3 = C.accent, TextColor3 = rgb(255, 255, 255), Font = Enum.Font.GothamBold,
TextSize = 12, Visible = false, ZIndex = 5, Parent = Main,
}, { padding(0, 12, 0, 12) })
local Grip = new("TextButton", {
AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, -2, 1, -2), Size = UDim2.fromOffset(14, 14),
BackgroundTransparency = 1, Text = "", AutoButtonColor = false, ZIndex = 6, Parent = Main,
}, {
new("Frame", {
AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, -2, 1, -2), Size = UDim2.fromOffset(6, 6),
BackgroundColor3 = C.faint, BorderSizePixel = 0, ZIndex = 6,
}, { corner(1) }),
})
local Icon = button({
Size = UDim2.fromOffset(44, 44), Position = UDim2.new(0.5, -22, 0, 8),
BackgroundColor3 = C.panel, Text = "H", TextSize = 20, Font = Enum.Font.GothamBold,
Visible = false, ZIndex = 10, Parent = Gui,
})
local function isPointer(input)
return input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch
end
local function isMove(input)
return input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch
end
local function makeDraggable(handle, target, onClick)
local dragging, moved, startInput, startPos = false, false, nil, nil
handle.InputBegan:Connect(function(input)
if not isPointer(input) then return end
dragging, moved = true, false
startInput, startPos = input.Position, target.Position
local con
con = input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
con:Disconnect()
dragging = false
if not moved and onClick then onClick() end
end
end)
end)
Conns[#Conns + 1] = UIS.InputChanged:Connect(function(input)
if not dragging or not isMove(input) then return end
local d = input.Position - startInput
if not moved and d.Magnitude < 4 then return end
moved = true
target.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)
end)
end
makeDraggable(TitleBar, Main)
do
local resizing, startInput, startSize = false, nil, nil
Grip.InputBegan:Connect(function(input)
if not isPointer(input) then return end
resizing, startInput, startSize = true, input.Position, Main.AbsoluteSize
local con
con = input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
con:Disconnect()
resizing = false
end
end)
end)
Conns[#Conns + 1] = UIS.InputChanged:Connect(function(input)
if not resizing or not isMove(input) then return end
local d = input.Position - startInput
Main.Size = UDim2.fromOffset(math.max(460, startSize.X + d.X), math.max(260, startSize.Y + d.Y))
end)
end
local Records = {}
local newBelow = 0
local wantBottomAt = nil
local function maxScroll()
return math.max(0, Logs.CanvasSize.Y.Offset - Logs.AbsoluteWindowSize.Y)
end
local function isAtBottom()
return Logs.CanvasPosition.Y >= maxScroll() - 10
end
local function scrollBottom()
Logs.CanvasPosition = Vector2.new(0, maxScroll())
end
local function refreshPill()
if isAtBottom() then newBelow = 0 end
NewPill.Visible = newBelow > 0
NewPill.Text = newBelow .. " new - jump to bottom"
end
local function requestStick()
if State.follow and isAtBottom() then wantBottomAt = os.clock() end
end
Layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
Logs.CanvasSize = UDim2.fromOffset(0, Layout.AbsoluteContentSize.Y + 6)
if wantBottomAt and os.clock() - wantBottomAt < 1 then scrollBottom() end
wantBottomAt = nil
refreshPill()
end)
Logs:GetPropertyChangedSignal("CanvasPosition"):Connect(refreshPill)
NewPill.MouseButton1Click:Connect(function()
newBelow = 0
scrollBottom()
refreshPill()
end)
local function matches(rec)
return State.filter == "" or string.find(rec.search, State.filter, 1, true) ~= nil
end
local function updateCount()
local visible = 0
for _, r in ipairs(Records) do
if r.frame and r.frame.Visible then visible += 1 end
end
CountLabel.Text = State.filter ~= "" and (visible .. " / " .. #Records) or (#Records .. (#Records == 1 and " log" or " logs"))
EmptyLabel.Visible = visible == 0
EmptyLabel.Text = #Records == 0 and "No requests yet" or "Nothing matches the filter"
end
local function trim()
while #Records > Options.MaxEntries do
local old = table.remove(Records, 1)
if old.frame then
local h = old.frame.Visible and (old.frame.AbsoluteSize.Y + LIST_PAD) or 0
old.frame:Destroy()
old.frame = nil
if h > 0 and not wantBottomAt then
Logs.CanvasPosition = Vector2.new(0, math.max(0, Logs.CanvasPosition.Y - h))
end
end
end
end
local function infoText(rec)
local p = {}
if rec.statusCode then
local msg = (type(rec.statusMsg) == "string" and rec.statusMsg ~= "") and (" " .. rec.statusMsg) or ""
p[#p + 1] = "HTTP " .. tostring(rec.statusCode) .. msg
end
if rec.state == "pending" then
p[#p + 1] = "waiting for response..."
elseif rec.state == "blocked" then
p[#p + 1] = "Blocked"
elseif rec.state == "error" then
p[#p + 1] = "Error: " .. clip(rec.err or "?", 160)
elseif rec.count then
p[#p + 1] = "Returned " .. fmtNum(rec.count) .. (rec.count == 1 and " object" or " objects")
elseif rec.body then
p[#p + 1] = #rec.body == 0 and "Empty response" or ("Response: " .. fmtNum(#rec.body) .. " characters")
elseif rec.note then
p[#p + 1] = rec.note
end
if rec.sent then p[#p + 1] = "Sent: " .. fmtNum(#rec.sent) .. " characters" end
if rec.dt and (rec.state == "done" or rec.state == "error") then p[#p + 1] = fmtTime(rec.dt) end
return table.concat(p, " | ")
end
local function writeLog(rec)
if not logName then return end
pcall(appendfile, logName, string.format("[%s] %-6s %-16s %s\n %s\n", rec.time, rec.badge, rec.source, rec.url, infoText(rec)))
end
local function smallButton(text, order, parent)
return button({
Size = UDim2.fromOffset(0, 20), AutomaticSize = Enum.AutomaticSize.X,
Text = text, TextSize = 11, TextColor3 = C.dim, LayoutOrder = order, Parent = parent,
}, { padding(0, 8, 0, 8) })
end
local function buildEntry(rec)
if State.unloaded then return end
local wasBottom = isAtBottom()
local col = BADGE[rec.badge] or BADGE.INFO
local isSys = rec.badge == "INFO"
local frame = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y,
BackgroundColor3 = C.panel, BorderSizePixel = 0, LayoutOrder = rec.id,
}, {
corner(6),
padding(7, 8, 8, 10),
new("UIListLayout", { SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 4) }),
})
local frameStroke = stroke(C.stroke)
frameStroke.Parent = frame
local header = new("Frame", { Size = UDim2.new(1, 0, 0, 20), BackgroundTransparency = 1, LayoutOrder = 1, Parent = frame })
local left = new("Frame", { Size = UDim2.new(1, 0, 1, 0), BackgroundTransparency = 1, Parent = header }, {
new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 8),
VerticalAlignment = Enum.VerticalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder,
}),
})
new("TextLabel", {
Size = UDim2.fromOffset(0, 18), AutomaticSize = Enum.AutomaticSize.X,
BackgroundColor3 = col, BackgroundTransparency = 0.82, Text = rec.badge, TextColor3 = col,
Font = Enum.Font.GothamBold, TextSize = 11, LayoutOrder = 1, Parent = left,
}, { corner(4), padding(0, 6, 0, 6) })
new("TextLabel", {
Size = UDim2.fromOffset(0, 18), AutomaticSize = Enum.AutomaticSize.X, BackgroundTransparency = 1,
Text = rec.time .. (rec.source ~= "" and (" " .. rec.source) or ""), TextColor3 = C.faint,
Font = Enum.Font.Gotham, TextSize = 11, LayoutOrder = 2, Parent = left,
})
local btns = new("Frame", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, 0, 0, 0),
Size = UDim2.new(0, 0, 1, 0), AutomaticSize = Enum.AutomaticSize.X,
BackgroundTransparency = 1, Parent = header,
}, {
new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 4),
HorizontalAlignment = Enum.HorizontalAlignment.Right, SortOrder = Enum.SortOrder.LayoutOrder,
}),
})
local respBtn
if isSys then
btns.Visible = false
else
local urlBtn = smallButton("URL", 1, btns)
urlBtn.MouseButton1Click:Connect(function() copyTo(urlBtn, rec.url) end)
if rec.request then
local reqBtn = smallButton("Request", 2, btns)
reqBtn.MouseButton1Click:Connect(function() copyTo(reqBtn, serialize(rec.request)) end)
end
respBtn = smallButton("Copy response", 3, btns)
respBtn.TextColor3 = C.text
respBtn.Visible = false
respBtn.MouseButton1Click:Connect(function()
copyTo(respBtn, rec.body or rec.copyText or "", C.text)
end)
end
new("TextLabel", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1,
Text = clip(rec.url, 500), TextColor3 = isSys and C.dim or C.text, TextWrapped = true,
Font = isSys and Enum.Font.Gotham or Enum.Font.RobotoMono, TextSize = 12,
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
LayoutOrder = 2, Parent = frame,
})
local info = new("TextLabel", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1,
Text = "", TextColor3 = C.dim, TextWrapped = true, Font = Enum.Font.GothamMedium, TextSize = 12,
TextXAlignment = Enum.TextXAlignment.Left, LayoutOrder = 3, Parent = frame,
})
local preview = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y,
BackgroundColor3 = C.bg, BorderSizePixel = 0, Visible = false, LayoutOrder = 4, Parent = frame,
}, { corner(4), padding(6, 8, 6, 8) })
local previewText = new("TextLabel", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1,
Text = "", TextColor3 = rgb(200, 220, 200), TextWrapped = true, Font = Enum.Font.RobotoMono,
TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
Parent = preview,
})
rec.refresh = function()
if not rec.frame or not rec.frame.Parent then return end
requestStick()
local text = infoText(rec)
info.Text = text
info.Visible = text ~= ""
local bad = rec.state == "error" or rec.state == "blocked"
info.TextColor3 = bad and C.red or (rec.state == "pending" and C.faint or C.dim)
frameStroke.Color = bad and rgb(90, 40, 46) or C.stroke
local body = rec.body
local show = type(body) == "string" and #body > 0 and #body <= Options.PreviewLimit
preview.Visible = show
if show then previewText.Text = body end
if respBtn then
local copyable = (type(body) == "string" and #body > 0) or (rec.copyText and #rec.copyText > 0)
respBtn.Visible = copyable and true or false
end
end
rec.frame = frame
frame.Visible = matches(rec)
rec.refresh()
frame.Parent = Logs
Records[#Records + 1] = rec
if frame.Visible then
if State.follow and wasBottom then
wantBottomAt = os.clock()
else
newBelow += 1
end
end
trim()
updateCount()
end
local Seq = 0
local function newRecord(badge, source, url)
Seq += 1
local rec = {
id = Seq, badge = badge, source = source, url = url or "",
t0 = os.clock(), time = os.date("%H:%M:%S"), state = "pending",
}
rec.search = string.lower(badge .. " " .. source .. " " .. rec.url)
task.defer(buildEntry, rec)
return rec
end
local function finishRecord(rec, fields)
for k, v in pairs(fields) do rec[k] = v end
rec.dt = os.clock() - rec.t0
if rec.refresh then task.defer(rec.refresh) end
writeLog(rec)
end
local function sysRecord(text)
local rec = newRecord("INFO", "", text)
finishRecord(rec, { state = "done" })
end
local function paintStatus()
StatusBtn.Text = State.enabled and "ENABLED" or "DISABLED"
StatusBtn.TextColor3 = State.enabled and C.green or C.red
StatusBtn.BackgroundColor3 = State.enabled and rgb(24, 44, 32) or rgb(50, 26, 30)
Icon.TextColor3 = State.enabled and C.text or C.red
end
local function paintFollow()
FollowBtn.Text = State.follow and "Following" or "Follow"
FollowBtn.TextColor3 = State.follow and C.text or C.dim
FollowBtn.BackgroundColor3 = State.follow and rgb(48, 30, 36) or C.panel2
end
local function setEnabled(v)
State.enabled = v and true or false
paintStatus()
end
local function clearLogs()
for _, r in ipairs(Records) do
if r.frame then r.frame:Destroy() r.frame = nil end
end
table.clear(Records)
newBelow = 0
Logs.CanvasPosition = Vector2.zero
refreshPill()
updateCount()
end
StatusBtn.MouseButton1Click:Connect(function() setEnabled(not State.enabled) end)
FollowBtn.MouseButton1Click:Connect(function()
State.follow = not State.follow
paintFollow()
if State.follow then scrollBottom() end
end)
ClearBtn.MouseButton1Click:Connect(clearLogs)
FilterBox:GetPropertyChangedSignal("Text"):Connect(function()
State.filter = string.lower(FilterBox.Text)
for _, r in ipairs(Records) do
if r.frame then r.frame.Visible = matches(r) end
end
newBelow = 0
refreshPill()
updateCount()
end)
MinBtn.MouseButton1Click:Connect(function()
Main.Visible = false
Icon.Visible = true
end)
makeDraggable(Icon, Icon, function()
Icon.Visible = false
Main.Visible = true
end)
paintStatus()
paintFollow()
local WATCH = {
HttpGet = "GET", HttpGetAsync = "GET",
HttpPost = "POST", HttpPostAsync = "POST",
GetObjects = "OBJ",
}
local HookedSet = {}
local function wrapFor(target, fn)
if iscclosure and not iscclosure(target) then return fn end
return newcc(fn)
end
local function handleGameCall(method, invoke, ...)
local kind = WATCH[method]
local url = tostring((...))
local source = "game:" .. method
if isBlocked(url) then
if State.enabled then finishRecord(newRecord(kind, source, url), { state = "blocked" }) end
if kind == "OBJ" then return {} end
return ""
end
if not State.enabled then return invoke(...) end
local rec = newRecord(kind, source, url)
if kind == "POST" then
local data, ctype = select(2, ...)
if data ~= nil then rec.sent = tostring(data) end
rec.request = { Url = url, Data = data, ContentType = ctype }
end
local res = guarded(invoke, ...)
if not res[1] then
finishRecord(rec, { state = "error", err = tostring(res[2]) })
error(res[2], 0)
end
local out = res[2]
if kind == "OBJ" then
local names = {}
if type(out) == "table" then
for i, o in ipairs(out) do
names[i] = typeof(o) == "Instance" and (o.ClassName .. " " .. o.Name) or tostring(o)
end
end
finishRecord(rec, { state = "done", count = #names, copyText = table.concat(names, "\n") })
else
finishRecord(rec, { state = "done", body = out == nil and "" or tostring(out) })
end
task.defer(fireOnRequest, { Url = url, Method = method })
return table.unpack(res, 2, res.n)
end
local function handleRequest(old, req)
if State.unloaded or type(req) ~= "table" or busy[coroutine.running()] then
return old(req)
end
local url = tostring(req.Url)
local method = string.upper(tostring(req.Method or "GET"))
local snapshot = deepCopy(req)
if isBlocked(url) then
if State.enabled then
local r = newRecord(method, "request", url)
r.request = snapshot
finishRecord(r, { state = "blocked" })
end
return { Success = false, StatusCode = 403, StatusMessage = "Blocked by HttpSpy", Headers = {}, Body = "" }
end
local send = req
local host = string.match(url, "^https?://([^/:]+)")
if host and Proxies[host] then
send = {}
for k, v in pairs(req) do send[k] = v end
local s, e = string.find(url, host, 1, true)
send.Url = string.sub(url, 1, s - 1) .. Proxies[host] .. string.sub(url, e + 1)
end
local rec
if State.enabled then
rec = newRecord(method, "request", url)
rec.request = snapshot
if type(req.Body) == "string" and #req.Body > 0 then rec.sent = req.Body end
task.defer(fireOnRequest, snapshot)
end
local res = guarded(old, send)
if not res[1] then
if rec then finishRecord(rec, { state = "error", err = tostring(res[2]) }) end
error(res[2], 0)
end
local response = res[2]
local hook = ResponseHooks[url]
if hook then
local ok, r = pcall(hook, response)
if ok and r ~= nil then response = r end
end
if rec then
local f = { state = "done" }
if type(response) == "table" then
f.statusCode = response.StatusCode
f.statusMsg = response.StatusMessage
f.body = response.Body == nil and "" or tostring(response.Body)
else
f.body = tostring(response)
end
finishRecord(rec, f)
end
return response
end
local installed = {}
if hookmetamethod or getrawmetatable then
local oldNamecall
local hookFn = newcc(function(self, ...)
if not State.unloaded and rawequal(self, GAME) then
local method = getnamecallmethod()
if WATCH[method] and not busy[coroutine.running()] then
return handleGameCall(method, function(...)
if setnamecallmethod then setnamecallmethod(method) end
return oldNamecall(self, ...)
end, ...)
end
end
return oldNamecall(self, ...)
end)
local ok = pcall(function()
if hookmetamethod then
oldNamecall = hookmetamethod(GAME, "__namecall", hookFn)
else
local mt = getrawmetatable(GAME)
oldNamecall = mt.__namecall
if setreadonly then setreadonly(mt, false) elseif make_writeable then make_writeable(mt) end
mt.__namecall = hookFn
if setreadonly then setreadonly(mt, true) end
end
end)
installed[#installed + 1] = ok and "namecall ok" or "namecall failed"
end
if hookfunction then
if Options.HookDirect then
local n = 0
for method in pairs(WATCH) do
local ok, fn = pcall(function() return GAME[method] end)
if ok and type(fn) == "function" and not HookedSet[fn] then
HookedSet[fn] = true
local old
local hooked = pcall(function()
old = hookfunction(fn, wrapFor(fn, function(self, ...)
if State.unloaded or not rawequal(self, GAME) or busy[coroutine.running()] then
return old(self, ...)
end
return handleGameCall(method, function(...) return old(self, ...) end, ...)
end))
end)
if hooked then n += 1 end
end
end
installed[#installed + 1] = "Calls: " .. n
end
local candidates = {
type(syn) == "table" and syn.request or nil,
type(http) == "table" and http.request or nil,
http_request,
request,
type(fluxus) == "table" and fluxus.request or nil,
}
local n = 0
for i = 1, 5 do
local fn = candidates[i]
if type(fn) == "function" and not HookedSet[fn] then
HookedSet[fn] = true
local old
local hooked = pcall(function()
old = hookfunction(fn, wrapFor(fn, function(req)
return handleRequest(old, req)
end))
end)
if hooked then n += 1 end
end
end
installed[#installed + 1] = "request: " .. n
local wsCandidates = {
{ type(WebSocket) == "table" and WebSocket.connect or nil, "WebSocket.connect" },
{ type(syn) == "table" and type(syn.websocket) == "table" and syn.websocket.connect or nil, "syn.websocket" },
}
local w = 0
for _, c in ipairs(wsCandidates) do
local fn, label = c[1], c[2]
if type(fn) == "function" and not HookedSet[fn] then
HookedSet[fn] = true
local old
local hooked = pcall(function()
old = hookfunction(fn, wrapFor(fn, function(...)
if State.unloaded or not State.enabled or busy[coroutine.running()] then
return old(...)
end
local url = tostring((...))
if isBlocked(url) then
finishRecord(newRecord("WS", label, url), { state = "blocked" })
error("HttpSpy: Blocked url", 0)
end
local rec = newRecord("WS", label, url)
local res = guarded(old, ...)
if not res[1] then
finishRecord(rec, { state = "error", err = tostring(res[2]) })
error(res[2], 0)
end
finishRecord(rec, { state = "done", note = "Connected" })
return table.unpack(res, 2, res.n)
end))
end)
if hooked then w += 1 end
end
end
installed[#installed + 1] = "websocket: " .. w
else
installed[#installed + 1] = "Executor doesn't support hookfunction"
end
sysRecord("HttpSpy " .. VERSION .. " loaded - " .. table.concat(installed, " | ")
.. (logName and ("\nSaving to: " .. logName) or ""))
local API = { Version = VERSION, OnRequest = OnRequest.Event }
local function Unload()
if State.unloaded then return end
State.unloaded = true
for _, c in ipairs(Conns) do pcall(function() c:Disconnect() end) end
pcall(function() Gui:Destroy() end)
pcall(function() OnRequest:Destroy() end)
if genv.HttpSpy == API then genv.HttpSpy = nil end
end
CloseBtn.MouseButton1Click:Connect(Unload)
function API.Unload() Unload() end
function API:SetEnabled(v) setEnabled(v) end
function API:IsEnabled() return State.enabled end
function API:Clear() clearLogs() end
function API:BlockUrl(url) Blocked[url] = true end
function API:UnblockUrl(url) Blocked[url] = nil end
function API:BlockPattern(text) BlockPatterns[#BlockPatterns + 1] = text end
function API:HookRequest(url, fn) ResponseHooks[url] = fn end
function API:UnhookRequest(url) ResponseHooks[url] = nil end
function API:ProxyHost(host, proxy) Proxies[host] = proxy end
function API:RemoveProxy(host) Proxies[host] = nil end
function API:ToggleGui(visible) Gui.Enabled = visible and true or false end
function API:SetGuiPosition(pos) Main.Position = pos end
function API:SetGuiSize(size) Main.Size = size end
API.HookSynRequest = API.HookRequest
API.UnHookSynRequest = API.UnhookRequest
API.WhitelistUrl = API.UnblockUrl
genv.HttpSpy = API
return APIHow to Execute Universal Script – Httpspy V2 (remake from Bebomods)
Step 1: Copy Code: Click the Copy Code button in the viewer above to grab the clean Lua loadstring.
Step 2: Launch Executor: Open a compatible, unpatched executor. If you need one, check our Roblox Executors Directory.
Step 3: Join Experience: Launch Roblox and join Universal Script.
Step 4: Attach & Run: Attach/inject your executor into the Roblox process, paste the code into the script tab, and press Execute.
Created By
View Author ProfileFeatures & Information
Script Changelog (1)
Community Comments (0)
No comments yet for this script.
Frequently Asked Questions
How do I execute Universal Script – Httpspy V2 (remake from Bebomods) in Roblox?
To run Universal Script – Httpspy V2 (remake from Bebomods), copy the Lua loadstring from the code viewer above, launch Roblox and join Universal Script, attach a working executor (such as Potassium, Solara, or Delta from our Executors directory), paste the code into your executor console, and click Execute.
Is Universal Script – Httpspy V2 (remake from Bebomods) keyless or does it require an access key?
Universal Script – Httpspy V2 (remake from Bebomods) requires an access key. You can retrieve the official key directly using the Get Script Key link provided above.
Is Universal Script – Httpspy V2 (remake from Bebomods) currently safe and working?
This script is active and operational. Always test scripts using a secondary (alt) Roblox account to safeguard your main profile against anti-cheat bans.


![Ez Hub [Open Source] [150+ games] - Verified script for Universal Script](https://media.kocakz.me/b74a9ac15370ba766b2fa9531f17c9dad2c0befb2b951693ae723e4c7d2c3fb6.webp)

![[KEYLESS] Moondiety Script | 20+ supported Games - Verified script for Universal Script](https://media.kocakz.me/6834c33a36c9fbe66afae4c6754c2b80386ce636b2f972464a95866f4b6a42eb.webp)

