Advertisement
ZaggiieOnRoblox

Roblox Lumber Tycoon 2 Script

Sep 16th, 2023 (edited)
4,907
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 83.85 KB | None | 0 0
  1. local Library = loadstring(game:HttpGet("https://raw.githubusercontent.com/xHeptc/Kavo-UI-Library/main/source.lua"))()
  2. local Window = Library.CreateLib("LT2 gui", "Ocean")
  3. -----------------------------------------------------------------------------------------------
  4. --Main--
  5. local Main = Window:NewTab("Main")
  6. local MainSection = Main:NewSection("Teleport")
  7. -----------------------------------------------------------------------------------------------
  8. --WoodRus Teleport--
  9. MainSection:NewButton("Teleport to WoodRus", "Teleport to WoodRus", function()
  10. game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = CFrame.new(264.690308, 3.19999933, 57.94384, -0.234720662, 5.88442326e-08, -0.972062886, -5.47190311e-08, 1, 7.37482324e-08, 0.972062886, 7.0500576e-08, -0.234720662)
  11. end)
  12. -----------------------------------------------------------------------------------------------
  13. --Bridge(End) Teleport--
  14. MainSection:NewButton("Bridge(End)", "Teleport to Bridge End", function()
  15. game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = CFrame.new(111.643097, 11.0005236, -987.634766, 0.999399602, 1.84591331e-09, -0.0346479639, 8.60727767e-10, 1, 7.81034188e-08, 0.0346479639, -7.80863445e-08, 0.999399602)
  16. end)
  17. -----------------------------------------------------------------------------------------------
  18. --Bridge (Start)--
  19. MainSection:NewButton("Bridge(Start)", "Teleport to Bridge Start", function()
  20. game.Players.LocalPlayer.Character.HumanoidRootPart.CFrame = CFrame.new(114.276955, 3.20000458, -611.789795, 0.999616146, -2.6936366e-08, 0.0277046319, 2.65312057e-08, 1, 1.49918584e-08, -0.0277046319, -1.4251067e-08, 0.999616146)
  21. end)
  22. -----------------------------------------------------------------------------------------------
  23. --Player--
  24. --Fly gui--
  25. local Tab = Window:NewTab("Player")
  26. local Section = Tab:NewSection("Player")
  27.  
  28. Section:NewButton("Fly Gui", "Opens a fly Gui", function()
  29. loadstring(game:HttpGet("https://raw.githubusercontent.com/XNEOFF/FlyGuiV3/main/FlyGuiV3.txt"))()
  30. end)
  31. -----------------------------------------------------------------------------------------------
  32.  
  33.  
  34.  
  35. -----------------------------------------------------------------------------------------------
  36.  
  37.  
  38.  
  39. -----------------------------------------------------------------------------------------------
  40.  
  41.  
  42.  
  43. -----------------------------------------------------------------------------------------------
  44. --Usefull
  45. local Tab = Window:NewTab("Usefull")
  46. local Section = Tab:NewSection("Usefull")
  47.  
  48. Section:NewButton("Dex Explorer", "Opens Dex Explorer ", function()
  49. loadstring(game:HttpGet('https://ithinkimandrew.site/scripts/tools/dark-dex.lua'))()
  50. end)
  51. -----------------------------------------------------------------------------------------------
  52. --Infinte Yield--
  53. Section:NewButton("Ininite yield", "Opens Ininite yield", function()
  54. loadstring(game:HttpGet('https://raw.githubusercontent.com/EdgeIY/infiniteyield/master/source'))()
  55. end)
  56. -----------------------------------------------------------------------------------------------
  57. --Simple Spy
  58. Section:NewButton("Simple Spy", "Opens Simple Spy", function()
  59. -- sheruts down the previous instance of SimpleSpy
  60. if _G.SimpleSpyExecuted and type(_G.SimpleSpyShutdown) == "function" then
  61. print(pcall(_G.SimpleSpyShutdown))
  62. end
  63.  
  64. local Players = game:GetService("Players")
  65. local CoreGui = game:GetService("CoreGui")
  66. local Highlight =
  67. loadstring(
  68. game:HttpGet("https://github.com/exxtremestuffs/SimpleSpySource/raw/master/highlight.lua")
  69. )()
  70.  
  71. ---- GENERATED (kinda sorta mostly) BY GUI to LUA ----
  72.  
  73. -- Instances:
  74.  
  75. local SimpleSpy2 = Instance.new("ScreenGui")
  76. local Background = Instance.new("Frame")
  77. local LeftPanel = Instance.new("Frame")
  78. local LogList = Instance.new("ScrollingFrame")
  79. local UIListLayout = Instance.new("UIListLayout")
  80. local RemoteTemplate = Instance.new("Frame")
  81. local ColorBar = Instance.new("Frame")
  82. local Text = Instance.new("TextLabel")
  83. local Button = Instance.new("TextButton")
  84. local RightPanel = Instance.new("Frame")
  85. local CodeBox = Instance.new("Frame")
  86. local ScrollingFrame = Instance.new("ScrollingFrame")
  87. local UIGridLayout = Instance.new("UIGridLayout")
  88. local FunctionTemplate = Instance.new("Frame")
  89. local ColorBar_2 = Instance.new("Frame")
  90. local Text_2 = Instance.new("TextLabel")
  91. local Button_2 = Instance.new("TextButton")
  92. local TopBar = Instance.new("Frame")
  93. local Simple = Instance.new("TextButton")
  94. local CloseButton = Instance.new("TextButton")
  95. local ImageLabel = Instance.new("ImageLabel")
  96. local MaximizeButton = Instance.new("TextButton")
  97. local ImageLabel_2 = Instance.new("ImageLabel")
  98. local MinimizeButton = Instance.new("TextButton")
  99. local ImageLabel_3 = Instance.new("ImageLabel")
  100. local ToolTip = Instance.new("Frame")
  101. local TextLabel = Instance.new("TextLabel")
  102.  
  103. --Properties:
  104.  
  105. SimpleSpy2.Name = "SimpleSpy2"
  106. SimpleSpy2.ResetOnSpawn = false
  107.  
  108. Background.Name = "Background"
  109. Background.Parent = SimpleSpy2
  110. Background.BackgroundColor3 = Color3.new(1, 1, 1)
  111. Background.BackgroundTransparency = 1
  112. Background.Position = UDim2.new(0, 500, 0, 200)
  113. Background.Size = UDim2.new(0, 450, 0, 268)
  114.  
  115. LeftPanel.Name = "LeftPanel"
  116. LeftPanel.Parent = Background
  117. LeftPanel.BackgroundColor3 = Color3.fromRGB(53, 52, 55)
  118. LeftPanel.BorderSizePixel = 0
  119. LeftPanel.Position = UDim2.new(0, 0, 0, 19)
  120. LeftPanel.Size = UDim2.new(0, 131, 0, 249)
  121.  
  122. LogList.Name = "LogList"
  123. LogList.Parent = LeftPanel
  124. LogList.Active = true
  125. LogList.BackgroundColor3 = Color3.new(1, 1, 1)
  126. LogList.BackgroundTransparency = 1
  127. LogList.BorderSizePixel = 0
  128. LogList.Position = UDim2.new(0, 0, 0, 9)
  129. LogList.Size = UDim2.new(0, 131, 0, 232)
  130. LogList.CanvasSize = UDim2.new(0, 0, 0, 0)
  131. LogList.ScrollBarThickness = 4
  132.  
  133. UIListLayout.Parent = LogList
  134. UIListLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
  135. UIListLayout.SortOrder = Enum.SortOrder.LayoutOrder
  136.  
  137. RemoteTemplate.Name = "RemoteTemplate"
  138. RemoteTemplate.Parent = LogList
  139. RemoteTemplate.BackgroundColor3 = Color3.new(1, 1, 1)
  140. RemoteTemplate.BackgroundTransparency = 1
  141. RemoteTemplate.Size = UDim2.new(0, 117, 0, 27)
  142.  
  143. ColorBar.Name = "ColorBar"
  144. ColorBar.Parent = RemoteTemplate
  145. ColorBar.BackgroundColor3 = Color3.fromRGB(255, 242, 0)
  146. ColorBar.BorderSizePixel = 0
  147. ColorBar.Position = UDim2.new(0, 0, 0, 1)
  148. ColorBar.Size = UDim2.new(0, 7, 0, 18)
  149. ColorBar.ZIndex = 2
  150.  
  151. Text.Name = "Text"
  152. Text.Parent = RemoteTemplate
  153. Text.BackgroundColor3 = Color3.new(1, 1, 1)
  154. Text.BackgroundTransparency = 1
  155. Text.Position = UDim2.new(0, 12, 0, 1)
  156. Text.Size = UDim2.new(0, 105, 0, 18)
  157. Text.ZIndex = 2
  158. Text.Font = Enum.Font.SourceSans
  159. Text.Text = "TEXT"
  160. Text.TextColor3 = Color3.new(1, 1, 1)
  161. Text.TextSize = 14
  162. Text.TextXAlignment = Enum.TextXAlignment.Left
  163. Text.TextWrapped = true
  164.  
  165. Button.Name = "Button"
  166. Button.Parent = RemoteTemplate
  167. Button.BackgroundColor3 = Color3.new(0, 0, 0)
  168. Button.BackgroundTransparency = 0.75
  169. Button.BorderColor3 = Color3.new(1, 1, 1)
  170. Button.Position = UDim2.new(0, 0, 0, 1)
  171. Button.Size = UDim2.new(0, 117, 0, 18)
  172. Button.AutoButtonColor = false
  173. Button.Font = Enum.Font.SourceSans
  174. Button.Text = ""
  175. Button.TextColor3 = Color3.new(0, 0, 0)
  176. Button.TextSize = 14
  177.  
  178. RightPanel.Name = "RightPanel"
  179. RightPanel.Parent = Background
  180. RightPanel.BackgroundColor3 = Color3.fromRGB(37, 36, 38)
  181. RightPanel.BorderSizePixel = 0
  182. RightPanel.Position = UDim2.new(0, 131, 0, 19)
  183. RightPanel.Size = UDim2.new(0, 319, 0, 249)
  184.  
  185. CodeBox.Name = "CodeBox"
  186. CodeBox.Parent = RightPanel
  187. CodeBox.BackgroundColor3 = Color3.new(0.0823529, 0.0745098, 0.0784314)
  188. CodeBox.BorderSizePixel = 0
  189. CodeBox.Size = UDim2.new(0, 319, 0, 119)
  190.  
  191. ScrollingFrame.Parent = RightPanel
  192. ScrollingFrame.Active = true
  193. ScrollingFrame.BackgroundColor3 = Color3.new(1, 1, 1)
  194. ScrollingFrame.BackgroundTransparency = 1
  195. ScrollingFrame.Position = UDim2.new(0, 0, 0.5, 0)
  196. ScrollingFrame.Size = UDim2.new(1, 0, 0.5, -9)
  197. ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
  198. ScrollingFrame.ScrollBarThickness = 4
  199.  
  200. UIGridLayout.Parent = ScrollingFrame
  201. UIGridLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
  202. UIGridLayout.SortOrder = Enum.SortOrder.LayoutOrder
  203. UIGridLayout.CellPadding = UDim2.new(0, 0, 0, 0)
  204. UIGridLayout.CellSize = UDim2.new(0, 94, 0, 27)
  205.  
  206. FunctionTemplate.Name = "FunctionTemplate"
  207. FunctionTemplate.Parent = ScrollingFrame
  208. FunctionTemplate.BackgroundColor3 = Color3.new(1, 1, 1)
  209. FunctionTemplate.BackgroundTransparency = 1
  210. FunctionTemplate.Size = UDim2.new(0, 117, 0, 23)
  211.  
  212. ColorBar_2.Name = "ColorBar"
  213. ColorBar_2.Parent = FunctionTemplate
  214. ColorBar_2.BackgroundColor3 = Color3.new(1, 1, 1)
  215. ColorBar_2.BorderSizePixel = 0
  216. ColorBar_2.Position = UDim2.new(0, 7, 0, 10)
  217. ColorBar_2.Size = UDim2.new(0, 7, 0, 18)
  218. ColorBar_2.ZIndex = 3
  219.  
  220. Text_2.Name = "Text"
  221. Text_2.Parent = FunctionTemplate
  222. Text_2.BackgroundColor3 = Color3.new(1, 1, 1)
  223. Text_2.BackgroundTransparency = 1
  224. Text_2.Position = UDim2.new(0, 19, 0, 10)
  225. Text_2.Size = UDim2.new(0, 69, 0, 18)
  226. Text_2.ZIndex = 2
  227. Text_2.Font = Enum.Font.SourceSans
  228. Text_2.Text = "TEXT"
  229. Text_2.TextColor3 = Color3.new(1, 1, 1)
  230. Text_2.TextSize = 14
  231. Text_2.TextStrokeColor3 = Color3.new(0.145098, 0.141176, 0.14902)
  232. Text_2.TextXAlignment = Enum.TextXAlignment.Left
  233. Text_2.TextWrapped = true
  234.  
  235. Button_2.Name = "Button"
  236. Button_2.Parent = FunctionTemplate
  237. Button_2.BackgroundColor3 = Color3.new(0, 0, 0)
  238. Button_2.BackgroundTransparency = 0.69999998807907
  239. Button_2.BorderColor3 = Color3.new(1, 1, 1)
  240. Button_2.Position = UDim2.new(0, 7, 0, 10)
  241. Button_2.Size = UDim2.new(0, 80, 0, 18)
  242. Button_2.AutoButtonColor = false
  243. Button_2.Font = Enum.Font.SourceSans
  244. Button_2.Text = ""
  245. Button_2.TextColor3 = Color3.new(0, 0, 0)
  246. Button_2.TextSize = 14
  247.  
  248. TopBar.Name = "TopBar"
  249. TopBar.Parent = Background
  250. TopBar.BackgroundColor3 = Color3.fromRGB(37, 35, 38)
  251. TopBar.BorderSizePixel = 0
  252. TopBar.Size = UDim2.new(0, 450, 0, 19)
  253.  
  254. Simple.Name = "Simple"
  255. Simple.Parent = TopBar
  256. Simple.BackgroundColor3 = Color3.new(1, 1, 1)
  257. Simple.AutoButtonColor = false
  258. Simple.BackgroundTransparency = 1
  259. Simple.Position = UDim2.new(0, 5, 0, 0)
  260. Simple.Size = UDim2.new(0, 57, 0, 18)
  261. Simple.Font = Enum.Font.SourceSansBold
  262. Simple.Text = "SimpleSpy"
  263. Simple.TextColor3 = Color3.new(1, 1, 1)
  264. Simple.TextSize = 14
  265. Simple.TextXAlignment = Enum.TextXAlignment.Left
  266.  
  267. CloseButton.Name = "CloseButton"
  268. CloseButton.Parent = TopBar
  269. CloseButton.BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902)
  270. CloseButton.BorderSizePixel = 0
  271. CloseButton.Position = UDim2.new(1, -19, 0, 0)
  272. CloseButton.Size = UDim2.new(0, 19, 0, 19)
  273. CloseButton.Font = Enum.Font.SourceSans
  274. CloseButton.Text = ""
  275. CloseButton.TextColor3 = Color3.new(0, 0, 0)
  276. CloseButton.TextSize = 14
  277.  
  278. ImageLabel.Parent = CloseButton
  279. ImageLabel.BackgroundColor3 = Color3.new(1, 1, 1)
  280. ImageLabel.BackgroundTransparency = 1
  281. ImageLabel.Position = UDim2.new(0, 5, 0, 5)
  282. ImageLabel.Size = UDim2.new(0, 9, 0, 9)
  283. ImageLabel.Image = "http://www.roblox.com/asset/?id=5597086202"
  284.  
  285. MaximizeButton.Name = "MaximizeButton"
  286. MaximizeButton.Parent = TopBar
  287. MaximizeButton.BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902)
  288. MaximizeButton.BorderSizePixel = 0
  289. MaximizeButton.Position = UDim2.new(1, -38, 0, 0)
  290. MaximizeButton.Size = UDim2.new(0, 19, 0, 19)
  291. MaximizeButton.Font = Enum.Font.SourceSans
  292. MaximizeButton.Text = ""
  293. MaximizeButton.TextColor3 = Color3.new(0, 0, 0)
  294. MaximizeButton.TextSize = 14
  295.  
  296. ImageLabel_2.Parent = MaximizeButton
  297. ImageLabel_2.BackgroundColor3 = Color3.new(1, 1, 1)
  298. ImageLabel_2.BackgroundTransparency = 1
  299. ImageLabel_2.Position = UDim2.new(0, 5, 0, 5)
  300. ImageLabel_2.Size = UDim2.new(0, 9, 0, 9)
  301. ImageLabel_2.Image = "http://www.roblox.com/asset/?id=5597108117"
  302.  
  303. MinimizeButton.Name = "MinimizeButton"
  304. MinimizeButton.Parent = TopBar
  305. MinimizeButton.BackgroundColor3 = Color3.new(0.145098, 0.141176, 0.14902)
  306. MinimizeButton.BorderSizePixel = 0
  307. MinimizeButton.Position = UDim2.new(1, -57, 0, 0)
  308. MinimizeButton.Size = UDim2.new(0, 19, 0, 19)
  309. MinimizeButton.Font = Enum.Font.SourceSans
  310. MinimizeButton.Text = ""
  311. MinimizeButton.TextColor3 = Color3.new(0, 0, 0)
  312. MinimizeButton.TextSize = 14
  313.  
  314. ImageLabel_3.Parent = MinimizeButton
  315. ImageLabel_3.BackgroundColor3 = Color3.new(1, 1, 1)
  316. ImageLabel_3.BackgroundTransparency = 1
  317. ImageLabel_3.Position = UDim2.new(0, 5, 0, 5)
  318. ImageLabel_3.Size = UDim2.new(0, 9, 0, 9)
  319. ImageLabel_3.Image = "http://www.roblox.com/asset/?id=5597105827"
  320.  
  321. ToolTip.Name = "ToolTip"
  322. ToolTip.Parent = SimpleSpy2
  323. ToolTip.BackgroundColor3 = Color3.fromRGB(26, 26, 26)
  324. ToolTip.BackgroundTransparency = 0.1
  325. ToolTip.BorderColor3 = Color3.new(1, 1, 1)
  326. ToolTip.Size = UDim2.new(0, 200, 0, 50)
  327. ToolTip.ZIndex = 3
  328. ToolTip.Visible = false
  329.  
  330. TextLabel.Parent = ToolTip
  331. TextLabel.BackgroundColor3 = Color3.new(1, 1, 1)
  332. TextLabel.BackgroundTransparency = 1
  333. TextLabel.Position = UDim2.new(0, 2, 0, 2)
  334. TextLabel.Size = UDim2.new(0, 196, 0, 46)
  335. TextLabel.ZIndex = 3
  336. TextLabel.Font = Enum.Font.SourceSans
  337. TextLabel.Text = "This is some slightly longer text."
  338. TextLabel.TextColor3 = Color3.new(1, 1, 1)
  339. TextLabel.TextSize = 14
  340. TextLabel.TextWrapped = true
  341. TextLabel.TextXAlignment = Enum.TextXAlignment.Left
  342. TextLabel.TextYAlignment = Enum.TextYAlignment.Top
  343.  
  344. -------------------------------------------------------------------------------
  345. -- init
  346. local RunService = game:GetService("RunService")
  347. local UserInputService = game:GetService("UserInputService")
  348. local TweenService = game:GetService("TweenService")
  349. local ContentProvider = game:GetService("ContentProvider")
  350. local TextService = game:GetService("TextService")
  351. local Mouse
  352.  
  353. local selectedColor = Color3.new(0.321569, 0.333333, 1)
  354. local deselectedColor = Color3.new(0.8, 0.8, 0.8)
  355. --- So things are descending
  356. local layoutOrderNum = 999999999
  357. --- Whether or not the gui is closing
  358. local mainClosing = false
  359. --- Whether or not the gui is closed (defaults to false)
  360. local closed = false
  361. --- Whether or not the sidebar is closing
  362. local sideClosing = false
  363. --- Whether or not the sidebar is closed (defaults to true but opens automatically on remote selection)
  364. local sideClosed = false
  365. --- Whether or not the code box is maximized (defaults to false)
  366. local maximized = false
  367. --- The event logs to be read from
  368. local logs = {}
  369. --- The event currently selected.Log (defaults to nil)
  370. local selected = nil
  371. --- The blacklist (can be a string name or the Remote Instance)
  372. local blacklist = {}
  373. --- The block list (can be a string name or the Remote Instance)
  374. local blocklist = {}
  375. --- Whether or not to add getNil function
  376. local getNil = false
  377. --- Array of remotes (and original functions) connected to
  378. local connectedRemotes = {}
  379. --- True = hookfunction, false = namecall
  380. local toggle = false
  381. local gm
  382. local original
  383. --- used to prevent recursives
  384. local prevTables = {}
  385. --- holds logs (for deletion)
  386. local remoteLogs = {}
  387. --- used for hookfunction
  388. local remoteEvent = Instance.new("RemoteEvent")
  389. --- used for hookfunction
  390. local remoteFunction = Instance.new("RemoteFunction")
  391. local originalEvent = remoteEvent.FireServer
  392. local originalFunction = remoteFunction.InvokeServer
  393. --- the maximum amount of remotes allowed in logs
  394. _G.SIMPLESPYCONFIG_MaxRemotes = 500
  395. --- how many spaces to indent
  396. local indent = 4
  397. --- used for task scheduler
  398. local scheduled = {}
  399. --- RBXScriptConnect of the task scheduler
  400. local schedulerconnect
  401. local SimpleSpy = {}
  402. local topstr = ""
  403. local bottomstr = ""
  404. local remotesFadeIn
  405. local rightFadeIn
  406. local codebox
  407. local p
  408. local getnilrequired = false
  409.  
  410. -- autoblock variables
  411. local autoblock = false
  412. local history = {}
  413. local excluding = {}
  414.  
  415. -- function info variables
  416. local funcEnabled = true
  417.  
  418. -- remote hooking/connecting api variables
  419. local remoteSignals = {}
  420. local remoteHooks = {}
  421.  
  422. -- original mouse icon
  423. local oldIcon
  424.  
  425. -- if mouse inside gui
  426. local mouseInGui = false
  427.  
  428. -- handy array of RBXScriptConnections to disconnect on shutdown
  429. local connections = {}
  430.  
  431. -- whether or not SimpleSpy uses 'getcallingscript()' to get the script (default is false because detection)
  432. local useGetCallingScript = false
  433.  
  434. --- used to enable/disable SimpleSpy's keyToString for remotes
  435. local keyToString = false
  436.  
  437. -- determines whether return values are recorded
  438. local recordReturnValues = false
  439.  
  440. -- functions
  441.  
  442. --- Converts arguments to a string and generates code that calls the specified method with them, recommended to be used in conjunction with ValueToString (method must be a string, e.g. `game:GetService("ReplicatedStorage").Remote.remote:FireServer`)
  443. --- @param method string
  444. --- @param args any[]
  445. --- @return string
  446. function SimpleSpy:ArgsToString(method, args)
  447. assert(typeof(method) == "string", "string expected, got " .. typeof(method))
  448. assert(typeof(args) == "table", "table expected, got " .. typeof(args))
  449. return v2v({ args = args }) .. "\n\n" .. method .. "(unpack(args))"
  450. end
  451.  
  452. --- Converts a value to variables with the specified index as the variable name (if nil/invalid then the name will be assigned automatically)
  453. --- @param t any[]
  454. --- @return string
  455. function SimpleSpy:TableToVars(t)
  456. assert(typeof(t) == "table", "table expected, got " .. typeof(t))
  457. return v2v(t)
  458. end
  459.  
  460. --- Converts a value to a variable with the specified `variablename` (if nil/invalid then the name will be assigned automatically)
  461. --- @param value any
  462. --- @return string
  463. function SimpleSpy:ValueToVar(value, variablename)
  464. assert(variablename == nil or typeof(variablename) == "string", "string expected, got " .. typeof(variablename))
  465. if not variablename then
  466. variablename = 1
  467. end
  468. return v2v({ [variablename] = value })
  469. end
  470.  
  471. --- Converts any value to a string, cannot preserve function contents
  472. --- @param value any
  473. --- @return string
  474. function SimpleSpy:ValueToString(value)
  475. return v2s(value)
  476. end
  477.  
  478. --- Generates the simplespy function info
  479. --- @param func function
  480. --- @return string
  481. function SimpleSpy:GetFunctionInfo(func)
  482. assert(typeof(func) == "function", "Instance expected, got " .. typeof(func))
  483. warn("Function info currently unavailable due to crashing in Synapse X")
  484. return v2v({ functionInfo = {
  485. info = debug.getinfo(func),
  486. constants = debug.getconstants(func),
  487. } })
  488. end
  489.  
  490. --- Gets the ScriptSignal for a specified remote being fired
  491. --- @param remote Instance
  492. function SimpleSpy:GetRemoteFiredSignal(remote)
  493. assert(typeof(remote) == "Instance", "Instance expected, got " .. typeof(remote))
  494. if not remoteSignals[remote] then
  495. remoteSignals[remote] = newSignal()
  496. end
  497. return remoteSignals[remote]
  498. end
  499.  
  500. --- Allows for direct hooking of remotes **THIS CAN BE VERY DANGEROUS**
  501. --- @param remote Instance
  502. --- @param f function
  503. function SimpleSpy:HookRemote(remote, f)
  504. assert(typeof(remote) == "Instance", "Instance expected, got " .. typeof(remote))
  505. assert(typeof(f) == "function", "function expected, got " .. typeof(f))
  506. remoteHooks[remote] = f
  507. end
  508.  
  509. --- Blocks the specified remote instance/string
  510. --- @param remote any
  511. function SimpleSpy:BlockRemote(remote)
  512. assert(
  513. typeof(remote) == "Instance" or typeof(remote) == "string",
  514. "Instance | string expected, got " .. typeof(remote)
  515. )
  516. blocklist[remote] = true
  517. end
  518.  
  519. --- Excludes the specified remote from logs (instance/string)
  520. --- @param remote any
  521. function SimpleSpy:ExcludeRemote(remote)
  522. assert(
  523. typeof(remote) == "Instance" or typeof(remote) == "string",
  524. "Instance | string expected, got " .. typeof(remote)
  525. )
  526. blacklist[remote] = true
  527. end
  528.  
  529. --- Creates a new ScriptSignal that can be connected to and fired
  530. --- @return table
  531. function newSignal()
  532. local connected = {}
  533. return {
  534. Connect = function(self, f)
  535. assert(connected, "Signal is closed")
  536. connected[tostring(f)] = f
  537. return {
  538. Connected = true,
  539. Disconnect = function(self)
  540. if not connected then
  541. warn("Signal is already closed")
  542. end
  543. self.Connected = false
  544. connected[tostring(f)] = nil
  545. end,
  546. }
  547. end,
  548. Wait = function(self)
  549. local thread = coroutine.running()
  550. local connection
  551. connection = self:Connect(function()
  552. connection:Disconnect()
  553. if coroutine.status(thread) == "suspended" then
  554. coroutine.resume(thread)
  555. end
  556. end)
  557. coroutine.yield()
  558. end,
  559. Fire = function(self, ...)
  560. for _, f in pairs(connected) do
  561. coroutine.wrap(f)(...)
  562. end
  563. end,
  564. }
  565. end
  566.  
  567. --- Prevents remote spam from causing lag (clears logs after `_G.SIMPLESPYCONFIG_MaxRemotes` or 500 remotes)
  568. function clean()
  569. local max = _G.SIMPLESPYCONFIG_MaxRemotes
  570. if not typeof(max) == "number" and math.floor(max) ~= max then
  571. max = 500
  572. end
  573. if #remoteLogs > max then
  574. for i = 100, #remoteLogs do
  575. local v = remoteLogs[i]
  576. if typeof(v[1]) == "RBXScriptConnection" then
  577. v[1]:Disconnect()
  578. end
  579. if typeof(v[2]) == "Instance" then
  580. v[2]:Destroy()
  581. end
  582. end
  583. local newLogs = {}
  584. for i = 1, 100 do
  585. table.insert(newLogs, remoteLogs[i])
  586. end
  587. remoteLogs = newLogs
  588. end
  589. end
  590.  
  591. --- Scales the ToolTip to fit containing text
  592. function scaleToolTip()
  593. local size = TextService:GetTextSize(
  594. TextLabel.Text,
  595. TextLabel.TextSize,
  596. TextLabel.Font,
  597. Vector2.new(196, math.huge)
  598. )
  599. TextLabel.Size = UDim2.new(0, size.X, 0, size.Y)
  600. ToolTip.Size = UDim2.new(0, size.X + 4, 0, size.Y + 4)
  601. end
  602.  
  603. --- Executed when the toggle button (the SimpleSpy logo) is hovered over
  604. function onToggleButtonHover()
  605. if not toggle then
  606. TweenService:Create(Simple, TweenInfo.new(0.5), { TextColor3 = Color3.fromRGB(252, 51, 51) }):Play()
  607. else
  608. TweenService:Create(Simple, TweenInfo.new(0.5), { TextColor3 = Color3.fromRGB(68, 206, 91) }):Play()
  609. end
  610. end
  611.  
  612. --- Executed when the toggle button is unhovered over
  613. function onToggleButtonUnhover()
  614. TweenService:Create(Simple, TweenInfo.new(0.5), { TextColor3 = Color3.fromRGB(255, 255, 255) }):Play()
  615. end
  616.  
  617. --- Executed when the X button is hovered over
  618. function onXButtonHover()
  619. TweenService:Create(CloseButton, TweenInfo.new(0.2), { BackgroundColor3 = Color3.fromRGB(255, 60, 60) }):Play()
  620. end
  621.  
  622. --- Executed when the X button is unhovered over
  623. function onXButtonUnhover()
  624. TweenService:Create(CloseButton, TweenInfo.new(0.2), { BackgroundColor3 = Color3.fromRGB(37, 36, 38) }):Play()
  625. end
  626.  
  627. --- Toggles the remote spy method (when button clicked)
  628. function onToggleButtonClick()
  629. if toggle then
  630. TweenService:Create(Simple, TweenInfo.new(0.5), { TextColor3 = Color3.fromRGB(252, 51, 51) }):Play()
  631. else
  632. TweenService:Create(Simple, TweenInfo.new(0.5), { TextColor3 = Color3.fromRGB(68, 206, 91) }):Play()
  633. end
  634. toggleSpyMethod()
  635. end
  636.  
  637. --- Reconnects bringBackOnResize if the current viewport changes and also connects it initially
  638. function connectResize()
  639. local lastCam = workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(bringBackOnResize)
  640. workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
  641. lastCam:Disconnect()
  642. if workspace.CurrentCamera then
  643. lastCam = workspace.CurrentCamera:GetPropertyChangedSignal("ViewportSize"):Connect(bringBackOnResize)
  644. end
  645. end)
  646. end
  647.  
  648. --- Brings gui back if it gets lost offscreen (connected to the camera viewport changing)
  649. function bringBackOnResize()
  650. validateSize()
  651. if sideClosed then
  652. minimizeSize()
  653. else
  654. maximizeSize()
  655. end
  656. local currentX = Background.AbsolutePosition.X
  657. local currentY = Background.AbsolutePosition.Y
  658. local viewportSize = workspace.CurrentCamera.ViewportSize
  659. if (currentX < 0) or (currentX > (viewportSize.X - (sideClosed and 131 or Background.AbsoluteSize.X))) then
  660. if currentX < 0 then
  661. currentX = 0
  662. else
  663. currentX = viewportSize.X - (sideClosed and 131 or Background.AbsoluteSize.X)
  664. end
  665. end
  666. if (currentY < 0) or (currentY > (viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36)) then
  667. if currentY < 0 then
  668. currentY = 0
  669. else
  670. currentY = viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36
  671. end
  672. end
  673. TweenService.Create(
  674. TweenService,
  675. Background,
  676. TweenInfo.new(0.1),
  677. { Position = UDim2.new(0, currentX, 0, currentY) }
  678. ):Play()
  679. end
  680.  
  681. --- Drags gui (so long as mouse is held down)
  682. --- @param input InputObject
  683. function onBarInput(input)
  684. if input.UserInputType == Enum.UserInputType.MouseButton1 then
  685. local lastPos = UserInputService.GetMouseLocation(UserInputService)
  686. local mainPos = Background.AbsolutePosition
  687. local offset = mainPos - lastPos
  688. local currentPos = offset + lastPos
  689. RunService.BindToRenderStep(RunService, "drag", 1, function()
  690. local newPos = UserInputService.GetMouseLocation(UserInputService)
  691. if newPos ~= lastPos then
  692. local currentX = (offset + newPos).X
  693. local currentY = (offset + newPos).Y
  694. local viewportSize = workspace.CurrentCamera.ViewportSize
  695. if
  696. (currentX < 0 and currentX < currentPos.X)
  697. or (
  698. currentX > (viewportSize.X - (sideClosed and 131 or TopBar.AbsoluteSize.X))
  699. and currentX > currentPos.X
  700. )
  701. then
  702. if currentX < 0 then
  703. currentX = 0
  704. else
  705. currentX = viewportSize.X - (sideClosed and 131 or TopBar.AbsoluteSize.X)
  706. end
  707. end
  708. if
  709. (currentY < 0 and currentY < currentPos.Y)
  710. or (
  711. currentY > (viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36)
  712. and currentY > currentPos.Y
  713. )
  714. then
  715. if currentY < 0 then
  716. currentY = 0
  717. else
  718. currentY = viewportSize.Y - (closed and 19 or Background.AbsoluteSize.Y) - 36
  719. end
  720. end
  721. currentPos = Vector2.new(currentX, currentY)
  722. lastPos = newPos
  723. TweenService.Create(
  724. TweenService,
  725. Background,
  726. TweenInfo.new(0.1),
  727. { Position = UDim2.new(0, currentPos.X, 0, currentPos.Y) }
  728. ):Play()
  729. end
  730. -- if input.UserInputState ~= Enum.UserInputState.Begin then
  731. -- RunService.UnbindFromRenderStep(RunService, "drag")
  732. -- end
  733. end)
  734. table.insert(
  735. connections,
  736. UserInputService.InputEnded:Connect(function(inputE)
  737. if input == inputE then
  738. RunService:UnbindFromRenderStep("drag")
  739. end
  740. end)
  741. )
  742. end
  743. end
  744.  
  745. --- Fades out the table of elements (and makes them invisible), returns a function to make them visible again
  746. function fadeOut(elements)
  747. local data = {}
  748. for _, v in pairs(elements) do
  749. if typeof(v) == "Instance" and v:IsA("GuiObject") and v.Visible then
  750. coroutine.wrap(function()
  751. data[v] = {
  752. BackgroundTransparency = v.BackgroundTransparency,
  753. }
  754. TweenService:Create(v, TweenInfo.new(0.5), { BackgroundTransparency = 1 }):Play()
  755. if v:IsA("TextBox") or v:IsA("TextButton") or v:IsA("TextLabel") then
  756. data[v].TextTransparency = v.TextTransparency
  757. TweenService:Create(v, TweenInfo.new(0.5), { TextTransparency = 1 }):Play()
  758. elseif v:IsA("ImageButton") or v:IsA("ImageLabel") then
  759. data[v].ImageTransparency = v.ImageTransparency
  760. TweenService:Create(v, TweenInfo.new(0.5), { ImageTransparency = 1 }):Play()
  761. end
  762. wait(0.5)
  763. v.Visible = false
  764. for i, x in pairs(data[v]) do
  765. v[i] = x
  766. end
  767. data[v] = true
  768. end)()
  769. end
  770. end
  771. return function()
  772. for i, _ in pairs(data) do
  773. coroutine.wrap(function()
  774. local properties = {
  775. BackgroundTransparency = i.BackgroundTransparency,
  776. }
  777. i.BackgroundTransparency = 1
  778. TweenService
  779. :Create(i, TweenInfo.new(0.5), { BackgroundTransparency = properties.BackgroundTransparency })
  780. :Play()
  781. if i:IsA("TextBox") or i:IsA("TextButton") or i:IsA("TextLabel") then
  782. properties.TextTransparency = i.TextTransparency
  783. i.TextTransparency = 1
  784. TweenService
  785. :Create(i, TweenInfo.new(0.5), { TextTransparency = properties.TextTransparency })
  786. :Play()
  787. elseif i:IsA("ImageButton") or i:IsA("ImageLabel") then
  788. properties.ImageTransparency = i.ImageTransparency
  789. i.ImageTransparency = 1
  790. TweenService
  791. :Create(i, TweenInfo.new(0.5), { ImageTransparency = properties.ImageTransparency })
  792. :Play()
  793. end
  794. i.Visible = true
  795. end)()
  796. end
  797. end
  798. end
  799.  
  800. --- Expands and minimizes the gui (closed is the toggle boolean)
  801. function toggleMinimize(override)
  802. if mainClosing and not override or maximized then
  803. return
  804. end
  805. mainClosing = true
  806. closed = not closed
  807. if closed then
  808. if not sideClosed then
  809. toggleSideTray(true)
  810. end
  811. LeftPanel.Visible = true
  812. TweenService:Create(LeftPanel, TweenInfo.new(0.5), { Size = UDim2.new(0, 131, 0, 0) }):Play()
  813. wait(0.5)
  814. remotesFadeIn = fadeOut(LeftPanel:GetDescendants())
  815. wait(0.5)
  816. else
  817. TweenService:Create(LeftPanel, TweenInfo.new(0.5), { Size = UDim2.new(0, 131, 0, 249) }):Play()
  818. wait(0.5)
  819. if remotesFadeIn then
  820. remotesFadeIn()
  821. remotesFadeIn = nil
  822. end
  823. bringBackOnResize()
  824. end
  825. mainClosing = false
  826. end
  827.  
  828. --- Expands and minimizes the sidebar (sideClosed is the toggle boolean)
  829. function toggleSideTray(override)
  830. if sideClosing and not override or maximized then
  831. return
  832. end
  833. sideClosing = true
  834. sideClosed = not sideClosed
  835. if sideClosed then
  836. rightFadeIn = fadeOut(RightPanel:GetDescendants())
  837. wait(0.5)
  838. minimizeSize(0.5)
  839. wait(0.5)
  840. RightPanel.Visible = false
  841. else
  842. if closed then
  843. toggleMinimize(true)
  844. end
  845. RightPanel.Visible = true
  846. maximizeSize(0.5)
  847. wait(0.5)
  848. if rightFadeIn then
  849. rightFadeIn()
  850. end
  851. bringBackOnResize()
  852. end
  853. sideClosing = false
  854. end
  855.  
  856. --- Expands code box to fit screen for more convenient viewing
  857. function toggleMaximize()
  858. if not sideClosed and not maximized then
  859. maximized = true
  860. local disable = Instance.new("TextButton")
  861. local prevSize = UDim2.new(0, CodeBox.AbsoluteSize.X, 0, CodeBox.AbsoluteSize.Y)
  862. local prevPos = UDim2.new(0, CodeBox.AbsolutePosition.X, 0, CodeBox.AbsolutePosition.Y)
  863. disable.Size = UDim2.new(1, 0, 1, 0)
  864. disable.BackgroundColor3 = Color3.new()
  865. disable.BorderSizePixel = 0
  866. disable.Text = 0
  867. disable.ZIndex = 3
  868. disable.BackgroundTransparency = 1
  869. disable.AutoButtonColor = false
  870. CodeBox.ZIndex = 4
  871. CodeBox.Position = prevPos
  872. CodeBox.Size = prevSize
  873. TweenService
  874. :Create(
  875. CodeBox,
  876. TweenInfo.new(0.5),
  877. { Size = UDim2.new(0.5, 0, 0.5, 0), Position = UDim2.new(0.25, 0, 0.25, 0) }
  878. )
  879. :Play()
  880. TweenService:Create(disable, TweenInfo.new(0.5), { BackgroundTransparency = 0.5 }):Play()
  881. disable.MouseButton1Click:Connect(function()
  882. if
  883. UserInputService:GetMouseLocation().Y + 36 >= CodeBox.AbsolutePosition.Y
  884. and UserInputService:GetMouseLocation().Y + 36 <= CodeBox.AbsolutePosition.Y + CodeBox.AbsoluteSize.Y
  885. and UserInputService:GetMouseLocation().X >= CodeBox.AbsolutePosition.X
  886. and UserInputService:GetMouseLocation().X <= CodeBox.AbsolutePosition.X + CodeBox.AbsoluteSize.X
  887. then
  888. return
  889. end
  890. TweenService:Create(CodeBox, TweenInfo.new(0.5), { Size = prevSize, Position = prevPos }):Play()
  891. TweenService:Create(disable, TweenInfo.new(0.5), { BackgroundTransparency = 1 }):Play()
  892. maximized = false
  893. wait(0.5)
  894. disable:Destroy()
  895. CodeBox.Size = UDim2.new(1, 0, 0.5, 0)
  896. CodeBox.Position = UDim2.new(0, 0, 0, 0)
  897. CodeBox.ZIndex = 0
  898. end)
  899. end
  900. end
  901.  
  902. --- Checks if cursor is within resize range
  903. --- @param p Vector2
  904. function isInResizeRange(p)
  905. local relativeP = p - Background.AbsolutePosition
  906. local range = 5
  907. if
  908. relativeP.X >= TopBar.AbsoluteSize.X - range
  909. and relativeP.Y >= Background.AbsoluteSize.Y - range
  910. and relativeP.X <= TopBar.AbsoluteSize.X
  911. and relativeP.Y <= Background.AbsoluteSize.Y
  912. then
  913. return true, "B"
  914. elseif relativeP.X >= TopBar.AbsoluteSize.X - range and relativeP.X <= Background.AbsoluteSize.X then
  915. return true, "X"
  916. elseif relativeP.Y >= Background.AbsoluteSize.Y - range and relativeP.Y <= Background.AbsoluteSize.Y then
  917. return true, "Y"
  918. end
  919. return false
  920. end
  921.  
  922. --- Checks if cursor is within dragging range
  923. --- @param p Vector2
  924. function isInDragRange(p)
  925. local relativeP = p - Background.AbsolutePosition
  926. if
  927. relativeP.X <= TopBar.AbsoluteSize.X - CloseButton.AbsoluteSize.X * 3
  928. and relativeP.X >= 0
  929. and relativeP.Y <= TopBar.AbsoluteSize.Y
  930. and relativeP.Y >= 0
  931. then
  932. return true
  933. end
  934. return false
  935. end
  936.  
  937. --- Called when mouse enters SimpleSpy
  938. function mouseEntered()
  939. local existingCursor = SimpleSpy2:FindFirstChild("Cursor")
  940. while existingCursor do
  941. existingCursor:Destroy()
  942. existingCursor = SimpleSpy2:FindFirstChild("Cursor")
  943. end
  944. local customCursor = Instance.new("ImageLabel")
  945. customCursor.Name = "Cursor"
  946. customCursor.Size = UDim2.fromOffset(200, 200)
  947. customCursor.ZIndex = 1e5
  948. customCursor.BackgroundTransparency = 1
  949. customCursor.Image = ""
  950. customCursor.Parent = SimpleSpy2
  951. UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.ForceHide
  952. RunService:BindToRenderStep("SIMPLESPY_CURSOR", 1, function()
  953. if mouseInGui and _G.SimpleSpyExecuted then
  954. local mouseLocation = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  955. customCursor.Position = UDim2.fromOffset(
  956. mouseLocation.X - customCursor.AbsoluteSize.X / 2,
  957. mouseLocation.Y - customCursor.AbsoluteSize.Y / 2
  958. )
  959. local inRange, type = isInResizeRange(mouseLocation)
  960. if inRange and not sideClosed and not closed then
  961. customCursor.Image = type == "B" and "rbxassetid://6065821980"
  962. or type == "X" and "rbxassetid://6065821086"
  963. or type == "Y" and "rbxassetid://6065821596"
  964. elseif inRange and not closed and type == "Y" or type == "B" then
  965. customCursor.Image = "rbxassetid://6065821596"
  966. elseif customCursor.Image ~= "rbxassetid://6065775281" then
  967. customCursor.Image = "rbxassetid://6065775281"
  968. end
  969. else
  970. UserInputService.OverrideMouseIconBehavior = Enum.OverrideMouseIconBehavior.None
  971. customCursor:Destroy()
  972. RunService:UnbindFromRenderStep("SIMPLESPY_CURSOR")
  973. end
  974. end)
  975. end
  976.  
  977. --- Called when mouse moves
  978. function mouseMoved()
  979. local mousePos = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  980. if
  981. not closed
  982. and mousePos.X >= TopBar.AbsolutePosition.X
  983. and mousePos.X <= TopBar.AbsolutePosition.X + TopBar.AbsoluteSize.X
  984. and mousePos.Y >= Background.AbsolutePosition.Y
  985. and mousePos.Y <= Background.AbsolutePosition.Y + Background.AbsoluteSize.Y
  986. then
  987. if not mouseInGui then
  988. mouseInGui = true
  989. mouseEntered()
  990. end
  991. else
  992. mouseInGui = false
  993. end
  994. end
  995.  
  996. --- Adjusts the ui elements to the 'Maximized' size
  997. function maximizeSize(speed)
  998. if not speed then
  999. speed = 0.05
  1000. end
  1001. TweenService
  1002. :Create(
  1003. LeftPanel,
  1004. TweenInfo.new(speed),
  1005. { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }
  1006. )
  1007. :Play()
  1008. TweenService
  1009. :Create(RightPanel, TweenInfo.new(speed), {
  1010. Size = UDim2.fromOffset(
  1011. Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X,
  1012. Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y
  1013. ),
  1014. })
  1015. :Play()
  1016. TweenService
  1017. :Create(
  1018. TopBar,
  1019. TweenInfo.new(speed),
  1020. { Size = UDim2.fromOffset(Background.AbsoluteSize.X, TopBar.AbsoluteSize.Y) }
  1021. )
  1022. :Play()
  1023. TweenService
  1024. :Create(ScrollingFrame, TweenInfo.new(speed), {
  1025. Size = UDim2.fromOffset(Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X, 110),
  1026. Position = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y),
  1027. })
  1028. :Play()
  1029. TweenService
  1030. :Create(CodeBox, TweenInfo.new(speed), {
  1031. Size = UDim2.fromOffset(
  1032. Background.AbsoluteSize.X - LeftPanel.AbsoluteSize.X,
  1033. Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y
  1034. ),
  1035. })
  1036. :Play()
  1037. TweenService
  1038. :Create(
  1039. LogList,
  1040. TweenInfo.new(speed),
  1041. { Size = UDim2.fromOffset(LogList.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y - 18) }
  1042. )
  1043. :Play()
  1044. end
  1045.  
  1046. --- Adjusts the ui elements to close the side
  1047. function minimizeSize(speed)
  1048. if not speed then
  1049. speed = 0.05
  1050. end
  1051. TweenService
  1052. :Create(
  1053. LeftPanel,
  1054. TweenInfo.new(speed),
  1055. { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }
  1056. )
  1057. :Play()
  1058. TweenService
  1059. :Create(
  1060. RightPanel,
  1061. TweenInfo.new(speed),
  1062. { Size = UDim2.fromOffset(0, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y) }
  1063. )
  1064. :Play()
  1065. TweenService
  1066. :Create(
  1067. TopBar,
  1068. TweenInfo.new(speed),
  1069. { Size = UDim2.fromOffset(LeftPanel.AbsoluteSize.X, TopBar.AbsoluteSize.Y) }
  1070. )
  1071. :Play()
  1072. TweenService
  1073. :Create(ScrollingFrame, TweenInfo.new(speed), {
  1074. Size = UDim2.fromOffset(0, 119),
  1075. Position = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y),
  1076. })
  1077. :Play()
  1078. TweenService
  1079. :Create(
  1080. CodeBox,
  1081. TweenInfo.new(speed),
  1082. { Size = UDim2.fromOffset(0, Background.AbsoluteSize.Y - 119 - TopBar.AbsoluteSize.Y) }
  1083. )
  1084. :Play()
  1085. TweenService
  1086. :Create(
  1087. LogList,
  1088. TweenInfo.new(speed),
  1089. { Size = UDim2.fromOffset(LogList.AbsoluteSize.X, Background.AbsoluteSize.Y - TopBar.AbsoluteSize.Y - 18) }
  1090. )
  1091. :Play()
  1092. end
  1093.  
  1094. --- Ensures size is within screensize limitations
  1095. function validateSize()
  1096. local x, y = Background.AbsoluteSize.X, Background.AbsoluteSize.Y
  1097. local screenSize = workspace.CurrentCamera.ViewportSize
  1098. if x + Background.AbsolutePosition.X > screenSize.X then
  1099. if screenSize.X - Background.AbsolutePosition.X >= 450 then
  1100. x = screenSize.X - Background.AbsolutePosition.X
  1101. else
  1102. x = 450
  1103. end
  1104. elseif y + Background.AbsolutePosition.Y > screenSize.Y then
  1105. if screenSize.X - Background.AbsolutePosition.Y >= 268 then
  1106. y = screenSize.Y - Background.AbsolutePosition.Y
  1107. else
  1108. y = 268
  1109. end
  1110. end
  1111. Background.Size = UDim2.fromOffset(x, y)
  1112. end
  1113.  
  1114. --- Called on user input while mouse in 'Background' frame
  1115. --- @param input InputObject
  1116. function backgroundUserInput(input)
  1117. local mousePos = UserInputService:GetMouseLocation() - Vector2.new(0, 36)
  1118. local inResizeRange, type = isInResizeRange(mousePos)
  1119. if input.UserInputType == Enum.UserInputType.MouseButton1 and inResizeRange then
  1120. local lastPos = UserInputService:GetMouseLocation()
  1121. local offset = Background.AbsoluteSize - lastPos
  1122. local currentPos = lastPos + offset
  1123. RunService:BindToRenderStep("SIMPLESPY_RESIZE", 1, function()
  1124. local newPos = UserInputService:GetMouseLocation()
  1125. if newPos ~= lastPos then
  1126. local currentX = (newPos + offset).X
  1127. local currentY = (newPos + offset).Y
  1128. if currentX < 450 then
  1129. currentX = 450
  1130. end
  1131. if currentY < 268 then
  1132. currentY = 268
  1133. end
  1134. currentPos = Vector2.new(currentX, currentY)
  1135. Background.Size = UDim2.fromOffset(
  1136. (not sideClosed and not closed and (type == "X" or type == "B")) and currentPos.X
  1137. or Background.AbsoluteSize.X,
  1138. (--[[(not sideClosed or currentPos.X <= LeftPanel.AbsolutePosition.X + LeftPanel.AbsoluteSize.X) and]]not closed and (type == "Y" or type == "B"))
  1139. and currentPos.Y
  1140. or Background.AbsoluteSize.Y
  1141. )
  1142. validateSize()
  1143. if sideClosed then
  1144. minimizeSize()
  1145. else
  1146. maximizeSize()
  1147. end
  1148. lastPos = newPos
  1149. end
  1150. end)
  1151. table.insert(
  1152. connections,
  1153. UserInputService.InputEnded:Connect(function(inputE)
  1154. if input == inputE then
  1155. RunService:UnbindFromRenderStep("SIMPLESPY_RESIZE")
  1156. end
  1157. end)
  1158. )
  1159. elseif isInDragRange(mousePos) then
  1160. onBarInput(input)
  1161. end
  1162. end
  1163.  
  1164. --- Gets the player an instance is descended from
  1165. function getPlayerFromInstance(instance)
  1166. for _, v in pairs(Players:GetPlayers()) do
  1167. if v.Character and (instance:IsDescendantOf(v.Character) or instance == v.Character) then
  1168. return v
  1169. end
  1170. end
  1171. end
  1172.  
  1173. --- Runs on MouseButton1Click of an event frame
  1174. function eventSelect(frame)
  1175. if selected and selected.Log and selected.Log.Button then
  1176. TweenService
  1177. :Create(selected.Log.Button, TweenInfo.new(0.5), { BackgroundColor3 = Color3.fromRGB(0, 0, 0) })
  1178. :Play()
  1179. selected = nil
  1180. end
  1181. for _, v in pairs(logs) do
  1182. if frame == v.Log then
  1183. selected = v
  1184. end
  1185. end
  1186. if selected and selected.Log then
  1187. TweenService
  1188. :Create(frame.Button, TweenInfo.new(0.5), { BackgroundColor3 = Color3.fromRGB(92, 126, 229) })
  1189. :Play()
  1190. codebox:setRaw(selected.GenScript)
  1191. end
  1192. if sideClosed then
  1193. toggleSideTray()
  1194. end
  1195. end
  1196.  
  1197. --- Updates the canvas size to fit the current amount of function buttons
  1198. function updateFunctionCanvas()
  1199. ScrollingFrame.CanvasSize = UDim2.fromOffset(UIGridLayout.AbsoluteContentSize.X, UIGridLayout.AbsoluteContentSize.Y)
  1200. end
  1201.  
  1202. --- Updates the canvas size to fit the amount of current remotes
  1203. function updateRemoteCanvas()
  1204. LogList.CanvasSize = UDim2.fromOffset(UIListLayout.AbsoluteContentSize.X, UIListLayout.AbsoluteContentSize.Y)
  1205. end
  1206.  
  1207. --- Allows for toggling of the tooltip and easy setting of le description
  1208. --- @param enable boolean
  1209. --- @param text string
  1210. function makeToolTip(enable, text)
  1211. if enable then
  1212. if ToolTip.Visible then
  1213. ToolTip.Visible = false
  1214. RunService:UnbindFromRenderStep("ToolTip")
  1215. end
  1216. local first = true
  1217. RunService:BindToRenderStep("ToolTip", 1, function()
  1218. local topLeft = Vector2.new(Mouse.X + 20, Mouse.Y + 20)
  1219. local bottomRight = topLeft + ToolTip.AbsoluteSize
  1220. if topLeft.X < 0 then
  1221. topLeft = Vector2.new(0, topLeft.Y)
  1222. elseif bottomRight.X > workspace.CurrentCamera.ViewportSize.X then
  1223. topLeft = Vector2.new(workspace.CurrentCamera.ViewportSize.X - ToolTip.AbsoluteSize.X, topLeft.Y)
  1224. end
  1225. if topLeft.Y < 0 then
  1226. topLeft = Vector2.new(topLeft.X, 0)
  1227. elseif bottomRight.Y > workspace.CurrentCamera.ViewportSize.Y - 35 then
  1228. topLeft = Vector2.new(topLeft.X, workspace.CurrentCamera.ViewportSize.Y - ToolTip.AbsoluteSize.Y - 35)
  1229. end
  1230. if topLeft.X <= Mouse.X and topLeft.Y <= Mouse.Y then
  1231. topLeft = Vector2.new(Mouse.X - ToolTip.AbsoluteSize.X - 2, Mouse.Y - ToolTip.AbsoluteSize.Y - 2)
  1232. end
  1233. if first then
  1234. ToolTip.Position = UDim2.fromOffset(topLeft.X, topLeft.Y)
  1235. first = false
  1236. else
  1237. ToolTip:TweenPosition(UDim2.fromOffset(topLeft.X, topLeft.Y), "Out", "Linear", 0.1)
  1238. end
  1239. end)
  1240. TextLabel.Text = text
  1241. ToolTip.Visible = true
  1242. else
  1243. if ToolTip.Visible then
  1244. ToolTip.Visible = false
  1245. RunService:UnbindFromRenderStep("ToolTip")
  1246. end
  1247. end
  1248. end
  1249.  
  1250. --- Creates new function button (below codebox)
  1251. --- @param name string
  1252. ---@param description function
  1253. ---@param onClick function
  1254. function newButton(name, description, onClick)
  1255. local button = FunctionTemplate:Clone()
  1256. button.Text.Text = name
  1257. button.Button.MouseEnter:Connect(function()
  1258. makeToolTip(true, description())
  1259. end)
  1260. button.Button.MouseLeave:Connect(function()
  1261. makeToolTip(false)
  1262. end)
  1263. button.AncestryChanged:Connect(function()
  1264. makeToolTip(false)
  1265. end)
  1266. button.Button.MouseButton1Click:Connect(function(...)
  1267. onClick(button, ...)
  1268. end)
  1269. button.Parent = ScrollingFrame
  1270. updateFunctionCanvas()
  1271. end
  1272.  
  1273. --- Adds new Remote to logs
  1274. --- @param name string The name of the remote being logged
  1275. --- @param type string The type of the remote being logged (either 'function' or 'event')
  1276. --- @param args any
  1277. --- @param remote any
  1278. --- @param function_info string
  1279. --- @param blocked any
  1280. function newRemote(type, name, args, remote, function_info, blocked, src, returnValue)
  1281. local remoteFrame = RemoteTemplate:Clone()
  1282. remoteFrame.Text.Text = string.sub(name, 1, 50)
  1283. remoteFrame.ColorBar.BackgroundColor3 = type == "event" and Color3.new(255, 242, 0) or Color3.fromRGB(99, 86, 245)
  1284. local id = Instance.new("IntValue")
  1285. id.Name = "ID"
  1286. id.Value = #logs + 1
  1287. id.Parent = remoteFrame
  1288. local weakRemoteTable = setmetatable({ remote = remote }, { __mode = "v" })
  1289. local log = {
  1290. Name = name,
  1291. Function = function_info,
  1292. Remote = weakRemoteTable,
  1293. Log = remoteFrame,
  1294. Blocked = blocked,
  1295. Source = src,
  1296. GenScript = "-- Generating, please wait... (click to reload)\n-- (If this message persists, the remote args are likely extremely long)",
  1297. ReturnValue = returnValue,
  1298. }
  1299. logs[#logs + 1] = log
  1300. schedule(function()
  1301. log.GenScript = genScript(remote, args)
  1302. if blocked then
  1303. logs[#logs].GenScript = "-- THIS REMOTE WAS PREVENTED FROM FIRING THE SERVER BY SIMPLESPY\n\n"
  1304. .. logs[#logs].GenScript
  1305. end
  1306. end)
  1307. local connect = remoteFrame.Button.MouseButton1Click:Connect(function()
  1308. eventSelect(remoteFrame)
  1309. end)
  1310. if layoutOrderNum < 1 then
  1311. layoutOrderNum = 999999999
  1312. end
  1313. remoteFrame.LayoutOrder = layoutOrderNum
  1314. layoutOrderNum = layoutOrderNum - 1
  1315. remoteFrame.Parent = LogList
  1316. table.insert(remoteLogs, 1, { connect, remoteFrame })
  1317. clean()
  1318. updateRemoteCanvas()
  1319. end
  1320.  
  1321. --- Generates a script from the provided arguments (first has to be remote path)
  1322. function genScript(remote, args)
  1323. prevTables = {}
  1324. local gen = ""
  1325. if #args > 0 then
  1326. if not pcall(function()
  1327. gen = v2v({ args = args }) .. "\n"
  1328. end) then
  1329. gen = gen
  1330. .. "-- TableToString failure! Reverting to legacy functionality (results may vary)\nlocal args = {"
  1331. if
  1332. not pcall(function()
  1333. for i, v in pairs(args) do
  1334. if type(i) ~= "Instance" and type(i) ~= "userdata" then
  1335. gen = gen .. "\n [object] = "
  1336. elseif type(i) == "string" then
  1337. gen = gen .. '\n ["' .. i .. '"] = '
  1338. elseif type(i) == "userdata" and typeof(i) ~= "Instance" then
  1339. gen = gen .. "\n [" .. string.format("nil --[[%s]]", typeof(v)) .. ")] = "
  1340. elseif type(i) == "userdata" then
  1341. gen = gen .. "\n [game." .. i:GetFullName() .. ")] = "
  1342. end
  1343. if type(v) ~= "Instance" and type(v) ~= "userdata" then
  1344. gen = gen .. "object"
  1345. elseif type(v) == "string" then
  1346. gen = gen .. '"' .. v .. '"'
  1347. elseif type(v) == "userdata" and typeof(v) ~= "Instance" then
  1348. gen = gen .. string.format("nil --[[%s]]", typeof(v))
  1349. elseif type(v) == "userdata" then
  1350. gen = gen .. "game." .. v:GetFullName()
  1351. end
  1352. end
  1353. gen = gen .. "\n}\n\n"
  1354. end)
  1355. then
  1356. gen = gen .. "}\n-- Legacy tableToString failure! Unable to decompile."
  1357. end
  1358. end
  1359. if not remote:IsDescendantOf(game) and not getnilrequired then
  1360. gen = "function getNil(name,class) for _,v in pairs(getnilinstances())do if v.ClassName==class and v.Name==name then return v;end end end\n\n"
  1361. .. gen
  1362. end
  1363. if remote:IsA("RemoteEvent") then
  1364. gen = gen .. v2s(remote) .. ":FireServer(unpack(args))"
  1365. elseif remote:IsA("RemoteFunction") then
  1366. gen = gen .. v2s(remote) .. ":InvokeServer(unpack(args))"
  1367. end
  1368. else
  1369. if remote:IsA("RemoteEvent") then
  1370. gen = gen .. v2s(remote) .. ":FireServer()"
  1371. elseif remote:IsA("RemoteFunction") then
  1372. gen = gen .. v2s(remote) .. ":InvokeServer()"
  1373. end
  1374. end
  1375. gen = "-- Script generated by SimpleSpy - credits to exx#9394\n\n" .. gen
  1376. prevTables = {}
  1377. return gen
  1378. end
  1379.  
  1380. --- value-to-string: value, string (out), level (indentation), parent table, var name, is from tovar
  1381. function v2s(v, l, p, n, vtv, i, pt, path, tables, tI)
  1382. if not tI then
  1383. tI = { 0 }
  1384. else
  1385. tI[1] += 1
  1386. end
  1387. if typeof(v) == "number" then
  1388. if v == math.huge then
  1389. return "math.huge"
  1390. elseif tostring(v):match("nan") then
  1391. return "0/0 --[[NaN]]"
  1392. end
  1393. return tostring(v)
  1394. elseif typeof(v) == "boolean" then
  1395. return tostring(v)
  1396. elseif typeof(v) == "string" then
  1397. return formatstr(v, l)
  1398. elseif typeof(v) == "function" then
  1399. return f2s(v)
  1400. elseif typeof(v) == "table" then
  1401. return t2s(v, l, p, n, vtv, i, pt, path, tables, tI)
  1402. elseif typeof(v) == "Instance" then
  1403. return i2p(v)
  1404. elseif typeof(v) == "userdata" then
  1405. return "newproxy(true)"
  1406. elseif type(v) == "userdata" then
  1407. return u2s(v)
  1408. elseif type(v) == "vector" then
  1409. return string.format("Vector3.new(%s, %s, %s)", v2s(v.X), v2s(v.Y), v2s(v.Z))
  1410. else
  1411. return "nil --[[" .. typeof(v) .. "]]"
  1412. end
  1413. end
  1414.  
  1415. --- value-to-variable
  1416. --- @param t any
  1417. function v2v(t)
  1418. topstr = ""
  1419. bottomstr = ""
  1420. getnilrequired = false
  1421. local ret = ""
  1422. local count = 1
  1423. for i, v in pairs(t) do
  1424. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1425. ret = ret .. "local " .. i .. " = " .. v2s(v, nil, nil, i, true) .. "\n"
  1426. elseif tostring(i):match("^[%a_]+[%w_]*$") then
  1427. ret = ret
  1428. .. "local "
  1429. .. tostring(i):lower()
  1430. .. "_"
  1431. .. tostring(count)
  1432. .. " = "
  1433. .. v2s(v, nil, nil, tostring(i):lower() .. "_" .. tostring(count), true)
  1434. .. "\n"
  1435. else
  1436. ret = ret
  1437. .. "local "
  1438. .. type(v)
  1439. .. "_"
  1440. .. tostring(count)
  1441. .. " = "
  1442. .. v2s(v, nil, nil, type(v) .. "_" .. tostring(count), true)
  1443. .. "\n"
  1444. end
  1445. count = count + 1
  1446. end
  1447. if getnilrequired then
  1448. topstr = "function getNil(name,class) for _,v in pairs(getnilinstances())do if v.ClassName==class and v.Name==name then return v;end end end\n"
  1449. .. topstr
  1450. end
  1451. if #topstr > 0 then
  1452. ret = topstr .. "\n" .. ret
  1453. end
  1454. if #bottomstr > 0 then
  1455. ret = ret .. bottomstr
  1456. end
  1457. return ret
  1458. end
  1459.  
  1460. --- table-to-string
  1461. --- @param t table
  1462. --- @param l number
  1463. --- @param p table
  1464. --- @param n string
  1465. --- @param vtv boolean
  1466. --- @param i any
  1467. --- @param pt table
  1468. --- @param path string
  1469. --- @param tables table
  1470. --- @param tI table
  1471. function t2s(t, l, p, n, vtv, i, pt, path, tables, tI)
  1472. local globalIndex = table.find(getgenv(), t) -- checks if table is a global
  1473. if type(globalIndex) == "string" then
  1474. return globalIndex
  1475. end
  1476. if not tI then
  1477. tI = { 0 }
  1478. end
  1479. if not path then -- sets path to empty string (so it doesn't have to manually provided every time)
  1480. path = ""
  1481. end
  1482. if not l then -- sets the level to 0 (for indentation) and tables for logging tables it already serialized
  1483. l = 0
  1484. tables = {}
  1485. end
  1486. if not p then -- p is the previous table but doesn't really matter if it's the first
  1487. p = t
  1488. end
  1489. for _, v in pairs(tables) do -- checks if the current table has been serialized before
  1490. if n and rawequal(v, t) then
  1491. bottomstr = bottomstr
  1492. .. "\n"
  1493. .. tostring(n)
  1494. .. tostring(path)
  1495. .. " = "
  1496. .. tostring(n)
  1497. .. tostring(({ v2p(v, p) })[2])
  1498. return "{} --[[DUPLICATE]]"
  1499. end
  1500. end
  1501. table.insert(tables, t) -- logs table to past tables
  1502. local s = "{" -- start of serialization
  1503. local size = 0
  1504. l = l + indent -- set indentation level
  1505. for k, v in pairs(t) do -- iterates over table
  1506. size = size + 1 -- changes size for max limit
  1507. if size > (_G.SimpleSpyMaxTableSize or 1000) then
  1508. s = s
  1509. .. "\n"
  1510. .. string.rep(" ", l)
  1511. .. "-- MAXIMUM TABLE SIZE REACHED, CHANGE '_G.SimpleSpyMaxTableSize' TO ADJUST MAXIMUM SIZE "
  1512. break
  1513. end
  1514. if rawequal(k, t) then -- checks if the table being iterated over is being used as an index within itself (yay, lua)
  1515. bottomstr = bottomstr
  1516. .. "\n"
  1517. .. tostring(n)
  1518. .. tostring(path)
  1519. .. "["
  1520. .. tostring(n)
  1521. .. tostring(path)
  1522. .. "]"
  1523. .. " = "
  1524. .. (
  1525. rawequal(v, k) and tostring(n) .. tostring(path)
  1526. or v2s(v, l, p, n, vtv, k, t, path .. "[" .. tostring(n) .. tostring(path) .. "]", tables)
  1527. )
  1528. size -= 1
  1529. continue
  1530. end
  1531. local currentPath = "" -- initializes the path of 'v' within 't'
  1532. if type(k) == "string" and k:match("^[%a_]+[%w_]*$") then -- cleanly handles table path generation (for the first half)
  1533. currentPath = "." .. k
  1534. else
  1535. currentPath = "[" .. k2s(k, l, p, n, vtv, k, t, path .. currentPath, tables, tI) .. "]"
  1536. end
  1537. if size % 100 == 0 then
  1538. scheduleWait()
  1539. end
  1540. -- actually serializes the member of the table
  1541. s = s
  1542. .. "\n"
  1543. .. string.rep(" ", l)
  1544. .. "["
  1545. .. k2s(k, l, p, n, vtv, k, t, path .. currentPath, tables, tI)
  1546. .. "] = "
  1547. .. v2s(v, l, p, n, vtv, k, t, path .. currentPath, tables, tI)
  1548. .. ","
  1549. end
  1550. 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...)
  1551. s = s:sub(1, #s - 1)
  1552. end
  1553. if size > 0 then -- cleanly indents the last curly bracket
  1554. s = s .. "\n" .. string.rep(" ", l - indent)
  1555. end
  1556. return s .. "}"
  1557. end
  1558.  
  1559. --- key-to-string
  1560. function k2s(v, ...)
  1561. if keyToString then
  1562. if typeof(v) == "userdata" and getrawmetatable(v) then
  1563. return string.format(
  1564. '"<void> (%s)" --[[Potentially hidden data (tostring in SimpleSpy:HookRemote/GetRemoteFiredSignal at your own risk)]]',
  1565. safetostring(v)
  1566. )
  1567. elseif typeof(v) == "userdata" then
  1568. return string.format('"<void> (%s)"', safetostring(v))
  1569. elseif type(v) == "userdata" and typeof(v) ~= "Instance" then
  1570. return string.format('"<%s> (%s)"', typeof(v), tostring(v))
  1571. elseif type(v) == "function" then
  1572. return string.format('"<Function> (%s)"', tostring(v))
  1573. end
  1574. end
  1575. return v2s(v, ...)
  1576. end
  1577.  
  1578. --- function-to-string
  1579. function f2s(f)
  1580. for k, x in pairs(getgenv()) do
  1581. local isgucci, gpath
  1582. if rawequal(x, f) then
  1583. isgucci, gpath = true, ""
  1584. elseif type(x) == "table" then
  1585. isgucci, gpath = v2p(f, x)
  1586. end
  1587. if isgucci and type(k) ~= "function" then
  1588. if type(k) == "string" and k:match("^[%a_]+[%w_]*$") then
  1589. return k .. gpath
  1590. else
  1591. return "getgenv()[" .. v2s(k) .. "]" .. gpath
  1592. end
  1593. end
  1594. end
  1595. if funcEnabled and debug.getinfo(f).name:match("^[%a_]+[%w_]*$") then
  1596. return "function()end --[[" .. debug.getinfo(f).name .. "]]"
  1597. end
  1598. return "function()end --[[" .. tostring(f) .. "]]"
  1599. end
  1600.  
  1601. --- instance-to-path
  1602. --- @param i userdata
  1603. function i2p(i)
  1604. local player = getplayer(i)
  1605. local parent = i
  1606. local out = ""
  1607. if parent == nil then
  1608. return "nil"
  1609. elseif player then
  1610. while true do
  1611. if parent and parent == player.Character then
  1612. if player == Players.LocalPlayer then
  1613. return 'game:GetService("Players").LocalPlayer.Character' .. out
  1614. else
  1615. return i2p(player) .. ".Character" .. out
  1616. end
  1617. else
  1618. if parent.Name:match("[%a_]+[%w+]*") ~= parent.Name then
  1619. out = ":FindFirstChild(" .. formatstr(parent.Name) .. ")" .. out
  1620. else
  1621. out = "." .. parent.Name .. out
  1622. end
  1623. end
  1624. parent = parent.Parent
  1625. end
  1626. elseif parent ~= game then
  1627. while true do
  1628. if parent and parent.Parent == game then
  1629. local service = game:FindService(parent.ClassName)
  1630. if service then
  1631. if parent.ClassName == "Workspace" then
  1632. return "workspace" .. out
  1633. else
  1634. return 'game:GetService("' .. service.ClassName .. '")' .. out
  1635. end
  1636. else
  1637. if parent.Name:match("[%a_]+[%w_]*") then
  1638. return "game." .. parent.Name .. out
  1639. else
  1640. return "game:FindFirstChild(" .. formatstr(parent.Name) .. ")" .. out
  1641. end
  1642. end
  1643. elseif parent.Parent == nil then
  1644. getnilrequired = true
  1645. return "getNil(" .. formatstr(parent.Name) .. ', "' .. parent.ClassName .. '")' .. out
  1646. elseif parent == Players.LocalPlayer then
  1647. out = ".LocalPlayer" .. out
  1648. else
  1649. if parent.Name:match("[%a_]+[%w_]*") ~= parent.Name then
  1650. out = ":FindFirstChild(" .. formatstr(parent.Name) .. ")" .. out
  1651. else
  1652. out = "." .. parent.Name .. out
  1653. end
  1654. end
  1655. parent = parent.Parent
  1656. end
  1657. else
  1658. return "game"
  1659. end
  1660. end
  1661.  
  1662. --- userdata-to-string: userdata
  1663. --- @param u userdata
  1664. function u2s(u)
  1665. if typeof(u) == "TweenInfo" then
  1666. -- TweenInfo
  1667. return "TweenInfo.new("
  1668. .. tostring(u.Time)
  1669. .. ", Enum.EasingStyle."
  1670. .. tostring(u.EasingStyle)
  1671. .. ", Enum.EasingDirection."
  1672. .. tostring(u.EasingDirection)
  1673. .. ", "
  1674. .. tostring(u.RepeatCount)
  1675. .. ", "
  1676. .. tostring(u.Reverses)
  1677. .. ", "
  1678. .. tostring(u.DelayTime)
  1679. .. ")"
  1680. elseif typeof(u) == "Ray" then
  1681. -- Ray
  1682. return "Ray.new(" .. u2s(u.Origin) .. ", " .. u2s(u.Direction) .. ")"
  1683. elseif typeof(u) == "NumberSequence" then
  1684. -- NumberSequence
  1685. local ret = "NumberSequence.new("
  1686. for i, v in pairs(u.KeyPoints) do
  1687. ret = ret .. tostring(v)
  1688. if i < #u.Keypoints then
  1689. ret = ret .. ", "
  1690. end
  1691. end
  1692. return ret .. ")"
  1693. elseif typeof(u) == "DockWidgetPluginGuiInfo" then
  1694. -- DockWidgetPluginGuiInfo
  1695. return "DockWidgetPluginGuiInfo.new(Enum.InitialDockState" .. tostring(u) .. ")"
  1696. elseif typeof(u) == "ColorSequence" then
  1697. -- ColorSequence
  1698. local ret = "ColorSequence.new("
  1699. for i, v in pairs(u.KeyPoints) do
  1700. ret = ret .. "Color3.new(" .. tostring(v) .. ")"
  1701. if i < #u.Keypoints then
  1702. ret = ret .. ", "
  1703. end
  1704. end
  1705. return ret .. ")"
  1706. elseif typeof(u) == "BrickColor" then
  1707. -- BrickColor
  1708. return "BrickColor.new(" .. tostring(u.Number) .. ")"
  1709. elseif typeof(u) == "NumberRange" then
  1710. -- NumberRange
  1711. return "NumberRange.new(" .. tostring(u.Min) .. ", " .. tostring(u.Max) .. ")"
  1712. elseif typeof(u) == "Region3" then
  1713. -- Region3
  1714. local center = u.CFrame.Position
  1715. local size = u.CFrame.Size
  1716. local vector1 = center - size / 2
  1717. local vector2 = center + size / 2
  1718. return "Region3.new(" .. u2s(vector1) .. ", " .. u2s(vector2) .. ")"
  1719. elseif typeof(u) == "Faces" then
  1720. -- Faces
  1721. local faces = {}
  1722. if u.Top then
  1723. table.insert(faces, "Enum.NormalId.Top")
  1724. end
  1725. if u.Bottom then
  1726. table.insert(faces, "Enum.NormalId.Bottom")
  1727. end
  1728. if u.Left then
  1729. table.insert(faces, "Enum.NormalId.Left")
  1730. end
  1731. if u.Right then
  1732. table.insert(faces, "Enum.NormalId.Right")
  1733. end
  1734. if u.Back then
  1735. table.insert(faces, "Enum.NormalId.Back")
  1736. end
  1737. if u.Front then
  1738. table.insert(faces, "Enum.NormalId.Front")
  1739. end
  1740. return "Faces.new(" .. table.concat(faces, ", ") .. ")"
  1741. elseif typeof(u) == "EnumItem" then
  1742. return tostring(u)
  1743. elseif typeof(u) == "Enums" then
  1744. return "Enum"
  1745. elseif typeof(u) == "Enum" then
  1746. return "Enum." .. tostring(u)
  1747. elseif typeof(u) == "RBXScriptSignal" then
  1748. return "nil --[[RBXScriptSignal]]"
  1749. elseif typeof(u) == "Vector3" then
  1750. return string.format("Vector3.new(%s, %s, %s)", v2s(u.X), v2s(u.Y), v2s(u.Z))
  1751. elseif typeof(u) == "CFrame" then
  1752. local xAngle, yAngle, zAngle = u:ToEulerAnglesXYZ()
  1753. return string.format(
  1754. "CFrame.new(%s, %s, %s) * CFrame.Angles(%s, %s, %s)",
  1755. v2s(u.X),
  1756. v2s(u.Y),
  1757. v2s(u.Z),
  1758. v2s(xAngle),
  1759. v2s(yAngle),
  1760. v2s(zAngle)
  1761. )
  1762. elseif typeof(u) == "DockWidgetPluginGuiInfo" then
  1763. return string.format(
  1764. "DockWidgetPluginGuiInfo(%s, %s, %s, %s, %s, %s, %s)",
  1765. "Enum.InitialDockState.Right",
  1766. v2s(u.InitialEnabled),
  1767. v2s(u.InitialEnabledShouldOverrideRestore),
  1768. v2s(u.FloatingXSize),
  1769. v2s(u.FloatingYSize),
  1770. v2s(u.MinWidth),
  1771. v2s(u.MinHeight)
  1772. )
  1773. elseif typeof(u) == "PathWaypoint" then
  1774. return string.format("PathWaypoint.new(%s, %s)", v2s(u.Position), v2s(u.Action))
  1775. elseif typeof(u) == "UDim" then
  1776. return string.format("UDim.new(%s, %s)", v2s(u.Scale), v2s(u.Offset))
  1777. elseif typeof(u) == "UDim2" then
  1778. return string.format(
  1779. "UDim2.new(%s, %s, %s, %s)",
  1780. v2s(u.X.Scale),
  1781. v2s(u.X.Offset),
  1782. v2s(u.Y.Scale),
  1783. v2s(u.Y.Offset)
  1784. )
  1785. elseif typeof(u) == "Rect" then
  1786. return string.format("Rect.new(%s, %s)", v2s(u.Min), v2s(u.Max))
  1787. else
  1788. return string.format("nil --[[%s]]", typeof(u))
  1789. end
  1790. end
  1791.  
  1792. --- Gets the player an instance is descended from
  1793. function getplayer(instance)
  1794. for _, v in pairs(Players:GetPlayers()) do
  1795. if v.Character and (instance:IsDescendantOf(v.Character) or instance == v.Character) then
  1796. return v
  1797. end
  1798. end
  1799. end
  1800.  
  1801. --- value-to-path (in table)
  1802. function v2p(x, t, path, prev)
  1803. if not path then
  1804. path = ""
  1805. end
  1806. if not prev then
  1807. prev = {}
  1808. end
  1809. if rawequal(x, t) then
  1810. return true, ""
  1811. end
  1812. for i, v in pairs(t) do
  1813. if rawequal(v, x) then
  1814. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1815. return true, (path .. "." .. i)
  1816. else
  1817. return true, (path .. "[" .. v2s(i) .. "]")
  1818. end
  1819. end
  1820. if type(v) == "table" then
  1821. local duplicate = false
  1822. for _, y in pairs(prev) do
  1823. if rawequal(y, v) then
  1824. duplicate = true
  1825. end
  1826. end
  1827. if not duplicate then
  1828. table.insert(prev, t)
  1829. local found
  1830. found, p = v2p(x, v, path, prev)
  1831. if found then
  1832. if type(i) == "string" and i:match("^[%a_]+[%w_]*$") then
  1833. return true, "." .. i .. p
  1834. else
  1835. return true, "[" .. v2s(i) .. "]" .. p
  1836. end
  1837. end
  1838. end
  1839. end
  1840. end
  1841. return false, ""
  1842. end
  1843.  
  1844. --- format s: string, byte encrypt (for weird symbols)
  1845. function formatstr(s, indentation)
  1846. if not indentation then
  1847. indentation = 0
  1848. end
  1849. local handled, reachedMax = handlespecials(s, indentation)
  1850. return '"'
  1851. .. handled
  1852. .. '"'
  1853. .. (
  1854. reachedMax
  1855. and " --[[ MAXIMUM STRING SIZE REACHED, CHANGE '_G.SimpleSpyMaxStringSize' TO ADJUST MAXIMUM SIZE ]]"
  1856. or ""
  1857. )
  1858. end
  1859.  
  1860. --- Adds \'s to the text as a replacement to whitespace chars and other things because string.format can't yayeet
  1861. function handlespecials(value, indentation)
  1862. local buildStr = {}
  1863. local i = 1
  1864. local char = string.sub(value, i, i)
  1865. local indentStr
  1866. while char ~= "" do
  1867. if char == '"' then
  1868. buildStr[i] = '\\"'
  1869. elseif char == "\\" then
  1870. buildStr[i] = "\\\\"
  1871. elseif char == "\n" then
  1872. buildStr[i] = "\\n"
  1873. elseif char == "\t" then
  1874. buildStr[i] = "\\t"
  1875. elseif string.byte(char) > 126 or string.byte(char) < 32 then
  1876. buildStr[i] = string.format("\\%d", string.byte(char))
  1877. else
  1878. buildStr[i] = char
  1879. end
  1880. i = i + 1
  1881. char = string.sub(value, i, i)
  1882. if i % 200 == 0 then
  1883. indentStr = indentStr or string.rep(" ", indentation + indent)
  1884. table.move({ '"\n', indentStr, '... "' }, 1, 3, i, buildStr)
  1885. i += 3
  1886. end
  1887. end
  1888. return table.concat(buildStr)
  1889. end
  1890.  
  1891. -- safe (ish) tostring
  1892. function safetostring(v: any)
  1893. if typeof(v) == "userdata" or type(v) == "table" then
  1894. local mt = getrawmetatable(v)
  1895. local badtostring = mt and rawget(mt, "__tostring")
  1896. if mt and badtostring then
  1897. rawset(mt, "__tostring", nil)
  1898. local out = tostring(v)
  1899. rawset(mt, "__tostring", badtostring)
  1900. return out
  1901. end
  1902. end
  1903. return tostring(v)
  1904. end
  1905.  
  1906. --- finds script from 'src' from getinfo, returns nil if not found
  1907. --- @param src string
  1908. function getScriptFromSrc(src)
  1909. local realPath
  1910. local runningTest
  1911. --- @type number
  1912. local s, e
  1913. local match = false
  1914. if src:sub(1, 1) == "=" then
  1915. realPath = game
  1916. s = 2
  1917. else
  1918. runningTest = src:sub(2, e and e - 1 or -1)
  1919. for _, v in pairs(getnilinstances()) do
  1920. if v.Name == runningTest then
  1921. realPath = v
  1922. break
  1923. end
  1924. end
  1925. s = #runningTest + 1
  1926. end
  1927. if realPath then
  1928. e = src:sub(s, -1):find("%.")
  1929. local i = 0
  1930. repeat
  1931. i += 1
  1932. if not e then
  1933. runningTest = src:sub(s, -1)
  1934. local test = realPath.FindFirstChild(realPath, runningTest)
  1935. if test then
  1936. realPath = test
  1937. end
  1938. match = true
  1939. else
  1940. runningTest = src:sub(s, e)
  1941. local test = realPath.FindFirstChild(realPath, runningTest)
  1942. local yeOld = e
  1943. if test then
  1944. realPath = test
  1945. s = e + 2
  1946. e = src:sub(e + 2, -1):find("%.")
  1947. e = e and e + yeOld or e
  1948. else
  1949. e = src:sub(e + 2, -1):find("%.")
  1950. e = e and e + yeOld or e
  1951. end
  1952. end
  1953. until match or i >= 50
  1954. end
  1955. return realPath
  1956. end
  1957.  
  1958. --- schedules the provided function (and calls it with any args after)
  1959. function schedule(f, ...)
  1960. table.insert(scheduled, { f, ... })
  1961. end
  1962.  
  1963. --- yields the current thread until the scheduler gives the ok
  1964. function scheduleWait()
  1965. local thread = coroutine.running()
  1966. schedule(function()
  1967. coroutine.resume(thread)
  1968. end)
  1969. coroutine.yield()
  1970. end
  1971.  
  1972. --- the big (well tbh small now) boi task scheduler himself, handles p much anything as quicc as possible
  1973. function taskscheduler()
  1974. if not toggle then
  1975. scheduled = {}
  1976. return
  1977. end
  1978. if #scheduled > 1000 then
  1979. table.remove(scheduled, #scheduled)
  1980. end
  1981. if #scheduled > 0 then
  1982. local currentf = scheduled[1]
  1983. table.remove(scheduled, 1)
  1984. if type(currentf) == "table" and type(currentf[1]) == "function" then
  1985. pcall(unpack(currentf))
  1986. end
  1987. end
  1988. end
  1989.  
  1990. --- Handles remote logs
  1991. function remoteHandler(hookfunction, methodName, remote, args, funcInfo, calling, returnValue)
  1992. local validInstance, validClass = pcall(function()
  1993. return remote:IsA("RemoteEvent") or remote:IsA("RemoteFunction")
  1994. end)
  1995. if validInstance and validClass then
  1996. local func = funcInfo.func
  1997. if not calling then
  1998. _, calling = pcall(getScriptFromSrc, funcInfo.source)
  1999. end
  2000. coroutine.wrap(function()
  2001. if remoteSignals[remote] then
  2002. remoteSignals[remote]:Fire(args)
  2003. end
  2004. end)()
  2005. if autoblock then
  2006. if excluding[remote] then
  2007. return
  2008. end
  2009. if not history[remote] then
  2010. history[remote] = { badOccurances = 0, lastCall = tick() }
  2011. end
  2012. if tick() - history[remote].lastCall < 1 then
  2013. history[remote].badOccurances += 1
  2014. return
  2015. else
  2016. history[remote].badOccurances = 0
  2017. end
  2018. if history[remote].badOccurances > 3 then
  2019. excluding[remote] = true
  2020. return
  2021. end
  2022. history[remote].lastCall = tick()
  2023. end
  2024. local functionInfoStr
  2025. local src
  2026. if func and islclosure(func) then
  2027. local functionInfo = {}
  2028. functionInfo.info = funcInfo
  2029. pcall(function()
  2030. functionInfo.constants = debug.getconstants(func)
  2031. end)
  2032. pcall(function()
  2033. functionInfoStr = v2v({ functionInfo = functionInfo })
  2034. end)
  2035. pcall(function()
  2036. if type(calling) == "userdata" then
  2037. src = calling
  2038. end
  2039. end)
  2040. end
  2041. if methodName:lower() == "fireserver" then
  2042. newRemote(
  2043. "event",
  2044. remote.Name,
  2045. args,
  2046. remote,
  2047. functionInfoStr,
  2048. (blocklist[remote] or blocklist[remote.Name]),
  2049. src
  2050. )
  2051. elseif methodName:lower() == "invokeserver" then
  2052. newRemote(
  2053. "function",
  2054. remote.Name,
  2055. args,
  2056. remote,
  2057. functionInfoStr,
  2058. (blocklist[remote] or blocklist[remote.Name]),
  2059. src,
  2060. returnValue
  2061. )
  2062. end
  2063. end
  2064. end
  2065.  
  2066. --- Used for hookfunction
  2067. function hookRemote(remoteType, remote, ...)
  2068. if typeof(remote) == "Instance" then
  2069. local args = { ... }
  2070. local validInstance, remoteName = pcall(function()
  2071. return remote.Name
  2072. end)
  2073. if validInstance and not (blacklist[remote] or blacklist[remoteName]) then
  2074. local funcInfo = {}
  2075. local calling
  2076. if funcEnabled then
  2077. funcInfo = debug.getinfo(4) or funcInfo
  2078. calling = useGetCallingScript and getcallingscript() or nil
  2079. end
  2080. if recordReturnValues and remoteType == "RemoteFunction" then
  2081. local thread = coroutine.running()
  2082. local args = { ... }
  2083. task.defer(function()
  2084. local returnValue
  2085. if remoteHooks[remote] then
  2086. args = { remoteHooks[remote](unpack(args)) }
  2087. returnValue = originalFunction(remote, unpack(args))
  2088. else
  2089. returnValue = originalFunction(remote, unpack(args))
  2090. end
  2091. schedule(
  2092. remoteHandler,
  2093. true,
  2094. remoteType == "RemoteEvent" and "fireserver" or "invokeserver",
  2095. remote,
  2096. args,
  2097. funcInfo,
  2098. calling,
  2099. returnValue
  2100. )
  2101. if blocklist[remote] or blocklist[remoteName] then
  2102. coroutine.resume(thread)
  2103. else
  2104. coroutine.resume(thread, unpack(returnValue))
  2105. end
  2106. end)
  2107. else
  2108. schedule(
  2109. remoteHandler,
  2110. true,
  2111. remoteType == "RemoteEvent" and "fireserver" or "invokeserver",
  2112. remote,
  2113. args,
  2114. funcInfo,
  2115. calling
  2116. )
  2117. if blocklist[remote] or blocklist[remoteName] then
  2118. return
  2119. end
  2120. end
  2121. end
  2122. end
  2123. if recordReturnValues and remoteType == "RemoteFunction" then
  2124. return coroutine.yield()
  2125. elseif remoteType == "RemoteEvent" then
  2126. if remoteHooks[remote] then
  2127. return originalEvent(remote, remoteHooks[remote](...))
  2128. end
  2129. return originalEvent(remote, ...)
  2130. else
  2131. if remoteHooks[remote] then
  2132. return originalFunction(remote, remoteHooks[remote](...))
  2133. end
  2134. return originalFunction(remote, ...)
  2135. end
  2136. end
  2137.  
  2138. local newnamecall = newcclosure(function(remote, ...)
  2139. if typeof(remote) == "Instance" then
  2140. local args = { ... }
  2141. local methodName = getnamecallmethod()
  2142. local validInstance, remoteName = pcall(function()
  2143. return remote.Name
  2144. end)
  2145. if
  2146. validInstance
  2147. and (methodName == "FireServer" or methodName == "fireServer" or methodName == "InvokeServer" or methodName == "invokeServer")
  2148. and not (blacklist[remote] or blacklist[remoteName])
  2149. then
  2150. local funcInfo = {}
  2151. local calling
  2152. if funcEnabled then
  2153. funcInfo = debug.getinfo(3) or funcInfo
  2154. calling = useGetCallingScript and getcallingscript() or nil
  2155. end
  2156. if recordReturnValues and (methodName == "InvokeServer" or methodName == "invokeServer") then
  2157. local namecallThread = coroutine.running()
  2158. local args = { ... }
  2159. task.defer(function()
  2160. local returnValue
  2161. setnamecallmethod(methodName)
  2162. if remoteHooks[remote] then
  2163. args = { remoteHooks[remote](unpack(args)) }
  2164. returnValue = { original(remote, unpack(args)) }
  2165. else
  2166. returnValue = { original(remote, unpack(args)) }
  2167. end
  2168. coroutine.resume(namecallThread, unpack(returnValue))
  2169. coroutine.wrap(function()
  2170. schedule(remoteHandler, false, methodName, remote, args, funcInfo, calling, returnValue)
  2171. end)()
  2172. end)
  2173. else
  2174. coroutine.wrap(function()
  2175. schedule(remoteHandler, false, methodName, remote, args, funcInfo, calling)
  2176. end)()
  2177. end
  2178. end
  2179. if recordReturnValues and (methodName == "InvokeServer" or methodName == "invokeServer") then
  2180. return coroutine.yield()
  2181. elseif
  2182. validInstance
  2183. and (methodName == "FireServer" or methodName == "fireServer" or methodName == "InvokeServer" or methodName == "invokeServer")
  2184. and (blocklist[remote] or blocklist[remoteName])
  2185. then
  2186. return nil
  2187. elseif
  2188. (not recordReturnValues or methodName ~= "InvokeServer" or methodName ~= "invokeServer")
  2189. and validInstance
  2190. and (methodName == "FireServer" or methodName == "fireServer" or methodName == "InvokeServer" or methodName == "invokeServer")
  2191. and remoteHooks[remote]
  2192. then
  2193. return original(remote, remoteHooks[remote](...))
  2194. else
  2195. return original(remote, ...)
  2196. end
  2197. end
  2198. return original(remote, ...)
  2199. end, original)
  2200.  
  2201. local newFireServer = newcclosure(function(...)
  2202. return hookRemote("RemoteEvent", ...)
  2203. end, originalEvent)
  2204.  
  2205. local newInvokeServer = newcclosure(function(...)
  2206. return hookRemote("RemoteFunction", ...)
  2207. end, originalFunction)
  2208.  
  2209. --- Toggles on and off the remote spy
  2210. function toggleSpy()
  2211. if not toggle then
  2212. if hookmetamethod then
  2213. local oldNamecall = hookmetamethod(game, "__namecall", newnamecall)
  2214. original = original or function(...)
  2215. return oldNamecall(...)
  2216. end
  2217. _G.OriginalNamecall = original
  2218. else
  2219. gm = gm or getrawmetatable(game)
  2220. original = original or function(...)
  2221. return gm.__namecall(...)
  2222. end
  2223. setreadonly(gm, false)
  2224. if not original then
  2225. warn("SimpleSpy: namecall method not found!")
  2226. onToggleButtonClick()
  2227. return
  2228. end
  2229. gm.__namecall = newnamecall
  2230. setreadonly(gm, true)
  2231. end
  2232. originalEvent = hookfunction(remoteEvent.FireServer, newFireServer)
  2233. originalFunction = hookfunction(remoteFunction.InvokeServer, newInvokeServer)
  2234. else
  2235. if hookmetamethod then
  2236. if original then
  2237. hookmetamethod(game, "__namecall", original)
  2238. end
  2239. else
  2240. gm = gm or getrawmetatable(game)
  2241. setreadonly(gm, false)
  2242. gm.__namecall = original
  2243. setreadonly(gm, true)
  2244. end
  2245. hookfunction(remoteEvent.FireServer, originalEvent)
  2246. hookfunction(remoteFunction.InvokeServer, originalFunction)
  2247. end
  2248. end
  2249.  
  2250. --- Toggles between the two remotespy methods (hookfunction currently = disabled)
  2251. function toggleSpyMethod()
  2252. toggleSpy()
  2253. toggle = not toggle
  2254. end
  2255.  
  2256. --- Shuts down the remote spy
  2257. function shutdown()
  2258. if schedulerconnect then
  2259. schedulerconnect:Disconnect()
  2260. end
  2261. for _, connection in pairs(connections) do
  2262. coroutine.wrap(function()
  2263. connection:Disconnect()
  2264. end)()
  2265. end
  2266. SimpleSpy2:Destroy()
  2267. hookfunction(remoteEvent.FireServer, originalEvent)
  2268. hookfunction(remoteFunction.InvokeServer, originalFunction)
  2269. if hookmetamethod then
  2270. if original then
  2271. hookmetamethod(game, "__namecall", original)
  2272. end
  2273. else
  2274. gm = gm or getrawmetatable(game)
  2275. setreadonly(gm, false)
  2276. gm.__namecall = original
  2277. setreadonly(gm, true)
  2278. end
  2279. _G.SimpleSpyExecuted = false
  2280. end
  2281.  
  2282. -- main
  2283. if not _G.SimpleSpyExecuted then
  2284. local succeeded, err = pcall(function()
  2285. if not RunService:IsClient() then
  2286. error("SimpleSpy cannot run on the server!")
  2287. end
  2288. if
  2289. not hookfunction
  2290. or not getrawmetatable
  2291. or getrawmetatable and not getrawmetatable(game).__namecall
  2292. or not setreadonly
  2293. then
  2294. local missing = {}
  2295. if not hookfunction then
  2296. table.insert(missing, "hookfunction")
  2297. end
  2298. if not getrawmetatable then
  2299. table.insert(missing, "getrawmetatable")
  2300. end
  2301. if getrawmetatable and not getrawmetatable(game).__namecall then
  2302. table.insert(missing, "getrawmetatable(game).__namecall")
  2303. end
  2304. if not setreadonly then
  2305. table.insert(missing, "setreadonly")
  2306. end
  2307. shutdown()
  2308. error(
  2309. "This environment does not support method hooks!\n(Your exploit is not capable of running SimpleSpy)\nMissing: "
  2310. .. table.concat(missing, ", ")
  2311. )
  2312. end
  2313. _G.SimpleSpyShutdown = shutdown
  2314. ContentProvider:PreloadAsync({
  2315. "rbxassetid://6065821980",
  2316. "rbxassetid://6065774948",
  2317. "rbxassetid://6065821086",
  2318. "rbxassetid://6065821596",
  2319. ImageLabel,
  2320. ImageLabel_2,
  2321. ImageLabel_3,
  2322. })
  2323. -- if gethui then funcEnabled = false end
  2324. onToggleButtonClick()
  2325. RemoteTemplate.Parent = nil
  2326. FunctionTemplate.Parent = nil
  2327. codebox = Highlight.new(CodeBox)
  2328. codebox:setRaw("")
  2329. getgenv().SimpleSpy = SimpleSpy
  2330. getgenv().getNil = function(name, class)
  2331. for _, v in pairs(getnilinstances()) do
  2332. if v.ClassName == class and v.Name == name then
  2333. return v
  2334. end
  2335. end
  2336. end
  2337. TextLabel:GetPropertyChangedSignal("Text"):Connect(scaleToolTip)
  2338. -- TopBar.InputBegan:Connect(onBarInput)
  2339. MinimizeButton.MouseButton1Click:Connect(toggleMinimize)
  2340. MaximizeButton.MouseButton1Click:Connect(toggleSideTray)
  2341. Simple.MouseButton1Click:Connect(onToggleButtonClick)
  2342. CloseButton.MouseEnter:Connect(onXButtonHover)
  2343. CloseButton.MouseLeave:Connect(onXButtonUnhover)
  2344. Simple.MouseEnter:Connect(onToggleButtonHover)
  2345. Simple.MouseLeave:Connect(onToggleButtonUnhover)
  2346. CloseButton.MouseButton1Click:Connect(shutdown)
  2347. table.insert(connections, UserInputService.InputBegan:Connect(backgroundUserInput))
  2348. connectResize()
  2349. SimpleSpy2.Enabled = true
  2350. coroutine.wrap(function()
  2351. wait(1)
  2352. onToggleButtonUnhover()
  2353. end)()
  2354. schedulerconnect = RunService.Heartbeat:Connect(taskscheduler)
  2355. if syn and syn.protect_gui then
  2356. pcall(syn.protect_gui, SimpleSpy2)
  2357. end
  2358. bringBackOnResize()
  2359. SimpleSpy2.Parent = --[[gethui and gethui() or]]
  2360. CoreGui
  2361. _G.SimpleSpyExecuted = true
  2362. if not Players.LocalPlayer then
  2363. Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
  2364. end
  2365. Mouse = Players.LocalPlayer:GetMouse()
  2366. oldIcon = Mouse.Icon
  2367. table.insert(connections, Mouse.Move:Connect(mouseMoved))
  2368. end)
  2369. if not succeeded then
  2370. warn(
  2371. "A fatal error has occured, SimpleSpy was unable to launch properly.\nPlease DM this error message to @exx#9394:\n\n"
  2372. .. tostring(err)
  2373. )
  2374. SimpleSpy2:Destroy()
  2375. hookfunction(remoteEvent.FireServer, originalEvent)
  2376. hookfunction(remoteFunction.InvokeServer, originalFunction)
  2377. if hookmetamethod then
  2378. if original then
  2379. hookmetamethod(game, "__namecall", original)
  2380. end
  2381. else
  2382. setreadonly(gm, false)
  2383. gm.__namecall = original
  2384. setreadonly(gm, true)
  2385. end
  2386. return
  2387. end
  2388. else
  2389. SimpleSpy2:Destroy()
  2390. return
  2391. end
  2392.  
  2393. ----- ADD ONS ----- (easily add or remove additonal functionality to the RemoteSpy!)
  2394. --[[
  2395. Some helpful things:
  2396. - add your function in here, and create buttons for them through the 'newButton' function
  2397. - the first argument provided is the TextButton the player clicks to run the function
  2398. - generated scripts are generated when the namecall is initially fired and saved in remoteFrame objects
  2399. - blacklisted remotes will be ignored directly in namecall (less lag)
  2400. - the properties of a 'remoteFrame' object:
  2401. {
  2402. Name: (string) The name of the Remote
  2403. GenScript: (string) The generated script that appears in the codebox (generated when namecall fired)
  2404. Source: (Instance (LocalScript)) The script that fired/invoked the remote
  2405. Remote: (Instance (RemoteEvent) | Instance (RemoteFunction)) The remote that was fired/invoked
  2406. Log: (Instance (TextButton)) The button being used for the remote (same as 'selected.Log')
  2407. }
  2408. - globals list: (contact @exx#9394 for more information or if you have suggestions for more to be added)
  2409. - closed: (boolean) whether or not the GUI is currently minimized
  2410. - logs: (table[remoteFrame]) full of remoteFrame objects (properties listed above)
  2411. - selected: (remoteFrame) the currently selected remoteFrame (properties listed above)
  2412. - blacklist: (string[] | Instance[] (RemoteEvent) | Instance[] (RemoteFunction)) an array of blacklisted names and remotes
  2413. - codebox: (Instance (TextBox)) the textbox that holds all the code- cleared often
  2414. ]]
  2415. -- Copies the contents of the codebox
  2416. newButton("Copy Code", function()
  2417. return "Click to copy code"
  2418. end, function()
  2419. setclipboard(codebox:getString())
  2420. TextLabel.Text = "Copied successfully!"
  2421. end)
  2422.  
  2423. --- Copies the source script (that fired the remote)
  2424. newButton("Copy Remote", function()
  2425. return "Click to copy the path of the remote"
  2426. end, function()
  2427. if selected then
  2428. setclipboard(v2s(selected.Remote.remote))
  2429. TextLabel.Text = "Copied!"
  2430. end
  2431. end)
  2432.  
  2433. -- Executes the contents of the codebox through loadstring
  2434. newButton("Run Code", function()
  2435. return "Click to execute code"
  2436. end, function()
  2437. local orText = "Click to execute code"
  2438. TextLabel.Text = "Executing..."
  2439. local succeeded = pcall(function()
  2440. return loadstring(codebox:getString())()
  2441. end)
  2442. if succeeded then
  2443. TextLabel.Text = "Executed successfully!"
  2444. else
  2445. TextLabel.Text = "Execution error!"
  2446. end
  2447. end)
  2448.  
  2449. --- Gets the calling script (not super reliable but w/e)
  2450. newButton("Get Script", function()
  2451. return "Click to copy calling script to clipboard\nWARNING: Not super reliable, nil == could not find"
  2452. end, function()
  2453. if selected then
  2454. setclipboard(SimpleSpy:ValueToString(selected.Source))
  2455. TextLabel.Text = "Done!"
  2456. end
  2457. end)
  2458.  
  2459. --- Decompiles the script that fired the remote and puts it in the code box
  2460. newButton("Function Info", function()
  2461. return "Click to view calling function information"
  2462. end, function()
  2463. if selected then
  2464. if selected.Function then
  2465. codebox:setRaw(
  2466. "-- Calling function info\n-- Generated by the SimpleSpy serializer\n\n" .. tostring(selected.Function)
  2467. )
  2468. end
  2469. TextLabel.Text = "Done! Function info generated by the SimpleSpy Serializer."
  2470. end
  2471. end)
  2472.  
  2473. --- Clears the Remote logs
  2474. newButton("Clr Logs", function()
  2475. return "Click to clear logs"
  2476. end, function()
  2477. TextLabel.Text = "Clearing..."
  2478. logs = {}
  2479. for _, v in pairs(LogList:GetChildren()) do
  2480. if not v:IsA("UIListLayout") then
  2481. v:Destroy()
  2482. end
  2483. end
  2484. codebox:setRaw("")
  2485. selected = nil
  2486. TextLabel.Text = "Logs cleared!"
  2487. end)
  2488.  
  2489. --- Excludes the selected.Log Remote from the RemoteSpy
  2490. newButton("Exclude (i)", function()
  2491. return "Click to exclude this Remote.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable."
  2492. end, function()
  2493. if selected then
  2494. blacklist[selected.Remote.remote] = true
  2495. TextLabel.Text = "Excluded!"
  2496. end
  2497. end)
  2498.  
  2499. --- Excludes all Remotes that share the same name as the selected.Log remote from the RemoteSpy
  2500. newButton("Exclude (n)", function()
  2501. return "Click to exclude all remotes with this name.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable."
  2502. end, function()
  2503. if selected then
  2504. blacklist[selected.Name] = true
  2505. TextLabel.Text = "Excluded!"
  2506. end
  2507. end)
  2508.  
  2509. --- clears blacklist
  2510. newButton("Clr Blacklist", function()
  2511. return "Click to clear the blacklist.\nExcluding a remote makes SimpleSpy ignore it, but it will continue to be usable."
  2512. end, function()
  2513. blacklist = {}
  2514. TextLabel.Text = "Blacklist cleared!"
  2515. end)
  2516.  
  2517. --- Prevents the selected.Log Remote from firing the server (still logged)
  2518. newButton("Block (i)", function()
  2519. 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."
  2520. end, function()
  2521. if selected then
  2522. if selected.Remote.remote then
  2523. blocklist[selected.Remote.remote] = true
  2524. TextLabel.Text = "Excluded!"
  2525. else
  2526. TextLabel.Text = "Error! Instance may no longer exist, try using Block (n)."
  2527. end
  2528. end
  2529. end)
  2530.  
  2531. --- Prevents all remotes from firing that share the same name as the selected.Log remote from the RemoteSpy (still logged)
  2532. newButton("Block (n)", function()
  2533. 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."
  2534. end, function()
  2535. if selected then
  2536. blocklist[selected.Name] = true
  2537. TextLabel.Text = "Excluded!"
  2538. end
  2539. end)
  2540.  
  2541. --- clears blacklist
  2542. newButton("Clr Blocklist", function()
  2543. 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."
  2544. end, function()
  2545. blocklist = {}
  2546. TextLabel.Text = "Blocklist cleared!"
  2547. end)
  2548.  
  2549. --- Attempts to decompile the source script
  2550. newButton("Decompile", function()
  2551. return "Attempts to decompile source script\nWARNING: Not super reliable, nil == could not find"
  2552. end, function()
  2553. if selected then
  2554. if selected.Source then
  2555. codebox:setRaw(decompile(selected.Source))
  2556. TextLabel.Text = "Done!"
  2557. else
  2558. TextLabel.Text = "Source not found!"
  2559. end
  2560. end
  2561. end)
  2562.  
  2563. newButton("Disable Info", function()
  2564. return string.format(
  2565. "[%s] Toggle function info (because it can cause lag in some games)",
  2566. funcEnabled and "ENABLED" or "DISABLED"
  2567. )
  2568. end, function()
  2569. funcEnabled = not funcEnabled
  2570. TextLabel.Text = string.format(
  2571. "[%s] Toggle function info (because it can cause lag in some games)",
  2572. funcEnabled and "ENABLED" or "DISABLED"
  2573. )
  2574. end)
  2575.  
  2576. newButton("Autoblock", function()
  2577. return string.format(
  2578. "[%s] [BETA] Intelligently detects and excludes spammy remote calls from logs",
  2579. autoblock and "ENABLED" or "DISABLED"
  2580. )
  2581. end, function()
  2582. autoblock = not autoblock
  2583. TextLabel.Text = string.format(
  2584. "[%s] [BETA] Intelligently detects and excludes spammy remote calls from logs",
  2585. autoblock and "ENABLED" or "DISABLED"
  2586. )
  2587. history = {}
  2588. excluding = {}
  2589. end)
  2590.  
  2591. newButton("CallingScript", function()
  2592. return string.format(
  2593. "[%s] [UNSAFE] Uses 'getcallingscript' to get calling script for Decompile and GetScript. Much more reliable, but opens up SimpleSpy to detection and/or instability.",
  2594. useGetCallingScript and "ENABLED" or "DISABLED"
  2595. )
  2596. end, function()
  2597. useGetCallingScript = not useGetCallingScript
  2598. TextLabel.Text = string.format(
  2599. "[%s] [UNSAFE] Uses 'getcallingscript' to get calling script for Decompile and GetScript. Much more reliable, but opens up SimpleSpy to detection and/or instability.",
  2600. useGetCallingScript and "ENABLED" or "DISABLED"
  2601. )
  2602. end)
  2603.  
  2604. newButton("KeyToString", function()
  2605. return string.format(
  2606. "[%s] [BETA] Uses an experimental new function to replicate Roblox's behavior when a non-primitive type is used as a key in a table. Still in development and may not properly reflect tostringed (empty) userdata.",
  2607. keyToString and "ENABLED" or "DISABLED"
  2608. )
  2609. end, function()
  2610. keyToString = not keyToString
  2611. TextLabel.Text = string.format(
  2612. "[%s] [BETA] Uses an experimental new function to replicate Roblox's behavior when a non-primitive type is used as a key in a table. Still in development and may not properly reflect tostringed (empty) userdata.",
  2613. keyToString and "ENABLED" or "DISABLED"
  2614. )
  2615. end)
  2616.  
  2617. newButton("ToggleReturnValues", function()
  2618. return string.format(
  2619. "[%s] [EXPERIMENTAL] Enables recording of return values for 'GetReturnValue'\n\nUse this method at your own risk, as it could be detectable.",
  2620. recordReturnValues and "ENABLED" or "DISABLED"
  2621. )
  2622. end, function()
  2623. recordReturnValues = not recordReturnValues
  2624. TextLabel.Text = string.format(
  2625. "[%s] [EXPERIMENTAL] Enables recording of return values for 'GetReturnValue'\n\nUse this method at your own risk, as it could be detectable.",
  2626. recordReturnValues and "ENABLED" or "DISABLED"
  2627. )
  2628. end)
  2629.  
  2630. newButton("GetReturnValue", function()
  2631. return "[Experimental] If 'ReturnValues' is enabled, this will show the recorded return value for the RemoteFunction (if available)."
  2632. end, function()
  2633. if selected then
  2634. codebox:setRaw(SimpleSpy:ValueToVar(selected.ReturnValue, "returnValue"))
  2635. end
  2636. end)
  2637. end)
  2638. -----------------------------------------------------------------------------------------------
  2639. --Credits
  2640. local Tab = Window:NewTab("Credits")
  2641. local Section = Tab:NewSection("Credits")
  2642. -----------------------------------------------------------------------------------------------
  2643. Section:NewLabel("This Gui is made by Zaggiie")
  2644. -----------------------------------------------------------------------------------------------
  2645. Section:NewLabel("You can Join the Discord, for more Scripts!")
  2646. -----------------------------------------------------------------------------------------------
  2647. Section:NewLabel("Enjoy!")
  2648.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement