Advertisement
XZTablets

SaveInstance

Jul 13th, 2020
2,263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.36 KB | None | 0 0
  1. local function fetchAPI()
  2. local api
  3. local s,e = pcall(function()
  4. local version = game:HttpGet("http://setup.roblox.com/versionQTStudio",true)
  5. local rawApi = game:HttpGet("http://setup.roblox.com/"..version.."-API-Dump.json",true)
  6. api = game:GetService("HttpService"):JSONDecode(rawApi)
  7. end)
  8. if not s then warn("API Fail") return end
  9. local classes,enums = {},{}
  10.  
  11. for _,class in pairs(api.Classes) do
  12. local newClass = {}
  13. newClass.Name = class.Name
  14. newClass.Superclass = class.Superclass
  15. newClass.Properties = {}
  16. newClass.Functions = {}
  17. newClass.Events = {}
  18. newClass.Callbacks = {}
  19. newClass.Tags = {}
  20.  
  21. if class.Tags then for c,tag in pairs(class.Tags) do newClass.Tags[tag] = true end end
  22. for __,member in pairs(class.Members) do
  23. local mType = member.MemberType
  24. if mType == "Property" then
  25. local newProp = {}
  26. newProp.Name = member.Name
  27. newProp.Class = class.Name
  28. newProp.ValueType = member.ValueType.Name
  29. newProp.Category = member.Category
  30. newProp.Serialization = member.Serialization
  31. newProp.Tags = {}
  32. if member.Tags then for c,tag in pairs(member.Tags) do newProp.Tags[tag] = true end end
  33. table.insert(newClass.Properties,newProp)
  34. elseif mType == "Function" then
  35. local newFunc = {}
  36. newFunc.Name = member.Name
  37. newFunc.Class = class.Name
  38. newFunc.Parameters = {}
  39. newFunc.ReturnType = member.ReturnType.Name
  40. newFunc.Tags = {}
  41. for c,param in pairs(member.Parameters) do
  42. table.insert(newFunc.Parameters,{Name = param.Name, Type = param.Type.Name})
  43. end
  44. if member.Tags then for c,tag in pairs(member.Tags) do newFunc.Tags[tag] = true end end
  45. table.insert(newClass.Functions,newFunc)
  46. elseif mType == "Event" then
  47. local newEvent = {}
  48. newEvent.Name = member.Name
  49. newEvent.Class = class.Name
  50. newEvent.Parameters = {}
  51. newEvent.Tags = {}
  52. for c,param in pairs(member.Parameters) do
  53. table.insert(newEvent.Parameters,{Name = param.Name, Type = param.Type.Name})
  54. end
  55. if member.Tags then for c,tag in pairs(member.Tags) do newEvent.Tags[tag] = true end end
  56. table.insert(newClass.Events,newEvent)
  57. end
  58. end
  59.  
  60. classes[class.Name] = newClass
  61. end
  62.  
  63. for _,enum in pairs(api.Enums) do
  64. local newEnum = {}
  65. newEnum.Name = enum.Name
  66. newEnum.Items = {}
  67. newEnum.Tags = {}
  68.  
  69. if enum.Tags then for c,tag in pairs(enum.Tags) do newEnum.Tags[tag] = true end end
  70. for __,item in pairs(enum.Items) do
  71. local newItem = {}
  72. newItem.Name = item.Name
  73. newItem.Value = item.Value
  74. table.insert(newEnum.Items,newItem)
  75. end
  76.  
  77. enums[enum.Name] = newEnum
  78. end
  79.  
  80. local function getMember(class,member)
  81. if not classes[class] or not classes[class][member] then return end
  82. local result = {}
  83.  
  84. local currentClass = classes[class]
  85. while currentClass do
  86. for _,entry in pairs(currentClass[member]) do
  87. table.insert(result,entry)
  88. end
  89. currentClass = classes[currentClass.Superclass]
  90. end
  91.  
  92. table.sort(result,function(a,b) return a.Name < b.Name end)
  93. return result
  94. end
  95.  
  96. return {
  97. Classes = classes,
  98. Enums = enums,
  99. GetMember = getMember
  100. }
  101. end
  102.  
  103. -- Dex Serializer Module
  104. local function SerializerModule()
  105. -- Modules
  106. local Serializer,API
  107.  
  108. -- Un-init
  109. local _writefile,_getnilinstances,oldIndex,classes,enums
  110.  
  111. -- Rest
  112. local t_ins,t_concat = table.insert,table.concat
  113. local buffer = {}
  114. local refCount = 0
  115. local getChildren = Instance.new("Part").GetChildren
  116. local toDecompile = {}
  117. local saveFilter = {}
  118. local instDir = {}
  119.  
  120. local elyFuncs = false
  121.  
  122. local xmlReplace = {
  123. ["'"] = "&apos;",
  124. ["\""] = "&quot;",
  125. ["<"] = "&lt;",
  126. [">"] = "&gt;",
  127. ["&"] = "&amp;"
  128. }
  129.  
  130. local propBypass = {
  131. ["BasePart"] = {
  132. ["Size"] = true,
  133. ["Color"] = true,
  134. },
  135. ["Part"] = {
  136. ["Shape"] = true
  137. },
  138. ["Fire"] = {
  139. ["Heat"] = true,
  140. ["Size"] = true,
  141. },
  142. ["Smoke"] = {
  143. ["Opacity"] = true,
  144. ["RiseVelocity"] = true,
  145. ["Size"] = true,
  146. },
  147. ["DoubleConstrainedValue"] = {
  148. ["Value"] = true
  149. },
  150. ["IntConstrainedValue"] = {
  151. ["Value"] = true
  152. },
  153. ["TrussPart"] = {
  154. ["Style"] = true
  155. }
  156. }
  157.  
  158. local propFilter = {
  159. ["BaseScript"] = {
  160. ["LinkedSource"] = true
  161. },
  162. ["ModuleScript"] = {
  163. ["LinkedSource"] = true
  164. },
  165. ["Players"] = {
  166. ["CharacterAutoLoads"] = true
  167. }
  168. }
  169.  
  170. local sProps = setmetatable({},{__index = function(self,class)
  171. local props = {}
  172.  
  173. local apiProps = API.GetMember(class,"Properties") or {}
  174. for i,v in pairs(apiProps) do
  175. if (v.Serialization.CanSave and not v.Tags.NotScriptable) or (propBypass[v.Class] and propBypass[v.Class][v.Name]) then
  176. if not propFilter[v.Class] or not propFilter[v.Class][v.Name] then
  177. local s,e = pcall(function() local exist = instDir[class][v.Name] end)
  178. if s then table.insert(props,v) end
  179. end
  180. end
  181. end
  182.  
  183. self[class] = props
  184.  
  185. return props
  186. end})
  187.  
  188. local testInsts = setmetatable({},{__index = function(self,class)
  189. local s,testInst = pcall(function() return Instance.new(class) end)
  190. local testInstTable = {}
  191.  
  192. if testInst then
  193. for i,v in pairs(sProps[class]) do
  194. testInstTable[v.Name] = testInst[v.Name]
  195. end
  196. end
  197.  
  198. self[class] = testInstTable
  199.  
  200. return testInstTable
  201. end})
  202.  
  203. local refMt = {__index = function(self,inst)
  204. if not inst then return "" end
  205. refCount = refCount + 1
  206. self[inst] = refCount
  207. return refCount
  208. end}
  209. local refs = setmetatable({},refMt)
  210.  
  211. local valueHandlers = {
  212. ["bool"] = function(name,val)
  213. t_ins(buffer,'\n<bool name="'..name..'">'..tostring(val)..'</bool>')
  214. end,
  215. ["float"] = function(name,val)
  216. t_ins(buffer,'\n<float name="'..name..'">'..val..'</float>')
  217. end,
  218. ["int"] = function(name,val)
  219. t_ins(buffer,'\n<int name="'..name..'">'..val..'</int>')
  220. end,
  221. ["int64"] = function(name,val)
  222. t_ins(buffer,'\n<int64 name="'..name..'">'..val..'</int64>')
  223. end,
  224. ["double"] = function(name,val)
  225. t_ins(buffer,'\n<double name="'..name..'">'..val..'</double>')
  226. end,
  227. ["string"] = function(name,val)
  228. t_ins(buffer,'\n<string name="'..name..'">'..val:gsub("['\"<>&]",xmlReplace)..'</string>')
  229. end,
  230. ["BrickColor"] = function(name,val)
  231. t_ins(buffer,'\n<int name="'..name..'">'..val.Number..'</int>')
  232. end,
  233. ["Vector2"] = function(name,val)
  234. t_ins(buffer,'\n<Vector2 name="'..name..'">\
  235. <X>'..val.X..'</X>\
  236. <Y>'..val.Y..'</Y>\
  237. </Vector2>')
  238. end,
  239. ["Vector3"] = function(name,val)
  240. t_ins(buffer,'\n<Vector3 name="'..name..'">\
  241. <X>'..val.X..'</X>\
  242. <Y>'..val.Y..'</Y>\
  243. <Z>'..val.Z..'</Z>\
  244. </Vector3>')
  245. end,
  246. ["CFrame"] = function(name,val)
  247. t_ins(buffer,('\n<CoordinateFrame name="'..name..[[">
  248. <X>%f</X>
  249. <Y>%f</Y>
  250. <Z>%f</Z>
  251. <R00>%f</R00>
  252. <R01>%f</R01>
  253. <R02>%f</R02>
  254. <R10>%f</R10>
  255. <R11>%f</R11>
  256. <R12>%f</R12>
  257. <R20>%f</R20>
  258. <R21>%f</R21>
  259. <R22>%f</R22>
  260. </CoordinateFrame>]]):format(val:components()))
  261. end,
  262. ["Content"] = function(name,val)
  263. t_ins(buffer,'\n<Content name="'..name..'"><url>'..val:gsub("['\"<>&]",xmlReplace)..'</url></Content>')
  264. end,
  265. ["UDim"] = function(name,val)
  266. t_ins(buffer,'\n<UDim name="'..name..'">\
  267. <S>'..val.Scale..'</S>\
  268. <O>'..val.Offset..'</O>\
  269. </UDim>')
  270. end,
  271. ["UDim2"] = function(name,val)
  272. local x = val.X
  273. local y = val.Y
  274. t_ins(buffer,'\n<UDim2 name="'..name..'">\
  275. <XS>'..x.Scale..'</XS>\
  276. <XO>'..x.Offset..'</XO>\
  277. <YS>'..y.Scale..'</YS>\
  278. <YO>'..y.Offset..'</YO>\
  279. </UDim2>')
  280. end,
  281. ["Color3"] = function(name,val)
  282. t_ins(buffer,'\n<Color3 name="'..name..'">\
  283. <R>'..val.r..'</R>\
  284. <G>'..val.g..'</G>\
  285. <B>'..val.b..'</B>\
  286. </Color3>')
  287. end,
  288. ["NumberRange"] = function(name,val)
  289. t_ins(buffer,'\n<NumberRange name="'..name..'">'..tostring(val)..'</NumberRange>')
  290. end,
  291. ["NumberSequence"] = function(name,val)
  292. t_ins(buffer,'\n<NumberSequence name="'..name..'">'..tostring(val)..'</NumberSequence>')
  293. end,
  294. ["ColorSequence"] = function(name,val)
  295. t_ins(buffer,'\n<ColorSequence name="'..name..'">'..tostring(val)..'</ColorSequence>')
  296. end,
  297. ["Rect"] = function(name,val)
  298. local min,max = val.Min,val.Max
  299. t_ins(buffer,'\n<Rect2D name="'..name..'">\
  300. <min>\
  301. <X>'..min.X..'</X>\
  302. <Y>'..min.Y..'</Y>\
  303. </min>\
  304. <max>\
  305. <X>'..max.X..'</X>\
  306. <Y>'..max.Y..'</Y>\
  307. </max>\
  308. </Rect2D>')
  309. end,
  310. ["Object"] = function(name,val)
  311. t_ins(buffer,'\n<Ref name="'..name..'">RBX'..refs[val]..'</Ref>')
  312. end,
  313. ["PhysicalProperties"] = function(name,val)
  314. if val then
  315. t_ins(buffer,'\n<PhysicalProperties name="'..name..'">\
  316. <CustomPhysics>true</CustomPhysics>\
  317. <Density>'..val.Density..'</Density>\
  318. <Friction>'..val.Friction..'</Friction>\
  319. <Elasticity>'..val.Elasticity..'</Elasticity>\
  320. <FrictionWeight>'..val.FrictionWeight..'</FrictionWeight>\
  321. <ElasticityWeight>'..val.ElasticityWeight..'</ElasticityWeight>\
  322. </PhysicalProperties>')
  323. else
  324. t_ins(buffer,'\n<PhysicalProperties name="'..name..'">\n<CustomPhysics>false</CustomPhysics>\n</PhysicalProperties>')
  325. end
  326. end,
  327. ["Faces"] = function(name,val)
  328. local faceInt = (val.Front and 32 or 0)
  329. +(val.Bottom and 16 or 0)
  330. +(val.Left and 8 or 0)
  331. +(val.Back and 4 or 0)
  332. +(val.Top and 2 or 0)
  333. +(val.Right and 1 or 0)
  334. t_ins(buffer,'\n<Faces name="'..name..'">\
  335. <faces>'..faceInt..'</faces>\
  336. </Faces>')
  337. end,
  338. ["Axes"] = function(name,val)
  339. local axisInt = (val.Z and 4 or 0)
  340. +(val.Y and 2 or 0)
  341. +(val.X and 1 or 0)
  342. t_ins(buffer,'\n<Axes name="'..name..'">\
  343. <axes>'..axisInt..'</axes>\
  344. </Faces>')
  345. end,
  346. ["Ray"] = function(name,val)
  347. local origin = val.Origin
  348. local direction = val.Direction
  349. t_ins(buffer,'\n<Ray name="'..name..'">\
  350. <origin>\
  351. <X>'..origin.X..'</X>\
  352. <Y>'..origin.Y..'</Y>\
  353. <Z>'..origin.Z..'</Z>\
  354. </origin>\
  355. <direction>\
  356. <X>'..direction.X..'</X>\
  357. <Y>'..direction.Y..'</Y>\
  358. <Z>'..direction.Z..'</Z>\
  359. </direction>\
  360. </Ray>')
  361. end,
  362. }
  363.  
  364. local function getNS(inst,name)
  365. rfl_setscriptable(inst,name,true)
  366. local propVal = oldIndex and oldIndex(inst,name) or inst[name]
  367. rfl_setscriptable(inst,name,false)
  368. return propVal
  369. end
  370.  
  371. local function getBS(inst,name)
  372. local bs = getbspval(inst,name,true)
  373. if bs then
  374. return "<![CDATA["..bs.."]]>"
  375. else
  376. return ""
  377. end
  378. end
  379.  
  380. local specialInst = {
  381. ["UnionOperation"] = function(inst)
  382. if elyFuncs then -- Assume all ely funcs defined
  383. t_ins(buffer,'\n<Content name="AssetId"><url>'..getNS(inst,"AssetId"):gsub("['\"<>&]",xmlReplace)..'</url></Content>')
  384. local initialSize = getNS(inst,"InitialSize")
  385. t_ins(buffer,'\n<Vector3 name="InitialSize">\
  386. <X>'..initialSize.X..'</X>\
  387. <Y>'..initialSize.Y..'</Y>\
  388. <Z>'..initialSize.Z..'</Z>\
  389. </Vector3>')
  390. t_ins(buffer,'\n<BinaryString name="ChildData">'..getBS(inst,"ChildData")..'</BinaryString>')
  391. t_ins(buffer,'\n<BinaryString name="MeshData">'..getBS(inst,"MeshData")..'</BinaryString>')
  392. t_ins(buffer,'\n<BinaryString name="PhysicsData">'..getBS(inst,"PhysicsData")..'</BinaryString>')
  393. end
  394. end,
  395. ["MeshPart"] = function(inst)
  396. if elyFuncs then -- Assume all ely funcs defined
  397. local initialSize = getNS(inst,"InitialSize")
  398. t_ins(buffer,'\n<Vector3 name="InitialSize">\
  399. <X>'..initialSize.X..'</X>\
  400. <Y>'..initialSize.Y..'</Y>\
  401. <Z>'..initialSize.Z..'</Z>\
  402. </Vector3>')
  403. t_ins(buffer,'\n<BinaryString name="PhysicsData">'..getBS(inst,"PhysicsData")..'</BinaryString>')
  404. end
  405. end,
  406. ["Terrain"] = function(inst)
  407. if elyFuncs then
  408. t_ins(buffer,'\n<BinaryString name="MaterialColors">'..getBS(inst,"MaterialColors")..'</BinaryString>')
  409. t_ins(buffer,'\n<BinaryString name="SmoothGrid">'..getBS(inst,"SmoothGrid")..'</BinaryString>')
  410. end
  411. end,
  412. ["TerrainRegion"] = function(inst)
  413. if elyFuncs then
  414. t_ins(buffer,'\n<BinaryString name="SmoothGrid">'..getBS(inst,"SmoothGrid")..'</BinaryString>')
  415. end
  416. end,
  417. ["BinaryStringValue"] = function(inst)
  418. if elyFuncs then
  419. t_ins(buffer,'\n<BinaryString name="Value">'..getBS(inst,"Value")..'</BinaryString>')
  420. end
  421. end,
  422. ["Workspace"] = function(inst)
  423. if elyFuncs then
  424. t_ins(buffer,'\n<token name="AutoJointsMode">'..getNS(inst,"AutoJointsMode").Value..'</token>')
  425. end
  426. t_ins(buffer,'\n<bool name="PGSPhysicsSolverEnabled">'..tostring(inst:PGSIsEnabled())..'</bool>')
  427. local groupTable = {}
  428. for i,v in pairs(game:GetService("PhysicsService"):GetCollisionGroups()) do
  429. t_ins(groupTable,v.name:gsub("['\"<>&]",xmlReplace).."^"..v.id.."^"..v.mask)
  430. end
  431. t_ins(buffer,'\n<string name="CollisionGroups">'..t_concat(groupTable,"\\")..'</string>')
  432. end,
  433. ["Humanoid"] = function(inst)
  434. t_ins(buffer,'\n<float name="Health_XML">'..inst.Health..'</float>')
  435. end,
  436. ["Sound"] = function(inst)
  437. t_ins(buffer,'\n<float name="xmlRead_MaxDistance_3">'..inst.MaxDistance..'</float>')
  438. end,
  439. ["WeldConstraint"] = function(inst)
  440. if elyFuncs then
  441. valueHandlers["CFrame"]("CFrame0",getNS(inst,"CFrame0"))
  442. valueHandlers["CFrame"]("CFrame1",getNS(inst,"CFrame1"))
  443. end
  444. t_ins(buffer,'\n<Ref name="Part0Internal">RBX'..refs[inst.Part0]..'</Ref>')
  445. t_ins(buffer,'\n<Ref name="Part1Internal">RBX'..refs[inst.Part1]..'</Ref>')
  446. end,
  447. ["LocalScript"] = function(inst)
  448. t_ins(buffer,'\n<ProtectedString name="Source">')
  449. local src = decompile(inst):gsub("['\"<>&]",xmlReplace)
  450. t_ins(buffer, src)
  451. t_ins(buffer,'</ProtectedString>')
  452. t_ins(toDecompile,{inst,#buffer-1})
  453. end,
  454. ["ModuleScript"] = function(inst)
  455. t_ins(buffer,'\n<ProtectedString name="Source">')
  456. t_ins(buffer,"")
  457. t_ins(buffer,'</ProtectedString>')
  458. t_ins(toDecompile,{inst,#buffer-1})
  459. end,
  460. }
  461.  
  462. local savePlaceBlacklist = {
  463. ["CoreGui"] = true,
  464. ["CorePackages"] = true
  465. }
  466.  
  467. local function writeXML(inst)
  468. if saveFilter[inst] then return end
  469.  
  470. local class = oldIndex and oldIndex(inst,"ClassName") or inst.ClassName
  471. if not instDir[class] then instDir[class] = inst end
  472. local testInst = testInsts[class]
  473.  
  474. t_ins(buffer,'\n<Item class="'..class..'" referent="RBX'..refs[inst]..'">\n<Properties>')
  475.  
  476. for _,prop in pairs(sProps[class]) do
  477. local propName = prop.Name
  478. local propVal = oldIndex and oldIndex(inst,propName) or inst[propName]
  479. if testInst[propName] ~= propVal then
  480. local valueType = prop.ValueType
  481. if valueHandlers[valueType] then
  482. valueHandlers[valueType](propName,propVal)
  483. elseif enums[valueType] then
  484. t_ins(buffer,'\n<token name="'..propName..'">'..propVal.Value..'</token>')
  485. elseif classes[valueType] then
  486. valueHandlers["Object"](propName,propVal)
  487. end
  488. end
  489. end
  490.  
  491. if specialInst[class] then
  492. specialInst[class](inst)
  493. end
  494.  
  495. t_ins(buffer,"\n</Properties>")
  496.  
  497. for i,v in pairs(getChildren(inst)) do
  498. writeXML(v)
  499. end
  500.  
  501. t_ins(buffer,"\n</Item>")
  502. end
  503.  
  504. local function resetState()
  505. buffer = {}
  506. refs = setmetatable({},refMt)
  507. refCount = 0
  508. toDecompile = {}
  509. saveFilter = {}
  510. instDir = {}
  511. end
  512.  
  513. local defaultSettings = {
  514. DecompileMode = 0,
  515. NilInstances = false,
  516. RemovePlayers = true,
  517. SavePlayerDescendants = false,
  518. DecompileTimeout = 10,
  519. UnluacMaxThreads = 5,
  520. DecompileIgnore = {}
  521. }
  522.  
  523. Serializer = {
  524. Init = function(data)
  525. API = data.API
  526. _writefile = data.WriteFile
  527. _getnilinstances = data.GetNilInstances
  528. oldIndex = data.OldIndex
  529.  
  530. classes = API.Classes
  531. enums = API.Enums
  532.  
  533. elyFuncs = getbspval and rfl_setscriptable
  534.  
  535. Serializer.ResetSettings()
  536. end,
  537.  
  538. Settings = {},
  539.  
  540. ResetSettings = function()
  541. Serializer.Settings = {}
  542. for i,v in pairs(defaultSettings) do
  543. Serializer.Settings[i] = v
  544. end
  545. end,
  546.  
  547. SaveInstance = function(inst,name,sets)
  548. Serializer.ResetSettings()
  549.  
  550. for i,v in pairs(sets or {}) do
  551. Serializer.Settings[i] = v
  552. end
  553.  
  554. resetState()
  555.  
  556. if inst == game and Serializer.Settings.RemovePlayers then
  557. for i,v in pairs(game:GetService("Players"):GetPlayers()) do
  558. saveFilter[v.Character] = true
  559. end
  560. end
  561.  
  562. t_ins(buffer,[==[<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">
  563. <Meta name="ExplicitAutoJoints">true</Meta>
  564. <External>null</External>
  565. <External>nil</External>]==])
  566.  
  567. if inst ~= game then
  568. if type(inst) == "table" then
  569. for i,v in pairs(inst) do
  570. writeXML(v)
  571. end
  572. else
  573. writeXML(inst)
  574. end
  575. else
  576. for i,v in pairs(game:GetChildren()) do
  577. if not savePlaceBlacklist[v.ClassName] then
  578. writeXML(v)
  579. end
  580. end
  581. end
  582.  
  583. if inst == game and Serializer.Settings.NilInstances and _getnilinstances then
  584. t_ins(buffer,'\n<Item class="Folder" referent="RBX'..refs[Instance.new("Folder")]..'">\
  585. <Properties>\
  586. <string name="Name">Nil Instances</string>\
  587. </Properties>')
  588. for i,v in pairs(_getnilinstances()) do
  589. if ((API.Classes[v.ClassName] and not API.Classes[v.ClassName].Tags.Service) or not API.Classes[v.ClassName]) and v ~= game then
  590. writeXML(v)
  591. end
  592. end
  593. t_ins(buffer,"\n</Item>")
  594. end
  595.  
  596. if inst == game and Serializer.Settings.SavePlayerDescendants then
  597. t_ins(buffer,'\n<Item class="Folder" referent="RBX'..refs[Instance.new("Folder")]..'">\
  598. <Properties>\
  599. <string name="Name">Player Descendants</string>\
  600. </Properties>')
  601. for i,v in pairs(game:GetService("Players").LocalPlayer:GetChildren()) do
  602. if v:IsA("PlayerGui") or v:IsA("PlayerScripts") or v:IsA("StarterGear") then
  603. t_ins(buffer,'\n<Item class="Folder" referent="RBX'..refs[Instance.new("Folder")]..'">\
  604. <Properties>\
  605. <string name="Name">'..v.ClassName..'</string>\
  606. </Properties>')
  607. for _,c in pairs(v:GetChildren()) do
  608. writeXML(c)
  609. end
  610. t_ins(buffer,"\n</Item>")
  611. else
  612. writeXML(v)
  613. end
  614. end
  615. t_ins(buffer,"\n</Item>")
  616. end
  617.  
  618. if inst == game then
  619. t_ins(buffer,'\n<Item class="Script" referent="RBX'..refs[Instance.new("Folder")]..'">\
  620. <Properties>\
  621. <string name="Name">Please Read</string>\
  622. <ProtectedString name="Source">'..[==[--[[
  623. If you cannot play the game, please try relocating any scripts in StarterPlayer elsewhere.
  624. ]]]==]..'</ProtectedString>\
  625. </Properties>\
  626. </Item>')
  627. end
  628.  
  629. t_ins(buffer,"\n</roblox>")
  630.  
  631. if Serializer.Settings.DecompileMode > 0 and decompile then
  632. if inst == game and #Serializer.Settings.DecompileIgnore > 0 then
  633. local ignoreServices = {}
  634. for i,v in pairs(Serializer.Settings.DecompileIgnore) do t_ins(ignoreServices,game:GetService(v)) end
  635. for i = #toDecompile,1,-1 do
  636. for _,serv in pairs(ignoreServices) do
  637. if toDecompile[i][1]:IsDescendantOf(serv) then
  638. table.remove(toDecompile,i)
  639. break
  640. end
  641. end
  642. end
  643. end
  644.  
  645. if Serializer.Settings.DecompileMode == 1 then
  646. for i,v in pairs(toDecompile) do
  647. local decstr = "-- This could not decompile"
  648. pcall(function()
  649. if (false) then
  650. decstr = tostring(v[1]):gsub("['\"<>&]",xmlReplace)
  651. else
  652. decstr = ""
  653. end
  654. end)
  655. buffer[v[2]] = decstr
  656. end
  657. elseif Serializer.Settings.DecompileMode == 2 then
  658. local left = #toDecompile
  659. local totalScripts = left
  660.  
  661. local statusGui = Instance.new("ScreenGui")
  662. local statusText = Instance.new("TextLabel",statusGui)
  663. statusText.BackgroundTransparency = 1
  664. statusText.TextColor3 = Color3.new(1,1,1)
  665. statusText.Position = UDim2.new(0,0,0,0)
  666. statusText.Size = UDim2.new(1,0,0,36)
  667. statusText.TextSize = 32
  668. statusText.Font = Enum.Font.Code
  669. statusText.Text = left.."/"..totalScripts.." Scripts Left"
  670. statusGui.Parent = gethui()
  671.  
  672. local function doDec(scr)
  673. local thread = coroutine.running()
  674. local decompiled = false
  675.  
  676. tostring(scr,"unluac",function(scr,err)
  677. decompiled = true
  678. coroutine.resume(thread,scr,err)
  679. end)
  680.  
  681. spawn(function()
  682. wait(Serializer.Settings.DecompileTimeout)
  683. if decompiled then return end
  684. coroutine.resume(thread,nil,"timeout")
  685. end)
  686.  
  687. return coroutine.yield()
  688. end
  689.  
  690. for i = 1,Serializer.Settings.UnluacMaxThreads do
  691. spawn(function()
  692. while #toDecompile > 0 do
  693. local nextScript = table.remove(toDecompile)
  694. local scr,err = doDec(nextScript[1])
  695. if scr then
  696. buffer[nextScript[2]] = scr:gsub("['\"<>&]",xmlReplace)
  697. else
  698. buffer[nextScript[2]] = "-- This could not decompile because "..(err or ""):gsub("['\"<>&]",xmlReplace)
  699. end
  700. left = left - 1
  701. statusText.Text = left.."/"..totalScripts.." Scripts Left"
  702. end
  703. end)
  704. end
  705. while left > 0 do game:GetService("RunService").RenderStepped:wait() end
  706. statusGui:Destroy()
  707. end
  708. end
  709.  
  710. _writefile(name..(inst == game and ".rbxlx" or ".rbxmx"),(t_concat(buffer)))
  711. resetState()
  712. end
  713. }
  714.  
  715. return Serializer
  716. end
  717.  
  718. local initialized = false
  719. local serializer = SerializerModule()
  720.  
  721. local function init()
  722. local startup = {
  723. API = fetchAPI(),
  724. WriteFile = writefile,
  725. GetNilInstances = nil,
  726. OldIndex = oldindex
  727. }
  728. serializer.Init(startup)
  729. initialized = true
  730. end
  731.  
  732. if not initialized then
  733. init()
  734. end
  735.  
  736. serializer.SaveInstance(game,game.PlaceId.."-".."PlaceSave",sets)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement