1 | local wasLoaded = true; if not game.IsLoaded(game) then wasLoaded = false; repeat task.wait() until game.IsLoaded(game) end |
2 | local spy_settings = ({...})[1] or {} |
3 | local st = tick() |
4 | local service = setmetatable({}, {__index = function(t,k) return game.GetService(game,k) end}) |
5 | local decompile = decompile or disassemble or function() return "-- Decompiler not found." end |
6 | local setclipboardfunc = function(message) if setclipboard then setclipboard("-- This was generated from engospy RemoteSpy tool.\n"..tostring(message)) else print("Couldn't setclipboard.") end end |
7 | local setident = syn and syn.set_thread_identity or setidentity or setthreadcontext |
8 | local isV3 = syn and syn.toast_notification ~= nil |
9 | local lplr = service.Players.LocalPlayer |
10 | local mouse = lplr:GetMouse() |
11 | local spy = { |
12 | VERSION = "v1.02", |
13 | Connections = {}, |
14 | guiConnections = {}, |
15 | instances = {}, |
16 | blocked = {}, |
17 | ignored = {}, |
18 | currentTableDepth = 0, |
19 | saveCalls = spy_settings.saveCalls or false, |
20 | saveOnlyLastCall = spy_settings.saveCalls and false or spy_settings.saveOnlyLastCall or true, |
21 | maxTableDepth = spy_settings.maxTableDepth or 100, |
22 | maxCallsSaved = spy_settings.maxCallsSaved or 1000, |
23 | minimizeBind = spy_settings.minimizeBind or Enum.KeyCode.RightAlt, |
24 | newFunctionMethod = spy_settings.newFunctionMethod or true, |
25 | assets = { |
26 | RemoteEvent = "http://www.roblox.com/asset/?id=413369506", |
27 | RemoteFunction = "http://www.roblox.com/asset/?id=413369623" |
28 | }, |
29 | namecallmethods = { |
30 | RemoteEvent = "FireServer", |
31 | RemoteFunction = "InvokeServer", |
32 | --BindableEvent = "Fire", |
33 | --BindableFunction = "Invoke", |
34 | }, |
35 | event = Instance.new("BindableEvent"), |
36 | blacklistedNames = spy_settings.blacklistedNames or {}, |
37 | } |
38 | shared.engospy = spy |
39 | if getgenv then getgenv().engospy = spy end |
40 | local old_namecall = nil |
41 | local old_index = nil |
42 | local is_hooking = false |
43 | |
44 | function spy.newInstance(self, classname, properties) |
45 | local instance = Instance.new(classname) |
46 | for i,v in next, properties do |
47 | instance[i] = v |
48 | end |
49 | spy.instances[instance.Name] = instance |
50 | return instance |
51 | end |
52 | spy.createInstance = spy.newInstance |
53 | |
54 | function spy.Destroy(self) |
55 | for i,v in next, spy.instances do |
56 | v:Destroy() |
57 | spy.Connections[i] = nil |
58 | end |
59 | for i,v in next, spy.guiConnections do |
60 | v:Disconnect() |
61 | spy.guiConnections[i] = nil |
62 | end |
63 | spy.unhook() |
64 | spy = nil |
65 | end |
66 | |
67 | local function has_unicode(str) |
68 | local notAllowed = ":()[]{}+_-=\\|`~,.<>/?!@#$%^&*" |
69 | |
70 | for character in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do |
71 | if notAllowed:find(character) then |
72 | return true |
73 | end |
74 | end |
75 | end |
76 | |
77 | local function to_unicode(string) |
78 | local codepoints = "utf8.char(" |
79 | |
80 | for _i, v in utf8.codes(string) do |
81 | codepoints = codepoints .. v .. ', ' |
82 | end |
83 | |
84 | return codepoints:sub(1, -3) .. ')' |
85 | end |
86 | |
87 | local function format_string(str) |
88 | local str = str:gsub("\0", "\\0"):gsub("\n", "\\n"):gsub("\r", "\\r"):gsub("\t", "\\t"):gsub("\v", "\\v"):gsub("\b", "\\b"):gsub("\f", "\\f") |
89 | |
90 | return str |
91 | end |
92 | |
93 | function spy.get_path(instance) -- // Thanks to turtlespy for this code, see https://pastebin.com/raw/BDhSQqUU \\ |
94 | local name = instance.Name |
95 | local head = (#name > 0 and '.' .. name) or "['']" |
96 | if not instance.Parent and instance ~= game then |
97 | return head .. " --[[ Parented to nil ]]" |
98 | end |
99 | if instance == game then |
100 | return "game" |
101 | elseif instance == workspace then |
102 | return "workspace" |
103 | else |
104 | local _success, result = pcall(game.GetService, game, instance.ClassName) |
105 | |
106 | if _success and result then |
107 | head = ':GetService("' .. instance.ClassName .. '")' |
108 | elseif instance == lplr then |
109 | head = '.LocalPlayer' |
110 | else |
111 | local nonAlphaNum = name:gsub('[%w_]', '') |
112 | local noPunct = nonAlphaNum:gsub('[%s%p]', '') |
113 | |
114 | if tonumber(name:sub(1, 1)) or (#nonAlphaNum ~= 0 and #noPunct == 0) then |
115 | head = '["' .. name:gsub('"', '\\"'):gsub('\\', '\\\\') .. '"]' |
116 | elseif #nonAlphaNum ~= 0 and #noPunct > 0 then |
117 | head = '[' .. to_unicode(name) .. ']' |
118 | end |
119 | end |
120 | end |
121 | return spy.get_path(instance.Parent) .. head |
122 | end |
123 | |
124 | function spy.table_to_string(t) |
125 | spy.currentTableDepth = spy.currentTableDepth + 1 |
126 | if spy.currentTableDepth > spy.maxTableDepth+1 then |
127 | spy.currentTableDepth = spy.currentTableDepth - 1 |
128 | return "table_over_maxTableDepth (.."..tostring(t)..")" |
129 | end |
130 | local returnStr = "{" |
131 | for i,v in next, t do |
132 | returnStr = returnStr.."\n"..((" "):rep(spy.currentTableDepth)).."["..spy.get_real_value(i).."] = "..spy.get_real_value(v).."," |
133 | end |
134 | if returnStr:sub(-2) == ", " then returnStr = returnStr:sub(1, -3) end |
135 | spy.currentTableDepth = spy.currentTableDepth - 1 |
136 | return returnStr.."\n"..((" "):rep(spy.currentTableDepth)).."}" |
137 | end |
138 | |
139 | function spy.bettergetinfo(func) |
140 | local info = debug.getinfo(func) |
141 | info.func = nil |
142 | return info |
143 | end |
144 | |
145 | function spy.get_real_value(value) |
146 | local _t = typeof(value) |
147 | if _t == 'Instance' then |
148 | return spy.get_path(value) |
149 | elseif _t == 'string' then |
150 | local value = format_string(value) |
151 | return '"'..value..'"' |
152 | elseif _t == 'table' then |
153 | return spy.table_to_string(value) |
154 | elseif _t == 'function' then |
155 | if not islclosure((value)) then |
156 | return "newcclosure(function() end)" |
157 | end |
158 | if spy.newFunctionMethod then |
159 | return "--[[function -->]] "..spy.table_to_string({upvalues = debug.getupvalues(value), constants = debug.getconstants(value), protos = debug.getprotos(value), info = spy.bettergetinfo(value)}) |
160 | end |
161 | return "function() end" |
162 | elseif _t == 'UDim2' or _t == 'UDim' or _t == 'Vector3' or _t == 'Vector2' or _t == 'CFrame' or _t == 'Vector2int16' or _t == 'Vector3int16' or _t == 'BrickColor' or _t == 'Color3' then |
163 | local value = _t == 'BrickColor' and "'"..tostring(value).."'" or value |
164 | return _t..".new("..tostring(value)..")" |
165 | elseif _t == 'TweenInfo' then |
166 | return "TweenInfo.new("..spy.get_real_value(value.Time)..", "..spy.get_real_value(value.EasingStyle)..", "..spy.get_real_value(value.EasingDirection)..", "..spy.get_real_value(value.RepeatCount)..", "..spy.get_real_value(value.Reverses)..", "..spy.get_real_value(value.DelayTime)..")" |
167 | elseif _t == 'Enums' then |
168 | return "Enum" |
169 | elseif _t == 'Enum' then |
170 | return "Enum."..tostring(value) |
171 | elseif _t == 'Axes' or _t == 'Faces' then |
172 | local returnStr = _t..".new(" |
173 | local normals = Enum.NormalId:GetEnumItems() |
174 | for i,v in next, normals do |
175 | if value[v.Name] then |
176 | returnStr = returnStr..spy.get_real_value(v)..", " |
177 | end |
178 | end |
179 | return returnStr:sub(1, -3)..")" |
180 | elseif _t == 'ColorSequence' then |
181 | local returnStr = "ColorSequence.new{" |
182 | local keypoints = value.Keypoints |
183 | for i,v in next, keypoints do |
184 | returnStr = returnStr..spy.get_real_value(v)..", " |
185 | end |
186 | return returnStr:sub(1, -3).."}" |
187 | elseif _t == 'ColorSequenceKeypoint' then |
188 | return "ColorSequenceKeypoint.new("..tostring(value.Time)..", "..spy.get_real_value(value.Value)..")" |
189 | elseif _t == 'DockWidgetPluginGuiInfo' then -- // this was a pain to make \\ |
190 | local str = "" |
191 | local split1 = tostring(value):split(":") |
192 | for i,v in next, split1 do |
193 | str = str..v.." " |
194 | end |
195 | local split2 = str:split(" ") |
196 | local str = "" |
197 | local reali = 0 |
198 | for i,v in next, split2 do |
199 | if math.floor(i/2) == i/2 and v~=" " then |
200 | reali = reali + 1 |
201 | local _v = v |
202 | if reali == 1 then |
203 | _v = "Enum.InitialDockState."..v |
204 | end |
205 | str = str.._v..", " |
206 | end |
207 | end |
208 | return "DockWidgetPluginGuiInfo.new("..(str:sub(1, -3))..")" |
209 | elseif _t == 'DateTime' then |
210 | if value.UnixTimestampMillis == DateTime.now().UnixTimestampMillis then |
211 | return "DateTime.now()" |
212 | end |
213 | return "DateTime.fromUnixTimestampMillis("..value.UnixTimestampMillis..")" |
214 | elseif _t == 'FloatCurveKey' then |
215 | return "FloatCurveKey.new("..spy.get_real_value(value.Time)..", "..spy.get_real_value(value.Value)..", "..spy.get_real_value(value.Interpolation)..")" |
216 | elseif _t == 'NumberRange' then |
217 | return "NumberRange.new("..spy.get_real_value(value.Min)..", "..spy.get_real_value(value.Max)..")" |
218 | elseif _t == 'NumberSequence' then |
219 | local returnStr = "NumberSequence.new{" |
220 | local keypoints = value.Keypoints |
221 | for i,v in next, keypoints do |
222 | returnStr = returnStr..spy.get_real_value(v)..", " |
223 | end |
224 | return returnStr:sub(1, -3).."}" |
225 | elseif _t == 'NumberSequenceKeypoint' then |
226 | return "NumberSequenceKeypoint.new("..tostring(value.Time)..", "..spy.get_real_value(value.Value)..(value.Envelope and ", "..value.Envelope or "")..")" |
227 | elseif _t == 'PathWaypoint' then |
228 | return "PathWaypoint.new("..spy.get_real_value(value.Position)..", "..spy.get_real_value(value.Action)..")" |
229 | elseif _t == 'PhysicalProperties' then |
230 | return "PhysicalProperties.new("..spy.get_real_value(value.Density)..", "..spy.get_real_value(value.Friction)..", "..spy.get_real_value(value.Elasticity)..", "..spy.get_real_value(value.FrictionWeight)..", "..spy.get_real_value(value.ElasticityWeight)..")" |
231 | elseif _t == 'Random' then |
232 | return "Random.new()" |
233 | elseif _t == 'Ray' then |
234 | return "Ray.new("..spy.get_real_value(value.Origin)..", "..spy.get_real_value(value.Direction)..")" |
235 | elseif _t == 'RaycastParams' then |
236 | return "--[[typeof: RaycastParams ->]] {FilterDescendantsInstances = "..spy.get_real_value(value.FilterDescendantsInstances)..", FilterType = "..spy.get_real_value(value.FilterType)..", IgnoreWater = "..spy.get_real_value(value.IgnoreWater)..", CollisionGroup = '"..spy.get_real_value(value.CollisionGroup).."'}" |
237 | elseif _t == 'RaycastResult' then |
238 | return "--[[typeof: RaycastResult ->]] {Distance = " ..spy.get_real_value(value.Distance)..", Instance = "..spy.get_real_value(value.Instance)..", Material = "..spy.get_real_value(value.Material)..", Position = "..spy.get_real_value(value.Position)..", Normal = "..spy.get_real_value(value.Normal).."}" |
239 | elseif _t == 'RBXScriptConnection' then |
240 | return "--[[typeof: RBXScriptConnection ->]] {Connected = "..spy.get_real_value(value.Connected).."}" |
241 | elseif _t == 'RBXScriptSignal' then |
242 | return "RBXScriptSignal" |
243 | elseif _t == 'Rect' then |
244 | return "Rect.new("..spy.get_real_value(value.Min)..", "..spy.get_real_value(value.Max)..")" |
245 | elseif _t == 'Region3' then |
246 | local cframe = value.CFrame |
247 | local size = value.Size |
248 | local min = spy.get_real_value((cframe * CFrame.new(-size.X/2, -size.Y/2, -size.Z/2)).p) |
249 | local max = spy.get_real_value((cframe * CFrame.new(size.X/2, size.Y/2, size.Z/2)).p) |
250 | return "Region3.new("..min..", "..max..")" |
251 | elseif _t == 'Region3int16' then |
252 | return "Region3int16.new("..spy.get_real_value(value.Min)..", "..spy.get_real_value(value.Max)..")" |
253 | elseif _t == 'CatalogSearchParams' then |
254 | return "--[[typeof: CatalogSearchParams ->]] {SearchKeyword = "..spy.get_real_value(value.SearchKeyword)..", MinPrice = "..spy.get_real_value(value.MinPrice)..", MaxPrice = "..spy.get_real_value(value.MaxPrice)..", SortType = "..spy.get_real_value(value.SortType)..", CategoryFilter = "..spy.get_real_value(value.CategoryFilter)..", AssetTypes = "..spy.get_real_value(value.AssetTypes).."}" |
255 | elseif _t == 'OverlapParams' then |
256 | return "--[[typeof: OverlapParams ->]] {FilterDescendantsInstances = "..spy.get_real_value(value.FilterDescendantsInstances)..", FilterType = "..spy.get_real_value(value.FilterType)..", MaxParts ="..spy.get_real_value(value.MaxParts)..", CollisionGroup = "..spy.get_real_value(value.CollisionGroup).."}" |
257 | elseif _t == 'userdata' then |
258 | return "newproxy(true)" |
259 | elseif value == nil then |
260 | return "nil" |
261 | end |
262 | return tostring(value) |
263 | end |
264 | |
265 | function spy.convert_to_code(event, args, ncm) |
266 | local path = spy.get_real_value(event) |
267 | if #args == 0 then |
268 | return path..":"..ncm.."()" |
269 | elseif #args == 1 then |
270 | return path..":"..ncm.."("..spy.get_real_value(args[1])..")" |
271 | end |
272 | |
273 | |
274 | local codestr = path..":"..ncm.."(table.unpack(" |
275 | codestr = codestr..spy.get_real_value(args) |
276 | codestr = codestr.."))" |
277 | return codestr |
278 | end |
279 | |
280 | function spy.convert_to_code_client(event, args, ncm) |
281 | table.insert(args, 1, lplr) |
282 | |
283 | local path = spy.get_real_value(event) |
284 | if #args == 1 then |
285 | return path..":"..ncm.."("..spy.get_real_value(args[1])..")" |
286 | elseif #args == 2 then |
287 | return path..":"..ncm.."(".. spy.get_real_value(args[1]) .. ", " ..spy.get_real_value(args[2])..")" |
288 | end |
289 | |
290 | local codestr = path..":"..ncm.."(table.unpack(" |
291 | codestr = codestr..spy.get_real_value(args) |
292 | codestr = codestr.."))" |
293 | return codestr |
294 | end |
295 | |
296 | local function dragGUI(gui, dragpart) |
297 | spawn(function() |
298 | local dragging |
299 | local dragInput |
300 | local dragStart = Vector3.new(0,0,0) |
301 | local startPos |
302 | local function update(input) |
303 | local delta = input.Position - dragStart |
304 | local Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + (delta.X), startPos.Y.Scale, startPos.Y.Offset + (delta.Y)) |
305 | service.TweenService:Create(gui, TweenInfo.new(.20), {Position = Position}):Play() |
306 | end |
307 | dragpart.InputBegan:Connect(function(input) |
308 | if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch and dragging == false then |
309 | dragStart = input.Position |
310 | local delta = (input.Position - dragStart) |
311 | if delta.Y <= 30 then |
312 | startPos = gui.Position |
313 | |
314 | input.Changed:Connect(function() |
315 | if input.UserInputState == Enum.UserInputState.End then |
316 | dragging = false |
317 | end |
318 | end) |
319 | end |
320 | end |
321 | end) |
322 | dragpart.InputChanged:Connect(function(input) |
323 | if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then |
324 | dragInput = input |
325 | end |
326 | end) |
327 | service.UserInputService.InputChanged:Connect(function(input) |
328 | if input == dragInput and dragging then |
329 | update(input) |
330 | end |
331 | end) |
332 | end) |
333 | end |
334 | |
335 | function spy.createUILibrary() |
336 | local api = {} |
337 | local objects = {} |
338 | api.objects = objects |
339 | spy.MainGui = spy:createInstance("ScreenGui", {Name = "engospy "..tostring(spy.VERSION)}) |
340 | function spy.Minimize() |
341 | local isMinimizing = api.Main.Visible |
342 | for i,v in next, spy.MainGui:GetChildren() do |
343 | if v == api.Icon then |
344 | v.Visible = isMinimizing |
345 | elseif v == api.Main then |
346 | v.Visible = not isMinimizing |
347 | else |
348 | v.Visible = false |
349 | end |
350 | end |
351 | end |
352 | spy.guiConnections[#spy.guiConnections+1] = service.UserInputService.InputBegan:Connect(function(input) |
353 | if input.KeyCode == spy.minimizeBind then |
354 | spy.Minimize() |
355 | end |
356 | end) |
357 | if syn then syn.protect_gui(spy.MainGui) end; spy.MainGui.Parent = (gethui and gethui() or service.CoreGui) |
358 | api.Main = spy:createInstance("Frame", {Name = "Main", Parent = spy.MainGui, BackgroundColor3 = Color3.fromRGB(38, 38, 38), Position = UDim2.new(0.326838464, 0, 0.313684225, 0), Size = UDim2.new(0, 637, 0, 394), Draggable = true, Active = true}) |
359 | api.Topbar = spy:createInstance("Frame", {Name = "Topbar", Parent = api.Main, BackgroundColor3 = Color3.fromRGB(255, 255, 255), BackgroundTransparency = 1.000, Position = UDim2.new(0.230337083, 0, 0, 0), Size = UDim2.new(0, 411, 0, 46)}) |
360 | api.Sidebar = spy:createInstance("Frame", {Name = "Sidebar", Parent = api.Main, BackgroundColor3 = Color3.fromRGB(24, 24, 24), BorderSizePixel = 0, Size = UDim2.new(0, 124, 1, 0)}) |
361 | api.Title = spy:createInstance("TextLabel", {Name = "Title", Parent = api.Sidebar, AnchorPoint = Vector2.new(0.5, 0), BackgroundColor3 = Color3.fromRGB(255, 255, 255), BackgroundTransparency = 1.000, Position = UDim2.new(0.492128909, 0, 0.00581395347, 5), Size = UDim2.new(0, 84, 0, 30), Font = Enum.Font.GothamBold, Text = "engospy", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 24}) |
362 | api.ButtonContainer = spy:createInstance("Frame", {Name = "ButtonContainer", Parent = api.Sidebar, BackgroundTransparency = 1.000, Position = UDim2.new(0, 0, 0, 45), Size = UDim2.new(0, 124, 1, 0)}) |
363 | api.UIListLayout = spy:createInstance("UIListLayout", {Name = "UIListLayout", Parent = api.ButtonContainer, SortOrder = Enum.SortOrder.LayoutOrder}) |
364 | api.Version = spy:createInstance("TextLabel", {Name = "Version", Parent = api.Sidebar, AnchorPoint = Vector2.new(0.5, 0), BackgroundColor3 = Color3.fromRGB(255, 255, 255), BackgroundTransparency = 1.000, Position = UDim2.new(0.5, 0, 0.99000001, -20), Size = UDim2.new(0, 31, 0, 18), Font = Enum.Font.Gotham, Text = tostring(spy.VERSION),TextColor3 = Color3.fromRGB(190, 190, 190), TextSize = 15.000, TextWrapped = false, TextXAlignment = Enum.TextXAlignment.Center}) |
365 | api.UICorner = spy:createInstance("UICorner", {Parent = api.Main, CornerRadius = UDim.new(0, 6)}) |
366 | api.Close = spy:createInstance("TextButton", {Name = "Close", Parent = api.Main, BackgroundColor3 = Color3.fromRGB(222, 48, 48), BorderSizePixel = 0, Position = UDim2.new(0.974882185, -18, 0, 0), Size = UDim2.new(0, 26, 0, 7), Text = ""}) |
367 | api.UICorner2 = spy:createInstance("UICorner", {Parent = api.Close, CornerRadius = UDim.new(0, 6)}) |
368 | api.Minimize = spy:createInstance("TextButton", {Name = "Minimize", Parent = api.Main, BackgroundColor3 = Color3.fromRGB(253, 229, 119), BorderSizePixel = 0, Position = UDim2.new(0.919937134, -18, 0, 0), Size = UDim2.new(0, 26, 0, 7), Text = ""}) |
369 | api.UICorner3 = spy:createInstance("UICorner", {Parent = api.Minimize, CornerRadius = UDim.new(0, 6)}) |
370 | api.Icon = spy:createInstance("ImageButton", {Parent = spy.MainGui, BackgroundColor3 = Color3.fromRGB(24, 24, 24), Position = UDim2.new(0.957393527, 0, 0.603157878, 0), Size = UDim2.new(0, 44, 0, 44), Visible = false, AutoButtonColor = false}) |
371 | api.IconImage = spy:createInstance("ImageLabel", {Name = "ELogo", Parent = api.Icon, AnchorPoint = Vector2.new(0.5, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(0.699999988, 0, 0.699999988, 0), Image = "rbxassetid://9710071559"}) |
372 | api.UICorner4 = spy:createInstance("UICorner", {Parent = api.Icon, CornerRadius = UDim.new(0, 2147483647)}) |
373 | |
374 | api.Icon.MouseButton1Click:Connect(spy.Minimize) |
375 | function api.createCallContainer(name) |
376 | local callapi = {Name = name, FullName = name.."CallContainer", Type = "CallContainer", Calls = {}} |
377 | callapi.Button = spy:createInstance("TextButton", {Name = name, Parent = api.ButtonContainer,Size = UDim2.new(0, 124, 0, 25), BackgroundTransparency = 1, BackgroundColor3 = Color3.fromRGB(38, 38, 38), BorderSizePixel = 0, Font = Enum.Font.Gotham, Text = name, TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14}) |
378 | callapi.Background = spy:createInstance("Frame", {Name = "CallContainerBack", Parent = api.Main,ClipsDescendants = true, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(-0.0152793899, 140, 0.0169999953, 0), Size = UDim2.new(0.784279406, 0, 0.967999995, 0), Visible = false}) |
379 | callapi.Container = spy:createInstance("ScrollingFrame", {Name = callapi.FullName, Parent = callapi.Background,ClipsDescendants = true, Active = true, AnchorPoint = Vector2.new(0.5, 0.5), BackgroundColor3 = Color3.fromRGB(24, 24, 24), BackgroundTransparency = 1.000, BorderSizePixel = 0, Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(0.980000019, 0, 0.963999987, 0), ScrollBarThickness = 0, VerticalScrollBarPosition = Enum.VerticalScrollBarPosition.Left}) |
380 | callapi.UIListLayout = spy:createInstance("UIListLayout", {Parent = callapi.Container, HorizontalAlignment = Enum.HorizontalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 3)}) |
381 | callapi.UICorner = spy:createInstance("UICorner", {Parent = callapi.Background}) |
382 | spy.guiConnections[#spy.guiConnections+1] = callapi.UIListLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() |
383 | callapi.Container.CanvasSize = UDim2.new(0,0,0,callapi.UIListLayout.AbsoluteContentSize.Y) |
384 | end) |
385 | function callapi.open() |
386 | for i,v in next, objects do |
387 | if v.Type == "CallContainer" and v ~= callapi then |
388 | v.Background.Visible = false |
389 | v.Button.BackgroundTransparency = 1 |
390 | elseif v == callapi then |
391 | v.Background.Visible = true |
392 | v.Button.BackgroundTransparency = 0 |
393 | end |
394 | end |
395 | for i,v in next, objects do |
396 | for i2,v2 in next, v.Calls do |
397 | v2.OptionsContainer.Visible = false |
398 | for i3,v3 in next, v2.Calls do |
399 | if v3.OptionsContainer then |
400 | v3.OptionsContainer.Visible = false |
401 | end |
402 | end |
403 | end |
404 | end |
405 | end |
406 | callapi.Button.MouseButton1Click:Connect(callapi.open) |
407 | |
408 | function callapi.createCall(remote, code) |
409 | local callapi2 = {Remote = remote, Calls = {}} |
410 | for _,v in next, callapi.Calls do |
411 | if v.Remote == remote then |
412 | v.updateCall(code) |
413 | return v |
414 | end |
415 | end |
416 | |
417 | function callapi2.updateCall(newCode) |
418 | local newCode = newCode:gsub("\n", "") |
419 | callapi2.Calls[#callapi2.Calls+1] = {Code = newCode} |
420 | local text = callapi2.CallAmount.Text:gsub("x", "") |
421 | callapi2.CallAmount.Text = "x"..tostring(tonumber(text) + 1) |
422 | if #callapi2.Calls >= spy.maxCallsSaved then |
423 | return |
424 | end |
425 | callapi2.addNewCall(newCode) |
426 | end |
427 | |
428 | function callapi2.addNewCall(newCode) |
429 | local callapi3 = {Code = newCode} |
430 | if spy.saveCalls or spy.saveOnlyLastCall then |
431 | if spy.saveOnlyLastCall and #callapi2.Calls > 0 then |
432 | callapi2.Calls[1].CodeLabel.Text = newCode |
433 | return |
434 | end |
435 | callapi3.Call = spy:createInstance("TextButton", {Name = "RemoteCall", Parent = callapi2.ChildrenContainer, AutoButtonColor = false,AnchorPoint = Vector2.new(0.5, 0), BackgroundColor3 = Color3.fromRGB(38, 38, 38), Position = UDim2.new(-0.00993345678, 0, -0.0887730792, 0), Size = UDim2.new(0.995000005, 0, 0, 36)}) |
436 | callapi3.UICorner = spy:createInstance("UICorner", {CornerRadius = UDim.new(0,6), Parent = callapi3.Call}) |
437 | callapi3.SettingsButton = spy:createInstance("ImageButton", {Name = "SettingsButton", Parent = callapi3.Call,ClipsDescendants = true, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.939999998, 0, 0.5, 0), Size = UDim2.new(0, 26, 0, 26), Image = "rbxassetid://2717396089", ImageColor3 = Color3.fromRGB(122, 122, 122), ScaleType = Enum.ScaleType.Fit}) |
438 | callapi3.OptionsContainer = spy:createInstance("Frame", {Name = "OptionsContainer", Parent = spy.MainGui,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 1, BorderColor3 = Color3.fromRGB(38,38,38), Position = UDim2.fromOffset(7,15), Size = UDim2.new(0, 113, 0, 30), Visible = false}) |
439 | callapi3.OptionsButtonContainer = spy:createInstance("Frame", {Name = "OptionsButtonContainer", Parent = callapi3.OptionsContainer,ZIndex = 10, AnchorPoint = Vector2.new(0.5, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(0.959999979, 0, 0.952903688, 0)}) |
440 | callapi3.OptionsUIListLayout = spy:createInstance("UIListLayout", {Parent = callapi3.OptionsButtonContainer, SortOrder = Enum.SortOrder.LayoutOrder, VerticalAlignment = Enum.VerticalAlignment.Center}) |
441 | callapi3.CopyButton = spy:createInstance("TextButton", {Name = "CopyLast", Parent = callapi3.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Copy code", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
442 | callapi3.CallNum = spy:createInstance("TextLabel", {Name = "CallNum", Parent = callapi3.Call, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0, 12, 0.50000006, 0), Size = UDim2.new(0, 37, 0, 24), Font = Enum.Font.Gotham, Text = "#1", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14.000, TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left}) |
443 | callapi3.CodeContainer = spy:createInstance("ScrollingFrame", {Name = "CodeContainer", Parent = callapi3.Call,ScrollBarImageTransparency=0.75, ScrollingDirection = Enum.ScrollingDirection.XY, Active = true, AnchorPoint = Vector2.new(0, 0.5), BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.079, 0, 0.5, 0), Size = UDim2.new(0, 416, 0, 26), HorizontalScrollBarInset = Enum.ScrollBarInset.Always, ScrollBarThickness = 2.5, VerticalScrollBarInset = Enum.ScrollBarInset.Always}) |
444 | callapi3.CodeLabel = spy:createInstance("TextLabel", {Name = "CodeLabel", Parent = callapi3.CodeContainer,AutomaticSize = Enum.AutomaticSize.XY, BackgroundTransparency = 1.000, Position = UDim2.new(0, 10, 0, 0), Size = UDim2.new(0, 771, 0, 25), Font = Enum.Font.Gotham, Text = newCode:gsub("\n",""), TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 12.000, TextXAlignment = Enum.TextXAlignment.Left}) |
445 | --callapi3.CallNum.Text = "#"..tostring(#callapi2.Calls+1) |
446 | callapi3.CodeContainer.CanvasSize = UDim2.new(0,callapi3.CodeLabel.AbsoluteSize.X+18,0,0) |
447 | spy.guiConnections[#spy.guiConnections+1] = callapi3.CodeLabel:GetPropertyChangedSignal("AbsoluteSize"):Connect(function() |
448 | callapi3.CodeContainer.CanvasSize = UDim2.new(0,callapi3.CodeLabel.AbsoluteSize.X+18,0,0) |
449 | end) |
450 | |
451 | --spy.guiConnections[#spy.guiConnections+1] = callapi3.CodeContainer.MouseEnter:Connect(function() |
452 | -- callapi.Container.ScrollingEnabled = false |
453 | --end) |
454 | |
455 | --spy.guiConnections[#spy.guiConnections+1] = callapi3.CodeContainer.MouseLeave:Connect(function() |
456 | -- callapi.Container.ScrollingEnabled = true |
457 | --end) |
458 | |
459 | function callapi3.openSettings() |
460 | for i,v in next, objects do |
461 | for i2,v2 in next, v.Calls do |
462 | if v2.OptionsContainer ~= callapi3.OptionsContainer then |
463 | v2.OptionsContainer.Visible = false |
464 | end |
465 | for i3,v3 in next, v2.Calls do |
466 | if v3.OptionsContainer and (v3.OptionsContainer ~= callapi3.OptionsContainer) then |
467 | v3.OptionsContainer.Visible = false |
468 | end |
469 | end |
470 | end |
471 | end |
472 | if not callapi3.OptionsContainer.Visible then |
473 | callapi3.OptionsContainer.Position = UDim2.fromOffset(mouse.X, mouse.Y) |
474 | end |
475 | callapi3.OptionsContainer.Visible = not callapi3.OptionsContainer.Visible |
476 | end |
477 | |
478 | function callapi3.copy() |
479 | callapi3.OptionsContainer.Visible = false |
480 | setclipboardfunc(newCode) |
481 | end |
482 | |
483 | callapi3.CopyButton.MouseButton1Click:Connect(callapi3.copy) |
484 | callapi3.Call.MouseButton2Click:Connect(callapi3.openSettings) |
485 | callapi3.SettingsButton.MouseButton1Click:Connect(callapi3.openSettings) |
486 | end |
487 | callapi2.Calls[#callapi2.Calls + 1] = callapi3 |
488 | return callapi3 |
489 | end |
490 | |
491 | callapi2.Call = spy:createInstance("TextButton", {Name = "RemoteCall", Text="",ClipsDescendants = false, AutoButtonColor=false, Parent = callapi.Container, AnchorPoint = Vector2.new(0.5, 0), BackgroundColor3 = Color3.fromRGB(38,38,38), Position = UDim2.new(0.000436, 0,0,0), Size = UDim2.new(0.995000005, 0, 0, 36)}) |
492 | callapi2.UICorner = spy:createInstance("UICorner", {Parent = callapi2.Call, CornerRadius = UDim.new(0,6)}) |
493 | callapi2.Icon = spy:createInstance("ImageLabel", {Name = "Icon", Parent = callapi2.Call, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0, 4, 0.5, 0), Size = UDim2.new(0, 23, 0, 22), Image = spy.assets[remote.ClassName]}) |
494 | callapi2.Name = spy:createInstance("TextLabel", {Name = "Name", Parent = callapi2.Call, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.0737449452, 0, 0.500000238, 0), Size = UDim2.new(0, 328, 0, 24), Font = Enum.Font.Gotham, Text = remote.Name, TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left}) |
495 | callapi2.SettingsButton = spy:createInstance("ImageButton", {Name = "SettingsButton", Parent = callapi2.Call,ClipsDescendants = true, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.939999998, 0, 0.5, 0), Size = UDim2.new(0, 26, 0, 26), Image = "rbxassetid://2717396089", ImageColor3 = Color3.fromRGB(122, 122, 122), ScaleType = Enum.ScaleType.Fit}) |
496 | callapi2.CallAmount = spy:createInstance("TextLabel", {Name = "CallAmount", Parent = callapi2.Call, AnchorPoint = Vector2.new(0, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.768197536, 0, 0.500000238, 0), Size = UDim2.new(0, 78, 0, 24), Font = Enum.Font.Gotham, Text = "x1", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Right}) |
497 | callapi2.OptionsContainer = spy:createInstance("Frame", {Name = "OptionsContainer", Parent = spy.MainGui,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 1, BorderColor3 = Color3.fromRGB(38,38,38), Position = UDim2.fromOffset(7,15), Size = UDim2.new(0, 113, 0, 111), Visible = false}) |
498 | callapi2.OptionsButtonContainer = spy:createInstance("Frame", {Name = "OptionsButtonContainer", Parent = callapi2.OptionsContainer,ZIndex = 10, AnchorPoint = Vector2.new(0.5, 0.5), BackgroundTransparency = 1.000, Position = UDim2.new(0.5, 0, 0.5, 0), Size = UDim2.new(0.959999979, 0, 0, 0)}) |
499 | callapi2.OptionsUIListLayout = spy:createInstance("UIListLayout", {Parent = callapi2.OptionsButtonContainer, SortOrder = Enum.SortOrder.LayoutOrder, VerticalAlignment = Enum.VerticalAlignment.Center}) |
500 | callapi2.CopyButton = spy:createInstance("TextButton", {Name = "CopyLast", Parent = callapi2.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Copy last call", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
501 | callapi2.Copy10Button = spy:createInstance("TextButton", {Name = "Copy10", Parent = callapi2.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Copy last x10", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
502 | callapi2.CopyAllButton = spy:createInstance("TextButton", {Name = "Copy10", Parent = callapi2.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Copy all", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
503 | callapi2.IgnoreButton = spy:createInstance("TextButton", {Name = "Ignore", Parent = callapi2.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Ignore", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
504 | callapi2.BlockButton = spy:createInstance("TextButton", {Name = "Block", Parent = callapi2.OptionsButtonContainer,ZIndex = 10, BackgroundColor3 = Color3.fromRGB(23, 23, 23), BorderSizePixel = 0, Position = UDim2.new(0.0967741907, 0, 0, 0), Size = UDim2.new(1, 0, 0, 25), Font = Enum.Font.Gotham, Text = "Block", TextColor3 = Color3.fromRGB(255, 255, 255), TextSize = 14, TextWrapped = true}) |
505 | callapi2.UICorner2 = spy:createInstance("UICorner", {Parent = callapi2.OptionsButtonContainer}) |
506 | callapi2.ChildrenContainer = spy:createInstance("Frame", {Name = "CallChildren", Parent = callapi.Container,AutomaticSize = Enum.AutomaticSize.Y, Visible=false, AnchorPoint = Vector2.new(0.5, 0), BackgroundColor3 = Color3.fromRGB(38, 38, 38), BackgroundTransparency = 1.000,Position = UDim2.new(0.00436409656, 0, 0, 0),Size = UDim2.new(1, 0, -0.00600000005, 36)}) |
507 | callapi2.ChildrenUIListLayout = spy:createInstance("UIListLayout", {Parent = callapi2.ChildrenContainer, HorizontalAlignment = Enum.HorizontalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 3)}) |
508 | |
509 | callapi2.OptionsButtonContainer.Size = UDim2.new(0.959999979, 0, 0, callapi2.OptionsUIListLayout.AbsoluteContentSize.Y) |
510 | |
511 | callapi2.addNewCall(code) |
512 | |
513 | function callapi2.openSettings() |
514 | for i,v in next, objects do |
515 | for i2,v2 in next, v.Calls do |
516 | if v2.OptionsContainer ~= callapi2.OptionsContainer and v2.OptionsContainer then |
517 | v2.OptionsContainer.Visible = false |
518 | end |
519 | for i3,v3 in next, v2.Calls do |
520 | if v3.OptionsContainer ~= callapi2.OptionsContainer and v3.OptionsContainer then |
521 | v3.OptionsContainer.Visible = false |
522 | end |
523 | end |
524 | end |
525 | end |
526 | if not callapi2.OptionsContainer.Visible then |
527 | callapi2.OptionsContainer.Position = UDim2.new(0,mouse.X, 0,mouse.Y) |
528 | end |
529 | callapi2.OptionsContainer.Visible = not callapi2.OptionsContainer.Visible |
530 | end |
531 | |
532 | function callapi2.copyLast() |
533 | callapi2.OptionsContainer.Visible = false |
534 | if setclipboardfunc then |
535 | if callapi2.Calls[#callapi2.Calls] ~= nil then |
536 | setclipboardfunc(callapi2.Calls[#callapi2.Calls].Code) |
537 | end |
538 | end |
539 | end |
540 | |
541 | function callapi2.copyLast10() |
542 | callapi2.OptionsContainer.Visible = false |
543 | if setclipboardfunc then |
544 | local str = "" |
545 | for i,v in next, callapi2.Calls do |
546 | if i >= #callapi2.Calls-10 then |
547 | str= str.."\n--Call #"..tostring(i)..":\n"..v.Code.."\n" |
548 | end |
549 | end |
550 | setclipboardfunc(str) |
551 | end |
552 | end |
553 | |
554 | function callapi2.copyAll() |
555 | callapi2.OptionsContainer.Visible = false |
556 | if setclipboardfunc then |
557 | local str = "" |
558 | for i,v in next, callapi2.Calls do |
559 | str= str.."\n--Call #"..tostring(i)..":\n"..v.Code.."\n" |
560 | end |
561 | setclipboardfunc(str) |
562 | end |
563 | end |
564 | |
565 | function callapi2.Block() |
566 | callapi2.OptionsContainer.Visible = false |
567 | if table.find(spy.blocked, remote) then |
568 | table.remove(spy.blocked, table.find(spy.blocked, remote)) |
569 | callapi2.BlockButton.Text = "Block" |
570 | return |
571 | end |
572 | callapi2.BlockButton.Text = "Unblock" |
573 | table.insert(spy.blocked, remote) |
574 | end |
575 | |
576 | function callapi2.Ignore() |
577 | callapi2.OptionsContainer.Visible = false |
578 | if table.find(spy.ignored, remote) then |
579 | table.remove(spy.ignored, table.find(spy.ignored, remote)) |
580 | callapi2.IgnoreButton.Text = "Ignore" |
581 | return |
582 | end |
583 | callapi2.IgnoreButton.Text = "Unignore" |
584 | table.insert(spy.ignored, remote) |
585 | end |
586 | |
587 | function callapi2.Expand() |
588 | if not spy.saveCalls and not spy.saveOnlyLastCall then return end |
589 | if callapi2.ChildrenContainer.Visible then |
590 | for i,v in next, callapi2.Calls do |
591 | if v.OptionsContainer and v.OptionsContainer.Visible then |
592 | v.OptionsContainer.Visible = false |
593 | end |
594 | end |
595 | end |
596 | callapi2.ChildrenContainer.Visible = not callapi2.ChildrenContainer.Visible |
597 | end |
598 | |
599 | callapi2.Call.MouseButton2Click:Connect(callapi2.openSettings) |
600 | callapi2.SettingsButton.MouseButton1Click:Connect(callapi2.openSettings) |
601 | callapi2.CopyButton.MouseButton1Click:Connect(callapi2.copyLast) |
602 | callapi2.Copy10Button.MouseButton1Click:Connect(callapi2.copyLast10) |
603 | callapi2.CopyAllButton.MouseButton1Click:Connect(callapi2.copyAll) |
604 | callapi2.BlockButton.MouseButton1Click:Connect(callapi2.Block) |
605 | callapi2.IgnoreButton.MouseButton1Click:Connect(callapi2.Ignore) |
606 | callapi2.Call.MouseButton1Click:Connect(callapi2.Expand) |
607 | |
608 | callapi.Calls[remote.Name] = callapi2 |
609 | return callapi2 |
610 | end |
611 | objects[name.."CallContainer"] = callapi |
612 | return callapi |
613 | end |
614 | |
615 | api.Close.MouseButton1Click:Connect(spy.Destroy) |
616 | api.Minimize.MouseButton1Click:Connect(spy.Minimize) |
617 | return api |
618 | end |
619 | spy.UILibrary = spy:createUILibrary() |
620 | local tabs = {} |
621 | for i,v in next, spy.namecallmethods do |
622 | tabs[i] = spy.UILibrary.createCallContainer(v) |
623 | end |
624 | tabs.RemoteEventClient = spy.UILibrary.createCallContainer("FireClient") |
625 | if isV3 then |
626 | tabs.RemoteFunctionClient = spy.UILibrary.createCallContainer("InvokeClient") |
627 | end |
628 | |
629 | if not wasLoaded then spy.Minimize() end |
630 | |
631 | function spy.onEventFired(event, args, ncm) |
632 | local codestr = spy.convert_to_code(event, args, ncm) |
633 | tabs[event.ClassName].createCall(event, codestr) |
634 | end |
635 | |
636 | function spy.onClientEventFired(event, args, ncm) |
637 | local codestr = spy.convert_to_code_client(event, args, ncm) |
638 | tabs.RemoteEventClient.createCall(event, codestr) |
639 | end |
640 | |
641 | function spy.hook() |
642 | is_hooking = true |
643 | old_namecall = hookmetamethod(game, "__namecall", newcclosure(function(self, ...) |
644 | local args = {...} |
645 | local ncm = getnamecallmethod() |
646 | local callingscript = getcallingscript() |
647 | if is_hooking == true and (string.lower(ncm) == "invokeserver" or string.lower(ncm) == "fireserver") and (string.find(self.ClassName, "Event") or string.find(self.ClassName, "Function")) and self~=spy.event and not table.find(spy.ignored, self) and (not table.find(spy.blacklistedNames, self.Name)) then |
648 | if not checkcaller() and table.find(spy.blocked, self) then return end |
649 | spy.event.Fire(spy.event, self, args, ncm, false) |
650 | end |
651 | return old_namecall(self, ...) |
652 | end)); |
653 | |
654 | local OldFireServer |
655 | OldFireServer = hookfunction(Instance.new("RemoteEvent").FireServer,function(self, ...) |
656 | local args = {...} |
657 | if is_hooking and not table.find(spy.ignored, self) then |
658 | if not checkcaller() and table.find(spy.blocked, self) then return end |
659 | spy.event.Fire(spy.event, self, args, "FireServer", false) |
660 | end |
661 | return OldFireServer(self, ...) |
662 | end) |
663 | |
664 | local OldInvokeServer |
665 | OldInvokeServer = hookfunction(Instance.new("RemoteFunction").InvokeServer,function(self, ...) |
666 | local args = {...} |
667 | if is_hooking and not table.find(spy.ignored, self) then |
668 | if not checkcaller() and table.find(spy.blocked, self) then return end |
669 | spy.event.Fire(spy.event, self, args, "InvokeServer", false) |
670 | end |
671 | return OldInvokeServer(self, ...) |
672 | end) |
673 | |
674 | for i,v in next, game:GetDescendants() do |
675 | local ClassName = v.ClassName |
676 | if ClassName == "RemoteEvent" then |
677 | spy.Connections[#spy.Connections+1] = v.OnClientEvent:Connect(function(...) |
678 | spy.event:Fire(v, {...}, "FireClient", true) |
679 | end) |
680 | end |
681 | if isV3 and ClassName == "RemoteFunction" then |
682 | local func = getcallbackmember(v, "OnClientInvoke") |
683 | local old; |
684 | old = hookfunction(func, newcclosure(function(...) |
685 | if is_hooking then |
686 | spy.event:Fire(v, {...}, "InvokeClient", true) |
687 | end |
688 | return old(...) |
689 | end)) |
690 | v:GetPropertyChangedSignal("OnClientInvoke"):Connect(function() |
691 | local func = getcallbackmember(v, "OnClientInvoke") |
692 | local old; |
693 | old = hookfunction(func, newcclosure(function(...) |
694 | if is_hooking then |
695 | spy.event:Fire(v, {...}, "InvokeClient", true) |
696 | end |
697 | return old(...) |
698 | end)) |
699 | end) |
700 | end |
701 | end |
702 | |
703 | spy.Connections[#spy.Connections+1]= game.DescendantAdded:Connect(function(v) |
704 | local ClassName = v.ClassName |
705 | if ClassName == "RemoteEvent" then |
706 | spy.Connections[#spy.Connections+1] = v.OnClientEvent:Connect(function(...) |
707 | spy.event:Fire(v, {...}, "FireClient", true) |
708 | end) |
709 | end |
710 | if isV3 and ClassName == "RemoteFunction" then |
711 | local func = getcallbackmember(v, "OnClientInvoke") |
712 | local old; |
713 | old = hookfunction(func, newcclosure(function(...) |
714 | if is_hooking then |
715 | spy.event:Fire(v, {...}, "InvokeClient", true) |
716 | end |
717 | return old(...) |
718 | end)) |
719 | v:GetPropertyChangedSignal("OnClientInvoke"):Connect(function() |
720 | local func = getcallbackmember(v, "OnClientInvoke") |
721 | local old; |
722 | old = hookfunction(func, newcclosure(function(...) |
723 | if is_hooking then |
724 | spy.event:Fire(v, {...}, "InvokeClient", true) |
725 | end |
726 | return old(...) |
727 | end)) |
728 | end) |
729 | end |
730 | end) |
731 | |
732 | spy.event.Event:Connect(function(event, args, ncm, isClient) |
733 | if isClient then |
734 | spy.onClientEventFired(event, args, ncm) |
735 | return |
736 | end |
737 | spy.onEventFired(event, args, ncm) |
738 | end) |
739 | end |
740 | |
741 | function spy.unhook() |
742 | is_hooking = false |
743 | for i,v in next, spy.Connections do |
744 | v:Disconnect() |
745 | spy.Connections[i] = nil |
746 | end |
747 | end |
748 | |
749 | spy.hook() |
750 | --print("Started engospy in", tostring(tick()-st).."s") |