1 | local Numbers = {} |
2 | local Properties = {} |
3 | local HttpService = game:GetService('HttpService'); |
4 | function keyF(a) |
5 | return typeof(a) == 'number' and ('[%d] = '):format(a) or ('[\'%s\'] = '):format(tostring(a)) |
6 | end |
7 | function keyE(a, b) |
8 | if typeof(b):lower() == 'instance' then |
9 | return b.Name:gsub(' ', '_') |
10 | elseif typeof(b) == 'boolean' then return 'bool' .. tostring(a) elseif typeof(b) == 'string' then return 'str' .. tostring(a) elseif typeof(b) == 'number' then return 'num' .. tostring(a) elseif typeof(b) == 'table' then return 'tbl' .. tostring(a) else return typeof(b) .. tostring(a) end |
11 | end |
12 | function rnum(min, max) |
13 | local a; |
14 | repeat a = math.random(min, max) until not table.find(Numbers, a) |
15 | table.insert(Numbers, a) |
16 | return a |
17 | end |
18 | local _RENV = getrenv() |
19 | function inrenv(func) |
20 | name = typeof(func) == 'string' and func or typeof(func) == 'function' and debug.getinfo(func).name |
21 | for i, v in _RENV do |
22 | if typeof(v) == 'function' then |
23 | if i == name then return true end |
24 | end |
25 | end |
26 | return false |
27 | end |
28 | function buffermain(buff, indent, identifier) |
29 | identifier = tostring(identifier) |
30 | local str = 'buffer.create(' .. tostring(buffer.len(buff)) .. ');' |
31 | for i = 1, buffer.len(buff) - 1 do |
32 | local a = buffer.readi8(buff, i) |
33 | if a ~= 0 then -- null (empty cell) |
34 | local e = '' |
35 | pcall(function() |
36 | e = string.char(a) |
37 | end) |
38 | str = str .. ('\n%sbuffer.writei8(%s, %d, %d) --[[ Can possibly be \'%s\' ]]'):format(string.rep(' ', indent), identifier, i, a, a ~= 10 and e or '\\n') |
39 | end |
40 | end |
41 | return str |
42 | end |
43 | function GetFullName(instance) |
44 | local p = instance |
45 | local lo = {} |
46 | while (p ~= game and p.Parent ~= nil) do |
47 | table.insert(lo, p) |
48 | p = p.Parent |
49 | end |
50 | local fullName |
51 | if #lo == 0 then |
52 | return "nil --[[ PARENTED TO NIL OR DESTROYED ]]" |
53 | end |
54 | if lo[#lo].ClassName ~= "Workspace" then |
55 | fullName = 'game:GetService("' .. lo[#lo].ClassName .. '")' |
56 | else |
57 | fullName = "workspace" |
58 | end |
59 | for i = #lo - 1, 1, -1 do |
60 | fullName = fullName .. ':FindFirstChild("' .. lo[i].Name .. '")' |
61 | end |
62 | return fullName |
63 | end |
64 | function tableloop(tbl, indent, equal, meta) |
65 | meta = meta or 0 |
66 | indent = indent or 0 |
67 | local result = (not equal and string.rep(' ', indent) or '') .. '{' |
68 | equal = false |
69 | if typeof(tbl) ~= 'table' then return HandleDatatype(tbl, indent) end |
70 | local _AM = 0 |
71 | for key, value in pairs(tbl) do |
72 | _AM += 1 |
73 | if typeof(value) == 'table' then |
74 | if getrawmetatable(value) then |
75 | result = result .. string.rep(' ', indent) .. 'local meta' .. (meta ~= 0 and tostring(meta) or '') .. ' = ' .. tableloop(getrawmetatable(value), indent, true, meta+1) |
76 | meta+=1 |
77 | else |
78 | result = result .. '\n' .. (not equal and string.rep(' ', indent + 1) or '') .. keyF(key) .. tableloop(value, indent + 1, true, meta) |
79 | end |
80 | else |
81 | result = result .. '\n' .. (not equal and string.rep(' ', indent + 1) or '') .. keyF(key) .. HandleDatatype(value, indent + 1, keyE(key, value)) .. ';' |
82 | end |
83 | end |
84 | return _AM > 0 and (result .. '\n' .. string.rep(' ', indent) .. '}') or '{}' |
85 | end |
86 | |
87 | function HandleDatatype(data, indent, identifier) |
88 | local dataType = typeof(data) |
89 | local constructors = { |
90 | ['string'] = function(data) return "'" .. data .. "'" end, |
91 | ['table'] = function(data) return tableloop(data, indent and indent + 1 or 1, identifier and true or false) end, |
92 | ['function'] = function(data) return DecompileFunction(data, indent, false, true) end, |
93 | ['number'] = function(data) return tostring(data) end, |
94 | ['Vector3'] = function(data) return string.format("Vector3.new(%f, %f, %f)", data.X, data.Y, data.Z) end, |
95 | ['Vector2'] = function(data) return string.format("Vector2.new(%f, %f)", data.X, data.Y) end, |
96 | ['UDim'] = function(data) return string.format("UDim.new(%f, %f)", data.Scale, data.Offset) end, |
97 | ['UDim2'] = function(data) return string.format("UDim2.new(%f, %f, %f, %f)", data.X.Scale, data.X.Offset, data.Y.Scale, data.Y.Offset) end, |
98 | ['CFrame'] = function(data) local components = {data:GetComponents()} return string.format("CFrame.new(%s)", table.concat(components, ", ")) end, |
99 | ['Color3'] = function(data) return string.format("Color3.fromRGB(%d, %d, %d)", math.floor(data.R * 255), math.floor(data.G * 255), math.floor(data.B * 255)) end, |
100 | ['BrickColor'] = function(data) return string.format("BrickColor.new('%s')", tostring(data)) end, |
101 | ['Enum'] = function(data) return string.format("%s", tostring(data)) end, |
102 | ['EnumItem'] = function(data) return string.format("%s", tostring(data)) end, |
103 | ['Instance'] = function(data) return ('%s'):format(GetFullName(data)) end, |
104 | ['buffer'] = function(data) return buffermain(data, indent, identifier) end, |
105 | ['boolean'] = function(data) return tostring(data) end |
106 | } |
107 | if constructors[dataType] then |
108 | return constructors[dataType](data) |
109 | else |
110 | return tostring(typeof(data)) .. '.new(' .. tostring(data) .. ')' |
111 | end |
112 | end |
113 | function gcsenv(Scr) |
114 | local funcs = {} |
115 | for i, v in next, getgc(true) do |
116 | if (typeof(v) == "function" and islclosure(v) and getfenv(v).script == Scr and not table.find(funcs, v)) then |
117 | table.insert(funcs, v) |
118 | task.wait() |
119 | end |
120 | end |
121 | return funcs |
122 | end |
123 | function DecompileFunction(TargetFunc, indent, IsProto, ExcludeName, equal) |
124 | indent = indent or 0 |
125 | equal = not equal and ExcludeName or equal |
126 | local paramcount = debug.getinfo(TargetFunc).numparams |
127 | local vararg = debug.getinfo(TargetFunc).is_vararg |
128 | local function GetArgs() |
129 | local n, o = '(', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
130 | for i = 1, paramcount do |
131 | n = n .. o:sub(i, i) |
132 | if i < paramcount and not (i + 1 == #o or i + 1 > #o) then |
133 | n = n .. ', ' |
134 | end |
135 | end |
136 | return n .. ')' |
137 | end |
138 | local func = {} |
139 | local Body = (not equal and string.rep(' ', indent) or '') .. (IsProto and 'local ' or '') ..'function' |
140 | local name1 = debug.getinfo(TargetFunc).name or (IsProto and 'proto_' .. tostring(rnum(1,99)) or ('NO_NAME_FOUND' .. tostring(rnum(1, 9999)))) |
141 | local Name = not ExcludeName and (' ' .. name1) or '' |
142 | local ArgsBody = (vararg == 1 and '(...)') or GetArgs() |
143 | local _1, Upvalues = pcall(getupvalues, TargetFunc) |
144 | local _2, Constants = pcall(getconstants, TargetFunc) |
145 | local _3, Protos = pcall(getprotos, TargetFunc) |
146 | if not _1 then Upvalues = {'failed to get upvalues.'} end |
147 | if not _2 then Constants = {'failed to get constants.'} end |
148 | if not _3 then Protos = {'failed to get protos.'} end |
149 | func.ENV = getfenv(TargetFunc) |
150 | func._G = func.ENV._G |
151 | indent+=1 |
152 | Body = Body .. Name .. ArgsBody .. '\n' |
153 | local Found, Found1 = string.rep(' ', indent) .. '--[[ ROBLOX FUNCTIONS LIST\n', 0 |
154 | for i, v in Constants do |
155 | if inrenv(v) then |
156 | Found1+=1 |
157 | Found = Found .. string.rep(' ', indent+1) .. tostring(debug.getinfo(v).name) .. ' at index ' .. tostring(i) .. '\n' |
158 | end |
159 | end |
160 | Body = (Found1 > 0 and Body .. Found .. string.rep(' ', indent-1) .. ' ]]\n') or Body |
161 | Body = Body .. string.rep(' ', indent) .. 'local upvalues = ' .. tableloop(Upvalues, indent, true) .. '\n' |
162 | Body = Body .. string.rep(' ', indent) .. 'local constants = ' .. tableloop(Constants, indent, true) .. '\n' |
163 | for i, v in Protos do |
164 | if typeof(v) == 'function' then |
165 | Body = Body .. DecompileFunction(v, indent, true, ExcludeName) .. '\n' |
166 | end |
167 | end |
168 | return Body .. string.rep(' ', indent-1) .. 'end', func._G |
169 | end |
170 | function DecompileScript(Script) |
171 | local Code = '--[[ DECOMPILED WITH SIMPLEDECOMPILE V2\nhttps://discord.gg/gYhqMRBeZV ]]\nlocal script = ' .. GetFullName(Script) .. '\n' |
172 | local _g, _s = nil, nil; |
173 | for i, v in gcsenv(Script) do |
174 | if typeof(v) == 'function' then |
175 | local source, g = DecompileFunction(v, 0, false, false) |
176 | if not _g then |
177 | _g = g |
178 | Code = Code .. '_G = ' .. tableloop(_g, 0, true) .. '\n' |
179 | end |
180 | Code = Code .. source .. '\n' |
181 | elseif typeof(v) == 'table' and i ~= '_G' and i ~= 'shared' then |
182 | Code = Code .. tableloop(v, 0, false) .. '\n' |
183 | end |
184 | end |
185 | return Code |
186 | end |
187 | getgenv().decompile = DecompileScript |
188 | getgenv().Decompile = DecompileScript |
189 | return DecompileScript |