Dark_Agent

SignalSpy Tool 02

Jan 8th, 2026
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 75.26 KB | Cybersecurity | 0 0
  1. if getgenv().SignalSpyExecuted and type(getgenv().SignalSpyShutdown) == "function" then
  2.     pcall(getgenv().SignalSpyShutdown)
  3.     task.wait(0.3)
  4. end
  5.  
  6. getgenv().SignalSpyExecuted = true
  7. if not game:IsLoaded() then game.Loaded:Wait() end
  8.  
  9. getgenv().CaptureClasses = getgenv().CaptureClasses or {"Humanoid", "Tool", "ClickDetector", "ProximityPrompt", "Player"}
  10. getgenv().CaptureHidden = getgenv().CaptureHidden or false
  11. getgenv().CaptureDeprecated = getgenv().CaptureDeprecated or false
  12. getgenv().Ignore = getgenv().Ignore or {}
  13.  
  14. local function missing(t, f, fallback)
  15.     if type(f) == t then return f end
  16.     return fallback
  17. end
  18.  
  19. cloneref = missing("function", cloneref, function(...) return ... end)
  20. newcclosure = missing("function", newcclosure, function(f) return f end)
  21. checkcaller = missing("function", checkcaller, function() return false end)
  22. getconnections = missing("function", getconnections or get_signal_cons)
  23. firesignal = missing("function", firesignal or fire_signal)
  24. replicatesignal = missing("function", replicatesignal)
  25. getnilinstances = missing("function", getnilinstances or get_nil_instances, function() return {} end)
  26. everyClipboard = missing("function", setclipboard or toclipboard or set_clipboard)
  27. gethui = missing("function", gethui or get_hidden_gui)
  28. protect_gui = missing("function", protect_gui or (syn and syn.protect_gui))
  29. gethiddenproperty = missing("function", gethiddenproperty or get_hidden_property)
  30. sethiddenproperty = missing("function", sethiddenproperty or set_hidden_property)
  31. isscriptable = missing("function", isscriptable or is_scriptable)
  32. setscriptable = missing("function", setscriptable or set_scriptable)
  33. getrawmetatable = missing("function", getrawmetatable)
  34. setreadonly = missing("function", setreadonly)
  35. isfile = missing("function", isfile, function() return false end)
  36. isfolder = missing("function", isfolder, function() return false end)
  37. readfile = missing("function", readfile, function() return "" end)
  38. writefile = missing("function", writefile)
  39. makefolder = missing("function", makefolder)
  40. delfile = missing("function", delfile)
  41. listfiles = missing("function", listfiles, function() return {} end)
  42. iscclosure = missing("function", iscclosure, function() return false end)
  43. getinfo = missing("function", getinfo or debug.getinfo, function() return {} end)
  44.  
  45. local ExploitCapabilities = {
  46.     setscriptable = type(setscriptable) == "function",
  47.     isscriptable = type(isscriptable) == "function",
  48.     gethiddenproperty = type(gethiddenproperty) == "function",
  49.     getrawmetatable = type(getrawmetatable) == "function",
  50.     replicatesignal = type(replicatesignal) == "function",
  51.     firesignal = type(firesignal) == "function",
  52.     getconnections = type(getconnections) == "function",
  53. }
  54.  
  55. local HiddenAccessMethods = {}
  56. if ExploitCapabilities.setscriptable then table.insert(HiddenAccessMethods, "setscriptable") end
  57. if ExploitCapabilities.gethiddenproperty then table.insert(HiddenAccessMethods, "gethiddenproperty") end
  58. if ExploitCapabilities.getrawmetatable then table.insert(HiddenAccessMethods, "rawmetatable") end
  59. table.insert(HiddenAccessMethods, "direct")
  60.  
  61. local Services = setmetatable({}, {
  62.     __index = function(self, name)
  63.         local ok, svc = pcall(function() return cloneref(game:GetService(name)) end)
  64.         if ok and svc then rawset(self, name, svc) return svc end
  65.         return nil
  66.     end
  67. })
  68.  
  69. local Players = Services.Players
  70. local HttpService = Services.HttpService
  71. local TweenService = Services.TweenService
  72. local UserInputService = Services.UserInputService
  73. local RunService = Services.RunService
  74. local CoreGui = Services.CoreGui
  75. local TextService = Services.TextService
  76. local GuiService = Services.GuiService
  77.  
  78. local LocalPlayer = Players and Players.LocalPlayer
  79. local GuiInset = GuiService:GetGuiInset()
  80.  
  81. local Highlight
  82. pcall(function() Highlight = loadstring(game:HttpGet("https://raw.githubusercontent.com/infyiff/backup/refs/heads/main/SimpleSpyV3/highlight.lua"))() end)
  83.  
  84. local LazyFix
  85. pcall(function() LazyFix = loadstring(game:HttpGet("https://raw.githubusercontent.com/infyiff/backup/refs/heads/main/SimpleSpyV3/DataToCode.lua"))() end)
  86.  
  87. local COLORS = {
  88.     Background = Color3.fromRGB(37, 36, 38),
  89.     Panel = Color3.fromRGB(53, 52, 55),
  90.     Darker = Color3.fromRGB(21, 19, 20),
  91.     TopBar = Color3.fromRGB(37, 35, 38),
  92.     Accent = Color3.fromRGB(255, 100, 150),
  93.     Green = Color3.fromRGB(100, 255, 100),
  94.     Red = Color3.fromRGB(255, 100, 100),
  95.     Yellow = Color3.fromRGB(255, 200, 100),
  96.     Text = Color3.fromRGB(255, 255, 255),
  97.     TextDark = Color3.fromRGB(150, 150, 150),
  98.     Selected = Color3.fromRGB(92, 126, 229),
  99.     Orange = Color3.fromRGB(255, 150, 50),
  100.     Purple = Color3.fromRGB(180, 100, 255),
  101.     Cyan = Color3.fromRGB(100, 200, 255),
  102. }
  103.  
  104. local CONFIG = {
  105.     Enabled = true,
  106.     FilterSpammy = true,
  107.     FilterHiddenOnly = false,
  108.     FilterDeprecatedOnly = false,
  109.     SpamThreshold = 5,
  110.     SpamTimeWindow = 1,
  111.     MaxLogs = 500,
  112.     ShowClassName = true,
  113.     LeftPanelWidth = 131,
  114.     SafeMode = true,
  115. }
  116.  
  117. local logs = {}
  118. local groupedLogs = {}
  119. local selected = nil
  120. local layoutOrderNum = 999999999
  121. local SpamHistory = {}
  122. local HookedSignals = {}
  123. local Connections = {}
  124. local blacklist = {}
  125. local blocklist = {}
  126. local searchQuery = ""
  127. local classSearchQuery = ""
  128. local closed = false
  129. local sideClosed = false
  130. local sideClosing = false
  131. local mainClosing = false
  132. local classBrowserOpen = false
  133. local connectionViewerOpen = false
  134. local codebox
  135. local CachedAPIEvents = {}
  136. local TotalHookedCount = 0
  137. local HiddenHookedCount = 0
  138. local DeprecatedHookedCount = 0
  139. local FailedHooks = {hidden = {}, deprecated = {}, normal = {}}
  140. local SignalStats = {}
  141. local TotalCalls = 0
  142. local BlockedConnections = {}
  143. local HookAttempts = {}
  144.  
  145. local POPULAR_CLASSES = {"Humanoid", "Tool", "ClickDetector", "ProximityPrompt", "Player", "Sound", "AnimationTrack", "RemoteEvent", "RemoteFunction"}
  146.  
  147. local function Create(instance, properties, children)
  148.     local obj = Instance.new(instance)
  149.     for i, v in next, properties or {} do obj[i] = v end
  150.     for _, child in next, children or {} do child.Parent = obj end
  151.     return obj
  152. end
  153.  
  154. local function randomString()
  155.     local arr = {}
  156.     for i = 1, math.random(10, 20) do arr[i] = string.char(math.random(65, 90)) end
  157.     return table.concat(arr)
  158. end
  159.  
  160. local function safeCall(func, ...)
  161.     if CONFIG.SafeMode then
  162.         local ok, result = pcall(func, ...)
  163.         return ok, result
  164.     else
  165.         return true, func(...)
  166.     end
  167. end
  168.  
  169. local function getSignalFromInstance(instance, signalName, isHidden, isDeprecated)
  170.     local signal = nil
  171.     local method = "failed"
  172.     local wasScriptable = nil
  173.    
  174.     if (isHidden or isDeprecated) and ExploitCapabilities.setscriptable then
  175.         local ok1, wasScript = pcall(function()
  176.             return isscriptable and isscriptable(instance, signalName)
  177.         end)
  178.         wasScriptable = ok1 and wasScript
  179.        
  180.         if wasScriptable == false then
  181.             local ok2 = pcall(function()
  182.                 setscriptable(instance, signalName, true)
  183.             end)
  184.             if ok2 then
  185.                 local ok3, sig = pcall(function() return instance[signalName] end)
  186.                 if ok3 and sig and typeof(sig) == "RBXScriptSignal" then
  187.                     return sig, "setscriptable", true
  188.                 end
  189.             end
  190.         end
  191.     end
  192.    
  193.     local ok1, result1 = pcall(function() return instance[signalName] end)
  194.     if ok1 and result1 and typeof(result1) == "RBXScriptSignal" then
  195.         return result1, "direct", false
  196.     end
  197.    
  198.     if isHidden and ExploitCapabilities.gethiddenproperty then
  199.         local ok2, result2 = pcall(function() return gethiddenproperty(instance, signalName) end)
  200.         if ok2 and result2 and typeof(result2) == "RBXScriptSignal" then
  201.             return result2, "gethiddenproperty", false
  202.         end
  203.     end
  204.    
  205.     if isHidden and ExploitCapabilities.getrawmetatable then
  206.         local ok3, mt = pcall(function() return getrawmetatable(instance) end)
  207.         if ok3 and mt then
  208.             local oldReadonly
  209.             if setreadonly then
  210.                 pcall(function() oldReadonly = mt.__metatable setreadonly(mt, false) end)
  211.             end
  212.            
  213.             local ok4, result4 = pcall(function()
  214.                 local oldIndex = rawget(mt, "__index")
  215.                 if type(oldIndex) == "function" then
  216.                     return oldIndex(instance, signalName)
  217.                 elseif type(oldIndex) == "table" then
  218.                     return rawget(oldIndex, signalName)
  219.                 end
  220.             end)
  221.            
  222.             if setreadonly and oldReadonly then
  223.                 pcall(function() setreadonly(mt, true) end)
  224.             end
  225.            
  226.             if ok4 and result4 and typeof(result4) == "RBXScriptSignal" then
  227.                 return result4, "rawmetatable", false
  228.             end
  229.         end
  230.     end
  231.    
  232.     local ok5, result5 = pcall(function() return rawget(instance, signalName) end)
  233.     if ok5 and result5 and typeof(result5) == "RBXScriptSignal" then
  234.         return result5, "rawget", false
  235.     end
  236.    
  237.     return nil, "failed", false
  238. end
  239.  
  240. local function FetchAPIEvents()
  241.     local ok, response = pcall(function()
  242.         return game:HttpGet("https://raw.githubusercontent.com/MaximumADHD/Roblox-Client-Tracker/refs/heads/roblox/Full-API-Dump.json")
  243.     end)
  244.     if not ok or not response then return {} end
  245.    
  246.     local success, apiData = pcall(function() return HttpService:JSONDecode(response) end)
  247.     if not success or not apiData or not apiData.Classes then return {} end
  248.    
  249.     local events = {}
  250.     local stats = {normal = 0, hidden = 0, deprecated = 0, notscriptable = 0}
  251.    
  252.     for _, class in ipairs(apiData.Classes) do
  253.         if type(class.Name) == "string" then
  254.             events[class.Name] = {Superclass = class.Superclass, Events = {}, HiddenEvents = {}, DeprecatedEvents = {}}
  255.             if class.Members then
  256.                 for _, member in ipairs(class.Members) do
  257.                     if member.MemberType == "Event" and type(member.Name) == "string" then
  258.                         local isHidden = false
  259.                         local isDeprecated = false
  260.                         local isNotScriptable = false
  261.                        
  262.                         for _, tag in ipairs(member.Tags or {}) do
  263.                             if tag == "Hidden" then isHidden = true end
  264.                             if tag == "Deprecated" then isDeprecated = true end
  265.                             if tag == "NotScriptable" then isNotScriptable = true end
  266.                         end
  267.                        
  268.                         if isNotScriptable then
  269.                             stats.notscriptable = stats.notscriptable + 1
  270.                         elseif isDeprecated then
  271.                             table.insert(events[class.Name].DeprecatedEvents, member.Name)
  272.                             stats.deprecated = stats.deprecated + 1
  273.                         elseif isHidden then
  274.                             table.insert(events[class.Name].HiddenEvents, member.Name)
  275.                             stats.hidden = stats.hidden + 1
  276.                         else
  277.                             table.insert(events[class.Name].Events, member.Name)
  278.                             stats.normal = stats.normal + 1
  279.                         end
  280.                     end
  281.                 end
  282.             end
  283.         end
  284.     end
  285.    
  286.     print("[SignalSpy] API Stats - Normal:", stats.normal, "| Hidden:", stats.hidden, "| Deprecated:", stats.deprecated, "| NotScriptable:", stats.notscriptable)
  287.     return events
  288. end
  289.  
  290. local function GetClassEvents(className, includeHidden, includeDeprecated)
  291.     if type(className) ~= "string" then return {} end
  292.     local allEvents = {}
  293.     local current = className
  294.     local visited = {}
  295.    
  296.     while current and CachedAPIEvents[current] and not visited[current] do
  297.         visited[current] = true
  298.         local classData = CachedAPIEvents[current]
  299.        
  300.         for _, eventName in ipairs(classData.Events or {}) do
  301.             allEvents[eventName] = {hidden = false, deprecated = false}
  302.         end
  303.        
  304.         if includeHidden then
  305.             for _, eventName in ipairs(classData.HiddenEvents or {}) do
  306.                 allEvents[eventName] = {hidden = true, deprecated = false}
  307.             end
  308.         end
  309.        
  310.         if includeDeprecated then
  311.             for _, eventName in ipairs(classData.DeprecatedEvents or {}) do
  312.                 allEvents[eventName] = {hidden = false, deprecated = true}
  313.             end
  314.         end
  315.        
  316.         current = classData.Superclass
  317.     end
  318.    
  319.     local result = {}
  320.     for name, data in pairs(allEvents) do
  321.         table.insert(result, {name = name, hidden = data.hidden, deprecated = data.deprecated})
  322.     end
  323.     table.sort(result, function(a, b) return a.name < b.name end)
  324.     return result
  325. end
  326.  
  327. local function deepClone(args, seen)
  328.     seen = seen or {}
  329.     if type(args) ~= "table" then
  330.         if typeof(args) == "Instance" then
  331.             local ok, c = pcall(cloneref, args)
  332.             return ok and c or args
  333.         end
  334.         return args
  335.     end
  336.     if seen[args] then return seen[args] end
  337.     local copy = {}
  338.     seen[args] = copy
  339.     for k, v in next, args do copy[deepClone(k, seen)] = deepClone(v, seen) end
  340.     return copy
  341. end
  342.  
  343. local function instanceToPath(inst)
  344.     if not inst then return "nil" end
  345.     if inst == game then return "game" end
  346.     if inst == workspace then return "workspace" end
  347.     if inst == LocalPlayer then return 'game:GetService("Players").LocalPlayer' end
  348.    
  349.     local player = nil
  350.     for _, p in ipairs(Players:GetPlayers()) do
  351.         if p.Character then
  352.             if inst == p.Character then
  353.                 return p == LocalPlayer and 'game:GetService("Players").LocalPlayer.Character' or string.format('game:GetService("Players"):FindFirstChild("%s").Character', p.Name)
  354.             elseif inst:IsDescendantOf(p.Character) then
  355.                 player = p
  356.                 break
  357.             end
  358.         end
  359.     end
  360.    
  361.     local parts = {}
  362.     local current = inst
  363.    
  364.     if player then
  365.         while current and current ~= player.Character do
  366.             table.insert(parts, 1, current.Name:match("^[%a_][%w_]*$") and ("." .. current.Name) or string.format(':FindFirstChild("%s")', current.Name))
  367.             current = current.Parent
  368.         end
  369.         return (player == LocalPlayer and 'game:GetService("Players").LocalPlayer.Character' or string.format('game:GetService("Players"):FindFirstChild("%s").Character', player.Name)) .. table.concat(parts)
  370.     end
  371.    
  372.     local ok, result = pcall(function()
  373.         while current and current.Parent ~= game do
  374.             if not current.Parent then return string.format('getNil("%s", "%s")', inst.Name, inst.ClassName) end
  375.             table.insert(parts, 1, current.Name:match("^[%a_][%w_]*$") and ("." .. current.Name) or string.format(':FindFirstChild("%s")', current.Name))
  376.             current = current.Parent
  377.         end
  378.         if current and current.Parent == game then
  379.             local svc = current.ClassName
  380.             if pcall(function() return game:GetService(svc) end) then
  381.                 return string.format('game:GetService("%s")%s', svc, table.concat(parts))
  382.             end
  383.             return "game." .. current.Name .. table.concat(parts)
  384.         end
  385.         return "game"
  386.     end)
  387.     return ok and result or tostring(inst)
  388. end
  389.  
  390. local function deepSerialize(val, depth)
  391.     depth = depth or 0
  392.     if depth > 4 then return "..." end
  393.    
  394.     if LazyFix then
  395.         local ok, result = pcall(function() return LazyFix.Convert(val, true) end)
  396.         if ok and result then return result end
  397.     end
  398.    
  399.     local t = typeof(val)
  400.     local spacing = string.rep("    ", depth)
  401.     local nextSpacing = string.rep("    ", depth + 1)
  402.    
  403.     if t == "nil" then return "nil"
  404.     elseif t == "string" then return string.format("%q", #val > 150 and val:sub(1,150).."..." or val)
  405.     elseif t == "number" then return val == math.huge and "math.huge" or val == -math.huge and "-math.huge" or val ~= val and "0/0" or tostring(val)
  406.     elseif t == "boolean" then return tostring(val)
  407.     elseif t == "Instance" then return instanceToPath(val)
  408.     elseif t == "Vector3" then return string.format("Vector3.new(%s, %s, %s)", val.X, val.Y, val.Z)
  409.     elseif t == "CFrame" then return string.format("CFrame.new(%s)", table.concat({val:GetComponents()}, ", "))
  410.     elseif t == "Color3" then return string.format("Color3.new(%s, %s, %s)", val.R, val.G, val.B)
  411.     elseif t == "UDim2" then return string.format("UDim2.new(%s, %s, %s, %s)", val.X.Scale, val.X.Offset, val.Y.Scale, val.Y.Offset)
  412.     elseif t == "EnumItem" then return tostring(val)
  413.     elseif t == "function" then return "function() end"
  414.     elseif t == "table" then
  415.         local parts = {}
  416.         local count = 0
  417.         for k, v in pairs(val) do
  418.             count = count + 1
  419.             if count > 15 then table.insert(parts, nextSpacing .. "-- ...") break end
  420.             local ks = type(k) == "string" and k:match("^[%a_][%w_]*$") and k or ("[" .. deepSerialize(k, depth + 1) .. "]")
  421.             table.insert(parts, nextSpacing .. ks .. " = " .. deepSerialize(v, depth + 1))
  422.         end
  423.         return #parts == 0 and "{}" or "{\n" .. table.concat(parts, ",\n") .. "\n" .. spacing .. "}"
  424.     else return "<" .. t .. ">" end
  425. end
  426.  
  427. local function generateScript(data)
  428.     local tags = {}
  429.     if data.IsHidden then table.insert(tags, "HIDDEN") end
  430.     if data.IsDeprecated then table.insert(tags, "DEPRECATED") end
  431.    
  432.     local script = "-- Signal: " .. (data.ClassName or "?") .. "." .. data.SignalName
  433.     if #tags > 0 then script = script .. " [" .. table.concat(tags, ", ") .. "]" end
  434.     if data.AccessMethod and data.AccessMethod ~= "direct" then
  435.         script = script .. "\n-- Access: " .. data.AccessMethod
  436.         if data.UsedSetScriptable then script = script .. " (setscriptable used)" end
  437.     end
  438.     script = script .. "\n-- Instance: " .. instanceToPath(data.Instance)
  439.     script = script .. "\n-- Calls: " .. tostring(data.CallCount or 1) .. "\n\n"
  440.    
  441.     local path = instanceToPath(data.Instance)
  442.     if path:find("getNil") then
  443.         script = 'local function getNil(n,c) for _,v in ipairs(getnilinstances()) do if v.ClassName==c and v.Name==n then return v end end end\n\n' .. script
  444.     end
  445.    
  446.     if data.UsedSetScriptable then
  447.         script = script .. "-- Enable scriptable access first:\n"
  448.         script = script .. "setscriptable(" .. path .. ', "' .. data.SignalName .. '", true)\n\n'
  449.     end
  450.    
  451.     if data.Args and #data.Args > 0 then
  452.         script = script .. "local args = " .. deepSerialize(data.Args) .. "\n\n"
  453.     end
  454.    
  455.     local signalAccess
  456.     if data.AccessMethod == "gethiddenproperty" then
  457.         signalAccess = 'gethiddenproperty(' .. path .. ', "' .. data.SignalName .. '")'
  458.     else
  459.         signalAccess = path .. "." .. data.SignalName
  460.     end
  461.    
  462.     script = script .. "local signal = " .. signalAccess .. "\n\n"
  463.    
  464.     if replicatesignal then
  465.         script = script .. "-- Replicate (recommended for hidden):\n"
  466.         script = script .. "replicatesignal(signal, unpack(args or {}))\n\n"
  467.     end
  468.     if firesignal then
  469.         script = script .. "-- Fire (may crash on hidden):\n"
  470.         script = script .. "-- firesignal(signal, unpack(args or {}))"
  471.     end
  472.    
  473.     return script
  474. end
  475.  
  476. local function isSpammy(key)
  477.     if not CONFIG.FilterSpammy then return false end
  478.     local now = tick()
  479.     if not SpamHistory[key] then SpamHistory[key] = {count = 1, lastTime = now} return false end
  480.     local h = SpamHistory[key]
  481.     if now - h.lastTime > CONFIG.SpamTimeWindow then h.count = 1 else h.count = h.count + 1 end
  482.     h.lastTime = now
  483.     return h.count > CONFIG.SpamThreshold
  484. end
  485. --
  486. local SignalSpy = Create("ScreenGui", {ResetOnSpawn = false, Name = randomString(), ZIndexBehavior = Enum.ZIndexBehavior.Sibling})
  487.  
  488. local Background = Create("Frame", {
  489.     Parent = SignalSpy,
  490.     BackgroundTransparency = 1,
  491.     Position = UDim2.new(0, 500, 0, 200),
  492.     Size = UDim2.new(0, 480, 0, 320)
  493. })
  494.  
  495. local TopBar = Create("Frame", {Parent = Background, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Size = UDim2.new(0, 480, 0, 19), ZIndex = 2})
  496. local LeftPanel = Create("Frame", {Parent = Background, BackgroundColor3 = COLORS.Panel, BorderSizePixel = 0, Position = UDim2.new(0, 0, 0, 19), Size = UDim2.new(0, 131, 0, 301), ClipsDescendants = true})
  497. local PanelResizer = Create("Frame", {Parent = Background, BackgroundColor3 = COLORS.Accent, BackgroundTransparency = 0.7, BorderSizePixel = 0, Position = UDim2.new(0, 129, 0, 19), Size = UDim2.new(0, 4, 0, 301), ZIndex = 5})
  498. Create("TextLabel", {Parent = PanelResizer, BackgroundTransparency = 1, Size = UDim2.new(1, 0, 1, 0), Font = Enum.Font.SourceSansBold, Text = "⋮", TextColor3 = COLORS.Text, TextSize = 14, ZIndex = 5})
  499.  
  500. local SearchFrame = Create("Frame", {Parent = LeftPanel, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 5, 0, 5), Size = UDim2.new(1, -10, 0, 22)})
  501. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = SearchFrame})
  502. local SearchBox = Create("TextBox", {Parent = SearchFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 0), Size = UDim2.new(1, -10, 1, 0), Font = Enum.Font.SourceSans, PlaceholderText = "Search...", PlaceholderColor3 = COLORS.TextDark, Text = "", TextColor3 = COLORS.Text, TextSize = 12, ClearTextOnFocus = false})
  503.  
  504. local LogList = Create("ScrollingFrame", {Parent = LeftPanel, BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.new(0, 0, 0, 32), Size = UDim2.new(1, 0, 1, -40), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 4, ScrollBarImageColor3 = COLORS.Accent, ClipsDescendants = true})
  505. local UIListLayout = Create("UIListLayout", {Parent = LogList, HorizontalAlignment = Enum.HorizontalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 1)})
  506.  
  507. local RightPanel = Create("Frame", {Parent = Background, BackgroundColor3 = COLORS.Background, BorderSizePixel = 0, Position = UDim2.new(0, 133, 0, 19), Size = UDim2.new(0, 347, 0, 301), ClipsDescendants = true})
  508. local CodeBox = Create("Frame", {Parent = RightPanel, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Size = UDim2.new(1, 0, 0.5, 0)})
  509. local ButtonsFrame = Create("ScrollingFrame", {Parent = RightPanel, BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0.5, 0), Size = UDim2.new(1, 0, 0.5, -9), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 4, ScrollBarImageColor3 = COLORS.Accent})
  510. local UIGridLayout = Create("UIGridLayout", {Parent = ButtonsFrame, HorizontalAlignment = Enum.HorizontalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, CellSize = UDim2.new(0, 94, 0, 27)})
  511.  
  512. local TitleButton = Create("TextButton", {Parent = TopBar, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 0), Size = UDim2.new(0, 80, 0, 18), Font = Enum.Font.SourceSansBold, Text = "SignalSpy", TextColor3 = COLORS.Green, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 2})
  513. local StatusLabel = Create("TextLabel", {Parent = TopBar, BackgroundTransparency = 1, Position = UDim2.new(0, 90, 0, 0), Size = UDim2.new(0, 180, 0, 18), Font = Enum.Font.SourceSans, Text = "[Loading...]", TextColor3 = COLORS.TextDark, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 2})
  514.  
  515. local CloseButton = Create("TextButton", {Parent = TopBar, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Position = UDim2.new(1, -19, 0, 0), Size = UDim2.new(0, 19, 0, 19), Text = "", ZIndex = 2})
  516. Create("ImageLabel", {Parent = CloseButton, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 5), Size = UDim2.new(0, 9, 0, 9), Image = "rbxassetid://5597086202", ZIndex = 2})
  517. local MaximizeButton = Create("TextButton", {Parent = TopBar, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Position = UDim2.new(1, -38, 0, 0), Size = UDim2.new(0, 19, 0, 19), Text = "", ZIndex = 2})
  518. Create("ImageLabel", {Parent = MaximizeButton, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 5), Size = UDim2.new(0, 9, 0, 9), Image = "rbxassetid://5597108117", ZIndex = 2})
  519. local MinimizeButton = Create("TextButton", {Parent = TopBar, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Position = UDim2.new(1, -57, 0, 0), Size = UDim2.new(0, 19, 0, 19), Text = "", ZIndex = 2})
  520. Create("ImageLabel", {Parent = MinimizeButton, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 5), Size = UDim2.new(0, 9, 0, 9), Image = "rbxassetid://5597105827", ZIndex = 2})
  521.  
  522. local ToolTip = Create("Frame", {Parent = SignalSpy, BackgroundColor3 = Color3.fromRGB(20, 20, 22), BorderSizePixel = 1, BorderColor3 = COLORS.Accent, Size = UDim2.new(0, 200, 0, 50), ZIndex = 100, Visible = false})
  523. local ToolTipText = Create("TextLabel", {Parent = ToolTip, BackgroundTransparency = 1, Position = UDim2.new(0, 4, 0, 4), Size = UDim2.new(1, -8, 1, -8), ZIndex = 100, Font = Enum.Font.SourceSans, Text = "", TextColor3 = COLORS.Text, TextSize = 13, TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top})
  524.  
  525. local ConnectionViewer = Create("Frame", {Parent = SignalSpy, BackgroundColor3 = COLORS.Panel, BorderSizePixel = 0, Position = UDim2.new(0.5, -220, 0.5, -200), Size = UDim2.new(0, 440, 0, 400), Visible = false, ZIndex = 60})
  526. Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = ConnectionViewer})
  527. local CVTitle = Create("Frame", {Parent = ConnectionViewer, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Size = UDim2.new(1, 0, 0, 28), ZIndex = 60})
  528. Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = CVTitle})
  529. Create("TextLabel", {Parent = CVTitle, BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 0), Size = UDim2.new(0.7, 0, 1, 0), Font = Enum.Font.SourceSansBold, Text = "Connection Viewer", TextColor3 = COLORS.Text, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 60})
  530. local CVClose = Create("TextButton", {Parent = CVTitle, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Position = UDim2.new(1, -28, 0, 0), Size = UDim2.new(0, 28, 0, 28), Font = Enum.Font.SourceSansBold, Text = "×", TextColor3 = COLORS.Text, TextSize = 20, ZIndex = 61})
  531. local CVWarning = Create("TextLabel", {Parent = ConnectionViewer, BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 28), Size = UDim2.new(1, -20, 0, 18), Font = Enum.Font.SourceSans, Text = "", TextColor3 = COLORS.Yellow, TextSize = 10, ZIndex = 60})
  532. local CVInfo = Create("TextLabel", {Parent = ConnectionViewer, BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 46), Size = UDim2.new(1, -20, 0, 20), Font = Enum.Font.SourceSans, Text = "Signal: -", TextColor3 = COLORS.TextDark, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 60})
  533. local CVList = Create("ScrollingFrame", {Parent = ConnectionViewer, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 10, 0, 70), Size = UDim2.new(1, -20, 1, -80), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 4, ScrollBarImageColor3 = COLORS.Accent, ZIndex = 60})
  534. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = CVList})
  535. local CVListLayout = Create("UIListLayout", {Parent = CVList, Padding = UDim.new(0, 3)})
  536.  
  537. local cvDragging, cvDragStart, cvStartPos = false, nil, nil
  538. CVTitle.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then cvDragging, cvDragStart, cvStartPos = true, input.Position, ConnectionViewer.Position end end)
  539. CVTitle.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then cvDragging = false end end)
  540. CVClose.MouseButton1Click:Connect(function() ConnectionViewer.Visible = false connectionViewerOpen = false end)
  541. CVClose.MouseEnter:Connect(function() CVClose.BackgroundColor3 = COLORS.Red end)
  542. CVClose.MouseLeave:Connect(function() CVClose.BackgroundColor3 = COLORS.TopBar end)
  543.  
  544. local function createConnectionEntry(conn, index, signalKey, isHiddenSignal)
  545.     local Entry = Create("Frame", {Parent = CVList, BackgroundColor3 = Color3.fromRGB(45, 45, 48), BorderSizePixel = 0, Size = UDim2.new(1, -8, 0, 60), ZIndex = 60})
  546.     Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = Entry})
  547.    
  548.     local funcInfo = "Unknown"
  549.     if type(getinfo) == "function" and conn.Function then
  550.         local ok, info = pcall(function() return getinfo(conn.Function) end)
  551.         if ok and info then funcInfo = (info.source or "?") .. ":" .. (info.currentline or info.linedefined or "?") end
  552.     end
  553.    
  554.     local isEnabled = true
  555.     pcall(function() isEnabled = conn.Enabled end)
  556.    
  557.     Create("TextLabel", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(0, 8, 0, 3), Size = UDim2.new(1, -16, 0, 16), Font = Enum.Font.SourceSansBold, Text = "#" .. index .. " - " .. (isEnabled and "ENABLED" or "DISABLED"), TextColor3 = isEnabled and COLORS.Green or COLORS.Red, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 60})
  558.     Create("TextLabel", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(0, 8, 0, 20), Size = UDim2.new(1, -16, 0, 14), Font = Enum.Font.SourceSans, Text = "Src: " .. funcInfo, TextColor3 = COLORS.TextDark, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, ZIndex = 60})
  559.    
  560.     local isCClosure = false
  561.     pcall(function() isCClosure = iscclosure(conn.Function) end)
  562.     Create("TextLabel", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(0, 8, 0, 34), Size = UDim2.new(1, -16, 0, 12), Font = Enum.Font.SourceSans, Text = "Type: " .. (isCClosure and "C Closure" or "Lua"), TextColor3 = COLORS.TextDark, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 60})
  563.    
  564.     local ButtonFrame = Create("Frame", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(0, 8, 0, 44), Size = UDim2.new(1, -16, 0, 14), ZIndex = 60})
  565.     Create("UIListLayout", {Parent = ButtonFrame, FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 5)})
  566.    
  567.     local ToggleBtn = Create("TextButton", {Parent = ButtonFrame, BackgroundColor3 = isEnabled and COLORS.Yellow or COLORS.Green, BorderSizePixel = 0, Size = UDim2.new(0, 55, 0, 14), Font = Enum.Font.SourceSans, Text = isEnabled and "Disable" or "Enable", TextColor3 = COLORS.Darker, TextSize = 10, ZIndex = 61})
  568.     Create("UICorner", {CornerRadius = UDim.new(0, 3), Parent = ToggleBtn})
  569.    
  570.     local DisconnectBtn = Create("TextButton", {Parent = ButtonFrame, BackgroundColor3 = COLORS.Red, BorderSizePixel = 0, Size = UDim2.new(0, 60, 0, 14), Font = Enum.Font.SourceSans, Text = "Disconnect", TextColor3 = COLORS.Text, TextSize = 10, ZIndex = 61})
  571.     Create("UICorner", {CornerRadius = UDim.new(0, 3), Parent = DisconnectBtn})
  572.    
  573.     ToggleBtn.MouseButton1Click:Connect(function()
  574.         pcall(function()
  575.             conn.Enabled = not conn.Enabled
  576.             local newState = conn.Enabled
  577.             ToggleBtn.Text = newState and "Disable" or "Enable"
  578.             ToggleBtn.BackgroundColor3 = newState and COLORS.Yellow or COLORS.Green
  579.         end)
  580.     end)
  581.    
  582.     DisconnectBtn.MouseButton1Click:Connect(function()
  583.         pcall(function() conn:Disconnect() Entry:Destroy() end)
  584.     end)
  585.    
  586.     return Entry
  587. end
  588.  
  589. local function openConnectionViewer(data)
  590.     if not data or not data.Signal then return end
  591.    
  592.     for _, child in ipairs(CVList:GetChildren()) do
  593.         if child:IsA("Frame") then child:Destroy() end
  594.     end
  595.    
  596.     local signalKey = (data.ClassName or "?") .. "." .. data.SignalName
  597.     local tags = {}
  598.     if data.IsHidden then table.insert(tags, "HIDDEN") end
  599.     if data.IsDeprecated then table.insert(tags, "DEPRECATED") end
  600.    
  601.     CVInfo.Text = "Signal: " .. signalKey .. (#tags > 0 and " [" .. table.concat(tags, ", ") .. "]" or "")
  602.     CVInfo.TextColor3 = data.IsHidden and COLORS.Orange or (data.IsDeprecated and COLORS.Purple or COLORS.Text)
  603.    
  604.     if data.IsHidden then
  605.         CVWarning.Text = "⚠ WARNING: getconnections() on Hidden signals may CRASH!"
  606.         CVWarning.TextColor3 = COLORS.Red
  607.     else
  608.         CVWarning.Text = ""
  609.     end
  610.    
  611.     if not getconnections then
  612.         CVInfo.Text = "getconnections() not available!"
  613.         CVInfo.TextColor3 = COLORS.Red
  614.         ConnectionViewer.Visible = true
  615.         connectionViewerOpen = true
  616.         return
  617.     end
  618.    
  619.     local ok, connections = pcall(function() return getconnections(data.Signal) end)
  620.     if not ok or not connections then
  621.         CVInfo.Text = "Failed to get connections! (May have crashed)"
  622.         CVInfo.TextColor3 = COLORS.Red
  623.         ConnectionViewer.Visible = true
  624.         connectionViewerOpen = true
  625.         return
  626.     end
  627.    
  628.     for i, conn in ipairs(connections) do
  629.         pcall(function() createConnectionEntry(conn, i, signalKey, data.IsHidden) end)
  630.     end
  631.    
  632.     CVList.CanvasSize = UDim2.new(0, 0, 0, CVListLayout.AbsoluteContentSize.Y + 10)
  633.     ConnectionViewer.Visible = true
  634.     connectionViewerOpen = true
  635. end
  636.  
  637. local ClassBrowserFrame = Create("Frame", {Parent = SignalSpy, BackgroundColor3 = COLORS.Panel, BorderSizePixel = 0, Position = UDim2.new(0.5, -210, 0.5, -190), Size = UDim2.new(0, 420, 0, 380), Visible = false, ZIndex = 50})
  638. Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = ClassBrowserFrame})
  639. local ClassBrowserTitle = Create("Frame", {Parent = ClassBrowserFrame, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Size = UDim2.new(1, 0, 0, 28), ZIndex = 50})
  640. Create("UICorner", {CornerRadius = UDim.new(0, 6), Parent = ClassBrowserTitle})
  641. Create("TextLabel", {Parent = ClassBrowserTitle, BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 0), Size = UDim2.new(0, 90, 1, 0), Font = Enum.Font.SourceSansBold, Text = "Class Browser", TextColor3 = COLORS.Text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 50})
  642.  
  643. local HiddenToggle = Create("TextButton", {Parent = ClassBrowserTitle, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 105, 0, 4), Size = UDim2.new(0, 65, 0, 20), Font = Enum.Font.SourceSans, Text = "[H] OFF", TextColor3 = COLORS.Red, TextSize = 10, ZIndex = 51})
  644. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = HiddenToggle})
  645.  
  646. local DeprecatedToggle = Create("TextButton", {Parent = ClassBrowserTitle, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 175, 0, 4), Size = UDim2.new(0, 65, 0, 20), Font = Enum.Font.SourceSans, Text = "[D] OFF", TextColor3 = COLORS.Red, TextSize = 10, ZIndex = 51})
  647. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = DeprecatedToggle})
  648.  
  649. local SafeModeToggle = Create("TextButton", {Parent = ClassBrowserTitle, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 245, 0, 4), Size = UDim2.new(0, 65, 0, 20), Font = Enum.Font.SourceSans, Text = "Safe ON", TextColor3 = COLORS.Green, TextSize = 10, ZIndex = 51})
  650. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = SafeModeToggle})
  651.  
  652. local ClassBrowserClose = Create("TextButton", {Parent = ClassBrowserTitle, BackgroundColor3 = COLORS.TopBar, BorderSizePixel = 0, Position = UDim2.new(1, -28, 0, 0), Size = UDim2.new(0, 28, 0, 28), Font = Enum.Font.SourceSansBold, Text = "×", TextColor3 = COLORS.Text, TextSize = 20, ZIndex = 51})
  653.  
  654. local CapabilitiesLabel = Create("TextLabel", {Parent = ClassBrowserFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0, 30), Size = UDim2.new(1, -20, 0, 14), Font = Enum.Font.SourceSans, Text = "", TextColor3 = COLORS.TextDark, TextSize = 9, TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 50})
  655.  
  656. local ClassSearchFrame = Create("Frame", {Parent = ClassBrowserFrame, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 10, 0, 46), Size = UDim2.new(1, -20, 0, 24), ZIndex = 50})
  657. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = ClassSearchFrame})
  658. local ClassSearchBox = Create("TextBox", {Parent = ClassSearchFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 8, 0, 0), Size = UDim2.new(1, -16, 1, 0), Font = Enum.Font.SourceSans, PlaceholderText = "Search classes...", PlaceholderColor3 = COLORS.TextDark, Text = "", TextColor3 = COLORS.Text, TextSize = 12, ClearTextOnFocus = false, ZIndex = 50})
  659.  
  660. local ClassListFrame = Create("ScrollingFrame", {Parent = ClassBrowserFrame, BackgroundColor3 = COLORS.Darker, BorderSizePixel = 0, Position = UDim2.new(0, 10, 0, 75), Size = UDim2.new(1, -20, 0, 255), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 4, ScrollBarImageColor3 = COLORS.Accent, ZIndex = 50})
  661. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = ClassListFrame})
  662. local ClassListLayout = Create("UIListLayout", {Parent = ClassListFrame, Padding = UDim.new(0, 2)})
  663.  
  664. local ApplyButton = Create("TextButton", {Parent = ClassBrowserFrame, BackgroundColor3 = COLORS.Green, BorderSizePixel = 0, Position = UDim2.new(0, 10, 1, -38), Size = UDim2.new(0.5, -15, 0, 28), Font = Enum.Font.SourceSansBold, Text = "Apply & Rehook", TextColor3 = COLORS.Darker, TextSize = 13, ZIndex = 50})
  665. Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = ApplyButton})
  666. local SelectedCountLabel = Create("TextLabel", {Parent = ClassBrowserFrame, BackgroundTransparency = 1, Position = UDim2.new(0.5, 5, 1, -38), Size = UDim2.new(0.5, -15, 0, 28), Font = Enum.Font.SourceSans, Text = "Selected: 0", TextColor3 = COLORS.TextDark, TextSize = 12, ZIndex = 50})
  667.  
  668. HiddenToggle.MouseButton1Click:Connect(function()
  669.     getgenv().CaptureHidden = not getgenv().CaptureHidden
  670.     HiddenToggle.Text = getgenv().CaptureHidden and "[H] ON" or "[H] OFF"
  671.     HiddenToggle.TextColor3 = getgenv().CaptureHidden and COLORS.Orange or COLORS.Red
  672. end)
  673.  
  674. DeprecatedToggle.MouseButton1Click:Connect(function()
  675.     getgenv().CaptureDeprecated = not getgenv().CaptureDeprecated
  676.     DeprecatedToggle.Text = getgenv().CaptureDeprecated and "[D] ON" or "[D] OFF"
  677.     DeprecatedToggle.TextColor3 = getgenv().CaptureDeprecated and COLORS.Purple or COLORS.Red
  678. end)
  679.  
  680. SafeModeToggle.MouseButton1Click:Connect(function()
  681.     CONFIG.SafeMode = not CONFIG.SafeMode
  682.     SafeModeToggle.Text = CONFIG.SafeMode and "Safe ON" or "Safe OFF"
  683.     SafeModeToggle.TextColor3 = CONFIG.SafeMode and COLORS.Green or COLORS.Red
  684. end)
  685.  
  686. local cbDragging, cbDragStart, cbStartPos = false, nil, nil
  687. ClassBrowserTitle.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then cbDragging, cbDragStart, cbStartPos = true, input.Position, ClassBrowserFrame.Position end end)
  688. ClassBrowserTitle.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then cbDragging = false end end)
  689. ClassBrowserClose.MouseButton1Click:Connect(function() ClassBrowserFrame.Visible = false classBrowserOpen = false end)
  690. ClassBrowserClose.MouseEnter:Connect(function() ClassBrowserClose.BackgroundColor3 = COLORS.Red end)
  691. ClassBrowserClose.MouseLeave:Connect(function() ClassBrowserClose.BackgroundColor3 = COLORS.TopBar end)
  692.  
  693. if Highlight then
  694.     codebox = Highlight.new(CodeBox)
  695.     local caps = {}
  696.     for k, v in pairs(ExploitCapabilities) do if v then table.insert(caps, k) end end
  697.     codebox:setRaw("-- SignalSpy v4\n-- Capabilities: " .. table.concat(caps, ", ") .. "\n-- Classes: " .. table.concat(getgenv().CaptureClasses or {}, ", "))
  698. end
  699.  
  700. local function updateLogCanvas() task.defer(function() LogList.CanvasSize = UDim2.new(0, 0, 0, UIListLayout.AbsoluteContentSize.Y + 5) end) end
  701. local function updateButtonCanvas() ButtonsFrame.CanvasSize = UDim2.new(0, 0, 0, UIGridLayout.AbsoluteContentSize.Y) end
  702. local function setCode(text) if codebox then codebox:setRaw(text) end end
  703. local function getCode() return codebox and codebox:getString() or "" end
  704.  
  705. local function updatePanelSizes(speed)
  706.     speed = speed or 0.05
  707.     local leftWidth = CONFIG.LeftPanelWidth
  708.     TweenService:Create(LeftPanel, TweenInfo.new(speed), {Size = UDim2.fromOffset(leftWidth, Background.AbsoluteSize.Y - 19)}):Play()
  709.     TweenService:Create(PanelResizer, TweenInfo.new(speed), {Position = UDim2.fromOffset(leftWidth - 2, 19), Size = UDim2.fromOffset(4, Background.AbsoluteSize.Y - 19)}):Play()
  710.     TweenService:Create(RightPanel, TweenInfo.new(speed), {Position = UDim2.fromOffset(leftWidth + 2, 19), Size = UDim2.fromOffset(Background.AbsoluteSize.X - leftWidth - 2, Background.AbsoluteSize.Y - 19)}):Play()
  711.     TweenService:Create(TopBar, TweenInfo.new(speed), {Size = UDim2.fromOffset(Background.AbsoluteSize.X, 19)}):Play()
  712. end
  713.  
  714. local function minimizeSize(speed)
  715.     speed = speed or 0.05
  716.     TweenService:Create(RightPanel, TweenInfo.new(speed), {Size = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 19)}):Play()
  717.     TweenService:Create(PanelResizer, TweenInfo.new(speed), {Size = UDim2.fromOffset(0, 0)}):Play()
  718.     TweenService:Create(TopBar, TweenInfo.new(speed), {Size = UDim2.fromOffset(CONFIG.LeftPanelWidth, 19)}):Play()
  719. end
  720.  
  721. local function closeAllPopups() ClassBrowserFrame.Visible = false classBrowserOpen = false ConnectionViewer.Visible = false connectionViewerOpen = false end
  722.  
  723. local function makeToolTip(enable, text)
  724.     if enable and text then
  725.         ToolTipText.Text = text
  726.         local size = TextService:GetTextSize(text, 13, Enum.Font.SourceSans, Vector2.new(250, math.huge))
  727.         ToolTip.Size = UDim2.new(0, math.min(size.X + 12, 260), 0, math.min(size.Y + 12, 150))
  728.         ToolTip.Visible = true
  729.         if Connections["ToolTip"] then Connections["ToolTip"]:Disconnect() end
  730.         Connections["ToolTip"] = RunService.RenderStepped:Connect(function()
  731.             local mousePos = UserInputService:GetMouseLocation()
  732.             local x, y = mousePos.X + 15, mousePos.Y - 10 - GuiInset.Y
  733.             local viewSize = workspace.CurrentCamera.ViewportSize
  734.             if x + ToolTip.AbsoluteSize.X > viewSize.X then x = mousePos.X - ToolTip.AbsoluteSize.X - 10 end
  735.             if y + ToolTip.AbsoluteSize.Y > viewSize.Y - 50 then y = viewSize.Y - ToolTip.AbsoluteSize.Y - 50 end
  736.             ToolTip.Position = UDim2.new(0, x, 0, y)
  737.         end)
  738.     else
  739.         ToolTip.Visible = false
  740.         if Connections["ToolTip"] then Connections["ToolTip"]:Disconnect() end
  741.     end
  742. end
  743.  
  744. local function newButton(name, description, onClick)
  745.     local Template = Create("Frame", {Parent = ButtonsFrame, BackgroundTransparency = 1, Size = UDim2.new(0, 117, 0, 23)})
  746.     Create("Frame", {Parent = Template, BackgroundColor3 = COLORS.Accent, BorderSizePixel = 0, Position = UDim2.new(0, 7, 0, 10), Size = UDim2.new(0, 7, 0, 18), ZIndex = 3})
  747.     Create("TextLabel", {Parent = Template, BackgroundTransparency = 1, Position = UDim2.new(0, 19, 0, 10), Size = UDim2.new(0, 69, 0, 18), Font = Enum.Font.SourceSans, Text = name, TextColor3 = COLORS.Text, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left})
  748.     local Btn = Create("TextButton", {Parent = Template, BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 0.7, Position = UDim2.new(0, 7, 0, 10), Size = UDim2.new(0, 80, 0, 18), AutoButtonColor = false, Text = ""})
  749.     Btn.MouseEnter:Connect(function() makeToolTip(true, type(description) == "function" and description() or description) end)
  750.     Btn.MouseLeave:Connect(function() makeToolTip(false) end)
  751.     Btn.MouseButton1Click:Connect(function() pcall(onClick) end)
  752.     updateButtonCanvas()
  753. end
  754.  
  755. local SelectedClasses = {}
  756. local ClassCheckboxes = {}
  757.  
  758. local function updateSelectedCount()
  759.     local count = 0
  760.     for _ in pairs(SelectedClasses) do count = count + 1 end
  761.     SelectedCountLabel.Text = "Selected: " .. count
  762. end
  763.  
  764. local function createClassEntry(className, normalCount, hiddenCount, deprecatedCount)
  765.     local isSelected = SelectedClasses[className] == true
  766.     local Entry = Create("Frame", {Parent = ClassListFrame, BackgroundColor3 = isSelected and Color3.fromRGB(50, 80, 50) or Color3.fromRGB(40, 40, 43), BorderSizePixel = 0, Size = UDim2.new(1, -4, 0, 26), ZIndex = 50})
  767.     Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = Entry})
  768.     local Checkbox = Create("TextButton", {Parent = Entry, BackgroundColor3 = isSelected and COLORS.Green or Color3.fromRGB(55, 55, 58), BorderSizePixel = 0, Position = UDim2.new(0, 5, 0.5, -8), Size = UDim2.new(0, 16, 0, 16), Font = Enum.Font.SourceSansBold, Text = isSelected and "✓" or "", TextColor3 = COLORS.Text, TextSize = 12, ZIndex = 51})
  769.     Create("UICorner", {CornerRadius = UDim.new(0, 4), Parent = Checkbox})
  770.     Create("TextLabel", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(0, 26, 0, 0), Size = UDim2.new(1, -120, 1, 0), Font = Enum.Font.SourceSans, Text = className, TextColor3 = COLORS.Text, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, ZIndex = 50})
  771.    
  772.     local evtText = normalCount .. "e"
  773.     local evtColor = COLORS.TextDark
  774.     if hiddenCount > 0 then evtText = evtText .. " +" .. hiddenCount .. "h" evtColor = COLORS.Orange end
  775.     if deprecatedCount > 0 then evtText = evtText .. " +" .. deprecatedCount .. "d" end
  776.     Create("TextLabel", {Parent = Entry, BackgroundTransparency = 1, Position = UDim2.new(1, -92, 0, 0), Size = UDim2.new(0, 88, 1, 0), Font = Enum.Font.SourceSans, Text = evtText, TextColor3 = evtColor, TextSize = 9, TextXAlignment = Enum.TextXAlignment.Right, ZIndex = 50})
  777.    
  778.     ClassCheckboxes[className] = {Entry = Entry, Checkbox = Checkbox}
  779.     local function toggle()
  780.         SelectedClasses[className] = not SelectedClasses[className]
  781.         local sel = SelectedClasses[className]
  782.         Checkbox.Text = sel and "✓" or ""
  783.         Checkbox.BackgroundColor3 = sel and COLORS.Green or Color3.fromRGB(55, 55, 58)
  784.         Entry.BackgroundColor3 = sel and Color3.fromRGB(50, 80, 50) or Color3.fromRGB(40, 40, 43)
  785.         updateSelectedCount()
  786.     end
  787.     Checkbox.MouseButton1Click:Connect(toggle)
  788.     Entry.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then toggle() end end)
  789. end
  790.  
  791. local function refreshClassList()
  792.     for _, child in ipairs(ClassListFrame:GetChildren()) do if child:IsA("Frame") then child:Destroy() end end
  793.     ClassCheckboxes = {}
  794.     local query = (classSearchQuery or ""):lower()
  795.    
  796.     local function addClassIfMatch(className)
  797.         if CachedAPIEvents[className] and (query == "" or className:lower():find(query, 1, true)) then
  798.             local classData = CachedAPIEvents[className]
  799.             local normalCount = #(classData.Events or {})
  800.             local hiddenCount = #(classData.HiddenEvents or {})
  801.             local deprecatedCount = #(classData.DeprecatedEvents or {})
  802.             if normalCount > 0 or hiddenCount > 0 or deprecatedCount > 0 then
  803.                 createClassEntry(className, normalCount, hiddenCount, deprecatedCount)
  804.             end
  805.         end
  806.     end
  807.    
  808.     for _, popClass in ipairs(POPULAR_CLASSES) do addClassIfMatch(popClass) end
  809.     if query ~= "" then
  810.         for name in pairs(CachedAPIEvents) do
  811.             local isPop = false
  812.             for _, p in ipairs(POPULAR_CLASSES) do if p == name then isPop = true break end end
  813.             if not isPop then addClassIfMatch(name) end
  814.         end
  815.     end
  816.     ClassListFrame.CanvasSize = UDim2.new(0, 0, 0, ClassListLayout.AbsoluteContentSize.Y + 10)
  817. end
  818.  
  819. local function openClassBrowser()
  820.     SelectedClasses = {}
  821.     for _, className in ipairs(getgenv().CaptureClasses or {}) do SelectedClasses[className] = true end
  822.     classSearchQuery = ""
  823.     ClassSearchBox.Text = ""
  824.     HiddenToggle.Text = getgenv().CaptureHidden and "[H] ON" or "[H] OFF"
  825.     HiddenToggle.TextColor3 = getgenv().CaptureHidden and COLORS.Orange or COLORS.Red
  826.     DeprecatedToggle.Text = getgenv().CaptureDeprecated and "[D] ON" or "[D] OFF"
  827.     DeprecatedToggle.TextColor3 = getgenv().CaptureDeprecated and COLORS.Purple or COLORS.Red
  828.     SafeModeToggle.Text = CONFIG.SafeMode and "Safe ON" or "Safe OFF"
  829.     SafeModeToggle.TextColor3 = CONFIG.SafeMode and COLORS.Green or COLORS.Red
  830.    
  831.     local caps = {}
  832.     if ExploitCapabilities.setscriptable then table.insert(caps, "setscriptable✓") end
  833.     if ExploitCapabilities.gethiddenproperty then table.insert(caps, "gethidden✓") end
  834.     if ExploitCapabilities.replicatesignal then table.insert(caps, "replicate✓") end
  835.     if ExploitCapabilities.firesignal then table.insert(caps, "fire✓") end
  836.     CapabilitiesLabel.Text = "Caps: " .. (#caps > 0 and table.concat(caps, " ") or "none")
  837.    
  838.     refreshClassList()
  839.     updateSelectedCount()
  840.     ClassBrowserFrame.Visible = true
  841.     classBrowserOpen = true
  842. end
  843.  
  844. ClassSearchBox:GetPropertyChangedSignal("Text"):Connect(function() classSearchQuery = ClassSearchBox.Text refreshClassList() end)
  845. --
  846. local function eventSelect(data)
  847.     if selected and selected.Button then
  848.         TweenService:Create(selected.Button, TweenInfo.new(0.2), {BackgroundColor3 = Color3.new(0, 0, 0)}):Play()
  849.     end
  850.     selected = data
  851.     if selected.Button then
  852.         TweenService:Create(selected.Button, TweenInfo.new(0.2), {BackgroundColor3 = COLORS.Selected}):Play()
  853.     end
  854.     selected.GenScript = selected.GenScript or generateScript(selected)
  855.     setCode(selected.GenScript)
  856.     if sideClosed then sideClosed = false updatePanelSizes(0.3) end
  857. end
  858.  
  859. local function createGroupEntry(className, signalName, isHidden, isDeprecated)
  860.     local groupKey = className .. "." .. signalName
  861.     if groupedLogs[groupKey] then return groupedLogs[groupKey] end
  862.     if layoutOrderNum < 1 then layoutOrderNum = 999999999 end
  863.    
  864.     local group = {SignalName = signalName, ClassName = className, Logs = {}, Expanded = false, CallCount = 0, IsHidden = isHidden, IsDeprecated = isDeprecated}
  865.     local color = isHidden and COLORS.Orange or (isDeprecated and COLORS.Purple or COLORS.Accent)
  866.    
  867.     local GroupFrame = Create("Frame", {Parent = LogList, BackgroundTransparency = 1, Size = UDim2.new(1, -8, 0, 22), LayoutOrder = layoutOrderNum, ClipsDescendants = true})
  868.     local GroupLayout = Create("UIListLayout", {Parent = GroupFrame, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 1)})
  869.     GroupLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
  870.         GroupFrame.Size = UDim2.new(1, -8, 0, GroupLayout.AbsoluteContentSize.Y)
  871.         task.defer(updateLogCanvas)
  872.     end)
  873.    
  874.     local HeaderFrame = Create("Frame", {Parent = GroupFrame, BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 22), LayoutOrder = -999999})
  875.     local ExpandButton = Create("TextButton", {Parent = HeaderFrame, BackgroundTransparency = 1, Size = UDim2.new(0, 14, 0, 18), Position = UDim2.new(0, 0, 0, 2), Font = Enum.Font.SourceSansBold, Text = ">", TextColor3 = color, TextSize = 13})
  876.     Create("Frame", {Parent = HeaderFrame, BackgroundColor3 = color, BorderSizePixel = 0, Position = UDim2.new(0, 14, 0, 2), Size = UDim2.new(0, 4, 0, 18)})
  877.    
  878.     local displayText = CONFIG.ShowClassName and groupKey or signalName
  879.     local tags = {}
  880.     if isHidden then table.insert(tags, "H") end
  881.     if isDeprecated then table.insert(tags, "D") end
  882.     if #tags > 0 then displayText = displayText .. " [" .. table.concat(tags) .. "]" end
  883.    
  884.     Create("TextLabel", {Parent = HeaderFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 22, 0, 2), Size = UDim2.new(1, -48, 0, 18), Font = Enum.Font.SourceSans, Text = displayText, TextColor3 = color, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd})
  885.     local CountLabel = Create("TextLabel", {Parent = HeaderFrame, BackgroundTransparency = 1, Position = UDim2.new(1, -24, 0, 2), Size = UDim2.new(0, 22, 0, 18), Font = Enum.Font.SourceSans, Text = "0", TextColor3 = COLORS.TextDark, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Right})
  886.     local HeaderButton = Create("TextButton", {Parent = HeaderFrame, BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 0.8, Size = UDim2.new(1, 0, 0, 18), Position = UDim2.new(0, 0, 0, 2), AutoButtonColor = false, Text = ""})
  887.    
  888.     group.Frame = GroupFrame
  889.     group.CountLabel = CountLabel
  890.     group.ExpandButton = ExpandButton
  891.    
  892.     local function toggleExpand()
  893.         group.Expanded = not group.Expanded
  894.         ExpandButton.Text = group.Expanded and "v" or ">"
  895.         for _, logData in ipairs(group.Logs) do if logData.LogFrame then logData.LogFrame.Visible = group.Expanded end end
  896.         task.defer(function() GroupFrame.Size = UDim2.new(1, -8, 0, GroupLayout.AbsoluteContentSize.Y) updateLogCanvas() end)
  897.     end
  898.    
  899.     ExpandButton.MouseButton1Click:Connect(toggleExpand)
  900.     HeaderButton.MouseButton2Click:Connect(toggleExpand)
  901.     HeaderButton.MouseButton1Click:Connect(function() if #group.Logs > 0 then eventSelect(group.Logs[1]) end end)
  902.    
  903.     groupedLogs[groupKey] = group
  904.     layoutOrderNum = layoutOrderNum - 1
  905.     updateLogCanvas()
  906.     return group
  907. end
  908.  
  909. local function newSignalLog(data)
  910.     if CONFIG.FilterHiddenOnly and not data.IsHidden then return end
  911.     if CONFIG.FilterDeprecatedOnly and not data.IsDeprecated then return end
  912.    
  913.     local className = data.ClassName or "?"
  914.     local signalName = data.SignalName
  915.     local groupKey = className .. "." .. signalName
  916.     local group = createGroupEntry(className, signalName, data.IsHidden, data.IsDeprecated)
  917.    
  918.     group.CallCount = group.CallCount + 1
  919.     group.CountLabel.Text = tostring(group.CallCount)
  920.     data.CallCount = group.CallCount
  921.    
  922.     SignalStats[groupKey] = (SignalStats[groupKey] or 0) + 1
  923.     TotalCalls = TotalCalls + 1
  924.     StatusLabel.Text = "[" .. TotalHookedCount .. "/" .. HiddenHookedCount .. "h/" .. DeprecatedHookedCount .. "d | " .. TotalCalls .. "c]"
  925.    
  926.     local color = data.IsHidden and COLORS.Orange or (data.IsDeprecated and COLORS.Purple or Color3.fromRGB(190, 190, 190))
  927.     local LogFrame = Create("Frame", {Parent = group.Frame, BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 19), LayoutOrder = -group.CallCount, Visible = group.Expanded})
  928.     Create("TextLabel", {Parent = LogFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 5, 0, 0), Size = UDim2.new(0, 22, 1, 0), Font = Enum.Font.SourceSans, Text = "#" .. tostring(group.CallCount - 1), TextColor3 = COLORS.TextDark, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left})
  929.     Create("TextLabel", {Parent = LogFrame, BackgroundTransparency = 1, Position = UDim2.new(0, 28, 0, 0), Size = UDim2.new(1, -30, 1, 0), Font = Enum.Font.SourceSans, Text = CONFIG.ShowClassName and groupKey or signalName, TextColor3 = color, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd})
  930.     local LogButton = Create("TextButton", {Parent = LogFrame, BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 0.88, Size = UDim2.new(1, 0, 1, 0), AutoButtonColor = false, Text = ""})
  931.    
  932.     data.LogFrame = LogFrame
  933.     data.Button = LogButton
  934.     data.id = #logs + 1
  935.     table.insert(group.Logs, 1, data)
  936.     table.insert(logs, 1, data)
  937.     LogButton.MouseButton1Click:Connect(function() eventSelect(data) end)
  938.     if #logs > CONFIG.MaxLogs then local oldest = table.remove(logs) if oldest and oldest.LogFrame then oldest.LogFrame:Destroy() end end
  939. end
  940.  
  941. local function logSignal(instance, signalName, signal, args, isHidden, isDeprecated, accessMethod, usedSetScriptable)
  942.     if not CONFIG.Enabled then return end
  943.     local ok, className = pcall(function() return instance.ClassName end)
  944.     className = ok and className or "?"
  945.     local key = className .. "." .. signalName .. "." .. tostring(instance)
  946.     local groupKey = className .. "." .. signalName
  947.     if blacklist[key] or blacklist[signalName] or blacklist[groupKey] then return end
  948.     if blocklist[key] or blocklist[signalName] or blocklist[groupKey] then return end
  949.     if isSpammy(key) then return end
  950.    
  951.     newSignalLog({
  952.         SignalName = signalName, Instance = instance, Signal = signal, ClassName = className,
  953.         Args = deepClone(args or {}), Timestamp = os.time(), IsHidden = isHidden, IsDeprecated = isDeprecated,
  954.         AccessMethod = accessMethod, UsedSetScriptable = usedSetScriptable,
  955.     })
  956. end
  957.  
  958. local function hookSignal(instance, signalName, isHidden, isDeprecated)
  959.     local ok, className = pcall(function() return instance.ClassName end)
  960.     className = ok and className or "Unknown"
  961.     local key = className .. "." .. signalName .. "." .. tostring(instance)
  962.     if HookedSignals[key] then return false end
  963.    
  964.     HookAttempts[className .. "." .. signalName] = (HookAttempts[className .. "." .. signalName] or 0) + 1
  965.    
  966.     local signal, accessMethod, usedSetScriptable = getSignalFromInstance(instance, signalName, isHidden, isDeprecated)
  967.     if not signal then
  968.         local failType = isHidden and "hidden" or (isDeprecated and "deprecated" or "normal")
  969.         FailedHooks[failType][className .. "." .. signalName] = (FailedHooks[failType][className .. "." .. signalName] or 0) + 1
  970.         return false
  971.     end
  972.    
  973.     HookedSignals[key] = true
  974.     TotalHookedCount = TotalHookedCount + 1
  975.     if isHidden then HiddenHookedCount = HiddenHookedCount + 1 end
  976.     if isDeprecated then DeprecatedHookedCount = DeprecatedHookedCount + 1 end
  977.    
  978.     local conn = signal:Connect(function(...)
  979.         logSignal(instance, signalName, signal, {...}, isHidden, isDeprecated, accessMethod, usedSetScriptable)
  980.     end)
  981.     table.insert(Connections, conn)
  982.     return true
  983. end
  984.  
  985. local function hookInstanceByClass(instance)
  986.     local captureClasses = getgenv().CaptureClasses
  987.     if not captureClasses or type(captureClasses) ~= "table" then return end
  988.     for _, className in ipairs(captureClasses) do
  989.         local ok, isClass = pcall(function() return instance:IsA(className) end)
  990.         if ok and isClass then
  991.             local events = GetClassEvents(className, getgenv().CaptureHidden, getgenv().CaptureDeprecated)
  992.             for _, eventData in ipairs(events) do
  993.                 pcall(function() hookSignal(instance, eventData.name, eventData.hidden, eventData.deprecated) end)
  994.             end
  995.         end
  996.     end
  997. end
  998.  
  999. local function rehookAll()
  1000.     TotalHookedCount, HiddenHookedCount, DeprecatedHookedCount = 0, 0, 0
  1001.     HookedSignals = {}
  1002.     FailedHooks = {hidden = {}, deprecated = {}, normal = {}}
  1003.     HookAttempts = {}
  1004.     for _, conn in pairs(Connections) do if typeof(conn) == "RBXScriptConnection" then pcall(function() conn:Disconnect() end) end end
  1005.     Connections = {}
  1006.     StatusLabel.Text = "[Rehooking...]"
  1007.     StatusLabel.TextColor3 = COLORS.Yellow
  1008.    
  1009.     task.spawn(function()
  1010.         task.wait(0.1)
  1011.         local count = 0
  1012.         for _, desc in ipairs(game:GetDescendants()) do
  1013.             count = count + 1
  1014.             if count % 1000 == 0 then task.wait() end
  1015.             pcall(function() hookInstanceByClass(desc) end)
  1016.         end
  1017.         if LocalPlayer then pcall(function() hookSignal(LocalPlayer, "Idled", false, false) end) end
  1018.         Connections["DescAdded"] = game.DescendantAdded:Connect(function(desc) task.defer(function() pcall(function() hookInstanceByClass(desc) end) end) end)
  1019.         StatusLabel.Text = "[" .. TotalHookedCount .. "/" .. HiddenHookedCount .. "h/" .. DeprecatedHookedCount .. "d]"
  1020.         StatusLabel.TextColor3 = COLORS.Green
  1021.        
  1022.         print("[SignalSpy] === HOOK RESULTS ===")
  1023.         print("[SignalSpy] Total:", TotalHookedCount, "| Hidden:", HiddenHookedCount, "| Deprecated:", DeprecatedHookedCount)
  1024.         if HiddenHookedCount > 0 then print("[SignalSpy] SUCCESS: Hidden signals hooked via setscriptable!") end
  1025.         local failedHidden = 0 for _ in pairs(FailedHooks.hidden) do failedHidden = failedHidden + 1 end
  1026.         if failedHidden > 0 then print("[SignalSpy] Failed hidden:", failedHidden) end
  1027.     end)
  1028. end
  1029.  
  1030. ApplyButton.MouseButton1Click:Connect(function()
  1031.     local newClasses = {}
  1032.     for className, sel in pairs(SelectedClasses) do if sel then table.insert(newClasses, className) end end
  1033.     if #newClasses == 0 then setCode("-- Select at least 1 class!") return end
  1034.     getgenv().CaptureClasses = newClasses
  1035.     ClassBrowserFrame.Visible = false
  1036.     classBrowserOpen = false
  1037.     rehookAll()
  1038.     setCode("-- Rehooked!\n-- Hidden: " .. (getgenv().CaptureHidden and "ON" or "OFF") .. "\n-- Deprecated: " .. (getgenv().CaptureDeprecated and "ON" or "OFF") .. "\n-- Classes: " .. table.concat(newClasses, ", "))
  1039. end)
  1040.  
  1041. local function matchesSearch(key) if searchQuery == "" then return true end return key:lower():find(searchQuery:lower(), 1, true) ~= nil end
  1042. local function refreshLogList()
  1043.     for key, group in pairs(groupedLogs) do
  1044.         local visible = matchesSearch(key)
  1045.         if CONFIG.FilterHiddenOnly and not group.IsHidden then visible = false end
  1046.         if CONFIG.FilterDeprecatedOnly and not group.IsDeprecated then visible = false end
  1047.         if group.Frame then group.Frame.Visible = visible end
  1048.     end
  1049.     updateLogCanvas()
  1050. end
  1051. SearchBox:GetPropertyChangedSignal("Text"):Connect(function() searchQuery = SearchBox.Text refreshLogList() end)
  1052.  
  1053. local dragging, resizing, panelResizing = false, false, false
  1054. local dragStart, startPos, resizeType
  1055.  
  1056. local function isMouseInBackground(mousePos) local bgPos, bgSize = Background.AbsolutePosition, Background.AbsoluteSize return mousePos.X >= bgPos.X and mousePos.X <= bgPos.X + bgSize.X and mousePos.Y >= bgPos.Y and mousePos.Y <= bgPos.Y + bgSize.Y end
  1057. local function isInResizeRange(mousePos) if not isMouseInBackground(mousePos) then return false, nil end local rel = mousePos - Background.AbsolutePosition local w, h = Background.AbsoluteSize.X, Background.AbsoluteSize.Y if rel.X >= w - 10 and rel.Y >= h - 10 then return true, "BR" end if rel.X >= w - 10 then return true, "R" end if rel.Y >= h - 10 then return true, "B" end return false, nil end
  1058. local function isInDragRange(mousePos) if not isMouseInBackground(mousePos) then return false end local rel = mousePos - Background.AbsolutePosition return rel.X >= 0 and rel.X <= TopBar.AbsoluteSize.X - 60 and rel.Y >= 0 and rel.Y <= 19 end
  1059. local function isInPanelResizerRange(mousePos) local resPos, resSize = PanelResizer.AbsolutePosition, PanelResizer.AbsoluteSize return mousePos.X >= resPos.X - 3 and mousePos.X <= resPos.X + resSize.X + 3 and mousePos.Y >= resPos.Y and mousePos.Y <= resPos.Y + resSize.Y end
  1060.  
  1061. UserInputService.InputBegan:Connect(function(input)
  1062.     if classBrowserOpen or connectionViewerOpen then return end
  1063.     if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
  1064.     local mousePos = UserInputService:GetMouseLocation() - GuiInset
  1065.     if isInPanelResizerRange(mousePos) and not sideClosed and not closed then panelResizing, dragStart, startPos = true, input.Position, Vector2.new(CONFIG.LeftPanelWidth, 0) return end
  1066.     local inResize, rType = isInResizeRange(mousePos)
  1067.     if inResize and not closed then resizing, resizeType, dragStart, startPos = true, rType, input.Position, Background.AbsoluteSize
  1068.     elseif isInDragRange(mousePos) then dragging, dragStart, startPos = true, input.Position, Background.Position end
  1069. end)
  1070.  
  1071. UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 then dragging, resizing, panelResizing, resizeType = false, false, false, nil end end)
  1072.  
  1073. UserInputService.InputChanged:Connect(function(input)
  1074.     if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
  1075.     if cbDragging then local delta = input.Position - cbDragStart ClassBrowserFrame.Position = UDim2.new(cbStartPos.X.Scale, cbStartPos.X.Offset + delta.X, cbStartPos.Y.Scale, cbStartPos.Y.Offset + delta.Y) return end
  1076.     if cvDragging then local delta = input.Position - cvDragStart ConnectionViewer.Position = UDim2.new(cvStartPos.X.Scale, cvStartPos.X.Offset + delta.X, cvStartPos.Y.Scale, cvStartPos.Y.Offset + delta.Y) return end
  1077.     if not dragStart then return end
  1078.     local delta = input.Position - dragStart
  1079.     local viewSize = workspace.CurrentCamera.ViewportSize
  1080.     if panelResizing then CONFIG.LeftPanelWidth = math.clamp(startPos.X + delta.X, 80, Background.AbsoluteSize.X - 100) updatePanelSizes(0) return end
  1081.     if dragging then Background.Position = UDim2.new(0, math.clamp(startPos.X.Offset + delta.X, 0, viewSize.X - Background.AbsoluteSize.X), 0, math.clamp(startPos.Y.Offset + delta.Y, 0, viewSize.Y - Background.AbsoluteSize.Y - 36))
  1082.     elseif resizing then
  1083.         local newW, newH = math.clamp(startPos.X + delta.X, 350, viewSize.X - Background.AbsolutePosition.X), math.clamp(startPos.Y + delta.Y, 200, viewSize.Y - Background.AbsolutePosition.Y - 36)
  1084.         if resizeType == "BR" then Background.Size = UDim2.fromOffset(sideClosed and CONFIG.LeftPanelWidth or newW, newH)
  1085.         elseif resizeType == "R" and not sideClosed then Background.Size = UDim2.fromOffset(newW, Background.AbsoluteSize.Y)
  1086.         elseif resizeType == "B" then Background.Size = UDim2.fromOffset(Background.AbsoluteSize.X, newH) end
  1087.         if sideClosed then minimizeSize() else updatePanelSizes() end
  1088.     end
  1089. end)
  1090. --
  1091. MinimizeButton.MouseButton1Click:Connect(function()
  1092.     if mainClosing then return end
  1093.     mainClosing = true
  1094.     closed = not closed
  1095.     closeAllPopups()
  1096.     SearchFrame.Visible = not closed
  1097.     LogList.Visible = not closed
  1098.     TweenService:Create(LeftPanel, TweenInfo.new(0.3), {Size = UDim2.new(0, CONFIG.LeftPanelWidth, 0, closed and 0 or 301)}):Play()
  1099.     TweenService:Create(PanelResizer, TweenInfo.new(0.3), {Size = UDim2.new(0, 4, 0, closed and 0 or 301)}):Play()
  1100.     if not sideClosed then
  1101.         TweenService:Create(RightPanel, TweenInfo.new(0.3), {Size = UDim2.new(0, 347, 0, closed and 0 or 301)}):Play()
  1102.     end
  1103.     task.delay(0.3, function()
  1104.         mainClosing = false
  1105.         if not closed then
  1106.             SearchFrame.Visible = true
  1107.             LogList.Visible = true
  1108.         end
  1109.     end)
  1110. end)
  1111.  
  1112. MaximizeButton.MouseButton1Click:Connect(function()
  1113.     if sideClosing or closed then return end
  1114.     sideClosing = true
  1115.     sideClosed = not sideClosed
  1116.     if sideClosed then minimizeSize(0.3) else updatePanelSizes(0.3) end
  1117.     task.delay(0.3, function() sideClosing = false end)
  1118. end)
  1119.  
  1120. TitleButton.MouseButton1Click:Connect(function()
  1121.     CONFIG.Enabled = not CONFIG.Enabled
  1122.     TweenService:Create(TitleButton, TweenInfo.new(0.3), {TextColor3 = CONFIG.Enabled and COLORS.Green or COLORS.Red}):Play()
  1123. end)
  1124.  
  1125. CloseButton.MouseEnter:Connect(function() TweenService:Create(CloseButton, TweenInfo.new(0.2), {BackgroundColor3 = COLORS.Red}):Play() end)
  1126. CloseButton.MouseLeave:Connect(function() TweenService:Create(CloseButton, TweenInfo.new(0.2), {BackgroundColor3 = COLORS.TopBar}):Play() end)
  1127.  
  1128. local function shutdown()
  1129.     getgenv().SignalSpyExecuted = false
  1130.     for _, conn in pairs(Connections) do
  1131.         if typeof(conn) == "RBXScriptConnection" then
  1132.             pcall(function() conn:Disconnect() end)
  1133.         end
  1134.     end
  1135.     pcall(function() SignalSpy:Destroy() end)
  1136. end
  1137.  
  1138. CloseButton.MouseButton1Click:Connect(shutdown)
  1139. getgenv().SignalSpyShutdown = shutdown
  1140.  
  1141. newButton("Copy", "Copy code", function()
  1142.     if everyClipboard then everyClipboard(getCode()) end
  1143.     makeToolTip(true, "Copied!")
  1144.     task.delay(1, function() makeToolTip(false) end)
  1145. end)
  1146.  
  1147. newButton("View Full", "Full signal info", function()
  1148.     if not selected then return end
  1149.     local info = "-- SIGNAL INFO\n"
  1150.     info = info .. "Signal = " .. selected.ClassName .. "." .. selected.SignalName .. "\n"
  1151.     if selected.IsHidden then info = info .. "-- [HIDDEN]\n" end
  1152.     if selected.IsDeprecated then info = info .. "-- [DEPRECATED]\n" end
  1153.     info = info .. "Access = " .. (selected.AccessMethod or "direct") .. "\n"
  1154.     if selected.UsedSetScriptable then info = info .. "-- Used setscriptable()\n" end
  1155.     info = info .. "Instance = " .. instanceToPath(selected.Instance) .. "\n"
  1156.     info = info .. "Calls = " .. tostring(selected.CallCount) .. "\n\n"
  1157.     info = info .. "Args = " .. deepSerialize(selected.Args or {})
  1158.     setCode(info)
  1159. end)
  1160.  
  1161. newButton("Fire", "Fire signal (may crash on hidden)", function()
  1162.     if selected and selected.Signal and firesignal then
  1163.         if selected.IsHidden then
  1164.             makeToolTip(true, "WARNING: May crash!")
  1165.             task.wait(0.5)
  1166.         end
  1167.         pcall(function() firesignal(selected.Signal, unpack(selected.Args or {})) end)
  1168.         makeToolTip(true, "Fired!")
  1169.     else
  1170.         makeToolTip(true, "N/A")
  1171.     end
  1172.     task.delay(1, function() makeToolTip(false) end)
  1173. end)
  1174.  
  1175. newButton("Replicate", "Replicate (safer for hidden)", function()
  1176.     if selected and selected.Signal and replicatesignal then
  1177.         pcall(function() replicatesignal(selected.Signal, unpack(selected.Args or {})) end)
  1178.         makeToolTip(true, "Replicated!")
  1179.     else
  1180.         makeToolTip(true, "N/A")
  1181.     end
  1182.     task.delay(1, function() makeToolTip(false) end)
  1183. end)
  1184.  
  1185. newButton("Connections", "View connections (crash risk on hidden)", function()
  1186.     if selected then
  1187.         if selected.IsHidden then
  1188.             makeToolTip(true, "WARNING: May crash on hidden!")
  1189.             task.wait(1)
  1190.         end
  1191.         openConnectionViewer(selected)
  1192.     else
  1193.         makeToolTip(true, "Select signal!")
  1194.         task.delay(1, function() makeToolTip(false) end)
  1195.     end
  1196. end)
  1197.  
  1198. newButton("Classes", "Class Browser", openClassBrowser)
  1199.  
  1200. newButton("Refresh", "Rehook all", function()
  1201.     rehookAll()
  1202.     makeToolTip(true, "Rehooking...")
  1203.     task.delay(2, function() makeToolTip(false) end)
  1204. end)
  1205.  
  1206. newButton("Clr Logs", "Clear logs", function()
  1207.     for _, g in pairs(groupedLogs) do
  1208.         if g.Frame then g.Frame:Destroy() end
  1209.     end
  1210.     groupedLogs = {}
  1211.     logs = {}
  1212.     selected = nil
  1213.     layoutOrderNum = 999999999
  1214.     TotalCalls = 0
  1215.     setCode("-- Cleared")
  1216.     updateLogCanvas()
  1217. end)
  1218.  
  1219. newButton("Exclude (i)", "Exclude instance", function()
  1220.     if selected then
  1221.         blacklist[selected.ClassName .. "." .. selected.SignalName .. "." .. tostring(selected.Instance)] = true
  1222.         makeToolTip(true, "Excluded!")
  1223.     end
  1224.     task.delay(1, function() makeToolTip(false) end)
  1225. end)
  1226.  
  1227. newButton("Exclude (n)", "Exclude by name", function()
  1228.     if selected then
  1229.         blacklist[selected.ClassName .. "." .. selected.SignalName] = true
  1230.         makeToolTip(true, "Excluded!")
  1231.     end
  1232.     task.delay(1, function() makeToolTip(false) end)
  1233. end)
  1234.  
  1235. newButton("Clr Exclude", "Clear exclusions", function()
  1236.     blacklist = {}
  1237.     makeToolTip(true, "Cleared!")
  1238.     task.delay(1, function() makeToolTip(false) end)
  1239. end)
  1240.  
  1241. newButton("Block (i)", "Block + disconnect", function()
  1242.     if selected and getconnections then
  1243.         local key = selected.ClassName .. "." .. selected.SignalName .. "." .. tostring(selected.Instance)
  1244.         blocklist[key] = true
  1245.         if not selected.IsHidden then
  1246.             pcall(function()
  1247.                 for _, conn in ipairs(getconnections(selected.Signal)) do
  1248.                     conn:Disconnect()
  1249.                 end
  1250.             end)
  1251.         end
  1252.         makeToolTip(true, "Blocked!")
  1253.     else
  1254.         makeToolTip(true, "N/A")
  1255.     end
  1256.     task.delay(1, function() makeToolTip(false) end)
  1257. end)
  1258.  
  1259. newButton("Block (n)", "Block by name", function()
  1260.     if selected then
  1261.         blocklist[selected.ClassName .. "." .. selected.SignalName] = true
  1262.         makeToolTip(true, "Blocked!")
  1263.     else
  1264.         makeToolTip(true, "N/A")
  1265.     end
  1266.     task.delay(1, function() makeToolTip(false) end)
  1267. end)
  1268.  
  1269. newButton("Clr Blocks", "Clear blocks", function()
  1270.     blocklist = {}
  1271.     BlockedConnections = {}
  1272.     makeToolTip(true, "Cleared!")
  1273.     task.delay(1, function() makeToolTip(false) end)
  1274. end)
  1275.  
  1276. newButton("Filter", function()
  1277.     return "Spam: " .. (CONFIG.FilterSpammy and "ON" or "OFF")
  1278. end, function()
  1279.     CONFIG.FilterSpammy = not CONFIG.FilterSpammy
  1280.     SpamHistory = {}
  1281. end)
  1282.  
  1283. newButton("Filter [H]", function()
  1284.     return "Hidden only: " .. (CONFIG.FilterHiddenOnly and "ON" or "OFF")
  1285. end, function()
  1286.     CONFIG.FilterHiddenOnly = not CONFIG.FilterHiddenOnly
  1287.     if CONFIG.FilterHiddenOnly then CONFIG.FilterDeprecatedOnly = false end
  1288.     refreshLogList()
  1289. end)
  1290.  
  1291. newButton("Filter [D]", function()
  1292.     return "Deprecated only: " .. (CONFIG.FilterDeprecatedOnly and "ON" or "OFF")
  1293. end, function()
  1294.     CONFIG.FilterDeprecatedOnly = not CONFIG.FilterDeprecatedOnly
  1295.     if CONFIG.FilterDeprecatedOnly then CONFIG.FilterHiddenOnly = false end
  1296.     refreshLogList()
  1297. end)
  1298.  
  1299. newButton("Expand", "Expand all", function()
  1300.     for _, g in pairs(groupedLogs) do
  1301.         g.Expanded = true
  1302.         if g.ExpandButton then g.ExpandButton.Text = "v" end
  1303.         for _, l in ipairs(g.Logs) do
  1304.             if l.LogFrame then l.LogFrame.Visible = true end
  1305.         end
  1306.     end
  1307.     task.defer(updateLogCanvas)
  1308. end)
  1309.  
  1310. newButton("Collapse", "Collapse all", function()
  1311.     for _, g in pairs(groupedLogs) do
  1312.         g.Expanded = false
  1313.         if g.ExpandButton then g.ExpandButton.Text = ">" end
  1314.         for _, l in ipairs(g.Logs) do
  1315.             if l.LogFrame then l.LogFrame.Visible = false end
  1316.         end
  1317.     end
  1318.     task.defer(updateLogCanvas)
  1319. end)
  1320.  
  1321. newButton("Stats", "Statistics", function()
  1322.     local sorted = {}
  1323.     for key, count in pairs(SignalStats) do
  1324.         table.insert(sorted, {key = key, count = count})
  1325.     end
  1326.     table.sort(sorted, function(a, b) return a.count > b.count end)
  1327.    
  1328.     local info = "-- STATISTICS\n"
  1329.     info = info .. "-- Hooks: " .. TotalHookedCount .. " (H:" .. HiddenHookedCount .. " D:" .. DeprecatedHookedCount .. ")\n"
  1330.     info = info .. "-- Calls: " .. TotalCalls .. "\n"
  1331.     info = info .. "-- setscriptable: " .. (ExploitCapabilities.setscriptable and "YES" or "NO") .. "\n\n"
  1332.     info = info .. "-- TOP SIGNALS:\n"
  1333.    
  1334.     for i, data in ipairs(sorted) do
  1335.         if i > 15 then break end
  1336.         info = info .. "-- " .. data.key .. ": " .. data.count .. "\n"
  1337.     end
  1338.     setCode(info)
  1339. end)
  1340.  
  1341. newButton("Debug", "Debug info", function()
  1342.     local info = "-- DEBUG INFO\n\n"
  1343.     info = info .. "-- CAPABILITIES:\n"
  1344.     for k, v in pairs(ExploitCapabilities) do
  1345.         info = info .. "--   " .. k .. ": " .. (v and "YES" or "NO") .. "\n"
  1346.     end
  1347.    
  1348.     info = info .. "\n-- FAILED HOOKS:\n"
  1349.     info = info .. "-- Hidden failed:\n"
  1350.     local hc = 0
  1351.     for sig, cnt in pairs(FailedHooks.hidden) do
  1352.         hc = hc + 1
  1353.         if hc <= 10 then info = info .. "--   " .. sig .. " (" .. cnt .. "x)\n" end
  1354.     end
  1355.     if hc == 0 then info = info .. "--   (none)\n" end
  1356.    
  1357.     info = info .. "-- Deprecated failed:\n"
  1358.     local dc = 0
  1359.     for sig, cnt in pairs(FailedHooks.deprecated) do
  1360.         dc = dc + 1
  1361.         if dc <= 10 then info = info .. "--   " .. sig .. " (" .. cnt .. "x)\n" end
  1362.     end
  1363.     if dc == 0 then info = info .. "--   (none)\n" end
  1364.    
  1365.     setCode(info)
  1366. end)
  1367.  
  1368. local guiParent = CoreGui
  1369. if gethui then
  1370.     guiParent = gethui()
  1371. elseif protect_gui then
  1372.     protect_gui(SignalSpy)
  1373. end
  1374. SignalSpy.Parent = guiParent
  1375.  
  1376. task.spawn(function()
  1377.     StatusLabel.Text = "[Loading API...]"
  1378.     CachedAPIEvents = FetchAPIEvents()
  1379.    
  1380.     local classCount = 0
  1381.     for _ in pairs(CachedAPIEvents) do classCount = classCount + 1 end
  1382.    
  1383.     if classCount == 0 then
  1384.         StatusLabel.Text = "[API FAIL]"
  1385.         StatusLabel.TextColor3 = COLORS.Red
  1386.         return
  1387.     end
  1388.    
  1389.     task.wait(0.2)
  1390.     rehookAll()
  1391.    
  1392.     print("[SignalSpy v4] Loaded!")
  1393.     print("[SignalSpy] setscriptable:", ExploitCapabilities.setscriptable and "YES" or "NO")
  1394.     print("[SignalSpy] Hooks:", TotalHookedCount, "| Hidden:", HiddenHookedCount, "| Deprecated:", DeprecatedHookedCount)
  1395. end)
  1396.  
  1397. getgenv().SignalSpy = {
  1398.     CONFIG = CONFIG,
  1399.     logs = logs,
  1400.     blacklist = blacklist,
  1401.     blocklist = blocklist,
  1402.     shutdown = shutdown,
  1403.     hookSignal = hookSignal,
  1404.     rehookAll = rehookAll,
  1405.     newButton = newButton,
  1406.     openClassBrowser = openClassBrowser,
  1407.     FailedHooks = FailedHooks,
  1408.     ExploitCapabilities = ExploitCapabilities,
  1409. }
Advertisement
Add Comment
Please, Sign In to add comment