Advertisement
wA11

wt_spy

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