Advertisement
ExecutorForALLdomain

Untitled

Jun 26th, 2024
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 93.49 KB | None | 0 0
  1. if getgenv().SimpleSpyExecuted and type(getgenv().SimpleSpyShutdown) == "function" then
  2. getgenv().SimpleSpyShutdown()
  3. end
  4.  
  5. local realconfigs = {
  6. logcheckcaller = true,
  7. autoblock = false,
  8. funcEnabled = true,
  9. advancedinfo = true,
  10. --logreturnvalues = true,
  11. supersecretdevtoggle = true
  12. }
  13.  
  14. local configs = newproxy(true)
  15. local configsmetatable = getmetatable(configs)
  16.  
  17. configsmetatable.__index = function(self,index)
  18. return realconfigs[index]
  19. end
  20.  
  21. local oth = oth or syn and syn.oth
  22. local unhook = oth and oth.unhook
  23. local hook = oth and oth.hook
  24.  
  25. local lower = string.lower
  26. local byte = string.byte
  27. local round = math.round
  28. local running = coroutine.running
  29. local resume = coroutine.resume
  30. local status = coroutine.status
  31. local yield = coroutine.yield
  32. local create = coroutine.create
  33. local close = coroutine.close
  34. local OldDebugId = game.GetDebugId
  35. local info = debug.info
  36.  
  37. local IsA = game.IsA
  38. local tostring = tostring
  39. local tonumber = tonumber
  40. local delay = task.delay
  41. local spawn = task.spawn
  42. local clear = table.clear
  43. local clone = table.clone
  44.  
  45. local function blankfunction(...)
  46. return ...
  47. end
  48.  
  49. local get_thread_identity = (syn and syn.get_thread_identity) or getidentity or getthreadidentity
  50. local set_thread_identity = (syn and syn.set_thread_identity) or setidentity
  51. local islclosure = islclosure or is_l_closure
  52.  
  53. local getinfo = getinfo or blankfunction
  54. local getupvalues = getupvalues or debug.getupvalues or blankfunction
  55. local getconstants = getconstants or debug.getconstants or blankfunction
  56.  
  57. local getcustomasset = getsynasset or getcustomasset
  58. local getcallingscript = getcallingscript or blankfunction
  59. local newcclosure = newcclosure or blankfunction
  60. local clonefunction = clonefunction or blankfunction
  61. local cloneref = cloneref or blankfunction
  62. local request = request or syn and syn.request
  63. local makewritable = makewriteable or function(tbl)
  64. setreadonly(tbl,false)
  65. end
  66. local makereadonly = makereadonly or function(tbl)
  67. setreadonly(tbl,true)
  68. end
  69. local isreadonly = isreadonly or table.isfrozen
  70.  
  71. local setclipboard = setclipboard or toclipboard or set_clipboard or (Clipboard and Clipboard.set) or function(...)
  72. return ErrorPrompt("Attempted to set clipboard: "..(...),true)
  73. end
  74.  
  75. local hookmetamethod = hookmetamethod or (makewriteable and makereadonly and getrawmetatable) and function(obj: object, metamethod: string, func: Function)
  76. local old = getrawmetatable(obj)
  77.  
  78. if hookfunction then
  79. return hookfunction(old[metamethod],func)
  80. else
  81. local oldmetamethod = old[metamethod]
  82. makewriteable(old)
  83. old[metamethod] = func
  84. makereadonly(old)
  85. return oldmetamethod
  86. end
  87. end
  88.  
  89. local function Create(instance, properties, children)
  90. local obj = Instance.new(instance)
  91.  
  92. for i, v in next, properties or {} do
  93. obj[i] = v
  94. for _, child in next, children or {} do
  95. child.Parent = obj;
  96. end
  97. end
  98. return obj;
  99. end
  100.  
  101. local function SafeGetService(service)
  102. return cloneref(game:GetService(service))
  103. end
  104.  
  105. local function Search(logtable,tbl)
  106. table.insert(logtable,tbl)
  107.  
  108. for i,v in tbl do
  109. if type(v) == "table" then
  110. return table.find(logtable,v) ~= nil or Search(v)
  111. end
  112. end
  113. end
  114.  
  115. local function IsCyclicTable(tbl)
  116. local checkedtables = {}
  117.  
  118. local function SearchTable(tbl)
  119. table.insert(checkedtables,tbl)
  120.  
  121. for i,v in tbl do
  122. if type(v) == "table" then
  123. return table.find(checkedtables,v) and true or SearchTable(v)
  124. end
  125. end
  126. end
  127.  
  128. return SearchTable(tbl)
  129. end
  130.  
  131. local function deepclone(args: table, copies: table): table
  132. local copy = nil
  133. copies = copies or {}
  134.  
  135. if type(args) == 'table' then
  136. if copies[args] then
  137. copy = copies[args]
  138. else
  139. copy = {}
  140. copies[args] = copy
  141. for i, v in next, args do
  142. copy[deepclone(i, copies)] = deepclone(v, copies)
  143. end
  144. end
  145. elseif typeof(args) == "Instance" then
  146. copy = cloneref(args)
  147. else
  148. copy = args
  149. end
  150. return copy
  151. end
  152.  
  153. local function rawtostring(userdata)
  154. if type(userdata) == "table" or typeof(userdata) == "userdata" then
  155. local rawmetatable = getrawmetatable(userdata)
  156. local cachedstring = rawmetatable and rawget(rawmetatable, "__tostring")
  157.  
  158. if cachedstring then
  159. local wasreadonly = isreadonly(rawmetatable)
  160. if wasreadonly then
  161. makewritable(rawmetatable)
  162. end
  163. rawset(rawmetatable, "__tostring", nil)
  164. local safestring = tostring(userdata)
  165. rawset(rawmetatable, "__tostring", cachedstring)
  166. if wasreadonly then
  167. makereadonly(rawmetatable)
  168. end
  169. return safestring
  170. end
  171. end
  172. return tostring(userdata)
  173. end
  174.  
  175. local CoreGui = SafeGetService("CoreGui")
  176. local Players = SafeGetService("Players")
  177. local RunService = SafeGetService("RunService")
  178. local UserInputService = SafeGetService("UserInputService")
  179. local TweenService = SafeGetService("TweenService")
  180. local ContentProvider = SafeGetService("ContentProvider")
  181. local TextService = SafeGetService("TextService")
  182. local http = SafeGetService("HttpService")
  183.  
  184. local function jsone(str) return http:JSONEncode(str) end
  185. local function jsond(str)
  186. local suc,err = pcall(http.JSONDecode,http,str)
  187. return suc and err or suc
  188. end
  189.  
  190. function ErrorPrompt(Message,state)
  191. if getrenv then
  192. local ErrorPrompt = getrenv().require(CoreGui:WaitForChild("RobloxGui"):WaitForChild("Modules"):WaitForChild("ErrorPrompt")) -- File can be located in your roblox folder (C:\Users\%Username%\AppData\Local\Roblox\Versions\whateverversionitis\ExtraContent\scripts\CoreScripts\Modules)
  193. local prompt = ErrorPrompt.new("Default",{HideErrorCode = true})
  194. local ErrorStoarge = Create("ScreenGui",{Parent = CoreGui,ResetOnSpawn = false})
  195. local thread = state and running()
  196. prompt:setParent(ErrorStoarge)
  197. prompt:setErrorTitle("Simple Spy V3 Error")
  198. prompt:updateButtons({{
  199. Text = "Proceed",
  200. Callback = function()
  201. prompt:_close()
  202. ErrorStoarge:Destroy()
  203. if thread then
  204. resume(thread)
  205. end
  206. end,
  207. Primary = true
  208. }}, 'Default')
  209. prompt:_open(Message)
  210. if thread then
  211. yield(thread)
  212. end
  213. else
  214. warn(Message)
  215. end
  216. end
  217.  
  218. local Highlight = (isfile and loadfile and isfile("Highlight.lua") and loadfile("Highlight.lua")()) or loadstring(game:HttpGet("https://raw.githubusercontent.com/78n/SimpleSpy/main/Highlight.lua"))()
  219.  
  220. local SimpleSpy3 = Create("ScreenGui",{ResetOnSpawn = false})
  221. local Storage = Create("Folder",{})
  222. local Background = Create("Frame",{Parent = SimpleSpy3,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 500, 0, 200),Size = UDim2.new(0, 450, 0, 268)})
  223. local LeftPanel = Create("Frame",{Parent = Background,BackgroundColor3 = Color3.fromRGB(53, 52, 55),BorderSizePixel = 0,Position = UDim2.new(0, 0, 0, 19),Size = UDim2.new(0, 131, 0, 249)})
  224. local LogList = Create("ScrollingFrame",{Parent = LeftPanel,Active = true,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,BorderSizePixel = 0,Position = UDim2.new(0, 0, 0, 9),Size = UDim2.new(0, 131, 0, 232),CanvasSize = UDim2.new(0, 0, 0, 0),ScrollBarThickness = 4})
  225. local UIListLayout = Create("UIListLayout",{Parent = LogList,HorizontalAlignment = Enum.HorizontalAlignment.Center,SortOrder = Enum.SortOrder.LayoutOrder})
  226. local RightPanel = Create("Frame",{Parent = Background,BackgroundColor3 = Color3.fromRGB(37, 36, 38),BorderSizePixel = 0,Position = UDim2.new(0, 131, 0, 19),Size = UDim2.new(0, 319, 0, 249)})
  227. local CodeBox = Create("Frame",{Parent = RightPanel,BackgroundColor3 = Color3.new(0.0823529, 0.0745098, 0.0784314),BorderSizePixel = 0,Size = UDim2.new(0, 319, 0, 119)})
  228. local ScrollingFrame = Create("ScrollingFrame",{Parent = RightPanel,Active = true,BackgroundColor3 = Color3.new(1, 1, 1),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})
  229. local UIGridLayout = Create("UIGridLayout",{Parent = ScrollingFrame,HorizontalAlignment = Enum.HorizontalAlignment.Center,SortOrder = Enum.SortOrder.LayoutOrder,CellPadding = UDim2.new(0, 0, 0, 0),CellSize = UDim2.new(0, 94, 0, 27)})
  230. local TopBar = Create("Frame",{Parent = Background,BackgroundColor3 = Color3.fromRGB(37, 35, 38),BorderSizePixel = 0,Size = UDim2.new(0, 450, 0, 19)})
  231. local Simple = Create("TextButton",{Parent = TopBar,BackgroundColor3 = Color3.new(1, 1, 1),AutoButtonColor = false,BackgroundTransparency = 1,Position = UDim2.new(0, 5, 0, 0),Size = UDim2.new(0, 57, 0, 18),Font = Enum.Font.SourceSansBold,Text = "SimpleSpy",TextColor3 = Color3.new(1, 1, 1),TextSize = 14,TextXAlignment = Enum.TextXAlignment.Left})
  232. local CloseButton = Create("TextButton",{Parent = TopBar,BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902),BorderSizePixel = 0,Position = UDim2.new(1, -19, 0, 0),Size = UDim2.new(0, 19, 0, 19),Font = Enum.Font.SourceSans,Text = "",TextColor3 = Color3.new(0, 0, 0),TextSize = 14})
  233. local ImageLabel = Create("ImageLabel",{Parent = CloseButton,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 5, 0, 5),Size = UDim2.new(0, 9, 0, 9),Image = "http://www.roblox.com/asset/?id=5597086202"})
  234. local MaximizeButton = Create("TextButton",{Parent = TopBar,BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902),BorderSizePixel = 0,Position = UDim2.new(1, -38, 0, 0),Size = UDim2.new(0, 19, 0, 19),Font = Enum.Font.SourceSans,Text = "",TextColor3 = Color3.new(0, 0, 0),TextSize = 14})
  235. local ImageLabel_2 = Create("ImageLabel",{Parent = MaximizeButton,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 5, 0, 5),Size = UDim2.new(0, 9, 0, 9),Image = "http://www.roblox.com/asset/?id=5597108117"})
  236. local MinimizeButton = Create("TextButton",{Parent = TopBar,BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902),BorderSizePixel = 0,Position = UDim2.new(1, -57, 0, 0),Size = UDim2.new(0, 19, 0, 19),Font = Enum.Font.SourceSans,Text = "",TextColor3 = Color3.new(0, 0, 0),TextSize = 14})
  237. local ImageLabel_3 = Create("ImageLabel",{Parent = MinimizeButton,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 5, 0, 5),Size = UDim2.new(0, 9, 0, 9),Image = "http://www.roblox.com/asset/?id=5597105827"})
  238.  
  239. local ToolTip = Create("Frame",{Parent = SimpleSpy3,BackgroundColor3 = Color3.fromRGB(26, 26, 26),BackgroundTransparency = 0.1,BorderColor3 = Color3.new(1, 1, 1),Size = UDim2.new(0, 200, 0, 50),ZIndex = 3,Visible = false})
  240. local TextLabel = Create("TextLabel",{Parent = ToolTip,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 2, 0, 2),Size = UDim2.new(0, 196, 0, 46),ZIndex = 3,Font = Enum.Font.SourceSans,Text = "This is some slightly longer text.",TextColor3 = Color3.new(1, 1, 1),TextSize = 14,TextWrapped = true,TextXAlignment = Enum.TextXAlignment.Left,TextYAlignment = Enum.TextYAlignment.Top})
  241.  
  242. -------------------------------------------------------------------------------
  243.  
  244. local selectedColor = Color3.new(0.321569, 0.333333, 1)
  245. local deselectedColor = Color3.new(0.8, 0.8, 0.8)
  246. --- So things are descending
  247. local layoutOrderNum = 999999999
  248. --- Whether or not the gui is closing
  249. local mainClosing = false
  250. --- Whether or not the gui is closed (defaults to false)
  251. local closed = false
  252. --- Whether or not the sidebar is closing
  253. local sideClosing = false
  254. --- Whether or not the sidebar is closed (defaults to true but opens automatically on remote selection)
  255. local sideClosed = false
  256. --- Whether or not the code box is maximized (defaults to false)
  257. local maximized = false
  258. --- The event logs to be read from
  259. local logs = {}
  260. --- The event currently selected.Log (defaults to nil)
  261. local selected = nil
  262. --- The blacklist (can be a string name or the Remote Instance)
  263. local blacklist = {}
  264. --- The block list (can be a string name or the Remote Instance)
  265. local blocklist = {}
  266. --- Whether or not to add getNil function
  267. local getNil = false
  268. --- Array of remotes (and original functions) connected to
  269. local connectedRemotes = {}
  270. --- True = hookfunction, false = namecall
  271. local toggle = false
  272. --- used to prevent recursives
  273. local prevTables = {}
  274. --- holds logs (for deletion)
  275. local remoteLogs = {}
  276. --- used for hookfunction
  277. getgenv().SIMPLESPYCONFIG_MaxRemotes = 300
  278. local indent = 4
  279. local scheduled = {}
  280. local schedulerconnect
  281. local SimpleSpy = {}
  282. local topstr = ""
  283. local bottomstr = ""
  284. local remotesFadeIn
  285. local rightFadeIn
  286. local codebox
  287. local p
  288. local getnilrequired = false
  289.  
  290. -- autoblock variables
  291. local history = {}
  292. local excluding = {}
  293.  
  294. -- if mouse inside gui
  295. local mouseInGui = false
  296.  
  297. local connections = {}
  298. local DecompiledScripts = {}
  299. local generation = {}
  300. local running_threads = {}
  301. local originalnamecall
  302.  
  303. local remoteEvent = Instance.new("RemoteEvent",Storage)
  304. local UnreliableRemoteEvent = Instance.new("UnreliableRemoteEvent", Storage)
  305. local remoteFunction = Instance.new("RemoteFunction",Storage)
  306. local NamecallHandler = Instance.new("BindableEvent",Storage)
  307. local IndexHandler = Instance.new("BindableEvent",Storage)
  308. local GetDebugIdHandler = Instance.new("BindableFunction",Storage) --Thanks engo for the idea of using BindableFunctions
  309.  
  310. local originalEvent = remoteEvent.FireServer
  311. local originalUnreliableEvent = UnreliableRemoteEvent.FireServer
  312. local originalFunction = remoteFunction.InvokeServer
  313. local GetDebugIDInvoke = GetDebugIdHandler.Invoke
  314.  
  315. function GetDebugIdHandler.OnInvoke(obj: Instance) -- To avoid having to set thread identity and ect
  316. return OldDebugId(obj)
  317. end
  318.  
  319. local function ThreadGetDebugId(obj: Instance): string
  320. return GetDebugIDInvoke(GetDebugIdHandler,obj) -- indexing to avoid having to setnamecall later
  321. end
  322.  
  323. xpcall(function()
  324. if isfile and readfile and isfolder and makefolder then
  325. local cachedconfigs = isfile("SimpleSpy//Settings.json") and jsond(readfile("SimpleSpy//Settings.json"))
  326.  
  327. if cachedconfigs then
  328. for i,v in next, realconfigs do
  329. if cachedconfigs[i] == nil then
  330. cachedconfigs[i] = v
  331. end
  332. end
  333. realconfigs = cachedconfigs
  334. end
  335.  
  336. if not isfolder("SimpleSpy") then
  337. makefolder("SimpleSpy")
  338. end
  339. if not isfolder("SimpleSpy//Assets") then
  340. makefolder("SimpleSpy//Assets")
  341. end
  342. if not isfile("SimpleSpy//Settings.json") then
  343. writefile("SimpleSpy//Settings.json",jsone(realconfigs))
  344. end
  345.  
  346. configsmetatable.__newindex = function(self,index,newindex)
  347. realconfigs[index] = newindex
  348. writefile("SimpleSpy//Settings.json",jsone(realconfigs))
  349. end
  350. else
  351. configsmetatable.__newindex = function(self,index,newindex)
  352. realconfigs[index] = newindex
  353. end
  354. end
  355. end,function(err)
  356. ErrorPrompt(("An error has occured: (%s)"):format(err))
  357. end)
  358.  
  359. local function logthread(thread: thread)
  360. table.insert(running_threads,thread)
  361. end
  362.  
  363. --- Prevents remote spam from causing lag (clears logs after `getgenv().SIMPLESPYCONFIG_MaxRemotes` or 500 remotes)
  364. function clean()
  365. local max = getgenv().SIMPLESPYCONFIG_MaxRemotes
  366. if not typeof(max) == "number" and math.floor(max) ~= max then
  367. max = 500
  368. end
  369. if #remoteLogs > max then
  370. for i = 100, #remoteLogs do
  371. local v = remoteLogs[i]
  372. if typeof(v[1]) == "RBXScriptConnection" then
  373. v[1]:Disconnect()
  374. end
  375. if typeof(v[2]) == "Instance" then
  376. v[2]:Destroy()
  377. end
  378. end
  379. local newLogs = {}
  380. for i = 1, 100 do
  381. table.insert(newLogs, remoteLogs[i])
  382. end
  383. remoteLogs = newLogs
  384. end
  385. end
  386.  
  387. local function ThreadIsNotDead(thread: thread): boolean
  388. return not status(thread) == "dead"
  389. end
  390.  
  391. --- Scales the ToolTip to fit containing text
  392. function scaleToolTip()
  393. local size = TextService:GetTextSize(TextLabel.Text, TextLabel.TextSize, TextLabel.Font, Vector2.new(196, math.huge))
  394. TextLabel.Size = UDim2.new(0, size.X, 0, size.Y)
  395. ToolTip.Size = UDim2.new(0, size.X + 4, 0, size.Y + 4)
  396. end
  397.  
  398. --- Executed when the toggle button (the SimpleSpy logo) is hovered over
  399. function onToggleButtonHover()
  400. if not toggle then
  401. TweenService:Create(Simple, TweenInfo.new(0.5), {TextColor3 = Color3.fromRGB(252, 51, 51)}):Play()
  402. else
  403. TweenService:Create(Simple, TweenInfo.new(0.5), {TextColor3 = Color3.fromRGB(68, 206, 91)}):Play()
  404. end
  405. end
  406.  
  407. --- Executed when the toggle button is unhovered over
  408. function onToggleButtonUnhover()
  409. TweenService:Create(Simple, TweenInfo.new(0.5), {TextColor3 = Color3.fromRGB(255, 255, 255)}):Play()
  410. end
  411.  
  412. --- Executed when the X button is hovered over
  413. function onXButtonHover()
  414. TweenService:Create(CloseButton, TweenInfo.new(0.2), {BackgroundColor3 = Color3.fromRGB(255, 60, 60)}):Play()
  415. end
  416.  
  417. --- Executed when the X button is unhovered over
  418. function onXButtonUnhover()
  419. TweenService:Create(CloseButton, TweenInfo.new(0.2), {BackgroundColor3 = Color3.fromRGB(37, 36, 38)}):Play()
  420. end
  421.  
  422. --- Toggles the remote spy method (when button clicked)
  423. function onToggleButtonClick()
  424. if toggle then
  425. TweenService:Create(Simple, TweenInfo.new(0.5), {TextColor3 = Color3.fromRGB(252, 51, 51)}):Play()
  426. else
  427. TweenService:Create(Simple, TweenInfo.new(0.5), {TextColor3 = Color3.fromRGB(68, 206, 91)}):Play()
  428. end
  429. toggleSpyMethod()
  430. end
  431.  
  432. --- Reconnects bringBackOnResize if the current viewport changes and also connects it initially
  433. function connectResize()
  434. if not workspace.CurrentCamera then
  435. workspace:GetPropertyChangedSignal("CurrentCamera"):Wait()
  436. end
  437. local lastCam = workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(bringBackOnResize)
  438. workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
  439. lastCam:Disconnect()
  440. if typeof(lastCam) == 'Connection' then
  441. lastCam:Disconnect()
  442. end
  443. lastCam = workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(bringBackOnResize)
  444. end)
  445. end
  446.  
  447. --- Brings gui back if it gets lost offscreen (connected to the camera viewport changing)
  448. function bringBackOnResize()
  449. validateSize()
  450. if sideClosed then
  451. minimizeSize()
  452. else
  453. maximizeSize()
  454. end
  455. local currentX = Background.AbsolutePosition.X
  456. local currentY = Background.AbsolutePosition.Y
  457. local viewportSize = workspace.CurrentCamera.ViewportSize
  458. if (currentX < 0) or (currentX > (viewportSize.X - (sideClosed and 131 or Background.AbsoluteSize.X))) then
  459. if currentX < 0 then
  460. currentX = 0
  461. else
  462. currentX = viewportSize.X - (sideClosed and 131 or Background.AbsoluteSize.X)
  463. end
  464. end
  465. if (currentY < 0) or (currentY > (viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36)) then
  466. if currentY < 0 then
  467. currentY = 0
  468. else
  469. currentY = viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36
  470. end
  471. end
  472. TweenService.Create(TweenService, Background, TweenInfo.new(0.1), {Position = UDim2.new(0, currentX, 0, currentY)}):Play()
  473. end
  474.  
  475. --- Drags gui (so long as mouse is held down)
  476. --- @param input InputObject
  477. function onBarInput(input)
  478. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  479. local lastPos = UserInputService:GetMouseLocation()
  480. local mainPos = Background.AbsolutePosition
  481. local offset = mainPos - lastPos
  482. local currentPos = offset + lastPos
  483. if not connections["drag"] then
  484. connections["drag"] = RunService.RenderStepped:Connect(function()
  485. local newPos = UserInputService:GetMouseLocation()
  486. if newPos ~= lastPos then
  487. local currentX = (offset + newPos).X
  488. local currentY = (offset + newPos).Y
  489. local viewportSize = workspace.CurrentCamera.ViewportSize
  490. if (currentX < 0 and currentX < currentPos.X) or (currentX > (viewportSize.X - (sideClosed and 131 or TopBar.AbsoluteSize.X)) and currentX > currentPos.X) then
  491. if currentX < 0 then
  492. currentX = 0
  493. else
  494. currentX = viewportSize.X - (sideClosed and 131 or TopBar.AbsoluteSize.X)
  495. end
  496. end
  497. if (currentY < 0 and currentY < currentPos.Y) or (currentY > (viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36) and currentY > currentPos.Y) then
  498. if currentY < 0 then
  499. currentY = 0
  500. else
  501. currentY = viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36
  502. end
  503. end
  504. currentPos = Vector2.new(currentX, currentY)
  505. lastPos = newPos
  506. TweenService.Create(TweenService, Background, TweenInfo.new(0.1), {Position = UDim2.new(0, currentPos.X, 0, currentPos.Y)}):Play()
  507. end
  508. -- if input.UserInputState ~= Enum.UserInputState.Begin then
  509. -- RunService.UnbindFromRenderStep(RunService, "drag")
  510. -- end
  511. end)
  512. end
  513. table.insert(connections, UserInputService.InputEnded:Connect(function(inputE)
  514. if input == inputE then
  515. if connections["drag"] then
  516. connections["drag"]:Disconnect()
  517. connections["drag"] = nil
  518. end
  519. end
  520. end))
  521. end
  522. end
  523.  
  524. --- Fades out the table of elements (and makes them invisible), returns a function to make them visible again
  525. function fadeOut(elements)
  526. local data = {}
  527. for _, v in next, elements do
  528. if typeof(v) == "Instance" and v:IsA("GuiObject") and v.Visible then
  529. spawn(function()
  530. data[v] = {
  531. BackgroundTransparency = v.BackgroundTransparency
  532. }
  533. TweenService:Create(v, TweenInfo.new(0.5), {BackgroundTransparency = 1}):Play()
  534. if v:IsA("TextBox") or v:IsA("TextButton") or v:IsA("TextLabel") then
  535. data[v].TextTransparency = v.TextTransparency
  536. TweenService:Create(v, TweenInfo.new(0.5), {TextTransparency = 1}):Play()
  537. elseif v:IsA("ImageButton") or v:IsA("ImageLabel") then
  538. data[v].ImageTransparency = v.ImageTransparency
  539. TweenService:Create(v, TweenInfo.new(0.5), {ImageTransparency = 1}):Play()
  540. end
  541. delay(0.5,function()
  542. v.Visible = false
  543. for i, x in next, data[v] do
  544. v[i] = x
  545. end
  546. data[v] = true
  547. end)
  548. end)
  549. end
  550. end
  551. return function()
  552. for i, _ in next, data do
  553. spawn(function()
  554. local properties = {
  555. BackgroundTransparency = i.BackgroundTransparency
  556. }
  557. i.BackgroundTransparency = 1
  558. TweenService:Create(i, TweenInfo.new(0.5), {BackgroundTransparency = properties.BackgroundTransparency}):Play()
  559. if i:IsA("TextBox") or i:IsA("TextButton") or i:IsA("TextLabel") then
  560. properties.TextTransparency = i.TextTransparency
  561. i.TextTransparency = 1
  562. TweenService:Create(i, TweenInfo.new(0.5), {TextTransparency = properties.TextTransparency}):Play()
  563. elseif i:IsA("ImageButton") or i:IsA("ImageLabel") then
  564. properties.ImageTransparency = i.ImageTransparency
  565. i.ImageTransparency = 1
  566. TweenService:Create(i, TweenInfo.new(0.5), {ImageTransparency = properties.ImageTransparency}):Play()
  567. end
  568. i.Visible = true
  569. end)
  570. end
  571. end
  572. end
  573.  
  574. --- Expands and minimizes the gui (closed is the toggle boolean)
  575. function toggleMinimize(override)
  576. if mainClosing and not override or maximized then
  577. return
  578. end
  579. mainClosing = true
  580. closed = not closed
  581. if closed then
  582. if not sideClosed then
  583. toggleSideTray(true)
  584. end
  585. LeftPanel.Visible = true
  586. remotesFadeIn = fadeOut(LeftPanel:GetDescendants())
  587. TweenService:Create(LeftPanel, TweenInfo.new(0.5), {Size = UDim2.new(0, 131, 0, 0)}):Play()
  588. wait(0.5)
  589. else
  590. TweenService:Create(LeftPanel, TweenInfo.new(0.5), {Size = UDim2.new(0, 131, 0, 249)}):Play()
  591. wait(0.5)
  592. if remotesFadeIn then
  593. remotesFadeIn()
  594. remotesFadeIn = nil
  595. end
  596. bringBackOnResize()
  597. end
  598. mainClosing = false
  599. end
  600.  
  601. --- Expands and minimizes the sidebar (sideClosed is the toggle boolean)
  602. function toggleSideTray(override)
  603. if sideClosing and not override or maximized then
  604. return
  605. end
  606. sideClosing = true
  607. sideClosed = not sideClosed
  608. if sideClosed then
  609. rightFadeIn = fadeOut(RightPanel:GetDescendants())
  610. wait(0.5)
  611. minimizeSize(0.5)
  612. wait(0.5)
  613. RightPanel.Visible = false
  614. else
  615. if closed then
  616. toggleMinimize(true)
  617. end
  618. RightPanel.Visible = true
  619. maximizeSize(0.5)
  620. wait(0.5)
  621. if rightFadeIn then
  622. rightFadeIn()
  623. end
  624. bringBackOnResize()
  625. end
  626. sideClosing = false
  627. end
  628.  
  629. --- Expands code box to fit screen for more convenient viewing
  630. function toggleMaximize()
  631. if not sideClosed and not maximized then
  632. maximized = true
  633. local disable = Instance.new("TextButton")
  634. local prevSize = UDim2.new(0, CodeBox.AbsoluteSize.X, 0, CodeBox.AbsoluteSize.Y)
  635. local prevPos = UDim2.new(0,CodeBox.AbsolutePosition.X, 0, CodeBox.AbsolutePosition.Y)
  636. disable.Size = UDim2.new(1, 0, 1, 0)
  637. disable.BackgroundColor3 = Color3.new()
  638. disable.BorderSizePixel = 0
  639. disable.Text = 0
  640. disable.ZIndex = 3
  641. disable.BackgroundTransparency = 1
  642. disable.AutoButtonColor = false
  643. CodeBox.ZIndex = 4
  644. CodeBox.Position = prevPos
  645. CodeBox.Size = prevSize
  646. TweenService:Create(CodeBox, TweenInfo.new(0.5), {Size = UDim2.new(0.5, 0, 0.5, 0), Position = UDim2.new(0.25, 0, 0.25, 0)}):Play()
  647. TweenService:Create(disable, TweenInfo.new(0.5), {BackgroundTransparency = 0.5}):Play()
  648. disable.MouseButton1Click:Connect(function()
  649. if UserInputService:GetMouseLocation().Y + 36 >= CodeBox.AbsolutePosition.Y and UserInputService:GetMouseLocation().Y + 36 <= CodeBox.AbsolutePosition.Y + CodeBox.AbsoluteSize.Y and UserInputService:GetMouseLocation().X >= CodeBox.AbsolutePosition.X and UserInputService:GetMouseLocation().X <= CodeBox.AbsolutePosition.X + CodeBox.AbsoluteSize.X then
  650. return
  651. end
  652. TweenService:Create(CodeBox, TweenInfo.new(0.5), {Size = prevSize, Position = prevPos}):Play()
  653. TweenService:Create(disable, TweenInfo.new(0.5), {BackgroundTransparency = 1}):Play()
  654. wait(0.5)
  655. disable:Destroy()
  656. CodeBox.Size = UDim2.new(1, 0, 0.5, 0)
  657. CodeBox.Position = UDim2.new(0, 0, 0, 0)
  658. CodeBox.ZIndex = 0
  659. maximized = false
  660. end)
  661. end
  662. end
  663.  
  664. --- Checks if cursor is within resize range
  665. --- @param p Vector2
  666. function isInResizeRange(p)
  667. local relativeP = p - Background.AbsolutePosition
  668. local range = 5
  669. if relativeP.X >= TopBar.AbsoluteSize.X - range and relativeP.Y >= Background.AbsoluteSize.Y - range
  670. and relativeP.X <= TopBar.AbsoluteSize.X and relativeP.Y <= Background.AbsoluteSize.Y then
  671. return true, 'B'
  672. elseif relativeP.X >= TopBar.AbsoluteSize.X - range and relativeP.X <= Background.AbsoluteSize.X then
  673. return true, 'X'
  674. elseif relativeP.Y >= Background.AbsoluteSize.Y - range and relativeP.Y <= Background.AbsoluteSize.Y then
  675. return true, 'Y'
  676. end
  677. return false
  678. end
  679.  
  680. --- Checks if cursor is within dragging range
  681. --- @param p Vector2
  682. function isInDragRange(p)
  683. local relativeP = p - Background.AbsolutePosition
  684. local topbarAS = TopBar.AbsoluteSize
  685. return relativeP.X <= topbarAS.X - CloseButton.AbsoluteSize.X * 3 and relativeP.X >= 0 and relativeP.Y <= topbarAS.Y and relativeP.Y >= 0 or false
  686. end
  687.  
  688. --- Called when mouse enters SimpleSpy
  689. local customCursor = Create("ImageLabel",{Parent = SimpleSpy3,Visible = false,Size = UDim2.fromOffset(200, 200),ZIndex = 1e9,BackgroundTransparency = 1,Image = "",Parent = SimpleSpy3})
  690. function mouseEntered()
  691. local con = connections["SIMPLESPY_CURSOR"]
  692. if con then
  693. con:Disconnect()
  694. connections["SIMPLESPY_CURSOR"] = nil
  695. end
  696. connections["SIMPLESPY_CURSOR"] = RunService.RenderStepped:Connect(function()
  697. UserInputService.MouseIconEnabled = not mouseInGui
  698. customCursor.Visible = mouseInGui
  699. if mouseInGui and getgenv().SimpleSpyExecuted then
  700. local mouseLocation = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  701. customCursor.Position = UDim2.fromOffset(mouseLocation.X - customCursor.AbsoluteSize.X / 2, mouseLocation.Y - customCursor.AbsoluteSize.Y / 2)
  702. local inRange, type = isInResizeRange(mouseLocation)
  703. if inRange and not closed then
  704. if not sideClosed then
  705. customCursor.Image = type == 'B' and "rbxassetid://6065821980" or type == 'X' and "rbxassetid://6065821086" or type == 'Y' and "rbxassetid://6065821596"
  706. elseif type == 'Y' or type == 'B' then
  707. customCursor.Image = "rbxassetid://6065821596"
  708. end
  709. elseif customCursor.Image ~= "rbxassetid://6065775281" then
  710. customCursor.Image = "rbxassetid://6065775281"
  711. end
  712. else
  713. connections["SIMPLESPY_CURSOR"]:Disconnect()
  714. end
  715. end)
  716. end
  717.  
  718. --- Called when mouse moves
  719. function mouseMoved()
  720. local mousePos = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  721. if not closed
  722. and mousePos.X >= TopBar.AbsolutePosition.X and mousePos.X <= TopBar.AbsolutePosition.X + TopBar.AbsoluteSize.X
  723. and mousePos.Y >= Background.AbsolutePosition.Y and mousePos.Y <= Background.AbsolutePosition.Y + Background.AbsoluteSize.Y then
  724. if not mouseInGui then
  725. mouseInGui = true
  726. mouseEntered()
  727. end
  728. else
  729. mouseInGui = false
  730. end
  731. end
  732.  
  733. --- Adjusts the ui elements to the 'Maximized' size
  734. function maximizeSize(speed)
  735. if not speed then
  736. speed = 0.05
  737. end
  738. TweenService:Create(LeftPanel, TweenInfo.new(speed), { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }):Play()
  739. TweenService:Create(RightPanel, TweenInfo.new(speed), { Size = UDim2.fromOffset(Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }):Play()
  740. TweenService:Create(TopBar, TweenInfo.new(speed), { Size = UDim2.fromOffset(Background.AbsoluteSize.X, TopBar.AbsoluteSize.Y) }):Play()
  741. TweenService:Create(ScrollingFrame, TweenInfo.new(speed), { Size = UDim2.fromOffset(Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X, 110), Position = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y) }):Play()
  742. TweenService:Create(CodeBox, TweenInfo.new(speed), { Size = UDim2.fromOffset(Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y) }):Play()
  743. TweenService:Create(LogList, TweenInfo.new(speed), { Size = UDim2.fromOffset(LogList.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y - 18) }):Play()
  744. end
  745.  
  746. --- Adjusts the ui elements to close the side
  747. function minimizeSize(speed)
  748. if not speed then
  749. speed = 0.05
  750. end
  751. TweenService:Create(LeftPanel, TweenInfo.new(speed), { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }):Play()
  752. TweenService:Create(RightPanel, TweenInfo.new(speed), { Size = UDim2.fromOffset(0, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }):Play()
  753. TweenService:Create(TopBar, TweenInfo.new(speed), { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, TopBar.AbsoluteSize.Y) }):Play()
  754. TweenService:Create(ScrollingFrame, TweenInfo.new(speed), { Size = UDim2.fromOffset(0, 119), Position = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y) }):Play()
  755. TweenService:Create(CodeBox, TweenInfo.new(speed), { Size = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y) }):Play()
  756. TweenService:Create(LogList, TweenInfo.new(speed), { Size = UDim2.fromOffset(LogList.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y - 18) }):Play()
  757. end
  758.  
  759. --- Ensures size is within screensize limitations
  760. function validateSize()
  761. local x, y = Background.AbsoluteSize.X, Background.AbsoluteSize.Y
  762. local screenSize = workspace.CurrentCamera.ViewportSize
  763. if x + Background.AbsolutePosition.X > screenSize.X then
  764. if screenSize.X - Background.AbsolutePosition.X >= 450 then
  765. x = screenSize.X - Background.AbsolutePosition.X
  766. else
  767. x = 450
  768. end
  769. elseif y + Background.AbsolutePosition.Y > screenSize.Y then
  770. if screenSize.X - Background.AbsolutePosition.Y >= 268 then
  771. y = screenSize.Y - Background.AbsolutePosition.Y
  772. else
  773. y = 268
  774. end
  775. end
  776. Background.Size = UDim2.fromOffset(x, y)
  777. end
  778.  
  779. --- Called on user input while mouse in 'Background' frame
  780. --- @param input InputObject
  781. function backgroundUserInput(input)
  782. local mousePos = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  783. local inResizeRange, type = isInResizeRange(mousePos)
  784. if input.UserInputType == Enum.UserInputType.MouseButton1 and inResizeRange then
  785. local lastPos = UserInputService:GetMouseLocation()
  786. local offset = Background.AbsoluteSize - lastPos
  787. local currentPos = lastPos + offset
  788. if not connections["SIMPLESPY_RESIZE"] then
  789. connections["SIMPLESPY_RESIZE"] = RunService.RenderStepped:Connect(function()
  790. local newPos = UserInputService:GetMouseLocation()
  791. if newPos ~= lastPos then
  792. local currentX = (newPos + offset).X
  793. local currentY = (newPos + offset).Y
  794. if currentX < 450 then
  795. currentX = 450
  796. end
  797. if currentY < 268 then
  798. currentY = 268
  799. end
  800. currentPos = Vector2.new(currentX, currentY)
  801. Background.Size = UDim2.fromOffset((not sideClosed and not closed and (type == "X" or type == "B")) and currentPos.X or Background.AbsoluteSize.X, (--[[(not sideClosed or currentPos.X <= LeftPanel.AbsolutePosition.X + LeftPanel.AbsoluteSize.X) and]] not closed and (type == "Y" or type == "B")) and currentPos.Y or Background.AbsoluteSize.Y)
  802. validateSize()
  803. if sideClosed then
  804. minimizeSize()
  805. else
  806. maximizeSize()
  807. end
  808. lastPos = newPos
  809. end
  810. end)
  811. end
  812. table.insert(connections, UserInputService.InputEnded:Connect(function(inputE)
  813. if input == inputE then
  814. if connections["SIMPLESPY_RESIZE"] then
  815. connections["SIMPLESPY_RESIZE"]:Disconnect()
  816. connections["SIMPLESPY_RESIZE"] = nil
  817. end
  818. end
  819. end))
  820. elseif isInDragRange(mousePos) then
  821. onBarInput(input)
  822. end
  823. end
  824.  
  825. --- Gets the player an instance is descended from
  826. function getPlayerFromInstance(instance)
  827. for _, v in next, Players:GetPlayers() do
  828. if v.Character and (instance:IsDescendantOf(v.Character) or instance == v.Character) then
  829. return v
  830. end
  831. end
  832. end
  833.  
  834. --- Runs on MouseButton1Click of an event frame
  835. function eventSelect(frame)
  836. if selected and selected.Log then
  837. if selected.Button then
  838. spawn(function()
  839. TweenService:Create(selected.Button, TweenInfo.new(0.5), {BackgroundColor3 = Color3.fromRGB(0, 0, 0)}):Play()
  840. end)
  841. end
  842. selected = nil
  843. end
  844. for _, v in next, logs do
  845. if frame == v.Log then
  846. selected = v
  847. end
  848. end
  849. if selected and selected.Log then
  850. spawn(function()
  851. TweenService:Create(frame.Button, TweenInfo.new(0.5), {BackgroundColor3 = Color3.fromRGB(92, 126, 229)}):Play()
  852. end)
  853. codebox:setRaw(selected.GenScript)
  854. end
  855. if sideClosed then
  856. toggleSideTray()
  857. end
  858. end
  859.  
  860. --- Updates the canvas size to fit the current amount of function buttons
  861. function updateFunctionCanvas()
  862. ScrollingFrame.CanvasSize = UDim2.fromOffset(UIGridLayout.AbsoluteContentSize.X, UIGridLayout.AbsoluteContentSize.Y)
  863. end
  864.  
  865. --- Updates the canvas size to fit the amount of current remotes
  866. function updateRemoteCanvas()
  867. LogList.CanvasSize = UDim2.fromOffset(UIListLayout.AbsoluteContentSize.X, UIListLayout.AbsoluteContentSize.Y)
  868. end
  869.  
  870. --- Allows for toggling of the tooltip and easy setting of le description
  871. --- @param enable boolean
  872. --- @param text string
  873. function makeToolTip(enable, text)
  874. if enable and text then
  875. if ToolTip.Visible then
  876. ToolTip.Visible = false
  877. local tooltip = connections["ToolTip"]
  878. if tooltip then
  879. tooltip:Disconnect()
  880. end
  881. end
  882. local first = true
  883. connections["ToolTip"] = RunService.RenderStepped:Connect(function()
  884. local MousePos = UserInputService:GetMouseLocation()
  885. local topLeft = MousePos + Vector2.new(20, -15)
  886. local bottomRight = topLeft + ToolTip.AbsoluteSize
  887. local ViewportSize = workspace.CurrentCamera.ViewportSize
  888. local ViewportSizeX = ViewportSize.X
  889. local ViewportSizeY = ViewportSize.Y
  890.  
  891. if topLeft.X < 0 then
  892. topLeft = Vector2.new(0, topLeft.Y)
  893. elseif bottomRight.X > ViewportSizeX then
  894. topLeft = Vector2.new(ViewportSizeX - ToolTip.AbsoluteSize.X, topLeft.Y)
  895. end
  896. if topLeft.Y < 0 then
  897. topLeft = Vector2.new(topLeft.X, 0)
  898. elseif bottomRight.Y > ViewportSizeY - 35 then
  899. topLeft = Vector2.new(topLeft.X, ViewportSizeY - ToolTip.AbsoluteSize.Y - 35)
  900. end
  901. if topLeft.X <= MousePos.X and topLeft.Y <= MousePos.Y then
  902. topLeft = Vector2.new(MousePos.X - ToolTip.AbsoluteSize.X - 2, MousePos.Y - ToolTip.AbsoluteSize.Y - 2)
  903. end
  904. if first then
  905. ToolTip.Position = UDim2.fromOffset(topLeft.X, topLeft.Y)
  906. first = false
  907. else
  908. ToolTip:TweenPosition(UDim2.fromOffset(topLeft.X, topLeft.Y), "Out", "Linear", 0.1)
  909. end
  910. end)
  911. TextLabel.Text = text
  912. TextLabel.TextScaled = true
  913. ToolTip.Visible = true
  914. return
  915. else
  916. if ToolTip.Visible then
  917. ToolTip.Visible = false
  918. local tooltip = connections["ToolTip"]
  919. if tooltip then
  920. tooltip:Disconnect()
  921. end
  922. end
  923. end
  924. end
  925.  
  926. --- Creates new function button (below codebox)
  927. --- @param name string
  928. ---@param description function
  929. ---@param onClick function
  930. function newButton(name, description, onClick)
  931. local FunctionTemplate = Create("Frame",{Name = "FunctionTemplate",Parent = ScrollingFrame,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Size = UDim2.new(0, 117, 0, 23)})
  932. local ColorBar = Create("Frame",{Name = "ColorBar",Parent = FunctionTemplate,BackgroundColor3 = Color3.new(1, 1, 1),BorderSizePixel = 0,Position = UDim2.new(0, 7, 0, 10),Size = UDim2.new(0, 7, 0, 18),ZIndex = 3})
  933. local Text = Create("TextLabel",{Text = name,Name = "Text",Parent = FunctionTemplate,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 19, 0, 10),Size = UDim2.new(0, 69, 0, 18),ZIndex = 2,Font = Enum.Font.SourceSans,TextColor3 = Color3.new(1, 1, 1),TextSize = 14,TextStrokeColor3 = Color3.new(0.145098, 0.141176, 0.14902),TextXAlignment = Enum.TextXAlignment.Left})
  934. local Button = Create("TextButton",{Name = "Button",Parent = FunctionTemplate,BackgroundColor3 = Color3.new(0, 0, 0),BackgroundTransparency = 0.69999998807907,BorderColor3 = Color3.new(1, 1, 1),Position = UDim2.new(0, 7, 0, 10),Size = UDim2.new(0, 80, 0, 18),AutoButtonColor = false,Font = Enum.Font.SourceSans,Text = "",TextColor3 = Color3.new(0, 0, 0),TextSize = 14})
  935.  
  936. Button.MouseEnter:Connect(function()
  937. makeToolTip(true, description())
  938. end)
  939. Button.MouseLeave:Connect(function()
  940. makeToolTip(false)
  941. end)
  942. FunctionTemplate.AncestryChanged:Connect(function()
  943. makeToolTip(false)
  944. end)
  945. Button.MouseButton1Click:Connect(function(...)
  946. logthread(running())
  947. onClick(FunctionTemplate, ...)
  948. end)
  949. updateFunctionCanvas()
  950. end
  951.  
  952. --- Adds new Remote to logs
  953. --- @param name string The name of the remote being logged
  954. --- @param type string The type of the remote being logged (either 'function' or 'event')
  955. --- @param args any
  956. --- @param remote any
  957. --- @param function_info string
  958. --- @param blocked any
  959. function newRemote(type, data)
  960. if layoutOrderNum < 1 then layoutOrderNum = 999999999 end
  961. local remote = data.remote
  962. local callingscript = data.callingscript
  963.  
  964. local RemoteTemplate = Create("Frame",{LayoutOrder = layoutOrderNum,Name = "RemoteTemplate",Parent = LogList,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Size = UDim2.new(0, 117, 0, 27)})
  965. local ColorBar = Create("Frame",{Name = "ColorBar",Parent = RemoteTemplate,BackgroundColor3 = (type == "event" and Color3.fromRGB(255, 242, 0)) or Color3.fromRGB(99, 86, 245),BorderSizePixel = 0,Position = UDim2.new(0, 0, 0, 1),Size = UDim2.new(0, 7, 0, 18),ZIndex = 2})
  966. local Text = Create("TextLabel",{TextTruncate = Enum.TextTruncate.AtEnd,Name = "Text",Parent = RemoteTemplate,BackgroundColor3 = Color3.new(1, 1, 1),BackgroundTransparency = 1,Position = UDim2.new(0, 12, 0, 1),Size = UDim2.new(0, 105, 0, 18),ZIndex = 2,Font = Enum.Font.SourceSans,Text = remote.Name,TextColor3 = Color3.new(1, 1, 1),TextSize = 14,TextXAlignment = Enum.TextXAlignment.Left})
  967. local Button = Create("TextButton",{Name = "Button",Parent = RemoteTemplate,BackgroundColor3 = Color3.new(0, 0, 0),BackgroundTransparency = 0.75,BorderColor3 = Color3.new(1, 1, 1),Position = UDim2.new(0, 0, 0, 1),Size = UDim2.new(0, 117, 0, 18),AutoButtonColor = false,Font = Enum.Font.SourceSans,Text = "",TextColor3 = Color3.new(0, 0, 0),TextSize = 14})
  968.  
  969. local log = {
  970. Name = remote.name,
  971. Function = data.infofunc or "--Function Info is disabled",
  972. Remote = remote,
  973. DebugId = data.id,
  974. metamethod = data.metamethod,
  975. args = data.args,
  976. Log = RemoteTemplate,
  977. Button = Button,
  978. Blocked = data.blocked,
  979. Source = callingscript,
  980. returnvalue = data.returnvalue,
  981. GenScript = "-- Generating, please wait...\n-- (If this message persists, the remote args are likely extremely long)"
  982. }
  983.  
  984. logs[#logs + 1] = log
  985. local connect = Button.MouseButton1Click:Connect(function()
  986. logthread(running())
  987. eventSelect(RemoteTemplate)
  988. log.GenScript = genScript(log.Remote, log.args)
  989. if blocked then
  990. log.GenScript = "-- THIS REMOTE WAS PREVENTED FROM FIRING TO THE SERVER BY SIMPLESPY\n\n" .. log.GenScript
  991. end
  992. if selected == log and RemoteTemplate then
  993. eventSelect(RemoteTemplate)
  994. end
  995. end)
  996. layoutOrderNum -= 1
  997. table.insert(remoteLogs, 1, {connect, RemoteTemplate})
  998. clean()
  999. updateRemoteCanvas()
  1000. end
  1001.  
  1002. --- Generates a script from the provided arguments (first has to be remote path)
  1003. function genScript(remote, args)
  1004. prevTables = {}
  1005. local gen = ""
  1006. if #args > 0 then
  1007. xpcall(function()
  1008. gen = v2v({args = args}) .. "\n"
  1009. end,function(err)
  1010. gen ..= "-- An error has occured:\n--"..err.."\n-- TableToString failure! Reverting to legacy functionality (results may vary)\nlocal args = {"
  1011. xpcall(function()
  1012. for i, v in next, args do
  1013. if type(i) ~= "Instance" and type(i) ~= "userdata" then
  1014. gen = gen .. "\n [object] = "
  1015. elseif type(i) == "string" then
  1016. gen = gen .. '\n ["' .. i .. '"] = '
  1017. elseif type(i) == "userdata" and typeof(i) ~= "Instance" then
  1018. gen = gen .. "\n [" .. string.format("nil --[[%s]]", typeof(v)) .. ")] = "
  1019. elseif type(i) == "userdata" then
  1020. gen = gen .. "\n [game." .. i:GetFullName() .. ")] = "
  1021. end
  1022. if type(v) ~= "Instance" and type(v) ~= "userdata" then
  1023. gen = gen .. "object"
  1024. elseif type(v) == "string" then
  1025. gen = gen .. '"' .. v .. '"'
  1026. elseif type(v) == "userdata" and typeof(v) ~= "Instance" then
  1027. gen = gen .. string.format("nil --[[%s]]", typeof(v))
  1028. elseif type(v) == "userdata" then
  1029. gen = gen .. "game." .. v:GetFullName()
  1030. end
  1031. end
  1032. gen ..= "\n}\n\n"
  1033. end,function()
  1034. gen ..= "}\n-- Legacy tableToString failure! Unable to decompile."
  1035. end)
  1036. end)
  1037. if not remote:IsDescendantOf(game) and not getnilrequired then
  1038. gen = "function getNil(name,class) for _,v in next, getnilinstances()do if v.ClassName==class and v.Name==name then return v;end end end\n\n" .. gen
  1039. end
  1040. if remote:IsA("RemoteEvent") or remote:IsA("UnreliableRemoteEvent") then
  1041. gen ..= v2s(remote) .. ":FireServer(unpack(args))"
  1042. elseif remote:IsA("RemoteFunction") then
  1043. gen = gen .. v2s(remote) .. ":InvokeServer(unpack(args))"
  1044. end
  1045. else
  1046. if remote:IsA("RemoteEvent") or remote:IsA("UnreliableRemoteEvent") then
  1047. gen ..= v2s(remote) .. ":FireServer()"
  1048. elseif remote:IsA("RemoteFunction") then
  1049. gen ..= v2s(remote) .. ":InvokeServer()"
  1050. end
  1051. end
  1052. prevTables = {}
  1053. return gen
  1054. end
  1055.  
  1056. --- value-to-string: value, string (out), level (indentation), parent table, var name, is from tovar
  1057. local CustomGeneration = {
  1058. Vector3 = (function()
  1059. local temp = {}
  1060. for i,v in Vector3 do
  1061. if type(v) == "vector" then
  1062. temp[v] = `Vector3.{i}`
  1063. end
  1064. end
  1065. return temp
  1066. end)(),
  1067. Vector2 = (function()
  1068. local temp = {}
  1069. for i,v in Vector2 do
  1070. if type(v) == "userdata" then
  1071. temp[v] = `Vector2.{i}`
  1072. end
  1073. end
  1074. return temp
  1075. end)(),
  1076. CFrame = {
  1077. [CFrame.identity] = "CFrame.identity"
  1078. }
  1079. }
  1080.  
  1081. local number_table = {
  1082. ["inf"] = "math.huge",
  1083. ["-inf"] = "-math.huge",
  1084. ["nan"] = "0/0"
  1085. }
  1086.  
  1087. local ufunctions
  1088. ufunctions = {
  1089. TweenInfo = function(u)
  1090. return `TweenInfo.new({u.Time}, {u.EasingStyle}, {u.EasingDirection}, {u.RepeatCount}, {u.Reverses}, {u.DelayTime})`
  1091. end,
  1092. Ray = function(u)
  1093. local Vector3tostring = ufunctions["Vector3"]
  1094.  
  1095. return `Ray.new({Vector3tostring(u.Origin)}, {Vector3tostring(u.Direction)})`
  1096. end,
  1097. BrickColor = function(u)
  1098. return `BrickColor.new({u.Number})`
  1099. end,
  1100. NumberRange = function(u)
  1101. return `NumberRange.new({u.Min}, {u.Max})`
  1102. end,
  1103. Region3 = function(u)
  1104. local center = u.CFrame.Position
  1105. local centersize = u.Size/2
  1106. local Vector3tostring = ufunctions["Vector3"]
  1107.  
  1108. return `Region3.new({Vector3tostring(center-centersize)}, {Vector3tostring(center+centersize)})`
  1109. end,
  1110. Faces = function(u)
  1111. local faces = {}
  1112. if u.Top then
  1113. table.insert(faces, "Top")
  1114. end
  1115. if u.Bottom then
  1116. table.insert(faces, "Enum.NormalId.Bottom")
  1117. end
  1118. if u.Left then
  1119. table.insert(faces, "Enum.NormalId.Left")
  1120. end
  1121. if u.Right then
  1122. table.insert(faces, "Enum.NormalId.Right")
  1123. end
  1124. if u.Back then
  1125. table.insert(faces, "Enum.NormalId.Back")
  1126. end
  1127. if u.Front then
  1128. table.insert(faces, "Enum.NormalId.Front")
  1129. end
  1130. return `Faces.new({table.concat(faces, ", ")})`
  1131. end,
  1132. EnumItem = function(u)
  1133. return tostring(u)
  1134. end,
  1135. Enums = function(u)
  1136. return "Enum"
  1137. end,
  1138. Enum = function(u)
  1139. return `Enum.{u}`
  1140. end,
  1141. Vector3 = function(u)
  1142. return CustomGeneration.Vector3[u] or `Vector3.new({u})`
  1143. end,
  1144. Vector2 = function(u)
  1145. return CustomGeneration.Vector2[u] or `Vector2.new({u})`
  1146. end,
  1147. CFrame = function(u)
  1148. return CustomGeneration.CFrame[u] or `CFrame.new({table.concat({u:GetComponents()},", ")})`
  1149. end,
  1150. PathWaypoint = function(u)
  1151. return `PathWaypoint.new({ufunctions["Vector3"](u.Position)}, {u.Action}, "{u.Label}")`
  1152. end,
  1153. UDim = function(u)
  1154. return `UDim.new({u})`
  1155. end,
  1156. UDim2 = function(u)
  1157. return `UDim2.new({u})`
  1158. end,
  1159. Rect = function(u)
  1160. local Vector2tostring = ufunctions["Vector2"]
  1161. return `Rect.new({Vector2tostring(u.Min)}, {Vector2tostring(u.Max)})`
  1162. end,
  1163. Color3 = function(u)
  1164. return `Color3.new({u.R}, {u.G}, {u.B})`
  1165. end,
  1166. RBXScriptSignal = function(u) -- The server doesnt recive this
  1167. return "RBXScriptSignal --[[RBXScriptSignal's are not supported]]"
  1168. end,
  1169. RBXScriptConnection = function(u) -- The server doesnt recive this
  1170. return "RBXScriptConnection --[[RBXScriptConnection's are not supported]]"
  1171. end,
  1172. }
  1173.  
  1174. local typeofv2sfunctions = {
  1175. number = function(v)
  1176. local number = tostring(v)
  1177. return number_table[number] or number
  1178. end,
  1179. boolean = function(v)
  1180. return tostring(v)
  1181. end,
  1182. string = function(v,l)
  1183. return formatstr(v, l)
  1184. end,
  1185. ["function"] = function(v) -- The server doesnt recive this
  1186. return f2s(v)
  1187. end,
  1188. table = function(v, l, p, n, vtv, i, pt, path, tables, tI)
  1189. return t2s(v, l, p, n, vtv, i, pt, path, tables, tI)
  1190. end,
  1191. Instance = function(v)
  1192. local DebugId = OldDebugId(v)
  1193. return i2p(v,generation[DebugId])
  1194. end,
  1195. userdata = function(v) -- The server doesnt recive this
  1196. if configs.advancedinfo then
  1197. if getrawmetatable(v) then
  1198. return "newproxy(true)"
  1199. end
  1200. return "newproxy(false)"
  1201. end
  1202. return "newproxy(true)"
  1203. end
  1204. }
  1205.  
  1206. local typev2sfunctions = {
  1207. userdata = function(v,vtypeof)
  1208. if ufunctions[vtypeof] then
  1209. return ufunctions[vtypeof](v)
  1210. end
  1211. return `{vtypeof}({rawtostring(v)}) --[[Generation Failure]]`
  1212. end,
  1213. vector = ufunctions["Vector3"]
  1214. }
  1215.  
  1216.  
  1217. function v2s(v, l, p, n, vtv, i, pt, path, tables, tI)
  1218. local vtypeof = typeof(v)
  1219. local vtypeoffunc = typeofv2sfunctions[vtypeof]
  1220. local vtypefunc = typev2sfunctions[type(v)]
  1221. local vtype = type(v)
  1222. if not tI then
  1223. tI = {0}
  1224. else
  1225. tI[1] += 1
  1226. end
  1227.  
  1228. if vtypeoffunc then
  1229. return vtypeoffunc(v, l, p, n, vtv, i, pt, path, tables, tI)
  1230. elseif vtypefunc then
  1231. return vtypefunc(v,vtypeof)
  1232. end
  1233. return `{vtypeof}({rawtostring(v)}) --[[Generation Failure]]`
  1234. end
  1235.  
  1236. --- value-to-variable
  1237. --- @param t any
  1238. function v2v(t)
  1239. topstr = ""
  1240. bottomstr = ""
  1241. getnilrequired = false
  1242. local ret = ""
  1243. local count = 1
  1244. for i, v in next, t do
  1245. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1246. ret = ret .. "local " .. i .. " = " .. v2s(v, nil, nil, i, true) .. "\n"
  1247. elseif rawtostring(i):match("^[%a_]+[%w_]*$") then
  1248. ret = ret .. "local " .. lower(rawtostring(i)) .. "_" .. rawtostring(count) .. " = " .. v2s(v, nil, nil, lower(rawtostring(i)) .. "_" .. rawtostring(count), true) .. "\n"
  1249. else
  1250. ret = ret .. "local " .. type(v) .. "_" .. rawtostring(count) .. " = " .. v2s(v, nil, nil, type(v) .. "_" .. rawtostring(count), true) .. "\n"
  1251. end
  1252. count = count + 1
  1253. end
  1254. if getnilrequired then
  1255. topstr = "function getNil(name,class) for _,v in next, getnilinstances() do if v.ClassName==class and v.Name==name then return v;end end end\n" .. topstr
  1256. end
  1257. if #topstr > 0 then
  1258. ret = topstr .. "\n" .. ret
  1259. end
  1260. if #bottomstr > 0 then
  1261. ret = ret .. bottomstr
  1262. end
  1263. return ret
  1264. end
  1265.  
  1266. function tabletostring(tbl: table,format: boolean)
  1267.  
  1268. end
  1269.  
  1270. --- table-to-string
  1271. --- @param t table
  1272. --- @param l number
  1273. --- @param p table
  1274. --- @param n string
  1275. --- @param vtv boolean
  1276. --- @param i any
  1277. --- @param pt table
  1278. --- @param path string
  1279. --- @param tables table
  1280. --- @param tI table
  1281. function t2s(t, l, p, n, vtv, i, pt, path, tables, tI)
  1282. local globalIndex = table.find(getgenv(), t) -- checks if table is a global
  1283. if type(globalIndex) == "string" then
  1284. return globalIndex
  1285. end
  1286. if not tI then
  1287. tI = {0}
  1288. end
  1289. if not path then -- sets path to empty string (so it doesn't have to manually provided every time)
  1290. path = ""
  1291. end
  1292. if not l then -- sets the level to 0 (for indentation) and tables for logging tables it already serialized
  1293. l = 0
  1294. tables = {}
  1295. end
  1296. if not p then -- p is the previous table but doesn't really matter if it's the first
  1297. p = t
  1298. end
  1299. for _, v in next, tables do -- checks if the current table has been serialized before
  1300. if n and rawequal(v, t) then
  1301. bottomstr = bottomstr .. "\n" .. rawtostring(n) .. rawtostring(path) .. " = " .. rawtostring(n) .. rawtostring(({v2p(v, p)})[2])
  1302. return "{} --[[DUPLICATE]]"
  1303. end
  1304. end
  1305. table.insert(tables, t) -- logs table to past tables
  1306. local s = "{" -- start of serialization
  1307. local size = 0
  1308. l += indent -- set indentation level
  1309. for k, v in next, t do -- iterates over table
  1310. size = size + 1 -- changes size for max limit
  1311. if size > (getgenv().SimpleSpyMaxTableSize or 1000) then
  1312. s = s .. "\n" .. string.rep(" ", l) .. "-- MAXIMUM TABLE SIZE REACHED, CHANGE 'getgenv().SimpleSpyMaxTableSize' TO ADJUST MAXIMUM SIZE "
  1313. break
  1314. end
  1315. if rawequal(k, t) then -- checks if the table being iterated over is being used as an index within itself (yay, lua)
  1316. bottomstr ..= `\n{n}{path}[{n}{path}] = {(rawequal(v,k) and `{n}{path}` or v2s(v, l, p, n, vtv, k, t, `{path}[{n}{path}]`, tables))}`
  1317. --bottomstr = bottomstr .. "\n" .. rawtostring(n) .. rawtostring(path) .. "[" .. rawtostring(n) .. rawtostring(path) .. "]" .. " = " .. (rawequal(v, k) and rawtostring(n) .. rawtostring(path) or v2s(v, l, p, n, vtv, k, t, path .. "[" .. rawtostring(n) .. rawtostring(path) .. "]", tables))
  1318. size -= 1
  1319. continue
  1320. end
  1321. local currentPath = "" -- initializes the path of 'v' within 't'
  1322. if type(k) == "string" and k:match("^[%a_]+[%w_]*$") then -- cleanly handles table path generation (for the first half)
  1323. currentPath = "." .. k
  1324. else
  1325. currentPath = "[" .. v2s(k, l, p, n, vtv, k, t, path .. currentPath, tables, tI) .. "]"
  1326. end
  1327. if size % 100 == 0 then
  1328. scheduleWait()
  1329. end
  1330. -- actually serializes the member of the table
  1331. s = s .. "\n" .. string.rep(" ", l) .. "[" .. v2s(k, l, p, n, vtv, k, t, path .. currentPath, tables, tI) .. "] = " .. v2s(v, l, p, n, vtv, k, t, path .. currentPath, tables, tI) .. ","
  1332. end
  1333. if #s > 1 then -- removes the last comma because it looks nicer (no way to tell if it's done 'till it's done so...)
  1334. s = s:sub(1, #s - 1)
  1335. end
  1336. if size > 0 then -- cleanly indents the last curly bracket
  1337. s = s .. "\n" .. string.rep(" ", l - indent)
  1338. end
  1339. return s .. "}"
  1340. end
  1341.  
  1342. --- function-to-string
  1343. function f2s(f)
  1344. for k, x in next, getgenv() do
  1345. local isgucci, gpath
  1346. if rawequal(x, f) then
  1347. isgucci, gpath = true, ""
  1348. elseif type(x) == "table" then
  1349. isgucci, gpath = v2p(f, x)
  1350. end
  1351. if isgucci and type(k) ~= "function" then
  1352. if type(k) == "string" and k:match("^[%a_]+[%w_]*$") then
  1353. return k .. gpath
  1354. else
  1355. return "getgenv()[" .. v2s(k) .. "]" .. gpath
  1356. end
  1357. end
  1358. end
  1359.  
  1360. if configs.funcEnabled then
  1361. local funcname = info(f,"n")
  1362.  
  1363. if funcname and funcname:match("^[%a_]+[%w_]*$") then
  1364. return `function {funcname}() end -- Function Called: {funcname}`
  1365. end
  1366. end
  1367. return tostring(f)
  1368. end
  1369.  
  1370. --- instance-to-path
  1371. --- @param i userdata
  1372. function i2p(i,customgen)
  1373. if customgen then
  1374. return customgen
  1375. end
  1376. local player = getplayer(i)
  1377. local parent = i
  1378. local out = ""
  1379. if parent == nil then
  1380. return "nil"
  1381. elseif player then
  1382. while true do
  1383. if parent and parent == player.Character then
  1384. if player == Players.LocalPlayer then
  1385. return 'game:GetService("Players").LocalPlayer.Character' .. out
  1386. else
  1387. return i2p(player) .. ".Character" .. out
  1388. end
  1389. else
  1390. if parent.Name:match("[%a_]+[%w+]*") ~= parent.Name then
  1391. out = ':FindFirstChild(' .. formatstr(parent.Name) .. ')' .. out
  1392. else
  1393. out = "." .. parent.Name .. out
  1394. end
  1395. end
  1396. task.wait()
  1397. parent = parent.Parent
  1398. end
  1399. elseif parent ~= game then
  1400. while true do
  1401. if parent and parent.Parent == game then
  1402. if SafeGetService(parent.ClassName) then
  1403. if lower(parent.ClassName) == "workspace" then
  1404. return `workspace{out}`
  1405. else
  1406. return 'game:GetService("' .. parent.ClassName .. '")' .. out
  1407. end
  1408. else
  1409. if parent.Name:match("[%a_]+[%w_]*") then
  1410. return "game." .. parent.Name .. out
  1411. else
  1412. return 'game:FindFirstChild(' .. formatstr(parent.Name) .. ')' .. out
  1413. end
  1414. end
  1415. elseif not parent.Parent then
  1416. getnilrequired = true
  1417. return 'getNil(' .. formatstr(parent.Name) .. ', "' .. parent.ClassName .. '")' .. out
  1418. else
  1419. if parent.Name:match("[%a_]+[%w_]*") ~= parent.Name then
  1420. out = ':WaitForChild(' .. formatstr(parent.Name) .. ')' .. out
  1421. else
  1422. out = ':WaitForChild("' .. parent.Name .. '")'..out
  1423. end
  1424. end
  1425. if i:IsDescendantOf(Players.LocalPlayer) then
  1426. return 'game:GetService("Players").LocalPlayer'..out
  1427. end
  1428. parent = parent.Parent
  1429. task.wait()
  1430. end
  1431. else
  1432. return "game"
  1433. end
  1434. end
  1435.  
  1436. --- Gets the player an instance is descended from
  1437. function getplayer(instance)
  1438. for _, v in next, Players:GetPlayers() do
  1439. if v.Character and (instance:IsDescendantOf(v.Character) or instance == v.Character) then
  1440. return v
  1441. end
  1442. end
  1443. end
  1444.  
  1445. --- value-to-path (in table)
  1446. function v2p(x, t, path, prev)
  1447. if not path then
  1448. path = ""
  1449. end
  1450. if not prev then
  1451. prev = {}
  1452. end
  1453. if rawequal(x, t) then
  1454. return true, ""
  1455. end
  1456. for i, v in next, t do
  1457. if rawequal(v, x) then
  1458. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1459. return true, (path .. "." .. i)
  1460. else
  1461. return true, (path .. "[" .. v2s(i) .. "]")
  1462. end
  1463. end
  1464. if type(v) == "table" then
  1465. local duplicate = false
  1466. for _, y in next, prev do
  1467. if rawequal(y, v) then
  1468. duplicate = true
  1469. end
  1470. end
  1471. if not duplicate then
  1472. table.insert(prev, t)
  1473. local found
  1474. found, p = v2p(x, v, path, prev)
  1475. if found then
  1476. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1477. return true, "." .. i .. p
  1478. else
  1479. return true, "[" .. v2s(i) .. "]" .. p
  1480. end
  1481. end
  1482. end
  1483. end
  1484. end
  1485. return false, ""
  1486. end
  1487.  
  1488. --- format s: string, byte encrypt (for weird symbols)
  1489. function formatstr(s, indentation)
  1490. if not indentation then
  1491. indentation = 0
  1492. end
  1493. local handled, reachedMax = handlespecials(s, indentation)
  1494. return '"' .. handled .. '"' .. (reachedMax and " --[[ MAXIMUM STRING SIZE REACHED, CHANGE 'getgenv().SimpleSpyMaxStringSize' TO ADJUST MAXIMUM SIZE ]]" or "")
  1495. end
  1496.  
  1497. --- Adds \'s to the text as a replacement to whitespace chars and other things because string.format can't yayeet
  1498.  
  1499. local function isFinished(coroutines: table)
  1500. for _, v in next, coroutines do
  1501. if status(v) == "running" then
  1502. return false
  1503. end
  1504. end
  1505. return true
  1506. end
  1507.  
  1508. local specialstrings = {
  1509. ["\n"] = function(thread,index)
  1510. resume(thread,index,"\\n")
  1511. end,
  1512. ["\t"] = function(thread,index)
  1513. resume(thread,index,"\\t")
  1514. end,
  1515. ["\\"] = function(thread,index)
  1516. resume(thread,index,"\\\\")
  1517. end,
  1518. ['"'] = function(thread,index)
  1519. resume(thread,index,"\\\"")
  1520. end
  1521. }
  1522.  
  1523. function handlespecials(s, indentation)
  1524. local i = 0
  1525. local n = 1
  1526. local coroutines = {}
  1527. local coroutineFunc = function(i, r)
  1528. s = s:sub(0, i - 1) .. r .. s:sub(i + 1, -1)
  1529. end
  1530. local timeout = 0
  1531. repeat
  1532. i += 1
  1533. if timeout >= 10 then
  1534. task.wait()
  1535. timeout = 0
  1536. end
  1537. local char = s:sub(i, i)
  1538.  
  1539. if byte(char) then
  1540. timeout += 1
  1541. local c = create(coroutineFunc)
  1542. table.insert(coroutines, c)
  1543. local specialfunc = specialstrings[char]
  1544.  
  1545. if specialfunc then
  1546. specialfunc(c,i)
  1547. i += 1
  1548. elseif byte(char) > 126 or byte(char) < 32 then
  1549. resume(c, i, "\\" .. byte(char))
  1550. -- s = s:sub(0, i - 1) .. "\\" .. byte(char) .. s:sub(i + 1, -1)
  1551. i += #rawtostring(byte(char))
  1552. end
  1553. if i >= n * 100 then
  1554. local extra = string.format('" ..\n%s"', string.rep(" ", indentation + indent))
  1555. s = s:sub(0, i) .. extra .. s:sub(i + 1, -1)
  1556. i += #extra
  1557. n += 1
  1558. end
  1559. end
  1560. until char == "" or i > (getgenv().SimpleSpyMaxStringSize or 10000)
  1561. while not isFinished(coroutines) do
  1562. RunService.Heartbeat:Wait()
  1563. end
  1564. clear(coroutines)
  1565. if i > (getgenv().SimpleSpyMaxStringSize or 10000) then
  1566. s = string.sub(s, 0, getgenv().SimpleSpyMaxStringSize or 10000)
  1567. return s, true
  1568. end
  1569. return s, false
  1570. end
  1571.  
  1572. --- finds script from 'src' from getinfo, returns nil if not found
  1573. --- @param src string
  1574. function getScriptFromSrc(src)
  1575. local realPath
  1576. local runningTest
  1577. --- @type number
  1578. local s, e
  1579. local match = false
  1580. if src:sub(1, 1) == "=" then
  1581. realPath = game
  1582. s = 2
  1583. else
  1584. runningTest = src:sub(2, e and e - 1 or -1)
  1585. for _, v in next, getnilinstances() do
  1586. if v.Name == runningTest then
  1587. realPath = v
  1588. break
  1589. end
  1590. end
  1591. s = #runningTest + 1
  1592. end
  1593. if realPath then
  1594. e = src:sub(s, -1):find("%.")
  1595. local i = 0
  1596. repeat
  1597. i += 1
  1598. if not e then
  1599. runningTest = src:sub(s, -1)
  1600. local test = realPath.FindFirstChild(realPath, runningTest)
  1601. if test then
  1602. realPath = test
  1603. end
  1604. match = true
  1605. else
  1606. runningTest = src:sub(s, e)
  1607. local test = realPath.FindFirstChild(realPath, runningTest)
  1608. local yeOld = e
  1609. if test then
  1610. realPath = test
  1611. s = e + 2
  1612. e = src:sub(e + 2, -1):find("%.")
  1613. e = e and e + yeOld or e
  1614. else
  1615. e = src:sub(e + 2, -1):find("%.")
  1616. e = e and e + yeOld or e
  1617. end
  1618. end
  1619. until match or i >= 50
  1620. end
  1621. return realPath
  1622. end
  1623.  
  1624. --- schedules the provided function (and calls it with any args after)
  1625.  
  1626. function schedule(f, ...)
  1627. table.insert(scheduled, {f, ...})
  1628. end
  1629.  
  1630. --- yields the current thread until the scheduler gives the ok
  1631. function scheduleWait()
  1632. local thread = running()
  1633. schedule(function()
  1634. resume(thread)
  1635. end)
  1636. yield()
  1637. end
  1638.  
  1639. --- the big (well tbh small now) boi task scheduler himself, handles p much anything as quicc as possible
  1640. local function taskscheduler()
  1641. if not toggle then
  1642. scheduled = {}
  1643. return
  1644. end
  1645. if #scheduled > SIMPLESPYCONFIG_MaxRemotes + 100 then
  1646. table.remove(scheduled, #scheduled)
  1647. end
  1648. if #scheduled > 0 then
  1649. local currentf = scheduled[1]
  1650. table.remove(scheduled, 1)
  1651. if type(currentf) == "table" and type(currentf[1]) == "function" then
  1652. pcall(unpack(currentf))
  1653. end
  1654. end
  1655. end
  1656.  
  1657. local function tablecheck(tabletocheck,instance,id)
  1658. return tabletocheck[id] or tabletocheck[instance.Name]
  1659. end
  1660.  
  1661. function remoteHandler(data)
  1662. if configs.autoblock then
  1663. local id = data.id
  1664.  
  1665. if excluding[id] then
  1666. return
  1667. end
  1668. if not history[id] then
  1669. history[id] = {badOccurances = 0, lastCall = tick()}
  1670. end
  1671. if tick() - history[id].lastCall < 1 then
  1672. history[id].badOccurances += 1
  1673. return
  1674. else
  1675. history[id].badOccurances = 0
  1676. end
  1677. if history[id].badOccurances > 3 then
  1678. excluding[id] = true
  1679. return
  1680. end
  1681. history[id].lastCall = tick()
  1682. end
  1683.  
  1684. if (data.remote:IsA("RemoteEvent") or data.remote:IsA("UnreliableRemoteEvent")) and lower(data.method) == "fireserver" then
  1685. newRemote("event", data)
  1686. elseif data.remote:IsA("RemoteFunction") and lower(data.method) == "invokeserver" then
  1687. newRemote("function", data)
  1688. end
  1689. end
  1690.  
  1691. local newindex = function(method,originalfunction,...)
  1692. if typeof(...) == 'Instance' then
  1693. local remote = cloneref(...)
  1694.  
  1695. if remote:IsA("RemoteEvent") or remote:IsA("UnreliableRemoteEvent") or remote:IsA("RemoteFunction") then
  1696. if not configs.logcheckcaller and checkcaller() then return originalfunction(...) end
  1697. local id = ThreadGetDebugId(remote)
  1698. local blockcheck = tablecheck(blocklist,remote,id)
  1699. local args = {select(2,...)}
  1700.  
  1701. if not tablecheck(blacklist,remote,id) and not IsCyclicTable(args) then
  1702. local data = {
  1703. method = method,
  1704. remote = remote,
  1705. args = deepclone(args),
  1706. infofunc = infofunc,
  1707. callingscript = callingscript,
  1708. metamethod = "__index",
  1709. blockcheck = blockcheck,
  1710. id = id,
  1711. returnvalue = {}
  1712. }
  1713. args = nil
  1714.  
  1715. if configs.funcEnabled then
  1716. data.infofunc = info(2,"f")
  1717. local calling = getcallingscript()
  1718. data.callingscript = calling and cloneref(calling) or nil
  1719. end
  1720.  
  1721. schedule(remoteHandler,data)
  1722.  
  1723. --[[if configs.logreturnvalues and remote:IsA("RemoteFunction") then
  1724. local thread = running()
  1725. local returnargs = {...}
  1726. local returndata
  1727.  
  1728. spawn(function()
  1729. setnamecallmethod(method)
  1730. returndata = originalnamecall(unpack(returnargs))
  1731. data.returnvalue.data = returndata
  1732. if ThreadIsNotDead(thread) then
  1733. resume(thread)
  1734. end
  1735. end)
  1736. yield()
  1737. if not blockcheck then
  1738. return returndata
  1739. end
  1740. end]]
  1741. end
  1742. if blockcheck then return end
  1743. end
  1744. end
  1745. return originalfunction(...)
  1746. end
  1747.  
  1748. local newnamecall = newcclosure(function(...)
  1749. local method = getnamecallmethod()
  1750.  
  1751. if method and (method == "FireServer" or method == "fireServer" or method == "InvokeServer" or method == "invokeServer") then
  1752. if typeof(...) == 'Instance' then
  1753. local remote = cloneref(...)
  1754.  
  1755. if IsA(remote,"RemoteEvent") or IsA(remote,"UnreliableRemoteEvent") or IsA(remote,"RemoteFunction") then
  1756. if not configs.logcheckcaller and checkcaller() then return originalnamecall(...) end
  1757. local id = ThreadGetDebugId(remote)
  1758. local blockcheck = tablecheck(blocklist,remote,id)
  1759. local args = {select(2,...)}
  1760.  
  1761. if not tablecheck(blacklist,remote,id) and not IsCyclicTable(args) then
  1762. local data = {
  1763. method = method,
  1764. remote = remote,
  1765. args = deepclone(args),
  1766. infofunc = infofunc,
  1767. callingscript = callingscript,
  1768. metamethod = "__namecall",
  1769. blockcheck = blockcheck,
  1770. id = id,
  1771. returnvalue = {}
  1772. }
  1773. args = nil
  1774.  
  1775. if configs.funcEnabled then
  1776. data.infofunc = info(2,"f")
  1777. local calling = getcallingscript()
  1778. data.callingscript = calling and cloneref(calling) or nil
  1779. end
  1780.  
  1781. schedule(remoteHandler,data)
  1782.  
  1783. --[[if configs.logreturnvalues and remote.IsA(remote,"RemoteFunction") then
  1784. local thread = running()
  1785. local returnargs = {...}
  1786. local returndata
  1787.  
  1788. spawn(function()
  1789. setnamecallmethod(method)
  1790. returndata = originalnamecall(unpack(returnargs))
  1791. data.returnvalue.data = returndata
  1792. if ThreadIsNotDead(thread) then
  1793. resume(thread)
  1794. end
  1795. end)
  1796. yield()
  1797. if not blockcheck then
  1798. return returndata
  1799. end
  1800. end]]
  1801. end
  1802. if blockcheck then return end
  1803. end
  1804. end
  1805. end
  1806. return originalnamecall(...)
  1807. end)
  1808.  
  1809. local newFireServer = newcclosure(function(...)
  1810. return newindex("FireServer",originalEvent,...)
  1811. end)
  1812.  
  1813. local newInvokeServer = newcclosure(function(...)
  1814. return newindex("InvokeServer",originalFunction,...)
  1815. end)
  1816.  
  1817. local function disablehooks()
  1818. if oth then
  1819. unhook(getrawmetatable(game).__namecall,originalnamecall)
  1820. unhook(Instance.new("RemoteEvent").FireServer, originalEvent)
  1821. unhook(Instance.new("RemoteFunction").InvokeServer, originalFunction)
  1822. unhook(Instance.new("UnreliableRemoteEvent").FireServer, originalUnreliableEvent)
  1823. restorefunction(originalnamecall)
  1824. restorefunction(originalEvent)
  1825. restorefunction(originalUnreliableEvent)
  1826. restorefunction(originalFunction)
  1827. else
  1828. if hookmetamethod then
  1829. hookmetamethod(game, "__namecall", originalnamecall)
  1830. end
  1831. if hookfunction then
  1832. hookfunction(Instance.new("RemoteEvent").FireServer, originalEvent)
  1833. hookfunction(Instance.new("RemoteFunction").InvokeServer, originalFunction)
  1834. hookfunction(Instance.new("UnreliableRemoteEvent").FireServer, originalUnreliableEvent)
  1835. end
  1836. end
  1837. end
  1838.  
  1839. --- Toggles on and off the remote spy
  1840. function toggleSpy()
  1841. if not toggle then
  1842. local oldnamecall = oth and hook(getrawmetatable(game).__namecall,clonefunction(newnamecall)) or hookmetamethod and hookmetamethod(game, "__namecall", clonefunction(newnamecall))
  1843.  
  1844. if oth then
  1845. originalEvent = hook(Instance.new("RemoteEvent").FireServer, clonefunction(newFireServer))
  1846. originalFunction = hook(Instance.new("RemoteFunction").InvokeServer, clonefunction(newInvokeServer))
  1847. originalUnreliableEvent = hook(Instance.new("UnreliableRemoteEvent").FireServer, clonefunction(newFireServer))
  1848. else
  1849. if hookfunction then
  1850. originalEvent = hookfunction(Instance.new("RemoteEvent").FireServer, clonefunction(newFireServer))
  1851. originalFunction = hookfunction(Instance.new("RemoteFunction").InvokeServer, clonefunction(newInvokeServer))
  1852. originalUnreliableEvent = hookfunction(Instance.new("UnreliableRemoteEvent").FireServer, clonefunction(newFireServer))
  1853. end
  1854. end
  1855. originalnamecall = originalnamecall or function(...)
  1856. return oldnamecall(...)
  1857. end
  1858. else
  1859. disablehooks()
  1860. end
  1861. end
  1862.  
  1863. --- Toggles between the two remotespy methods (hookfunction currently = disabled)
  1864. function toggleSpyMethod()
  1865. toggleSpy()
  1866. toggle = not toggle
  1867. end
  1868.  
  1869. --- Shuts down the remote spy
  1870. local function shutdown()
  1871. if schedulerconnect then
  1872. schedulerconnect:Disconnect()
  1873. end
  1874. for _, connection in next, connections do
  1875. connection:Disconnect()
  1876. end
  1877. for i,v in next, running_threads do
  1878. if ThreadIsNotDead(v) then
  1879. close(v)
  1880. end
  1881. end
  1882. clear(running_threads)
  1883. clear(connections)
  1884. clear(logs)
  1885. clear(remoteLogs)
  1886. disablehooks()
  1887. SimpleSpy3:Destroy()
  1888. Storage:Destroy()
  1889. UserInputService.MouseIconEnabled = true
  1890. getgenv().SimpleSpyExecuted = false
  1891. end
  1892.  
  1893. -- main
  1894. if not getgenv().SimpleSpyExecuted then
  1895. local succeeded,err = pcall(function()
  1896. if not RunService:IsClient() then
  1897. error("SimpleSpy cannot run on the server!")
  1898. end
  1899. getgenv().SimpleSpyShutdown = shutdown
  1900. onToggleButtonClick()
  1901. if not hookmetamethod then
  1902. ErrorPrompt("Simple Spy V3 will not function to it's fullest capablity due to your executor not supporting hookmetamethod.",true)
  1903. end
  1904. codebox = Highlight.new(CodeBox)
  1905. logthread(spawn(function()
  1906. local suc,err = pcall(game.HttpGet,game,"https://raw.githubusercontent.com/78n/SimpleSpy/main/UpdateLog.lua")
  1907. codebox:setRaw((suc and err) or "")
  1908. end))
  1909. getgenv().SimpleSpy = SimpleSpy
  1910. getgenv().getNil = function(name,class)
  1911. for _,v in next, getnilinstances() do
  1912. if v.ClassName == class and v.Name == name then
  1913. return v;
  1914. end
  1915. end
  1916. end
  1917. Background.MouseEnter:Connect(function(...)
  1918. mouseInGui = true
  1919. mouseEntered()
  1920. end)
  1921. Background.MouseLeave:Connect(function(...)
  1922. mouseInGui = false
  1923. mouseEntered()
  1924. end)
  1925. TextLabel:GetPropertyChangedSignal("Text"):Connect(scaleToolTip)
  1926. -- TopBar.InputBegan:Connect(onBarInput)
  1927. MinimizeButton.MouseButton1Click:Connect(toggleMinimize)
  1928. MaximizeButton.MouseButton1Click:Connect(toggleSideTray)
  1929. Simple.MouseButton1Click:Connect(onToggleButtonClick)
  1930. CloseButton.MouseEnter:Connect(onXButtonHover)
  1931. CloseButton.MouseLeave:Connect(onXButtonUnhover)
  1932. Simple.MouseEnter:Connect(onToggleButtonHover)
  1933. Simple.MouseLeave:Connect(onToggleButtonUnhover)
  1934. CloseButton.MouseButton1Click:Connect(shutdown)
  1935. table.insert(connections, UserInputService.InputBegan:Connect(backgroundUserInput))
  1936. connectResize()
  1937. SimpleSpy3.Enabled = true
  1938. logthread(spawn(function()
  1939. delay(1,onToggleButtonUnhover)
  1940. end))
  1941. schedulerconnect = RunService.Heartbeat:Connect(taskscheduler)
  1942. bringBackOnResize()
  1943. SimpleSpy3.Parent = (gethui and gethui()) or (syn and syn.protect_gui and syn.protect_gui(SimpleSpy3)) or CoreGui
  1944. logthread(spawn(function()
  1945. local lp = Players.LocalPlayer or Players:GetPropertyChangedSignal("LocalPlayer"):Wait() or Players.LocalPlayer
  1946. generation = {
  1947. [OldDebugId(lp)] = 'game:GetService("Players").LocalPlayer',
  1948. [OldDebugId(lp:GetMouse())] = 'game:GetService("Players").LocalPlayer:GetMouse',
  1949. [OldDebugId(game)] = "game",
  1950. [OldDebugId(workspace)] = "workspace"
  1951. }
  1952. end))
  1953. end)
  1954. if succeeded then
  1955. getgenv().SimpleSpyExecuted = true
  1956. else
  1957. shutdown()
  1958. ErrorPrompt("An error has occured:\n"..rawtostring(err))
  1959. return
  1960. end
  1961. else
  1962. SimpleSpy3:Destroy()
  1963. return
  1964. end
  1965.  
  1966. function SimpleSpy:newButton(name, description, onClick)
  1967. return newButton(name, description, onClick)
  1968. end
  1969.  
  1970. ----- ADD ONS ----- (easily add or remove additonal functionality to the RemoteSpy!)
  1971. --[[
  1972. Some helpful things:
  1973. - add your function in here, and create buttons for them through the 'newButton' function
  1974. - the first argument provided is the TextButton the player clicks to run the function
  1975. - generated scripts are generated when the namecall is initially fired and saved in remoteFrame objects
  1976. - blacklisted remotes will be ignored directly in namecall (less lag)
  1977. - the properties of a 'remoteFrame' object:
  1978. {
  1979. Name: (string) The name of the Remote
  1980. GenScript: (string) The generated script that appears in the codebox (generated when namecall fired)
  1981. Source: (Instance (LocalScript)) The script that fired/invoked the remote
  1982. Remote: (Instance (RemoteEvent) | Instance (RemoteFunction)) The remote that was fired/invoked
  1983. Log: (Instance (TextButton)) The button being used for the remote (same as 'selected.Log')
  1984. }
  1985. - globals list: (contact @exx#9394 for more information or if you have suggestions for more to be added)
  1986. - closed: (boolean) whether or not the GUI is currently minimized
  1987. - logs: (table[remoteFrame]) full of remoteFrame objects (properties listed above)
  1988. - selected: (remoteFrame) the currently selected remoteFrame (properties listed above)
  1989. - blacklist: (string[] | Instance[] (RemoteEvent) | Instance[] (RemoteFunction)) an array of blacklisted names and remotes
  1990. - codebox: (Instance (TextBox)) the textbox that holds all the code- cleared often
  1991. ]]
  1992. -- Copies the contents of the codebox
  1993. newButton(
  1994. "Copy Code",
  1995. function() return "Click to copy code" end,
  1996. function()
  1997. setclipboard(codebox:getString())
  1998. TextLabel.Text = "Copied successfully!"
  1999. end
  2000. )
  2001.  
  2002. --- Copies the source script (that fired the remote)
  2003. newButton(
  2004. "Copy Remote",
  2005. function() return "Click to copy the path of the remote" end,
  2006. function()
  2007. if selected and selected.Remote then
  2008. setclipboard(v2s(selected.Remote))
  2009. TextLabel.Text = "Copied!"
  2010. end
  2011. end
  2012. )
  2013.  
  2014. -- Executes the contents of the codebox through loadstring
  2015. newButton("Run Code",
  2016. function() return "Click to execute code" end,
  2017. function()
  2018. local Remote = selected and selected.Remote
  2019. if Remote then
  2020. TextLabel.Text = "Executing..."
  2021. xpcall(function()
  2022. local returnvalue
  2023. if Remote:IsA("RemoteEvent") or Remote:IsA("UnreliableRemoteEvent") then
  2024. returnvalue = Remote:FireServer(unpack(selected.args))
  2025. else
  2026. returnvalue = Remote:InvokeServer(unpack(selected.args))
  2027. end
  2028.  
  2029. TextLabel.Text = ("Executed successfully!\n%s"):format(v2s(returnvalue))
  2030. end,function(err)
  2031. TextLabel.Text = ("Execution error!\n%s"):format(err)
  2032. end)
  2033. return
  2034. end
  2035. TextLabel.Text = "Source not found"
  2036. end
  2037. )
  2038.  
  2039. --- Gets the calling script (not super reliable but w/e)
  2040. newButton(
  2041. "Get Script",
  2042. function() return "Click to copy calling script to clipboard\nWARNING: Not super reliable, nil == could not find" end,
  2043. function()
  2044. if selected then
  2045. if not selected.Source then
  2046. selected.Source = rawget(getfenv(selected.Function),"script")
  2047. end
  2048. setclipboard(v2s(selected.Source))
  2049. TextLabel.Text = "Done!"
  2050. end
  2051. end
  2052. )
  2053.  
  2054. --- Decompiles the script that fired the remote and puts it in the code box
  2055. newButton("Function Info",function() return "Click to view calling function information" end,
  2056. function()
  2057. local func = selected and selected.Function
  2058. if func then
  2059. local typeoffunc = typeof(func)
  2060.  
  2061. if typeoffunc ~= 'string' then
  2062. codebox:setRaw("--[[Generating Function Info please wait]]")
  2063. RunService.Heartbeat:Wait()
  2064. local lclosure = islclosure(func)
  2065. local SourceScript = rawget(getfenv(func),"script")
  2066. local CallingScript = selected.Source or nil
  2067. local info = {}
  2068.  
  2069. info = {
  2070. info = getinfo(func),
  2071. constants = lclosure and deepclone(getconstants(func)) or "N/A --Lua Closure expected got C Closure",
  2072. upvalues = deepclone(getupvalues(func)),
  2073. script = {
  2074. SourceScript = SourceScript or 'nil',
  2075. CallingScript = CallingScript or 'nil'
  2076. }
  2077. }
  2078.  
  2079. if configs.advancedinfo then
  2080. local Remote = selected.Remote
  2081.  
  2082. info["advancedinfo"] = {
  2083. Metamethod = selected.metamethod,
  2084. DebugId = {
  2085. SourceScriptDebugId = SourceScript and typeof(SourceScript) == "Instance" and OldDebugId(SourceScript) or "N/A",
  2086. CallingScriptDebugId = CallingScript and typeof(SourceScript) == "Instance" and OldDebugId(CallingScript) or "N/A",
  2087. RemoteDebugId = OldDebugId(Remote)
  2088. },
  2089. Protos = lclosure and getprotos(func) or "N/A --Lua Closure expected got C Closure"
  2090. }
  2091.  
  2092. if Remote:IsA("RemoteFunction") then
  2093. info["advancedinfo"]["OnClientInvoke"] = getcallbackmember and (getcallbackmember(Remote,"OnClientInvoke") or "N/A") or "N/A --Missing function getcallbackmember"
  2094. elseif getconnections then
  2095. info["advancedinfo"]["OnClientEvents"] = {}
  2096.  
  2097. for i,v in next, getconnections(Remote.OnClientEvent) do
  2098. info["advancedinfo"]["OnClientEvents"][i] = {
  2099. Function = v.Function or "N/A",
  2100. State = v.State or "N/A"
  2101. }
  2102. end
  2103. end
  2104. end
  2105. codebox:setRaw("--[[Converting table to string please wait]]")
  2106. selected.Function = v2v({functionInfo = info})
  2107. end
  2108. codebox:setRaw("-- Calling function info\n-- Generated by the SimpleSpy V3 serializer\n\n"..selected.Function)
  2109. TextLabel.Text = "Done! Function info generated by the SimpleSpy V3 Serializer."
  2110. else
  2111. TextLabel.Text = "Error! Selected function was not found."
  2112. end
  2113. end)
  2114.  
  2115. --- Clears the Remote logs
  2116. newButton(
  2117. "Clr Logs",
  2118. function() return "Click to clear logs" end,
  2119. function()
  2120. TextLabel.Text = "Clearing..."
  2121. clear(logs)
  2122. for i,v in next, LogList:GetChildren() do
  2123. if not v:IsA("UIListLayout") then
  2124. v:Destroy()
  2125. end
  2126. end
  2127. codebox:setRaw("")
  2128. selected = nil
  2129. TextLabel.Text = "Logs cleared!"
  2130. end
  2131. )
  2132.  
  2133. --- Excludes the selected.Log Remote from the RemoteSpy
  2134. newButton(
  2135. "Exclude (i)",
  2136. function() return "Click to exclude this Remote.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable." end,
  2137. function()
  2138. if selected then
  2139. blacklist[OldDebugId(selected.Remote)] = true
  2140. TextLabel.Text = "Excluded!"
  2141. end
  2142. end
  2143. )
  2144.  
  2145. --- Excludes all Remotes that share the same name as the selected.Log remote from the RemoteSpy
  2146. newButton(
  2147. "Exclude (n)",
  2148. function() return "Click to exclude all remotes with this name.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable." end,
  2149. function()
  2150. if selected then
  2151. blacklist[selected.Name] = true
  2152. TextLabel.Text = "Excluded!"
  2153. end
  2154. end
  2155. )
  2156.  
  2157. --- clears blacklist
  2158. newButton("Clr Blacklist",
  2159. function() return "Click to clear the blacklist.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable." end,
  2160. function()
  2161. blacklist = {}
  2162. TextLabel.Text = "Blacklist cleared!"
  2163. end)
  2164.  
  2165. --- Prevents the selected.Log Remote from firing the server (still logged)
  2166. newButton(
  2167. "Block (i)",
  2168. function() return "Click to stop this remote from firing.\nBlocking a remote won't remove it from SimpleSpy logs, but it will not continue to fire the server." end,
  2169. function()
  2170. if selected then
  2171. blocklist[OldDebugId(selected.Remote)] = true
  2172. TextLabel.Text = "Excluded!"
  2173. end
  2174. end
  2175. )
  2176.  
  2177. --- Prevents all remotes from firing that share the same name as the selected.Log remote from the RemoteSpy (still logged)
  2178. newButton("Block (n)",function()
  2179. return "Click to stop remotes with this name from firing.\nBlocking a remote won't remove it from SimpleSpy logs, but it will not continue to fire the server." end,
  2180. function()
  2181. if selected then
  2182. blocklist[selected.Name] = true
  2183. TextLabel.Text = "Excluded!"
  2184. end
  2185. end
  2186. )
  2187.  
  2188. --- clears blacklist
  2189. newButton(
  2190. "Clr Blocklist",
  2191. function() return "Click to stop blocking remotes.\nBlocking a remote won't remove it from SimpleSpy logs, but it will not continue to fire the server." end,
  2192. function()
  2193. blocklist = {}
  2194. TextLabel.Text = "Blocklist cleared!"
  2195. end
  2196. )
  2197.  
  2198. --- Attempts to decompile the source script
  2199. newButton("Decompile",
  2200. function()
  2201. return "Decompile source script"
  2202. end,function()
  2203. if decompile then
  2204. if selected and selected.Source then
  2205. local Source = selected.Source
  2206. if not DecompiledScripts[Source] then
  2207. codebox:setRaw("--[[Decompiling]]")
  2208.  
  2209. xpcall(function()
  2210. local decompiledsource = decompile(Source):gsub("-- Decompiled with the Synapse X Luau decompiler.","")
  2211. local Sourcev2s = v2s(Source)
  2212. if (decompiledsource):find("script") and Sourcev2s then
  2213. DecompiledScripts[Source] = ("local script = %s\n%s"):format(Sourcev2s,decompiledsource)
  2214. end
  2215. end,function(err)
  2216. return codebox:setRaw(("--[[\nAn error has occured\n%s\n]]"):format(err))
  2217. end)
  2218. end
  2219. codebox:setRaw(DecompiledScripts[Source] or "--No Source Found")
  2220. TextLabel.Text = "Done!"
  2221. else
  2222. TextLabel.Text = "Source not found!"
  2223. end
  2224. else
  2225. TextLabel.Text = "Missing function (decompile)"
  2226. end
  2227. end
  2228. )
  2229.  
  2230. --[[newButton(
  2231. "returnvalue",
  2232. function() return "Get a Remote's return data" end,
  2233. function()
  2234. if selected then
  2235. local Remote = selected.Remote
  2236. if Remote and Remote:IsA("RemoteFunction") then
  2237. if selected.returnvalue and selected.returnvalue.data then
  2238. return codebox:setRaw(v2s(selected.returnvalue.data))
  2239. end
  2240. return codebox:setRaw("No data was returned")
  2241. else
  2242. codebox:setRaw("RemoteFunction expected got "..(Remote and Remote.ClassName))
  2243. end
  2244. end
  2245. end
  2246. )]]
  2247.  
  2248. newButton(
  2249. "Disable Info",
  2250. function() return string.format("[%s] Toggle function info (because it can cause lag in some games)", configs.funcEnabled and "ENABLED" or "DISABLED") end,
  2251. function()
  2252. configs.funcEnabled = not configs.funcEnabled
  2253. TextLabel.Text = string.format("[%s] Toggle function info (because it can cause lag in some games)", configs.funcEnabled and "ENABLED" or "DISABLED")
  2254. end
  2255. )
  2256.  
  2257. newButton(
  2258. "Autoblock",
  2259. function() return string.format("[%s] [BETA] Intelligently detects and excludes spammy remote calls from logs", configs.autoblock and "ENABLED" or "DISABLED") end,
  2260. function()
  2261. configs.autoblock = not configs.autoblock
  2262. TextLabel.Text = string.format("[%s] [BETA] Intelligently detects and excludes spammy remote calls from logs", configs.autoblock and "ENABLED" or "DISABLED")
  2263. history = {}
  2264. excluding = {}
  2265. end
  2266. )
  2267.  
  2268. newButton("Logcheckcaller",function()
  2269. return ("[%s] Log remotes fired by the client"):format(configs.logcheckcaller and "ENABLED" or "DISABLED")
  2270. end,
  2271. function()
  2272. configs.logcheckcaller = not configs.logcheckcaller
  2273. TextLabel.Text = ("[%s] Log remotes fired by the client"):format(configs.logcheckcaller and "ENABLED" or "DISABLED")
  2274. end)
  2275.  
  2276. --[[newButton("Log returnvalues",function()
  2277. return ("[BETA] [%s] Log RemoteFunction's return values"):format(configs.logcheckcaller and "ENABLED" or "DISABLED")
  2278. end,
  2279. function()
  2280. configs.logreturnvalues = not configs.logreturnvalues
  2281. TextLabel.Text = ("[BETA] [%s] Log RemoteFunction's return values"):format(configs.logreturnvalues and "ENABLED" or "DISABLED")
  2282. end)]]
  2283.  
  2284. newButton("Advanced Info",function()
  2285. return ("[%s] Display more remoteinfo"):format(configs.advancedinfo and "ENABLED" or "DISABLED")
  2286. end,
  2287. function()
  2288. configs.advancedinfo = not configs.advancedinfo
  2289. TextLabel.Text = ("[%s] Display more remoteinfo"):format(configs.advancedinfo and "ENABLED" or "DISABLED")
  2290. end)
  2291.  
  2292. newButton("Join Discord",function()
  2293. return "Joins The Simple Spy Discord"
  2294. end,
  2295. function()
  2296. setclipboard("https://discord.com/invite/AWS6ez9")
  2297. TextLabel.Text = "Copied invite to your clipboard"
  2298. if request then
  2299. request({Url = 'http://127.0.0.1:6463/rpc?v=1',Method = 'POST',Headers = {['Content-Type'] = 'application/json', Origin = 'https://discord.com'},Body = http:JSONEncode({cmd = 'INVITE_BROWSER',nonce = http:GenerateGUID(false),args = {code = 'AWS6ez9'}})})
  2300. end
  2301. end)
  2302.  
  2303. if configs.supersecretdevtoggle then
  2304. newButton("Load SSV2.2",function()
  2305. return "Load's Simple Spy V2.2"
  2306. end,
  2307. function()
  2308. loadstring(game:HttpGet("https://raw.githubusercontent.com/exxtremestuffs/SimpleSpySource/master/SimpleSpy.lua"))()
  2309. end)
  2310. newButton("Load SSV3",function()
  2311. return "Load's Simple Spy V3"
  2312. end,
  2313. function()
  2314. loadstring(game:HttpGet("https://raw.githubusercontent.com/78n/SimpleSpy/main/SimpleSpySource.lua"))()
  2315. end)
  2316. local SuperSecretFolder = Create("Folder",{Parent = SimpleSpy3})
  2317. newButton("SUPER SECRET BUTTON",function()
  2318. return "You dont need a discription you already know what it does"
  2319. end,
  2320. function()
  2321. SuperSecretFolder:ClearAllChildren()
  2322. local random = listfiles("Music")
  2323. local NotSound = Create("Sound",{Parent = SuperSecretFolder,Looped = false,Volume = math.random(1,5),SoundId = getsynasset(random[math.random(1,#random)])})
  2324. NotSound:Play()
  2325. end)
  2326. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement