--please give credits if you use in projects -> discord: cool.guy.69 local settings = { copytoclipboard = true, copyasscript = true, logfireserver = true, loginvokeserver = true, logonclientevent = false, --half working logonclientinvoke = true, logindexing = true, } print("[signalspy] loaded") local safetostring = function(v) local t = typeof(v) if t == "string" then return '"' .. v:gsub('"', '\\"') .. '"' elseif t == "number" or t == "boolean" or t == "nil" then return tostring(v) elseif t == "Instance" then return v:GetFullName() elseif t == "EnumItem" then return tostring(v) elseif t == "table" then local parts = {} for k, val in pairs(v) do local kt = type(k) == "string" and '"' .. k:gsub('"', '\\"') .. '"' or tostring(k) local vt = safetostring(val) table.insert(parts, "[" .. kt .. "]=" .. vt) end return "{" .. table.concat(parts, ",") .. "}" elseif t == "vector" then return string.format("Vector3.new(%g, %g, %g)", v.X, v.Y, v.Z) else return "[" .. t .. "]" end end local function makescript(remote, method, args) local goodcurry = remote:GetFullName() .. ":" .. method if #args == 0 then return goodcurry .. "()" end local arguwu = {} for _, v in ipairs(args) do table.insert(arguwu, safetostring(v)) end return goodcurry .. "(" .. table.concat(arguwu, ", ") .. ")" end local function tts(tbl) local str = "" for i, v in ipairs(tbl) do str = str .. "arg[" .. i .. "] = " .. safetostring(v) .. "\n" end return str end local function isvalidremote(self) return typeof(self) == "Instance" and (self:IsA("RemoteEvent") or self:IsA("RemoteFunction")) end local function log(where, remote, method, ...) local args = {...} local out = "[" .. where .. "] " .. remote:GetFullName() .. ":" .. method .. "\n" .. tts(args) print(out) if settings.copytoclipboard and setclipboard then setclipboard(out) end if settings.copyasscript and setclipboard then local script = makescript(remote, method, args) setclipboard(script) end end local namecallorg namecallorg = hookmetamethod(game, "__namecall", newcclosure(function(self, ...) if oth and oth.is_hook_thread and oth.is_hook_thread() then return namecallorg(self, ...) end if not isvalidremote(self) then return namecallorg(self, ...) end local method = getnamecallmethod() if method == "FireServer" and settings.logfireserver then log("client -> server", self, method, ...) elseif method == "InvokeServer" and settings.loginvokeserver then log("client -> server", self, method, ...) end return namecallorg(self, ...) end)) local indexorg indexorg = hookmetamethod(game, "__index", newcclosure(function(self, key) if oth and oth.is_hook_thread and oth.is_hook_thread() then return indexorg(self, key) end if not isvalidremote(self) then return indexorg(self, key) end if settings.logindexing and (key == "FireServer" or key == "InvokeServer") then print("[signalspy] accessed -> " .. self:GetFullName() .. "." .. key) end if key == "OnClientInvoke" and settings.logonclientinvoke and self:IsA("RemoteFunction") then return function(...) log("server -> client", self, "OnClientInvoke", ...) end end return indexorg(self, key) end)) if settings.logonclientevent then for _, r in ipairs(game:GetDescendants()) do if r:IsA("RemoteEvent") then pcall(function() r.OnClientEvent:Connect(function(...) log("server -> client", r, "OnClientEvent", ...) end) end) end end game.DescendantAdded:Connect(function(obj) if obj:IsA("RemoteEvent") then task.wait(0.1) pcall(function() obj.OnClientEvent:Connect(function(...) log("server -> client", obj, "OnClientEvent", ...) end) end) end end) end --faded was here