View difference between Paste ID: kXYzx7WN and 7GmZyarT
SHOW: | | - or go back to the newest paste.
1
--[[
2
    SimpleSpy v0.8 SOURCE 
3
4
    Credits: 
5
        Not By Me
6
			You can make script FE with it
7
]]
8
---- GENERATED BY GUI to LUA ----
9
local Players = game:GetService("Players")
10-
local CoreGui = game:GetService("CoreGui")
10+
local CoreGui = owner.PlayerGui
11
12
local ScreenGui = Instance.new("ScreenGui")
13
local main = Instance.new("Frame")
14
local topbar = Instance.new("Frame")
15
local minimize = Instance.new("TextButton")
16
local titleLabel = Instance.new("TextLabel")
17
local remotes = Instance.new("ScrollingFrame")
18
local UIListLayout = Instance.new("UIListLayout")
19
local eTemplate = Instance.new("TextButton")
20
local icon = Instance.new("ImageLabel")
21
local name = Instance.new("TextLabel")
22
local fTemplate = Instance.new("TextButton")
23
local icon_2 = Instance.new("ImageLabel")
24
local name_2 = Instance.new("TextLabel")
25
local properties = Instance.new("Frame")
26
local codeframe = Instance.new("ScrollingFrame")
27
codebox = Instance.new("TextBox")
28
local propertyframe = Instance.new("ScrollingFrame")
29
local UIListLayout_2 = Instance.new("UIListLayout")
30
local property = Instance.new("Frame")
31
local name_3 = Instance.new("TextLabel")
32
local property_2 = Instance.new("TextButton")
33
local methodToggle = Instance.new("TextButton")
34
35
--Properties:
36
37
ScreenGui.ResetOnSpawn = false
38
ScreenGui.DisplayOrder = 999999999
39-
ScreenGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")
39+
ScreenGui.Parent = owner:WaitForChild("PlayerGui")
40
ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
41
42
main.Name = "main"
43
main.Parent = ScreenGui
44
main.BackgroundColor3 = Color3.new(0.219608, 0.219608, 0.219608)
45
main.BorderSizePixel = 0
46
main.Position = UDim2.new(0, 100, 0, 100)
47
main.Size = UDim2.new(0.5, 0, 0.5, 0)
48
49
topbar.Name = "topbar"
50
topbar.Parent = main
51
topbar.BorderSizePixel = 0
52
topbar.BackgroundColor3 = Color3.new(0.121569, 0.121569, 0.121569)
53
topbar.Size = UDim2.new(1, 0, 0, 18)
54
55
minimize.Name = "minimize"
56
minimize.Parent = topbar
57
minimize.BackgroundColor3 = Color3.new(0, 0.105882, 0.792157)
58
minimize.BorderSizePixel = 0
59
minimize.Position = UDim2.new(0, 0, 0, 0)
60
minimize.Size = UDim2.new(0, 18, 0, 18)
61
minimize.Font = Enum.Font.SourceSans
62
minimize.Text = ""
63
minimize.TextColor3 = Color3.new(0, 0, 0)
64
minimize.TextSize = 14
65
66
titleLabel.Parent = topbar
67
titleLabel.BackgroundColor3 = Color3.new(1, 1, 1)
68
titleLabel.BackgroundTransparency = 1
69
titleLabel.BorderSizePixel = 0
70
titleLabel.Position = UDim2.new(0.25, 0, 0, 0)
71
titleLabel.Size = UDim2.new(0.5, 0, 1, 0)
72
titleLabel.Font = Enum.Font.SourceSansBold
73
titleLabel.Text = "SimpleSpy v0.8 |  exxtremewa#9394"
74
titleLabel.TextColor3 = Color3.new(0.905882, 0.905882, 0.905882)
75
titleLabel.TextSize = 14
76
77
remotes.Name = "remotes"
78
remotes.Parent = main
79
remotes.BackgroundColor3 = Color3.new(1, 1, 1)
80
remotes.BackgroundTransparency = 1
81
remotes.BorderSizePixel = 0
82
remotes.Position = UDim2.new(0, 0, 0, 18)
83
remotes.Size = UDim2.new(0.5, 0, 1, -18)
84
remotes.BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
85
remotes.ScrollBarThickness = 10
86
remotes.TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
87
88
UIListLayout.Parent = remotes
89
UIListLayout.SortOrder = Enum.SortOrder.LayoutOrder
90
91
eTemplate.Name = "eTemplate"
92
eTemplate.Text = ""
93
eTemplate.Parent = remotes
94
eTemplate.BackgroundColor3 = Color3.new(0.219608, 0.219608, 0.219608)
95
eTemplate.BorderColor3 = Color3.new(0.8, 0.8, 0.8)
96
eTemplate.BorderSizePixel = 1
97
eTemplate.Size = UDim2.new(1, -10, 0, 20)
98
eTemplate.BorderMode = Enum.BorderMode.Inset
99
100
icon.Name = "icon"
101
icon.Parent = eTemplate
102
icon.BackgroundColor3 = Color3.new(1, 1, 1)
103
icon.BackgroundTransparency = 1
104
icon.BorderSizePixel = 0
105
icon.Size = UDim2.new(0, 18, 0, 18)
106
icon.Position = UDim2.new(0, 2, 0, 2)
107
icon.Image = "http://www.roblox.com/asset/?id=4640035463"
108
icon.ScaleType = Enum.ScaleType.Fit
109
110
name.Name = "name"
111
name.Parent = eTemplate
112
name.BackgroundColor3 = Color3.new(1, 1, 1)
113
name.BackgroundTransparency = 1
114
name.Position = UDim2.new(0, 25, 0, 0)
115
name.Size = UDim2.new(1, -25, 1, 0)
116
name.Font = Enum.Font.SourceSansBold
117
name.Text = "RemoteEventName"
118
name.TextColor3 = Color3.new(0.976471, 0.921569, 0.121569)
119
name.TextSize = 14
120
name.TextXAlignment = Enum.TextXAlignment.Left
121
122
fTemplate.Name = "fTemplate"
123
fTemplate.Text = ""
124
fTemplate.Parent = remotes
125
fTemplate.BackgroundColor3 = Color3.new(0.219608, 0.219608, 0.219608)
126
fTemplate.BorderColor3 = Color3.new(0.8, 0.8, 0.8)
127
fTemplate.BorderSizePixel = 1
128
fTemplate.Size = UDim2.new(1, -10, 0, 20)
129
fTemplate.BorderMode = Enum.BorderMode.Inset
130
131
icon_2.Name = "icon"
132
icon_2.Parent = fTemplate
133
icon_2.BackgroundColor3 = Color3.new(1, 1, 1)
134
icon_2.BackgroundTransparency = 1
135
icon_2.BorderSizePixel = 0
136
icon_2.Size = UDim2.new(0, 18, 0, 18)
137
icon_2.Position = UDim2.new(0, 2, 0, 2)
138
icon_2.Image = "http://www.roblox.com/asset/?id=4640035282"
139
icon_2.ScaleType = Enum.ScaleType.Fit
140
141
name_2.Name = "name"
142
name_2.Parent = fTemplate
143
name_2.BackgroundColor3 = Color3.new(1, 1, 1)
144
name_2.BackgroundTransparency = 1
145
name_2.Position = UDim2.new(0, 25, 0, 0)
146
name_2.Size = UDim2.new(1, -25, 1, 0)
147
name_2.Font = Enum.Font.SourceSansBold
148
name_2.Text = "RemoteFunctionName"
149
name_2.TextColor3 = Color3.new(0.666667, 0.12549, 1)
150
name_2.TextSize = 14
151
name_2.TextXAlignment = Enum.TextXAlignment.Left
152
153
properties.Name = "properties"
154
properties.Parent = main
155
properties.BackgroundColor3 = Color3.new(1, 1, 1)
156
properties.BackgroundTransparency = 1
157
properties.Position = UDim2.new(0.5, 0, 0, 18)
158
properties.Size = UDim2.new(0.5, 0, 1, -18)
159
160
codeframe.Name = "codeframe"
161
codeframe.Parent = properties
162
codeframe.BackgroundColor3 = Color3.new(1, 1, 1)
163
codeframe.BackgroundTransparency = 1
164
codeframe.Size = UDim2.new(1, 0, 0.5, 0)
165
codeframe.BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
166
codeframe.ScrollBarThickness = 10
167
codeframe.TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
168
169
codebox.Name = "codebox"
170
codebox.Parent = codeframe
171
codebox.BackgroundColor3 = Color3.new(0.0784314, 0.0784314, 0.0784314)
172
codebox.BorderSizePixel = 0
173
codebox.Selectable = true
174
codebox.Size = UDim2.new(1, -10, 1, 0)
175
codebox.Font = Enum.Font.SourceSansSemibold
176
codebox.Text = "{\\n    [1] = true\\n}"
177
codebox.TextColor3 = Color3.new(0.827451, 0.827451, 0.827451)
178
codebox.TextSize = 14
179
codebox.TextXAlignment = Enum.TextXAlignment.Left
180
codebox.TextYAlignment = Enum.TextYAlignment.Top
181
codebox.ClearTextOnFocus = false
182
183
propertyframe.Name = "propertyframe"
184
propertyframe.Parent = properties
185
propertyframe.BackgroundColor3 = Color3.new(0.141176, 0.141176, 0.141176)
186
propertyframe.BorderSizePixel = 0
187
propertyframe.Position = UDim2.new(0, 0, 0.5, 0)
188
propertyframe.Size = UDim2.new(1, 0, 0.5, 0)
189
propertyframe.BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
190
propertyframe.ScrollBarThickness = 10
191
propertyframe.TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png"
192
193
UIListLayout_2.Parent = propertyframe
194
UIListLayout_2.SortOrder = Enum.SortOrder.LayoutOrder
195
196
property.Name = "property"
197
property.Parent = propertyframe
198
property.BackgroundColor3 = Color3.new(0.164706, 0.164706, 0.164706)
199
property.BorderColor3 = Color3.new(0.415686, 0.415686, 0.415686)
200
property.BorderSizePixel = 0
201
property.Size = UDim2.new(1, -10, 0, 15)
202
203
name_3.Name = "name"
204
name_3.Parent = property
205
name_3.BackgroundColor3 = Color3.new(0.164706, 0.164706, 0.164706)
206
name_3.BorderColor3 = Color3.new(0.478431, 0.478431, 0.478431)
207
name_3.Size = UDim2.new(0.400000006, 0, 1, 0)
208
name_3.Font = Enum.Font.SourceSans
209
name_3.Text = "Name"
210
name_3.TextColor3 = Color3.new(0.909804, 0.909804, 0.909804)
211
name_3.TextSize = 14
212
name_3.TextXAlignment = Enum.TextXAlignment.Left
213
214
property_2.Name = "property"
215
property_2.Parent = property
216
property_2.BackgroundColor3 = Color3.new(0.0941177, 0.0941177, 0.0941177)
217
property_2.BorderColor3 = Color3.new(0.478431, 0.478431, 0.478431)
218
property_2.Position = UDim2.new(0.300000012, 0, 0, 0)
219
property_2.Size = UDim2.new(0.699999988, 0, 1, 0)
220
property_2.Font = Enum.Font.SourceSans
221
property_2.Text = "Function"
222
property_2.TextColor3 = Color3.new(0.909804, 0.909804, 0.909804)
223
property_2.TextSize = 14
224
property_2.TextXAlignment = Enum.TextXAlignment.Left
225
226
methodToggle.Name = "MethodToggle"
227
methodToggle.Parent = topbar
228
methodToggle.BackgroundColor3 = Color3.new(0.7450980392156863, 0.7450980392156863, 0.7450980392156863)
229
methodToggle.BorderSizePixel = 0
230
methodToggle.Position = UDim2.new(1, -80, 0, 0)
231
methodToggle.Size = UDim2.new(0, 80, 1, 0)
232
methodToggle.TextScaled = true
233
methodToggle.Font = Enum.Font.SourceSans
234
235
-------------------------------------------------------------------------------
236
-- init
237
local RunService = game:GetService("RunService")
238
local UserInputService = game:GetService("UserInputService")
239
local TweenService = game:GetService("TweenService")
240
local ContentProvider = game:GetService("ContentProvider")
241
242
--- UDim2 size of `main` while minimized
243
local minSize = UDim2.new(0, 100, 0, 15)
244
--- UDim2 size of `main` while expanded
245
local mainSize = main.Size
246
local selectedColor = Color3.new(0.321569, 0.333333, 1)
247
local deselectedColor = Color3.new(0.8, 0.8, 0.8)
248
--- So things are descending
249
local layoutOrderNum = 999999999
250
--- Whether or not the gui is closed (defaults to false)
251
closed = false
252
--- The event logs to be read from
253
logs = {}
254
--- The event currently selected.Log (defaults to nil)
255
selected = nil
256
--- The blacklist (can be a string name or the Remote Instance)
257
blacklist = {}
258
--- The block list (can be a string name or the Remote Instance)
259
blocklist = {}
260
--- Whether or not to add getNil function
261
local getNil = false
262
--- Array of remotes (and original functions) connected to
263
local connectedRemotes = {}
264
--- True = hookfunction, false = namecall
265
local toggle = false
266
local gm = getrawmetatable(game)
267
local original = gm.__namecall
268
setreadonly(gm, false)
269
--- This event is the main handler for remotes
270
local remoteHandlerEvent = Instance.new("BindableEvent")
271
272
-- functions
273
274
--- Toggles the remote spy method (when button clicked)
275
function onToggleButtonClick()
276
    if toggle then
277
        methodToggle.Text = "Disabled"
278
    else
279
        methodToggle.Text = "Enabled"
280
    end
281
    toggleSpyMethod()
282
end
283
284
--- Drags gui (so long as mouse is held down)
285
function onBarInput(input)
286
    if input.UserInputType == Enum.UserInputType.MouseButton1 then
287
        local lastPos = UserInputService:GetMouseLocation()
288
        RunService:BindToRenderStep(
289
            "drag",
290
            1,
291
            function()
292
                local newPos = UserInputService:GetMouseLocation()
293
                if newPos ~= lastPos then
294
                    main.Position =
295
                        UDim2.new(
296
                        0,
297
                        main.Position.X.Offset + (newPos - lastPos).X,
298
                        0,
299
                        main.Position.Y.Offset + (newPos - lastPos).Y
300
                    )
301
                    lastPos = newPos
302
                end
303
            end
304
        )
305
        topbar.InputEnded:Connect(
306
            function(input)
307
                if input.UserInputType == Enum.UserInputType.MouseButton1 then
308
                    RunService:UnbindFromRenderStep("drag")
309
                end
310
            end
311
        )
312
    end
313
end
314
315
--- Expands and minimizes the gui (closed is the toggle boolean)
316
function toggleMinimize()
317
    if not closed then
318
        closed = not closed
319
        remotes.Visible = false
320
        properties.Visible = false
321
        titleLabel.Visible = false
322
        methodToggle.Visible = false
323
        TweenService:Create(main, TweenInfo.new(0.5), {Size = minSize}):Play()
324
    else
325
        closed = not closed
326
        TweenService:Create(main, TweenInfo.new(0.5), {Size = mainSize}):Play()
327
        wait(0.5)
328
        methodToggle.Visible = true
329
        remotes.Visible = true
330
        properties.Visible = true
331
        titleLabel.Visible = true
332
    end
333
end
334
335
--- Checks if the given Remote is blacklisted; returns true if blacklisted, false if not
336
function blacklisted(remote)
337
    if #blacklist > 0 then
338
        for _, v in pairs(blacklist) do
339
            if type(v) == "string" and v == remote.Name then
340
                return true
341
            elseif typeof(v) == "Instance" and v == remote then
342
                return true
343
            end
344
        end
345
    end
346
    return false
347
end
348
349
--- Checks if the given Remote is blocked; returns true if blacklisted, false if not
350
function blocked(remote)
351
    if #blocklist > 0 then
352
        for _, v in pairs(blocklist) do
353
            if type(v) == "string" and v == remote.Name then
354
                return true
355
            elseif typeof(v) == "Instance" and v == remote then
356
                return true
357
            end
358
        end
359
    end
360
    return false
361
end
362
363
--- Runs on MouseButton1Click of an event frame
364
function eventSelect(frame)
365
    if --[[input.UserInputType == Enum.UserInputType.MouseButton1 and]] (not selected or selected.Log ~= frame) then
366
        if selected then
367
            TweenService:Create(selected.Log, TweenInfo.new(0.5), {BorderColor3 = deselectedColor, BorderSizePixel = 1}):Play(
368
369
            )
370
            selected = nil
371
        end
372
        for _, v in pairs(logs) do
373
            if frame == v.Log then
374
                selected = v
375
            end
376
        end
377
        if selected then
378
            TweenService:Create(selected.Log, TweenInfo.new(0.5), {BorderColor3 = selectedColor, BorderSizePixel = 2}):Play(
379
380
            )
381
            codebox.Text = selected.GenScript
382
        end
383
    end
384
end
385
386
--- Creates new function button (below codebox)
387
function newButton(name, defaultName, onClick)
388
    local button = property:Clone()
389
    button.name.Text = name
390
    button.property.Text = defaultName
391
    button.property.MouseButton1Click:Connect(
392
        function(...)
393
            if selected then
394
                onClick(button.property, ...)
395
            end
396
        end
397
    )
398
    button.Parent = propertyframe
399
end
400
401
--- Adds new RemoteEvent to logs
402
function newEvent(name, gen_script, remote, source_script, blocked, upvalues, constants, num)
403
    local remoteFrame = eTemplate:Clone()
404
    remoteFrame.name.Text = name
405
    local id = Instance.new("IntValue")
406
    id.Name = "ID"
407
    id.Value = #logs + 1
408
    id.Parent = remoteFrame
409
    logs[#logs + 1] = {
410
        Name = name,
411
        GenScript = gen_script,
412
        Source = source_script,
413
        Remote = remote,
414
        Log = remoteFrame,
415
        Upvalues = upvalues,
416
        Constants = constants,
417
        Blocked = blocked,
418
        FunNum = num
419
    }
420
    if blocked then
421
        logs[#logs].GenScript = "-- THIS REMOTE WAS PREVENTED FROM FIRING THE SERVER BY SIMPLESPY\n\n" .. logs[#logs].GenScript
422
    end
423
    remoteFrame.MouseButton1Click:Connect(
424
        function(...)
425
            eventSelect(remoteFrame, ...)
426
        end
427
    )
428
    if layoutOrderNum < 1 then
429
        layoutOrderNum = 999999999
430
    end
431
    remoteFrame.LayoutOrder = layoutOrderNum
432
    layoutOrderNum = layoutOrderNum - 1
433
    remoteFrame.Parent = remotes
434
end
435
436
--- Adds new RemoteFunction to logs
437
function newFunction(name, gen_script, remote, source_script, blocked, upvalues, constants, num)
438
    local remoteFrame = fTemplate:Clone()
439
    remoteFrame.name.Text = name
440
    local id = Instance.new("IntValue")
441
    id.Name = "ID"
442
    id.Value = #logs + 1
443
    id.Parent = remoteFrame
444
    logs[#logs + 1] = {
445
        Name = name,
446
        GenScript = gen_script,
447
        Source = source_script,
448
        Remote = remote,
449
        Log = remoteFrame,
450
        Upvalues = upvalues,
451
        Constants = constants,
452
        Blocked = blocked,
453
        FunNum = num
454
    }
455
    if blocked then
456
        logs[#logs].GenScript = "-- THIS REMOTE WAS PREVENTED FROM FIRING THE SERVER BY SIMPLESPY\n\n" .. logs[#logs].GenScript
457
    end
458
    remoteFrame.MouseButton1Click:Connect(
459
        function(...)
460
            eventSelect(remoteFrame, ...)
461
        end
462
    )
463
    if layoutOrderNum < 1 then
464
        layoutOrderNum = 999999999
465
    end
466
    remoteFrame.LayoutOrder = layoutOrderNum
467
    layoutOrderNum = layoutOrderNum - 1
468
    remoteFrame.Parent = remotes
469
end
470
471
--- Generates a script from the provided arguments (first has to be remote path)
472
function genScript(remote, ...)
473
    local gen = ""
474
    local args = {...}
475
    if #args > 0 then
476
        if
477
            not pcall(
478
                function()
479
                    gen = gen .. "local args = " .. tableToString(args) .. "\n\n"
480
                end
481
            )
482
         then
483
            gen =
484
                gen .. "-- TableToString failure! Reverting to legacy functionality (results may vary)\nlocal args = {"
485
            if
486
                not pcall(
487
                    function()
488
                        for i, v in pairs(args) do
489
                            if type(i) ~= "Instance" and type(i) ~= "userdata" then
490
                                gen = gen .. "\n    [" .. tostring(i) .. "] = "
491
                            elseif type(i) == "string" then
492
                                gen = gen .. '\n    ["' .. tostring(i) .. '"] = '
493
                            elseif type(i) == "userdata" and typeof(i) ~= "Instance" then
494
                                gen = gen .. "\n    [" .. typeof(i) .. ".new(" .. tostring(i) .. ")] = "
495
                            elseif type(i) == "userdata" then
496
                                gen = gen .. "\n    [game." .. i:GetFullName() .. ")] = "
497
                            end
498
                            if type(v) ~= "Instance" and type(v) ~= "userdata" then
499
                                gen = gen .. tostring(v)
500
                            elseif type(v) == "string" then
501
                                gen = gen .. '"' .. tostring(v) .. '"'
502
                            elseif type(v) == "userdata" and typeof(v) ~= "Instance" then
503
                                gen = gen .. typeof(v) .. ".new(" .. tostring(v) .. ")"
504
                            elseif type(v) == "userdata" then
505
                                gen = gen .. "game." .. v:GetFullName()
506
                            end
507
                        end
508
                        gen = gen .. "\n}\n\n"
509
                    end
510
                )
511
             then
512
                gen = gen .. "}\n-- Legacy tableToString failure! Unable to decompile."
513
            end
514
        end
515
        if remote:IsA("RemoteEvent") then
516
            gen = gen .. typeToString(remote) .. ":FireServer(unpack(args))"
517
        elseif remote:IsA("RemoteFunction") then
518
            gen = gen .. typeToString(remote) .. ":InvokeServer(unpack(args))"
519
        end
520
    else
521
        if remote:IsA("RemoteEvent") then
522
            gen = gen .. typeToString(remote) .. ":FireServer()"
523
        elseif remote:IsA("RemoteFunction") then
524
            gen = gen .. typeToString(remote) .. ":InvokeServer()"
525
        end
526
    end
527
    if getNil then
528
        gen =
529
            "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" ..
530
            gen
531
        getNil = false
532
    end
533
    gen =
534
        "-- Script generated by SimpleSpy - credits to exxtremewa#9394\n-- This generator is IN DEVELOPMENT, not compatible with all types/classes yet\n\n" ..
535
        gen
536
    return gen
537
end
538
539
--- Generates spaces based on the provided level
540
function space(level)
541
    local out = ""
542
    for i = 1, level do
543
        out = out .. " "
544
    end
545
    return out
546
end
547
548
--- Adds \'s to the text as a replacement to whitespace chars and other things
549
function getSpecials(s, nested)
550
    if not nested then
551
        s = s:gsub("\\", "\\\\")
552
    end
553
    if s:match("\n") then
554
        local pos, pos2 = s:find("\n")
555
        s = s:sub(0, pos - 1) .. "\\n" .. s:sub(pos2 + 1, s:len())
556
        return getSpecials(s, true)
557
    elseif s:match("\t") then
558
        local pos, pos2 = s:find("\t")
559
        s = s:sub(0, pos - 1) .. "\\t" .. s:sub(pos2 + 1, s:len())
560
        return getSpecials(s, true)
561
    elseif s:match("\t") then
562
        local pos, pos2 = s:find("\t")
563
        s = s:sub(0, pos - 1) .. "\\t" .. s:sub(pos2 + 1, s:len())
564
        return getSpecials(s, true)
565
    elseif s:match("\"") and (s:sub(s:find("\"") - 1, s:find("\"") - 1) ~= "\\") then
566
        local pos, pos2 = s:find("\"")
567
        s = s:sub(0, pos - 1) .. "\\\"" .. s:sub(pos2 + 1, s:len())
568
        return getSpecials(s, true)
569
    elseif s:match("'") and (s:sub(s:find("'") - 1, s:find("'") - 1) ~= "\\") then
570
        local pos, pos2 = s:find("'")
571
        s = s:sub(0, pos - 1) .. "\\'" .. s:sub(pos2 + 1, s:len())
572
        return getSpecials(s, true)
573
    else
574
        return s
575
    end
576
end
577
578
--- Converts a var to a string (including userdata)
579
function typeToString(var, level)
580
    if not level then
581
        level = 4
582
    end
583
    local out = ""
584
    if type(var) ~= "userdata" and type(var) ~= "table" and type(var) ~= "string" then
585
        -- Number, booleans
586
        out = out .. tostring(var)
587
    elseif type(var) == "string" then
588
        -- Strings
589
        out = out .. '"' .. getSpecials(var) .. '"'
590
    elseif type(var) == "table" then
591
        -- Tables
592
        out = out .. tableToString(var, level)
593
    elseif typeof(var) == "TweenInfo" then
594
        -- TweenInfo
595
        out =
596
            out ..
597
            "TweenInfo.new(" ..
598
                tostring(var.Time) ..
599
                    ", Enum.EasingStyle." ..
600
                        tostring(var.EasingStyle) ..
601
                            ", Enum.EasingDirection." ..
602
                                tostring(var.EasingDirection) ..
603
                                    ", " ..
604
                                        tostring(var.RepeatCount) ..
605
                                            ", " .. tostring(var.Reverses) .. ", " .. tostring(var.DelayTime) .. ")"
606
    elseif typeof(var) == "Ray" then
607
        -- Ray
608
        out =
609
            out ..
610
            "Ray.new(Vector3.new(" .. tostring(var.Origin) .. "), Vector3.new(" .. tostring(var.Direction) .. "))"
611
    elseif typeof(var) == "NumberSequence" then
612
        -- NumberSequence
613
        out = out .. "NumberSequence.new("
614
        for i, v in pairs(var.KeyPoints) do
615
            out = out .. tostring(v)
616
            if i < #var.Keypoints then
617
                out = out .. ", "
618
            end
619
        end
620
        out = out .. ")"
621
    elseif typeof(var) == "DockWidgetPluginGuiInfo" then
622
        -- DockWidgetPluginGuiInfo
623
        out = out .. "DockWidgetPluginGuiInfo.new(Enum.InitialDockState" .. tostring(var) .. ")"
624
    elseif typeof(var) == "ColorSequence" then
625
        -- ColorSequence
626
        out = out .. "ColorSequence.new("
627
        for i, v in pairs(var.KeyPoints) do
628
            out = out .. "Color3.new(" .. tostring(v) .. ")"
629
            if i < #var.Keypoints then
630
                out = out .. ", "
631
            end
632
        end
633
        out = out .. ")"
634
    elseif typeof(var) == "BrickColor" then
635
        -- BrickColor
636
        out = out .. "BrickColor.new(" .. tostring(var.Number) .. ")"
637
    elseif typeof(var) == "NumberRange" then
638
        -- NumberRange
639
        out = out .. "NumberRange.new(" .. tostring(var.Min) .. ", " .. tostring(var.Max) .. ")"
640
    elseif typeof(var) == "Region3" then
641
        -- Region3
642
        local center = var.CFrame.Position
643
        local size = var.CFrame.Size
644
        local vector1 = center - size / 2
645
        local vector2 = center + size / 2
646
        out = out .. "Region3.new(Vector3.new(" .. tostring(vector1) .. "), Vector3.new(" .. tostring(vector2) .. ")"
647
    elseif type(var) == "userdata" and typeof(var) ~= "Instance" then
648
        -- Default userdata (no instances)
649
        local dataName = typeof(var)
650
        local args = tostring(var)
651
        for i = 1, args:len() do
652
            if args:sub(i, i) == "}" or args:sub(i, i) == "{" then
653
                if i > 1 and i < args:len() then
654
                    args = args:sub(1, i - 1) .. " " .. args:sub(i + 1, args:len())
655
                elseif i == 1 then
656
                    args = " " .. args:sub(i + 1, args:len())
657
                elseif i == args:len() then
658
                    args = args:sub(1, i - 1) .. " "
659
                end
660
            end
661
        end
662
        out = out .. dataName .. ".new(" .. args .. ")"
663
    elseif type(var) == "userdata" and typeof(var) == "Instance" then
664
        -- Instances
665
        local parent = var
666
        if parent == nil then
667
            out = "nil"
668
        elseif parent ~= game then
669
            while true do
670
                if parent and parent.Parent == game then
671
                    if game:GetService(parent.ClassName) then
672
                        if parent.ClassName == "Workspace" then
673
                            out = "workspace" .. out
674
                        else
675
                            out = 'game:GetService("' .. parent.ClassName .. '")' .. out
676
                        end
677
                        break
678
                    else
679
                        out = 'game["' .. getSpecials(parent.Name) .. '"]'
680
                        break
681
                    end
682
                elseif parent.Parent == nil then
683
                    getNil = true
684
                    out = 'getNil("' .. getSpecials(parent.Name) .. '", "' .. parent.ClassName .. '")'
685
                    break
686
                else
687
                    if parent.Name:match("%a+") ~= parent.Name then
688
                        out = '["' .. getSpecials(parent.Name) .. '"]' .. out
689
                    else
690
                        out = "." .. parent.Name .. out
691
                    end
692
                end
693
                parent = parent.Parent
694
            end
695
        else
696
            out = "game"
697
        end
698
    -- legacy method
699
    -- out = out .. "game." .. var:GetFullName() .. ","
700
    end
701
    return out
702
end
703
704
--- Converts a table to a string (includes nested tables)
705
function tableToString(t, level)
706
    if type(level) ~= "number" then
707
        level = 4
708
    else
709
        level = level + 4
710
    end
711
    local out = ""
712
    for i, v in pairs(t) do
713
        out = out .. "\n" .. space(level) .. "[" .. typeToString(i, level) .. "] = " .. typeToString(v, level) .. ","
714
    end
715
    out = "{" .. out .. "\n" .. space(level - 4) .. "}"
716
    return out
717
end
718
719
--- Toggles on and off the Hookfunction remote spy method (DISABLED- will not run)
720
function toggleHook()
721
    if toggle then
722
        -- local function connect(remote)
723
        --     spawn(
724
        --         function()
725
        --             if remote:IsA("RemoteEvent") then
726
        --                 local old
727
        --                 old =
728
        --                     hookfunction(
729
        --                     remote.FireServer,
730
        --                     function(...)
731
        --                         newEvent(remote.Name, genScript(remote, ...), remote, rawget(getfenv(2), "script"))
732
        --                         return old(...)
733
        --                     end
734
        --                 )
735
        --                 table.insert(connectedRemotes, {remote, old})
736
        --             elseif remote:IsA("RemoteFunction") then
737
        --                 local old
738
        --                 old =
739
        --                     hookfunction(
740
        --                     remote.InvokeServer,
741
        --                     function(...)
742
        --                         newEvent(remote.Name, genScript(remote, ...), remote, rawget(getfenv(2), "script"))
743
        --                         return old(...)
744
        --                     end
745
        --                 )
746
        --                 table.insert(connectedRemotes, {remote, old})
747
        --             end
748
        --         end
749
        --     )
750
        -- end
751
        -- game.ChildAdded:Connect(
752
        --     function(c)
753
        --         pcall(
754
        --             function()
755
        --                 if c:IsA("RemoteEvent") and c:IsA("RemoteFunction") then
756
        --                     connect(c)
757
        --                 end
758
        --             end
759
        --         )
760
        --     end
761
        -- )
762
        -- spawn(
763
        --     function()
764
        --         for _, v in pairs(game:GetDescendants()) do
765
        --             if toggle then
766
        --                 pcall(
767
        --                     function()
768
        --                         if v:IsA("RemoteEvent") or v:IsA("RemoteFunction") then
769
        --                             connect(v)
770
        --                         end
771
        --                     end
772
        --                 )
773
        --                 wait()
774
        --             end
775
        --         end
776
        --     end
777
        -- )
778
    else
779
        -- for _, v in pairs(connectedRemotes) do
780
        --     if v[1] and v[2] then
781
        --         if v[1]:IsA("RemoteEvent") then
782
        --             hookfunction(v[1].FireServer, v[2])
783
        --         elseif v[1]:IsA("RemoteFunction") then
784
        --             hookfunction(v[1].InvokeServer, v[2])
785
        --         end
786
        --     end
787
        -- end
788
        -- connectedRemotes = {}
789
    end
790
end
791
792
--- Toggles on and off the namecall remote spy method
793
function toggleNamecall()
794
    if not toggle then
795
        gm.__namecall = function(...)
796
            local args = {...}
797
            local remote = args[1]
798
            local methodName = getnamecallmethod()
799
            if methodName == "FireServer" and not blacklisted(remote) then
800
                table.remove(args, 1)
801
                local script = rawget(getfenv(2), "script")
802
                local func = debug.getinfo(2).func
803
                spawn(
804
                    function()
805
                        local funNum
806
                        for i, v in pairs(getgc()) do
807
                            if v == func then
808
                                funNum = i
809
                                break
810
                            end
811
                        end
812
                        remoteHandlerEvent:Fire("RemoteEvent", remote.Name, genScript(remote, unpack(args)), remote, script, blocked(remote), tableToString(debug.getupvalues(func)), tableToString(debug.getconstants(func)), funNum)
813
                    end
814
                )
815
            elseif methodName == "InvokeServer" and not blacklisted(remote) then
816
                table.remove(args, 1)
817
                local script = rawget(getfenv(2), "script")
818
                local func = debug.getinfo(2).func
819
                spawn(
820
                    function()
821
                        local funNum
822
                        for i, v in pairs(getgc()) do
823
                            if v == func then
824
                                funNum = i
825
                                break
826
                            end
827
                        end
828
                        remoteHandlerEvent:Fire("RemoteFunction", remote.Name, genScript(remote, unpack(args)), remote, script, blocked(remote), tableToString(debug.getupvalues(func)), tableToString(debug.getconstants(func)), funNum)
829
                    end
830
                )
831
            end
832
            if (methodName == "InvokeServer" or methodName == "FireServer") and blocked(remote) then
833
                return nil
834
            else
835
                return original(...)
836
            end
837
        end
838
    else
839
        gm.__namecall = original
840
    end
841
end
842
843
--- Toggles between the two remotespy methods (hookfunction currently = disabled)
844
function toggleSpyMethod()
845
    toggleHook()
846
    toggleNamecall()
847
    toggle = not toggle
848
end
849
850
--- Handles the button creation things... Connected to `remoteHandlerEvent`
851
function bindableHandler(type, ...)
852
    if type == "RemoteEvent" then
853
        newEvent(...)
854
    elseif type == "RemoteFunction" then
855
        newFunction(...)
856
    end
857
end
858
859
-- main
860
if not _G.SimpleSpyExecuted then
861
    ContentProvider:PreloadAsync({icon, icon_2})
862
    property.Parent = nil
863
    fTemplate.Parent = nil
864
    eTemplate.Parent = nil
865
    codebox.Text = ""
866
    topbar.InputBegan:Connect(onBarInput)
867
    minimize.MouseButton1Click:Connect(toggleMinimize)
868
    methodToggle.MouseButton1Click:Connect(onToggleButtonClick)
869
    remoteHandlerEvent.Event:Connect(bindableHandler)
870
    onToggleButtonClick()
871
    _G.SimpleSpyExecuted = true
872
else
873
    ScreenGui:Destroy()
874
    collectgarbage()
875
end
876
877
----- ADD ONS ----- (easily add or remove additonal functionality to the RemoteSpy!)
878
--[[
879
    Some helpful things:
880
        - add your function in here, and create buttons for them through the 'newButton' function
881
        - the first argument provided is the TextButton the player clicks to run the function
882
        - generated scripts are generated when the namecall is initially fired and saved in remoteFrame objects
883
        - blacklisted remotes will be ignored directly in namecall (less lag)
884
        - the properties of a 'remoteFrame' object:
885
            {
886
                Name: (string) The name of the Remote
887
                GenScript: (string) The generated script that appears in the codebox (generated when namecall fired)
888
                Source: (Instance (LocalScript)) The script that fired/invoked the remote
889
                Remote: (Instance (RemoteEvent) | Instance (RemoteFunction)) The remote that was fired/invoked
890
                Log: (Instance (TextButton)) The button being used for the remote (same as 'selected.Log')
891
            }
892
        - globals list: (contact @exxtremewa#9394 for more information or if you have suggestions for more to be added)
893
            - closed: (boolean) whether or not the GUI is currently minimized
894
            - logs: (table[remoteFrame]) full of remoteFrame objects (properties listed above)
895
            - selected: (remoteFrame) the currently selected remoteFrame (properties listed above)
896
            - blacklist: (string[] | Instance[] (RemoteEvent) | Instance[] (RemoteFunction)) an array of blacklisted names and remotes
897
            - codebox: (Instance (TextBox)) the textbox that holds all the code- cleared often
898
]]
899
-- Copies the contents of the codebox
900
newButton(
901
    "Copy Code",
902
    "Click to copy code",
903
    function(button)
904
        local orText = "Click to copy code"
905
        syn.write_clipboard(codebox.Text)
906
        button.Text = "Copied successfully!"
907
        wait(2)
908
        button.Text = orText
909
    end
910
)
911
912
--- Copies the source script (that fired the remote)
913
newButton(
914
    "Copy Remote",
915
    "Click to copy the path of the remote",
916
    function(button)
917
        local orText = "Click to copy the path of the remote"
918
        syn.write_clipboard(typeToString(selected.Remote))
919
        button.Text = "Copied!"
920
        wait(3)
921
        button.Text = orText
922
    end
923
)
924
925
--- Copies the source script (that fired the remote)
926
newButton(
927
    "Copy Source",
928
    "Click to copy the path of the source script",
929
    function(button)
930
        local orText = "Click to copy the path of the source script"
931
        syn.write_clipboard(typeToString(selected.Source))
932
        button.Text = "Copied!"
933
        wait(3)
934
        button.Text = orText
935
    end
936
)
937
938
--- Puts the upvalues from the remote into the console for your viewing pleasure... (also puts function #)
939
newButton(
940
    "Get Upvalues",
941
    "Click to get the upvalues from the source",
942
    function(button)
943
        local orText = "Click to get upvalues from the source script"
944
        codebox.Text = "-- Serialized with SimpleSpy's TableToString! (credits to @exxtremewa#9394)\n-- (getgc) Function #" .. tostring(selected.FunNum) .. "\n\n" .. selected.Upvalues
945
        button.Text = "Put in Code Box!"
946
        wait(3)
947
        button.Text = orText
948
    end
949
)
950
951
--- Puts the constants from the remote into the console for your viewing pleasure... (also puts function #)
952
newButton(
953
    "Get Constants",
954
    "Click to get the constants from the source",
955
    function(button)
956
        local orText = "Click to get constants from the source script"
957
        codebox.Text = "-- Serialized with SimpleSpy's TableToString! (credits to @exxtremewa#9394)\n-- (getgc) Function #" .. tostring(selected.FunNum) .. "\n\n" .. selected.Constants
958
        button.Text = "Put in Code Box!"
959
        wait(3)
960
        button.Text = orText
961
    end
962
)
963
964
--- Decompiles the script that fired the remote and puts it in the code box
965
newButton(
966
    "Decompile Source",
967
    "Click to decompile the source script",
968
    function(button)
969
        local orText = "Click to decompile the source script"
970
        codebox.Text = "-- Decompiled code from:\n-- " .. typeToString(selected.Source) .. "\n\n" .. decompile(selected.Source)
971
        button.Text = "Decompiled!"
972
        wait(3)
973
        button.Text = orText
974
    end
975
)
976
977
-- Executes the contents of the codebox through loadstring
978
newButton(
979
    "Run Code",
980
    "Click to execute code",
981
    function(button)
982
        local orText = "Click to execute code"
983
        button.Text = "Executing..."
984
        local execute = {
985
            pcall(
986
                function()
987
                    return loadstring(codebox.Text)()
988
                end
989
            )
990
        }
991
        if execute[1] then
992
            button.Text = "Executed successfully!"
993
        else
994
            warn(execute[2], execute[3])
995
            button.Text = "Execution error!"
996
        end
997
        wait(3)
998
        button.Text = orText
999
    end
1000
)
1001
1002
--- Clears the Remote logs
1003
newButton(
1004
    "Clear Logs",
1005
    "Click to clear logs",
1006
    function(button)
1007
        local orText = "Click to clear logs"
1008
        button.Text = "Clearing..."
1009
        logs = {}
1010
        for _, v in pairs(remotes:GetChildren()) do
1011
            if not v:IsA("UIListLayout") then
1012
                v:Destroy()
1013
            end
1014
        end
1015
        codebox.Text = ""
1016
        selected = nil
1017
        button.Text = "Logs cleared!"
1018
        wait(3)
1019
        button.Text = orText
1020
    end
1021
)
1022
1023
--- Excludes the selected.Log Remote from the RemoteSpy
1024
newButton(
1025
    "Exclude (single)",
1026
    "Click to exclude this Remote",
1027
    function(button)
1028
        local orText = "Click to exclude this Remote"
1029
        table.insert(blacklist, #blacklist + 1, selected.Remote)
1030
        button.Text = "Excluded!"
1031
        wait(3)
1032
        button.Text = orText
1033
    end
1034
)
1035
1036
--- Excludes all Remotes that share the same name as the selected.Log remote from the RemoteSpy
1037
newButton(
1038
    "Exclude (by name)",
1039
    "Click to exclude all remotes with this name",
1040
    function(button)
1041
        local orText = "Click to exclude all remotes with this name"
1042
        table.insert(blacklist, #blacklist + 1, selected.Name)
1043
        button.Text = "Excluded!"
1044
        wait(3)
1045
        button.Text = orText
1046
    end
1047
)
1048
1049
--- clears blacklist
1050
newButton(
1051
    "Clear Blacklist",
1052
    "Click to clear the blacklist",
1053
    function(button)
1054
        local orText = "Click to clear the blacklist"
1055
        blacklist = {}
1056
        button.Text = "Blacklist cleared!"
1057
        wait(3)
1058
        button.Text = orText
1059
    end
1060
)
1061
1062
--- Prevents the selected.Log Remote from firing the server (still logged)
1063
newButton(
1064
    "Block (single)",
1065
    "Click to stop this remote from firing",
1066
    function(button)
1067
        local orText = "Click to stop this remote from firing"
1068
        table.insert(blocklist, #blocklist + 1, selected.Remote)
1069
        button.Text = "Excluded!"
1070
        wait(3)
1071
        button.Text = orText
1072
    end
1073
)
1074
1075
--- Prevents all remotes from firing that share the same name as the selected.Log remote from the RemoteSpy (still logged)
1076
newButton(
1077
    "Block (by name)",
1078
    "Click to stop remotes with this name from firing",
1079
    function(button)
1080
        local orText = "Click to stop remotes with this name from firing"
1081
        table.insert(blocklist, #blocklist + 1, selected.Name)
1082
        button.Text = "Excluded!"
1083
        wait(3)
1084
        button.Text = orText
1085
    end
1086
)
1087
1088
--- clears blacklist
1089
newButton(
1090
    "Clear Blocklist",
1091
    "Click to stop blocking remotes",
1092
    function(button)
1093
        local orText = "Click to stop blocking remotes"
1094
        blocklist = {}
1095
        button.Text = "Blocklist cleared!"
1096
        wait(3)
1097
        button.Text = orText
1098
    end
1099
)