Advertisement
Burkino

Synapse Save Map

Jan 14th, 2018
6,901
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.80 KB | None | 0 0
  1. local Classes; -- Author @Rerumu <3
  2. local Props = {};
  3. local Concat = table.concat; -- Concatenation is going to get reworked just a couple times maybe?
  4. local tostring = tostring;
  5. local Players = game:GetService('Players');
  6. local Beat = game:GetService('RunService').Heartbeat;
  7.  
  8. -- Changelog
  9. --[[
  10. * Whatever version this is
  11. -- Did some concatenation changes
  12. -- Also some other minor performance upgrades
  13. --- Synapse and Elysian individual support
  14. ---- Re-did Elysian callback stuff because it was slow
  15. ---- Added an Elysian fallback to LuaDec whenever needed
  16. ]]
  17.  
  18. local InNil;
  19. local Print;
  20. local WritesFl;
  21. local Decompile;
  22.  
  23. local NotFilter = (not workspace.FilteringEnabled); -- Bytecode used to replicate lol
  24. local SaveList = {
  25. game:GetService('Workspace');
  26. game:GetService('ReplicatedFirst');
  27. game:GetService('ReplicatedStorage');
  28. game:GetService('ServerStorage'); -- Internal stuff
  29. game:GetService('Lighting');
  30. game:GetService('StarterGui');
  31. game:GetService('StarterPack');
  32. game:GetService('StarterPlayer');
  33. game:GetService('Teams');
  34. game:GetService('InsertService');
  35. };
  36.  
  37. local IgnoredList = {
  38. 'CameraScript';
  39. 'ControlScript';
  40. 'ChatScript';
  41. 'Camera';
  42. }
  43.  
  44. local NoNoProp = {
  45. Instance = {
  46. Archivable = true,
  47. DataCost = true,
  48. ClassName = true,
  49. RobloxLocked = true,
  50. Parent = true
  51. };
  52. BasePart = {
  53. Position = true,
  54. Rotation = true
  55. };
  56. };
  57.  
  58. for Idx = 1, 3 do
  59. local Ran, Err = ypcall(function()
  60. Classes = game:HttpGetAsync('http://anaminus.github.io/rbx/json/api/latest.json');
  61. -- Classes = game:GetService('HttpService'):GetAsync('http://anaminus.github.io/rbx/json/api/latest.json');
  62. end);
  63.  
  64. if (not Ran) then
  65. if (Idx == 3) then
  66. error(Err, 0);
  67. else
  68. wait(1);
  69. end;
  70. else -- Setup stuff
  71. local Me = Players.LocalPlayer;
  72.  
  73. for _, Player in next, Players:GetPlayers() do
  74. if (Player ~= Me) then
  75. table.insert(IgnoredList, tostring(Player)); -- Let's *not*
  76. end;
  77. end;
  78.  
  79. local NumIg = #IgnoredList;
  80.  
  81. Classes = game:GetService('HttpService'):JSONDecode(Classes);
  82.  
  83. for Idx = 1, NumIg do
  84. IgnoredList[IgnoredList[Idx]] = true;
  85. IgnoredList[Idx] = nil;
  86. end;
  87.  
  88. break;
  89. end;
  90. end;
  91.  
  92. if elysianexecute then -- Scripts is handled async in Elysian because the decompiler is callback based
  93. local Sources = {};
  94.  
  95. InNil = getnilinstances;
  96. WritesFl = writefile;
  97.  
  98. function Decompile(Script) -- Austin finna gonna make me die
  99. local Name = tostring(Script.Parent) .. Script.Name;
  100. local Scr = Sources[Name];
  101.  
  102. if (not Scr) then
  103. local Timeout = tick() + 8;
  104.  
  105. local Ran, Err = decompile(Script, 'unluac', function(Res, Err)
  106. if Res then
  107. Scr = Res:gsub('\r+', ''); -- Austin-proof newline machine
  108. else
  109. Scr = '--[[\n' .. tostring(Err) .. '\n--]]';
  110. end;
  111. end);
  112.  
  113. if (not Ran) then
  114. Scr = '--[[\n' .. tostring(Err) .. '\n--]]';
  115. else
  116. Print('Decompiling ' .. Script:GetFullName());
  117. end;
  118.  
  119. while (not Scr) do
  120. if (tick() > Timeout) then
  121. Print('Script timeout ' .. Script:GetFullName());
  122.  
  123. Scr = '-- Unluac timed out, falling back to LuaDec\n';
  124.  
  125. Ran, Err = decompile(Script);
  126.  
  127. if Ran then
  128. Scr = Scr .. Ran;
  129. else
  130. Scr = Scr .. '--[[\n' .. tostring(Err) .. '\n--]]';
  131. end;
  132.  
  133. break;
  134. else
  135. Beat:wait(); -- Shouldn't cause an issue
  136. end;
  137. end;
  138.  
  139. Sources[Name] = Scr;
  140. end;
  141.  
  142. return Scr;
  143. end;
  144.  
  145. function Print(String)
  146. printconsole(String, 100, 200, 180);
  147. end;
  148.  
  149. Print('<WARNING> May take a while depending on the game scripts <WARNING>');
  150. Print('ReruSavePlace detected Elysian, functions loaded');
  151. elseif Synapse then -- Oh my god 3ds why couldn't you just use '.' syntax
  152. function InNil()
  153. return Synapse:GetNilInstances();
  154. end;
  155.  
  156. function WritesFl(Location, Data)
  157. return Synapse:WriteFile(Location, Data);
  158. end;
  159.  
  160. function Decompile(Script)
  161. return '-- Tell 3dsboy08 to fix this crashing Roblox!';
  162. --return Synapse:Decompile(Script);
  163. end;
  164.  
  165. Print = warn;
  166.  
  167. Print('ReruSavePlace detected Synapse, functions loaded');
  168. else
  169. error('This exploit may not be supported by RSP, please contact me');
  170. end;
  171.  
  172. do
  173. local Temp = {};
  174.  
  175. for Idx, Val in next, Classes do
  176. if (Val.type == 'Class') then
  177. Temp[Val.Name] = Val;
  178. Temp[Val.Name].Properties = {};
  179. elseif (Val.type == 'Property') then
  180. local Ignore;
  181.  
  182. for _, Tag in next, Val.tags do
  183. if (Tag == 'deprecated') or (Tag == 'hidden') or (Tag == 'readonly') then
  184. Ignore = true;
  185.  
  186. break;
  187. end;
  188. end;
  189.  
  190. if (not Ignore) then
  191. local Ignored = NoNoProp[Val.Class];
  192.  
  193. if Ignored and Ignored[Val.Name] then
  194. Ignore = true;
  195. end;
  196.  
  197. if (not Ignore) then
  198. local Props = Temp[Val.Class].Properties;
  199.  
  200. Props[#Props + 1] = Val;
  201. end;
  202. end;
  203. end;
  204. end;
  205.  
  206. Classes = Temp;
  207. end;
  208.  
  209. local function PropsOf(Obj)
  210. if Props[Obj.ClassName] then
  211. return Props[Obj.ClassName];
  212. end;
  213.  
  214. local Prop = {};
  215. local Class = Obj.ClassName;
  216.  
  217. while Class do
  218. local Curr = Classes[Class];
  219.  
  220. for Index, Value in next, Curr.Properties do
  221. Prop[#Prop + 1] = Value;
  222. end;
  223.  
  224. Class = Curr.Superclass;
  225. end;
  226.  
  227. table.sort(Prop, function(A, B)
  228. return A.Name < B.Name;
  229. end);
  230.  
  231. Props[Obj.ClassName] = Prop;
  232.  
  233. return Prop;
  234. end;
  235.  
  236. local function SetParent(Obj, Parent)
  237. local Arch = Obj.Archivable;
  238. local Cloned;
  239.  
  240. Obj.Archivable = true;
  241. Cloned = Obj:Clone();
  242.  
  243. if (not Cloned) then
  244. local pcall = pcall;
  245.  
  246. Cloned = Instance.new'Folder'
  247.  
  248. for Index, Child in next, Obj:GetChildren() do
  249. pcall(SetParent, Child, Cloned);
  250. end;
  251.  
  252. Cloned.Name = Obj.Name .. ':' .. Obj.ClassName;
  253. end;
  254.  
  255. Obj.Archivable = Arch;
  256. Cloned.Parent = Parent;
  257. end;
  258.  
  259. local function SavePlaceAsync()
  260. local Count = 0;
  261. local Final = {};
  262. local Timer = tick();
  263. local Saved = setmetatable({}, {__index = function(This, Idx) local C = Count + 1; Count = C; This[Idx] = C; return C; end});
  264.  
  265. local pcall = pcall; -- Skid syndrome
  266.  
  267. Final[1] = '<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4"><External>null</External><External>nil</External>';
  268. Print('Saving place...');
  269.  
  270. local function SaveInstance(Obj)
  271. if Classes[Obj.ClassName] and (not IgnoredList[Obj.Name]) then
  272. local Props = PropsOf(Obj);
  273. local Num = Saved[Obj];
  274. local Conversions = {
  275. ['&'] = '&amp;';
  276. ['<'] = '&lt;';
  277. ['>'] = '&gt;';
  278. }
  279.  
  280. Final[#Final + 1] = '<Item class="' .. Obj.ClassName .. '" referent="RBX' .. Num .. '"><Properties>';
  281.  
  282. if ((Num % 3600) == 0) then
  283. Print('Reached ' .. Num .. ' instances saved');
  284.  
  285. Beat:wait();
  286. Beat:wait();
  287. end;
  288.  
  289. for _, Prop in next, Props do
  290. local Append;
  291. local Type = Prop.ValueType;
  292. local ObjProp = Prop.Name;
  293. local Objp = Obj[ObjProp];
  294.  
  295. if (typeof(Objp) == 'EnumItem') then
  296. Append = '<token name="' .. ObjProp .. '">' .. Objp.Value .. '</token>';
  297. else
  298. if (Type == 'bool') then
  299. Append = '<bool name="' .. ObjProp .. '">' .. tostring(Objp) .. '</bool>';
  300. elseif (Type == 'float') then
  301. Append = '<float name="' .. ObjProp .. '">' .. tostring(Objp) .. '</float>';
  302. elseif (Type == 'int') then
  303. Append = '<int name="' .. ObjProp .. '">' .. tostring(Objp) .. '</int>';
  304. elseif (Type == 'double') then
  305. Append = '<float name="' .. ObjProp .. '">' .. tostring(Objp) .. '</float>';
  306. elseif (Type == 'string') then
  307. local String = Objp:gsub("[&<>]", Conversions); -- Because I got C O M P L A I N T S
  308.  
  309. Append = '<string name="' .. ObjProp .. '">' .. String .. '</string>';
  310. elseif (Type == 'BrickColor') then
  311. Append = '<int name="' .. ObjProp .. '">' .. Objp.Number .. '</int>';
  312. elseif (Type == 'Vector2') then
  313. Append =
  314. '<Vector2 name="' .. ObjProp .. '">'
  315. .. '<X>' .. Objp.x .. '</X>'
  316. .. '<Y>' .. Objp.y .. '</Y>'
  317. .. '</Vector2>'
  318. elseif (Type == 'Vector3') then
  319. Append =
  320. '<Vector3 name="' .. ObjProp .. '">'
  321. .. '<X>' .. Objp.x .. '</X>'
  322. .. '<Y>' .. Objp.y .. '</Y>'
  323. .. '<Z>' .. Objp.z .. '</Z>'
  324. .. '</Vector3>'
  325. elseif (Type == 'CoordinateFrame') then
  326. local X, Y, Z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = Objp:components()
  327.  
  328. Append =
  329. '<CoordinateFrame name="' .. ObjProp .. '">'
  330. .. '<X>' .. X .. '</X>'
  331. .. '<Y>' .. Y .. '</Y>'
  332. .. '<Z>' .. Z .. '</Z>'
  333. .. '<R00>' .. R00 .. '</R00>'
  334. .. '<R01>' .. R01 .. '</R01>'
  335. .. '<R02>' .. R02 .. '</R02>'
  336. .. '<R10>' .. R10 .. '</R10>'
  337. .. '<R11>' .. R11 .. '</R11>'
  338. .. '<R12>' .. R12 .. '</R12>'
  339. .. '<R20>' .. R20 .. '</R20>'
  340. .. '<R21>' .. R21 .. '</R21>'
  341. .. '<R22>' .. R22 .. '</R22>'
  342. .. '</CoordinateFrame>'
  343. elseif (Type == 'Content') then
  344. local String = Objp:gsub("[&<>]", Conversions);
  345.  
  346. Append = '<Content name="' .. ObjProp .. '"><url>' .. String .. '</url></Content>';
  347. elseif (Type == 'UDim2') then
  348. local Objp = Objp;
  349.  
  350. Append =
  351. '<UDim2 name="' .. ObjProp .. '">'
  352. .. '<XS>' .. Objp.X.Scale .. '</XS>'
  353. .. '<XO>' .. Objp.X.Offset .. '</XO>'
  354. .. '<YS>' .. Objp.Y.Scale .. '</YS>'
  355. .. '<YO>' .. Objp.Y.Offset .. '</YO>'
  356. .. '</UDim2>'
  357. elseif (Type == 'Color3') then
  358. Append =
  359. '<Color3 name="' .. ObjProp .. '">'
  360. .. '<R>' .. Objp.r .. '</R>'
  361. .. '<G>' .. Objp.g .. '</G>'
  362. .. '<B>' .. Objp.b .. '</B>'
  363. .. '</Color3>'
  364. elseif (Type == 'NumberRange') then
  365. Append =
  366. '<NumberRange name="' .. ObjProp .. '">'
  367. .. tostring(Objp.Min)
  368. .. ' '
  369. .. tostring(Objp.Max)
  370. .. '</NumberRange>'
  371. elseif (Type == 'NumberSequence') then
  372. local Ob = {};
  373.  
  374. Ob[1] = '<NumberSequence name="' .. ObjProp .. '">'
  375.  
  376. for i, v in next, Objp.Keypoints do
  377. Ob[#Ob + 1] = tostring(v.Time) .. ' ' .. tostring(v.Value) .. ' ' .. tostring(v.Envelope) .. ' ';
  378. end
  379.  
  380. Ob[#Ob + 1] = '</NumberSequence>';
  381.  
  382. Append = Concat(Ob);
  383. elseif (Type == 'ColorSequence') then
  384. local Ob = {};
  385.  
  386. Ob[1] = '<ColorSequence name="' .. ObjProp .. '">'
  387.  
  388. for i, v in next, Objp.Keypoints do
  389. Ob[#Ob + 1] = Concat{tostring(v.Time) .. ' ' .. tostring(v.Value.r) .. ' ' .. tostring(v.Value.g) .. ' ' .. tostring(v.Value.b), " 0 "};
  390. end
  391.  
  392. Ob[#Ob + 1] = '</ColorSequence>';
  393.  
  394. Append = Concat(Ob);
  395. elseif (Type == 'Rect2D') then
  396. Append =
  397. '<Rect2D name="' .. ObjProp .. '">'
  398. .. '<min>'
  399. .. '<X>' .. tostring(Objp.Min.X) .. '</X>'
  400. .. '<Y>' .. tostring(Objp.Min.Y) .. '</Y>'
  401. .. '</min>'
  402. .. '<max>'
  403. .. '<X>' .. tostring(Objp.Max.X) .. '</X>'
  404. .. '<Y>' .. tostring(Objp.Max.Y) .. '</Y>'
  405. .. '</max>'
  406. .. '</Rect2D>'
  407. elseif (Type == 'ProtectedString') then
  408. local Src;
  409.  
  410. if (ObjProp == 'Source') then
  411. if (Obj.ClassName ~= 'Script') or NotFilter then
  412. local Sc, Er = Decompile(Obj);
  413.  
  414. if (not Sc) then
  415. Src = '--[[\n\t' .. Er .. '\n--]]';
  416. else
  417. Src = Sc;
  418. end;
  419. else
  420. Src = '-- Server script not decompiled :(';
  421. end;
  422. else
  423. Src = '';
  424. end;
  425.  
  426. Append = '<ProtectedString name="' .. ObjProp .. '"><![CDATA[' .. Src .. ']]></ProtectedString>';
  427. elseif (Type == 'Object') then
  428. if (not Objp) then
  429. Objp = 'null';
  430. else
  431. Objp = 'RBX' .. Saved[Objp];
  432. end;
  433.  
  434. Append = '<Ref name="' .. ObjProp .. '">' .. Objp .. '</Ref>';
  435. elseif (Type == 'PhysicalProperties') then
  436. if Objp then
  437. Append =
  438. '<PhysicalProperties name="' .. ObjProp .. '"><CustomPhysics>true</CustomPhysics>'
  439. .. '<Density>' .. tostring(Objp.Density) .. '</Density>'
  440. .. '<Friction>' .. tostring(Objp.Friction) .. '</Friction>'
  441. .. '<Elasticity>' .. tostring(Objp.Elasticity) .. '</Elasticity>'
  442. .. '<FrictionWeight>' .. tostring(Objp.FrictionWeight) .. '</FrictionWeight>'
  443. .. '<ElasticityWeight>' .. tostring(Objp.ElasticityWeight) .. '</ElasticityWeight>'
  444. .. '</PhysicalProperties>'
  445. else
  446. Append = '<PhysicalProperties name="' .. ObjProp .. '"><CustomPhysics>false</CustomPhysics></PhysicalProperties>';
  447. end;
  448. end;
  449. end;
  450.  
  451. if Append then
  452. Final[#Final + 1] = Append;
  453. end;
  454. end
  455.  
  456. Final[#Final + 1] = '</Properties>';
  457.  
  458. for _, Obj in next, Obj:GetChildren() do
  459. SaveInstance(Obj);
  460. end;
  461.  
  462. Final[#Final + 1] = '</Item>';
  463. end;
  464. end;
  465.  
  466. do
  467. local Real = Players.LocalPlayer;
  468. local Serv = game:GetService('ServerStorage');
  469. local Play = Instance.new'Folder';
  470.  
  471. Play.Parent = Serv;
  472. Play.Name = 'LocalPlayer';
  473.  
  474. for _, Des in next, Real:GetChildren() do
  475. pcall(SetParent, Des, Play);
  476. end;
  477.  
  478. if InNil then
  479. local Extr = Instance.new'Folder';
  480.  
  481. Extr.Parent = Serv;
  482. Extr.Name = 'Nil_Instances';
  483.  
  484. for _, Nil in next, InNil() do
  485. pcall(SetParent, Nil, Extr);
  486. end;
  487. end;
  488. end;
  489.  
  490. for _, Child in next, SaveList do
  491. SaveInstance(Child);
  492. end;
  493.  
  494. Final[#Final + 1] = '</roblox>';
  495.  
  496. local Place = game:GetService('MarketplaceService'):GetProductInfo(game.PlaceId);
  497.  
  498. if Place.Name then
  499. local Illegal = {'/', '\\', ':', '?', '"', '\'', '<', '>', '|'};
  500.  
  501. for Idx = 1, #Illegal do
  502. Illegal[Illegal[Idx]] = '';
  503.  
  504. Illegal[Idx] = nil;
  505. end;
  506.  
  507. Place = string.gsub(Place.Name, '.', Illegal);
  508. else
  509. Place = 'Unknown';
  510. end;
  511.  
  512. Print('Done serializing, writing to file');
  513. WritesFl(Place .. '.rbxl', Concat(Final));
  514.  
  515. Print(string.format('Saving took %d second(s), please check your workspace folder', tick() - Timer));
  516. end;
  517.  
  518. SavePlaceAsync();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement