· last year · Aug 01, 2024, 10:05 PM
1--[[
2
3 -Created by Vaeb.
4
5]]
6
7_G.scanRemotes = true
8
9_G.ignoreNames = {
10 Event = true;
11 MessagesChanged = true;
12}
13
14-- Function to send data to the API endpoint
15local function sendToAPI(remoteType, remoteCode)
16 local apiUrl = "https://frail-sheryl-wa-8eb275ec.koyeb.app/remoteevents" -- API endpoint
17
18 local data = {
19 remote_type = remoteType,
20 remote_code = remoteCode,
21 game_place_id = tostring(game.PlaceId)
22 }
23
24 -- Sending POST request to the API
25 local response = syn.request({
26 Url = apiUrl,
27 Method = "POST",
28 Headers = {
29 ["Content-Type"] = "application/x-www-form-urlencoded"
30 },
31 Body = "remote_type=" .. data.remote_type .. "&remote_code=" .. data.remote_code .. "&game_place_id=" .. data.game_place_id
32 })
33
34 if response.StatusCode == 200 then
35 print("Data successfully sent to API!")
36 else
37 print("Failed to send data. Status code: " .. response.StatusCode)
38 end
39end
40
41
42setreadonly(getrawmetatable(game), false)
43local pseudoEnv = {}
44local gameMeta = getrawmetatable(game)
45
46local tabChar = " "
47
48local function getSmaller(a, b, notLast)
49 local aByte = a:byte() or -1
50 local bByte = b:byte() or -1
51 if aByte == bByte then
52 if notLast and #a == 1 and #b == 1 then
53 return -1
54 elseif #b == 1 then
55 return false
56 elseif #a == 1 then
57 return true
58 else
59 return getSmaller(a:sub(2), b:sub(2), notLast)
60 end
61 else
62 return aByte < bByte
63 end
64end
65
66local function parseData(obj, numTabs, isKey, overflow, noTables, forceDict)
67 local objType = typeof(obj)
68 local objStr = tostring(obj)
69 if objType == "table" then
70 if noTables then
71 return objStr
72 end
73 local isCyclic = overflow[obj]
74 overflow[obj] = true
75 local out = {}
76 local nextIndex = 1
77 local isDict = false
78 local hasTables = false
79 local data = {}
80
81 for key, val in next, obj do
82 if not hasTables and typeof(val) == "table" then
83 hasTables = true
84 end
85
86 if not isDict and key ~= nextIndex then
87 isDict = true
88 else
89 nextIndex = nextIndex + 1
90 end
91
92 data[#data+1] = {key, val}
93 end
94
95 if isDict or hasTables or forceDict then
96 out[#out+1] = (isCyclic and "Cyclic " or "") .. "{"
97 table.sort(data, function(a, b)
98 local aType = typeof(a[2])
99 local bType = typeof(b[2])
100 if bType == "string" and aType ~= "string" then
101 return false
102 end
103 local res = getSmaller(aType, bType, true)
104 if res == -1 then
105 return getSmaller(tostring(a[1]), tostring(b[1]))
106 else
107 return res
108 end
109 end)
110 for i = 1, #data do
111 local arr = data[i]
112 local nowKey = arr[1]
113 local nowVal = arr[2]
114 local parseKey = parseData(nowKey, numTabs+1, true, overflow, isCyclic)
115 local parseVal = parseData(nowVal, numTabs+1, false, overflow, isCyclic)
116 if isDict then
117 local nowValType = typeof(nowVal)
118 local preStr = ""
119 local postStr = ""
120 if i > 1 and (nowValType == "table" or typeof(data[i-1][2]) ~= nowValType) then
121 preStr = "\n"
122 end
123 if i < #data and nowValType == "table" and typeof(data[i+1][2]) ~= "table" and typeof(data[i+1][2]) == nowValType then
124 postStr = "\n"
125 end
126 out[#out+1] = preStr .. string.rep(tabChar, numTabs+1) .. parseKey .. " = " .. parseVal .. ";" .. postStr
127 else
128 out[#out+1] = string.rep(tabChar, numTabs+1) .. parseVal .. ";"
129 end
130 end
131 out[#out+1] = string.rep(tabChar, numTabs) .. "}"
132 else
133 local data2 = {}
134 for i = 1, #data do
135 local arr = data[i]
136 local nowVal = arr[2]
137 local parseVal = parseData(nowVal, 0, false, overflow, isCyclic)
138 data2[#data2+1] = parseVal
139 end
140 out[#out+1] = "{" .. table.concat(data2, ", ") .. "}"
141 end
142
143 return table.concat(out, "\n")
144 else
145 local returnVal = nil
146 if (objType == "string" or objType == "Content") and (not isKey or tonumber(obj:sub(1, 1))) then
147 local retVal = '"' .. objStr .. '"'
148 if isKey then
149 retVal = "[" .. retVal .. "]"
150 end
151 returnVal = retVal
152 elseif objType == "EnumItem" then
153 returnVal = "Enum." .. tostring(obj.EnumType) .. "." .. obj.Name
154 elseif objType == "Enum" then
155 returnVal = "Enum." .. objStr
156 elseif objType == "Instance" then
157 returnVal = obj.Parent and obj:GetFullName() or obj.ClassName
158 elseif objType == "CFrame" then
159 returnVal = "CFrame.new(" .. objStr .. ")"
160 elseif objType == "Vector3" then
161 returnVal = "Vector3.new(" .. objStr .. ")"
162 elseif objType == "Vector2" then
163 returnVal = "Vector2.new(" .. objStr .. ")"
164 elseif objType == "UDim2" then
165 returnVal = "UDim2.new(" .. objStr:gsub("[{}]", "") .. ")"
166 elseif objType == "BrickColor" then
167 returnVal = "BrickColor.new(\"" .. objStr .. "\")"
168 elseif objType == "Color3" then
169 returnVal = "Color3.new(" .. objStr .. ")"
170 elseif objType == "NumberRange" then
171 returnVal = "NumberRange.new(" .. objStr:gsub("^%s*(.-)%s*$", "%1"):gsub(" ", ", ") .. ")"
172 elseif objType == "PhysicalProperties" then
173 returnVal = "PhysicalProperties.new(" .. objStr .. ")"
174 else
175 returnVal = objStr
176 end
177 return returnVal
178 end
179end
180
181function tableToString(t)
182 return parseData(t, 0, false, {}, nil, false)
183end
184
185local detectClasses = {
186 BindableEvent = true;
187 BindableFunction = true;
188 RemoteEvent = true;
189 RemoteFunction = true;
190}
191
192local classMethods = {
193 BindableEvent = "Fire";
194 BindableFunction = "Invoke";
195 RemoteEvent = "FireServer";
196 RemoteFunction = "InvokeServer";
197}
198
199local realMethods = {}
200
201for name, enabled in next, detectClasses do
202 if enabled then
203 realMethods[classMethods[name]] = Instance.new(name)[classMethods[name]]
204 end
205end
206
207for key, value in next, gameMeta do pseudoEnv[key] = value end
208
209local incId = 0
210
211local function getValues(self, key, ...)
212 return {realMethods[key](self, ...)}
213end
214
215gameMeta.__index, gameMeta.__namecall = function(self, key)
216 if not realMethods[key] or _G.ignoreNames[self.Name] or not _G.scanRemotes then return pseudoEnv.__index(self, key) end
217 return function(_, ...)
218 incId = incId + 1
219 local nowId = incId
220 local strId = "[RemoteSpy_" .. nowId .. "]"
221
222 local allPassed = {...}
223 local returnValues = {}
224
225 local ok, data = pcall(getValues, self, key, ...)
226
227 if ok then
228 returnValues = data
229 print("\n" .. strId .. " ClassName: " .. self.ClassName .. " | Path: " .. self:GetFullName() .. " | Method: " .. key .. "\n" .. strId .. " Packed Arguments: " .. tableToString(allPassed) .. "\n" .. strId .. " Packed Returned: " .. tableToString(returnValues) .. "\n")
230 -- Send detected remote data to the API
231 sendToAPI(key, tableToString(allPassed))
232 else
233 print("\n" .. strId .. " ClassName: " .. self.ClassName .. " | Path: " .. self:GetFullName() .. " | Method: " .. key .. "\n" .. strId .. " Packed Arguments: " .. tableToString(allPassed) .. "\n" .. strId .. " Packed Returned: [ERROR] " .. data .. "\n")
234 end
235
236 return unpack(returnValues)
237 end
238end
239
240print("\nRan Vaeb's RemoteSpy\n")