Advertisement
Guest User

Untitled

a guest
Jan 15th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.33 KB | None | 0 0
  1. --[[
  2. SaveInstance V3.3 - Swift
  3.  
  4. THIS IS A SAVEINSTANCE CORE NOT A SAVEINSTANCE SCRIPT. THINK OF THIS AS A MOCK OF THE BUILT IN FUNCTION. ALL THIS DOES IT MAKE THE FUNCTION
  5. YOU NEED A COPIER SCRIPT THAT CALLS _G.SInstance(Instance, Name) FOR THIS TO WORK.
  6.  
  7. You have three options of saveinstance that you can change by setting "saveMethod".
  8. 1 - Using the "writefile" function if you support it
  9. 2 - Using a webhost like v2
  10. 3 - Using the new create model method
  11.  
  12. NEW: If you just want to save the place right away, go to the "SAVE PLACE UI OPTIONS".
  13. Get one of your place's id and set "savePlaceId" to it. This is where your place will be exported to.
  14.  
  15. Made by Pi and sad Moon :c
  16. --]]
  17.  
  18. -- ========== MAIN SETTINGS ==========
  19. local saveMethod = 1 -- 1 = writefile, 2 = host, 3 = createmodel
  20. local debugMessages = true -- Debug messages
  21. local useGetgenv = true -- Attempts to install the SaveInstance() and SavePlace() function to the global env
  22. local APIOverride = [==[]==] -- The JSON Api of Roblox if you have no TrustCheck
  23.  
  24. -- ========== FOR HOST OPTION ==========
  25. -- You need your host with the php set up on it for this to work. Make sure read/write permissions are enabled for php.
  26. -- You don't need it if you have a writefile function. Actually no setup if you have writefile ahaha.
  27.  
  28. local host = "http://slowcomplicatedafmethod.com/Master.php" -- Your php file
  29. local splitSize = 800000 -- If your host supports bigger post size then change this (1mb default)
  30.  
  31. -- ========== SAVE PLACE UI OPTIONS ==========
  32. local savePlaceId = 0 -- Put the PlaceID of ONE OF THE PLACES THAT YOU OWN here from https://www.roblox.com/develop which will be updated by this script.
  33. local savePlaceExtra = true -- Nil Instances, PlayerGui, etc
  34. local savePlaceScripts = true -- If you have decompiler
  35. local savePlaceTerrain = true -- Opens Terrain Chunk Selector
  36. local savePlaceTerrainShowChunks = true -- Shows the selection boxes which are your selected chunks
  37. local savePlaceNilInstances = true -- Nil Instances
  38. local savePlaceUseWriteFile = false -- Writes the place file to your disk instead if you have a writefile function
  39.  
  40. -- ========== DO NOT MODIFY BELOW ==========
  41. local consoleFunc = printconsole or writeconsole or print
  42.  
  43. local function debugMsg(msg)
  44. if debugMessages and consoleFunc then
  45. consoleFunc(msg)
  46. end
  47. end
  48.  
  49. if saveMethod == 1 and not writefile then debugMsg("no writefile, switching to method 3") saveMethod = 3 end
  50. if savePlaceUseWriteFile and not writefile then debugMsg("no writefile for place save, turning off") savePlaceUseWriteFile = false end
  51.  
  52. local http = game:GetService("HttpService")
  53. local API = {}
  54. local APIJson
  55. local LPlayer = game:GetService("Players").LocalPlayer
  56. local selectingTerrain = false
  57. local terrainChunks = {}
  58. local terrainChunksTemp = {}
  59. local terrainBeen = {}
  60. local pendingTerrain = {}
  61. local placeMode = false
  62.  
  63. local instanceCount = 0
  64. local saveString = ""
  65. local totalInstances = 1
  66.  
  67. local savedProps = {}
  68. local instanceRefs = {}
  69. local storedInstances = {}
  70. local splits = 0
  71.  
  72. local globalName = ""
  73. local extraFolder = Instance.new("Folder")
  74. extraFolder.Name = "_IMPORTANT_AND_EXTRA_INSTANCES_"
  75.  
  76. local terrainLoader = Instance.new("Script",extraFolder)
  77. terrainLoader.Name = "LoadTerrain"
  78. local terrainData = Instance.new("ModuleScript",terrainLoader)
  79. terrainData.Name = "Data"
  80.  
  81. local ignoreProps = {
  82. ["Instance"] = {
  83. ["Archivable"] = true,
  84. ["DataCost"] = true,
  85. ["ClassName"] = true,
  86. ["RobloxLocked"] = true,
  87. ["Parent"] = true
  88. },
  89. ["Workspace"] = {
  90. ["DistributedGameTime"] = true
  91. },
  92. ["BasePart"] = {
  93. ["Position"] = true,
  94. ["Rotation"] = true
  95. }
  96. }
  97.  
  98. local propAlt = {
  99. ["Sound"] = {
  100. ["MaxDistance"] = "xmlRead_MaxDistance_3"
  101. }
  102. }
  103.  
  104. local success,err = ypcall(function()
  105. if APIOverride and APIOverride ~= "" then
  106. APIJson = APIOverride
  107. else
  108. APIJson = game:HttpGetAsync("http://anaminus.github.io/rbx/json/api/latest.json")
  109. end
  110. end)
  111.  
  112. if err then
  113. if script:FindFirstChild("API") then
  114. APIJson = require(script.API)
  115. end
  116. end
  117.  
  118. APIJson = http:JSONDecode(APIJson)
  119.  
  120. for i,v in pairs(APIJson) do
  121. if v.type == "Class" then
  122. API[v.Name] = v
  123. API[v.Name].Properties = {}
  124. elseif v.type == "Property" then
  125. local dontuse = false
  126. for i2,v2 in pairs(v.tags) do
  127. if v2 == "deprecated" or v2 == "hidden" or v2 == "readonly" then
  128. dontuse = true
  129. end
  130. end
  131. if ignoreProps[v.Class] and ignoreProps[v.Class][v.Name] then dontuse = true end
  132. if propAlt[v.Class] and propAlt[v.Class][v.Name] then v.AltName = propAlt[v.Class][v.Name] end
  133. if not dontuse then
  134. table.insert(API[v.Class].Properties,v)
  135. end
  136. end
  137. end
  138.  
  139. local function getProperties(obj)
  140. if savedProps[obj.ClassName] then return savedProps[obj.ClassName] end
  141.  
  142. local tempProps = {}
  143. local currentClass = obj.ClassName
  144.  
  145. while currentClass do
  146. for i,v in pairs(API[currentClass].Properties) do
  147. table.insert(tempProps,v)
  148. end
  149. currentClass = API[currentClass].Superclass
  150. end
  151.  
  152. table.sort(tempProps,function(a,b)
  153. return (a.AltName or a.Name) < (b.AltName or b.Name)
  154. end)
  155. savedProps[obj.ClassName] = tempProps
  156. return tempProps
  157. end
  158.  
  159. local function appendToHost()
  160. game:HttpPostAsync(host,table.concat(storedInstances)) --http:PostAsync(host,http:JSONEncode({Option = "Append",Name = globalName,Data = table.concat(storedInstances)}))
  161. splits = splits + 1
  162. debugMsg("SaveAmounts: "..tostring(splits).." Progress = "..tostring(instanceCount/totalInstances*100).."%")
  163. end
  164.  
  165. local function submitSave()
  166. game:HttpPostAsync(host,http:JSONEncode({Option = "Submit",Name = globalName}))
  167. end
  168.  
  169. local function clearAll()
  170. game:HttpPostAsync(host,http:JSONEncode({Option = "Clear"}))
  171. end
  172.  
  173. local function checkRef(obj)
  174. local check = instanceRefs[obj]
  175. if check then
  176. return tostring(check)
  177. end
  178. instanceRefs[obj] = instanceCount
  179. return tostring(instanceCount)
  180. end
  181.  
  182. local function setRef(obj)
  183. if obj == nil then return "null" end
  184. local check = instanceRefs[obj]
  185. if check then
  186. return "RBX"..tostring(check)
  187. end
  188. instanceCount = instanceCount + 1
  189. instanceRefs[obj] = instanceCount
  190. return "RBX"..tostring(instanceCount)
  191. end
  192.  
  193. local function cleanUglyAf(str)
  194. if #str == 0 then return "" end
  195.  
  196. local firstChar = str:sub(1,1)
  197. local firstByte = string.byte(firstChar)
  198.  
  199. if firstByte >= 32 and firstByte <= 126 then
  200. return firstChar..cleanUglyAf(str:sub(2))
  201. elseif firstByte == 9 or firstByte == 10 then
  202. return firstChar..cleanUglyAf(str:sub(2))
  203. else
  204. return cleanUglyAf(str:sub(2))
  205. end
  206. end
  207.  
  208. function CreateInstance(cls,props)
  209. local inst = Instance.new(cls)
  210. for i,v in pairs(props) do
  211. inst[i] = v
  212. end
  213. return inst
  214. end
  215.  
  216. local function createTerrainGui()
  217. local TerrainGui = CreateInstance("Frame",{Style=0,Active=false,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(0.10980392992496,0.16470588743687,0.22352942824364),BackgroundTransparency=0,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=1,ClipsDescendants=false,Draggable=false,Position=UDim2.new(0,0,0.5,0),Rotation=0,Selectable=false,Size=UDim2.new(0,150,0,150),SizeConstraint=0,Visible=false,ZIndex=1,Name="Main",})
  218. local TerrainGui2 = CreateInstance("TextLabel",{Font=4,FontSize=5,Text="Terrain Chunk Selection",TextColor3=Color3.new(1,1,1),TextScaled=false,TextSize=14,TextStrokeColor3=Color3.new(0,0,0),TextStrokeTransparency=1,TextTransparency=0,TextWrapped=false,TextXAlignment=2,TextYAlignment=1,Active=false,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=1,ClipsDescendants=false,Draggable=false,Position=UDim2.new(0,0,0,0),Rotation=0,Selectable=false,Size=UDim2.new(1,0,0,20),SizeConstraint=0,Visible=true,ZIndex=1,Name="Title",Parent = TerrainGui})
  219. local TerrainGui3 = CreateInstance("TextLabel",{Font=3,FontSize=5,Text="Use your mouse to click on all the terrain to save. When you are finished, press done.",TextColor3=Color3.new(1,1,1),TextScaled=false,TextSize=14,TextStrokeColor3=Color3.new(0,0,0),TextStrokeTransparency=1,TextTransparency=0,TextWrapped=true,TextXAlignment=2,TextYAlignment=1,Active=false,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=1,ClipsDescendants=false,Draggable=false,Position=UDim2.new(0,0,0,25),Rotation=0,Selectable=false,Size=UDim2.new(1,0,0,50),SizeConstraint=0,Visible=true,ZIndex=1,Name="Desc",Parent = TerrainGui})
  220. local TerrainGui4 = CreateInstance("TextLabel",{Font=4,FontSize=5,Text="Chunks: 0",TextColor3=Color3.new(1,1,1),TextScaled=false,TextSize=14,TextStrokeColor3=Color3.new(0,0,0),TextStrokeTransparency=1,TextTransparency=0,TextWrapped=true,TextXAlignment=2,TextYAlignment=1,Active=false,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(1,1,1),BackgroundTransparency=1,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=1,ClipsDescendants=false,Draggable=false,Position=UDim2.new(0,0,0,80),Rotation=0,Selectable=false,Size=UDim2.new(1,0,0,20),SizeConstraint=0,Visible=true,ZIndex=1,Name="Chunks",Parent = TerrainGui})
  221. local TerrainGui5 = CreateInstance("TextButton",{Font=4,FontSize=6,Text="Done",TextColor3=Color3.new(1,1,1),TextScaled=false,TextSize=18,TextStrokeColor3=Color3.new(0,0,0),TextStrokeTransparency=1,TextTransparency=0,TextWrapped=false,TextXAlignment=2,TextYAlignment=1,AutoButtonColor=true,Modal=false,Selected=false,Style=0,Active=true,AnchorPoint=Vector2.new(0,0),BackgroundColor3=Color3.new(0.17254902422428,0.22745099663734,0.28627452254295),BackgroundTransparency=0,BorderColor3=Color3.new(0.10588236153126,0.16470588743687,0.20784315466881),BorderSizePixel=1,ClipsDescendants=false,Draggable=false,Position=UDim2.new(0,5,1,-30),Rotation=0,Selectable=true,Size=UDim2.new(1,-10,0,25),SizeConstraint=0,Visible=true,ZIndex=1,Name="Done",Parent = TerrainGui})
  222. return TerrainGui
  223. end
  224.  
  225. local terrainGui = createTerrainGui()
  226. terrainGui.Parent = game:GetService("CoreGui").RobloxGui
  227.  
  228. local ignorePlaceClasses = {
  229. ["CoreGui"] = true,
  230. ["Players"] = true,
  231. ["Chat"] = true,
  232. ["StarterPlayerScripts"] = true,
  233. ["StarterCharacterScripts"] = true
  234. }
  235.  
  236. local function placeInstCheck(inst)
  237. return not ignorePlaceClasses[inst.ClassName] and not game:GetService("Players"):GetPlayerFromCharacter(inst) and inst ~= workspace.CurrentCamera
  238. end
  239.  
  240. local propFunc = {
  241. ["bool"] = function(inst,prop)
  242. saveString = saveString..'\n<bool name="'..prop..'">'..tostring(inst[prop])..'</bool>'
  243. end,
  244. ["float"] = function(inst,prop)
  245. saveString = saveString..'\n<float name="'..prop..'">'..tostring(inst[prop])..'</float>'
  246. end,
  247. ["int"] = function(inst,prop)
  248. saveString = saveString..'\n<int name="'..prop..'">'..tostring(inst[prop])..'</int>'
  249. end,
  250. ["double"] = function(inst,prop)
  251. saveString = saveString..'\n<float name="'..prop..'">'..tostring(inst[prop])..'</float>'
  252. end,
  253. ["string"] = function(inst,prop)
  254. local cleanName = inst[prop]
  255. cleanName = string.gsub(cleanName,"&","&amp;")
  256. cleanName = string.gsub(cleanName,"<","&lt;")
  257. cleanName = string.gsub(cleanName,">","&gt;")
  258. saveString = saveString..'\n<string name="'..prop..'">'..cleanName..'</string>'
  259. end,
  260. ["BrickColor"] = function(inst,prop)
  261. saveString = saveString..'\n<int name="'..prop..'">'..tostring(inst[prop].Number)..'</int>'
  262. end,
  263. ["Vector2"] = function(inst,prop)
  264. saveString = saveString..'\n<Vector2 name="'..prop..'">'
  265. saveString = saveString..'\n<X>'..inst[prop].x..'</X>'
  266. saveString = saveString..'\n<Y>'..inst[prop].y..'</Y>'
  267. saveString = saveString..'\n</Vector2>'
  268. end,
  269. ["Vector3"] = function(inst,prop)
  270. saveString = saveString..'\n<Vector3 name="'..prop..'">'
  271. saveString = saveString..'\n<X>'..inst[prop].x..'</X>'
  272. saveString = saveString..'\n<Y>'..inst[prop].y..'</Y>'
  273. saveString = saveString..'\n<Z>'..inst[prop].z..'</Z>'
  274. saveString = saveString..'\n</Vector3>'
  275. end,
  276. ["CoordinateFrame"] = function(inst,prop)
  277. local X,Y,Z,R00,R01,R02,R10,R11,R12,R20,R21,R22 = inst[prop]:components()
  278. saveString = saveString..'\n<CoordinateFrame name="'..prop..'">'
  279. saveString = saveString..'\n<X>'..X..'</X>'
  280. saveString = saveString..'\n<Y>'..Y..'</Y>'
  281. saveString = saveString..'\n<Z>'..Z..'</Z>'
  282. saveString = saveString..'\n<R00>'..R00..'</R00>'
  283. saveString = saveString..'\n<R01>'..R01..'</R01>'
  284. saveString = saveString..'\n<R02>'..R02..'</R02>'
  285. saveString = saveString..'\n<R10>'..R10..'</R10>'
  286. saveString = saveString..'\n<R11>'..R11..'</R11>'
  287. saveString = saveString..'\n<R12>'..R12..'</R12>'
  288. saveString = saveString..'\n<R20>'..R20..'</R20>'
  289. saveString = saveString..'\n<R21>'..R21..'</R21>'
  290. saveString = saveString..'\n<R22>'..R22..'</R22>'
  291. saveString = saveString..'\n</CoordinateFrame>'
  292. end,
  293. ["Content"] = function(inst,prop)
  294. local cleanName = tostring(inst[prop])
  295. cleanName = string.gsub(cleanName,"&","&amp;")
  296. cleanName = string.gsub(cleanName,"<","&lt;")
  297. cleanName = string.gsub(cleanName,">","&gt;")
  298. saveString = saveString..'\n<Content name="'..prop..'"><url>'..cleanName..'</url></Content>'
  299. end,
  300. ["UDim2"] = function(inst,prop)
  301. saveString = saveString..'\n<UDim2 name="'..prop..'">'
  302. saveString = saveString..'\n<XS>'..inst[prop].X.Scale..'</XS>'
  303. saveString = saveString..'\n<XO>'..inst[prop].X.Offset..'</XO>'
  304. saveString = saveString..'\n<YS>'..inst[prop].Y.Scale..'</YS>'
  305. saveString = saveString..'\n<YO>'..inst[prop].Y.Offset..'</YO>'
  306. saveString = saveString..'\n</UDim2>'
  307. end,
  308. ["Color3"] = function(inst,prop)
  309. saveString = saveString..'\n<Color3 name="'..prop..'">'
  310. saveString = saveString..'\n<R>'..inst[prop].r..'</R>'
  311. saveString = saveString..'\n<G>'..inst[prop].g..'</G>'
  312. saveString = saveString..'\n<B>'..inst[prop].b..'</B>'
  313. saveString = saveString..'\n</Color3>'
  314. end,
  315. ["NumberRange"] = function(inst,prop)
  316. saveString = saveString..'\n<NumberRange name="'..prop..'">'..tostring(inst[prop].Min).." "..tostring(inst[prop].Max).." "..'</NumberRange>'
  317. end,
  318. ["NumberSequence"] = function(inst,prop)
  319. saveString = saveString..'\n<NumberSequence name="'..prop..'">'
  320. for i,v in pairs(inst[prop].Keypoints) do
  321. saveString = saveString..tostring(v.Time).." "..tostring(v.Value).." "..tostring(v.Envelope).." "
  322. end
  323. saveString = saveString..'</NumberSequence>'
  324. end,
  325. ["ColorSequence"] = function(inst,prop)
  326. saveString = saveString..'\n<ColorSequence name="'..prop..'">'
  327. for i,v in pairs(inst[prop].Keypoints) do
  328. saveString = saveString..tostring(v.Time).." "..tostring(v.Value.r).." "..tostring(v.Value.g).." "..tostring(v.Value.b).." 0 "
  329. end
  330. saveString = saveString..'</ColorSequence>'
  331. end,
  332. ["Rect2D"] = function(inst,prop)
  333. saveString = saveString..'\n<Rect2D name="'..prop..'">'
  334. saveString = saveString..'\n<min>'
  335. saveString = saveString..'\n<X>'..tostring(inst[prop].Min.X)..'</X>'
  336. saveString = saveString..'\n<Y>'..tostring(inst[prop].Min.Y)..'</Y>'
  337. saveString = saveString..'\n</min>'
  338. saveString = saveString..'\n<max>'
  339. saveString = saveString..'\n<X>'..tostring(inst[prop].Max.X)..'</X>'
  340. saveString = saveString..'\n<Y>'..tostring(inst[prop].Max.Y)..'</Y>'
  341. saveString = saveString..'\n</max>'
  342. saveString = saveString..'\n</Rect2D>'
  343. end,
  344. ["ProtectedString"] = function(inst,prop)
  345. local prostr = inst[prop]
  346. if placeMode and decompile and (inst:IsA("LocalScript") or inst:IsA("ModuleScript")) and savePlaceScripts and inst.Source == "" then prostr = decompile(inst) end
  347. if inst == terrainData then prostr = "return [==["..table.concat(terrainChunks,"|").."]==]" terrainChunks = {} end
  348. saveString = saveString..'\n<ProtectedString name="'..prop..'"><![CDATA['..prostr..']]></ProtectedString>'
  349. end,
  350. ["Object"] = function(inst,prop)
  351. saveString = saveString..'\n<Ref name="'..prop..'">'..setRef(inst[prop])..'</Ref>'
  352. end,
  353. ["PhysicalProperties"] = function(inst,prop)
  354. if inst[prop] then
  355. saveString = saveString..'\n<PhysicalProperties name="'..prop..'">\n<CustomPhysics>true</CustomPhysics>'
  356. saveString = saveString..'\n<Density>'..tostring(inst[prop].Density)..'</Density>'
  357. saveString = saveString..'\n<Friction>'..tostring(inst[prop].Friction)..'</Friction>'
  358. saveString = saveString..'\n<Elasticity>'..tostring(inst[prop].Elasticity)..'</Elasticity>'
  359. saveString = saveString..'\n<FrictionWeight>'..tostring(inst[prop].FrictionWeight)..'</FrictionWeight>'
  360. saveString = saveString..'\n<ElasticityWeight>'..tostring(inst[prop].ElasticityWeight)..'</ElasticityWeight>'
  361. saveString = saveString..'\n</PhysicalProperties>'
  362. else
  363. saveString = saveString..'\n<PhysicalProperties name="'..prop..'">\n<CustomPhysics>false</CustomPhysics>\n</PhysicalProperties>'
  364. end
  365. end
  366. }
  367.  
  368. local specialClassCases = {
  369. ["UnionOperation"] = function(inst)
  370. if not ypcall(function()local lolaf = inst.AssetId end) then return end
  371. propFunc["Content"](inst,"AssetId")
  372. propFunc["Vector3"](inst,"InitialSize")
  373. end,
  374. ["MeshPart"] = function(inst)
  375. if not ypcall(function()local lolaf = inst.InitialSize end) then return end
  376. propFunc["Vector3"](inst,"InitialSize")
  377. end,
  378. ["Workspace"] = function(inst)
  379. if inst:PGSIsEnabled() then
  380. saveString = saveString..'\n<bool name="PGSPhysicsSolverEnabled">true</bool>'
  381. else
  382. saveString = saveString..'\n<bool name="PGSPhysicsSolverEnabled">false</bool>'
  383. end
  384. if ypcall(function()local lolaf = inst.FallenPartsDestroyHeight end) then
  385. propFunc["double"](inst,"FallenPartsDestroyHeight")
  386. end
  387. end
  388. }
  389.  
  390. local function writeInstance(inst,altData)
  391. if API[inst.ClassName] and (placeMode and placeInstCheck(inst) or not placeMode) then
  392. if saveMethod == 2 and string.len(table.concat(storedInstances)) >= splitSize then
  393. appendToHost()
  394. storedInstances = {}
  395. end
  396. instanceCount = instanceCount + 1
  397. local props = getProperties(inst)
  398. saveString = saveString..'\n<Item class="'..inst.ClassName..'" referent="RBX'..checkRef(inst)..'">'
  399. saveString = saveString.."\n<Properties>"
  400. for _,prop in pairs(props) do
  401. ypcall(function()
  402. local propF = propFunc[prop.ValueType]
  403. if propF then
  404. if not prop.AltName then
  405. propF(inst,prop.Name)
  406. else
  407. table.insert(storedInstances,saveString)
  408. saveString = ""
  409. propF(inst,prop.Name)
  410. saveString = string.gsub(saveString,prop.Name,prop.AltName)
  411. end
  412. elseif inst[prop.Name].Value then
  413. saveString = saveString..'\n<token name="'..(prop.AltName or prop.Name)..'">'..inst[prop.Name].Value..'</token>'
  414. end
  415. table.insert(storedInstances,saveString)
  416. saveString = ""
  417. end)
  418. end
  419. if specialClassCases[inst.ClassName] then
  420. specialClassCases[inst.ClassName](inst)
  421. end
  422. saveString = saveString.."\n</Properties>"
  423. if inst == extraFolder then
  424. if getnilinstances and savePlaceNilInstances then
  425. local nilFolder = Instance.new("Folder",extraFolder)
  426. nilFolder.Name = "Nil Instances"
  427.  
  428. local nilledInstances = {}
  429. for i,v in pairs(getnilinstances()) do
  430. if v.Name ~= "_DexTrash_" and v ~= extraFolder then
  431. table.insert(nilledInstances,v)
  432. end
  433. end
  434. writeInstance(nilFolder,nilledInstances)
  435. end
  436.  
  437. if savePlaceExtra then
  438. local playerFolder = Instance.new("Folder",extraFolder)
  439. playerFolder.Name = "Instances In Player"
  440. writeInstance(playerFolder,LPlayer:GetChildren())
  441.  
  442. local playerGuiFolder = Instance.new("Folder",extraFolder)
  443. playerGuiFolder.Name = "Instances In PlayerGui"
  444. writeInstance(playerGuiFolder,LPlayer:FindFirstChildOfClass("PlayerGui"):GetChildren())
  445.  
  446. local cameraFolder = Instance.new("Folder",extraFolder)
  447. cameraFolder.Name = "Instances In Camera"
  448. writeInstance(cameraFolder,workspace.CurrentCamera:GetChildren())
  449.  
  450. local chatFolder = Instance.new("Folder",extraFolder)
  451. chatFolder.Name = "Instances In Chat"
  452. writeInstance(chatFolder,game:GetService("Chat"):GetChildren())
  453.  
  454. local SPSFolder = Instance.new("Folder",extraFolder)
  455. SPSFolder.Name = "Instances In StarterPlayerScripts"
  456. writeInstance(SPSFolder,game:GetService("StarterPlayer"):FindFirstChildOfClass("StarterPlayerScripts"):GetChildren())
  457.  
  458. local SCSFolder = Instance.new("Folder",extraFolder)
  459. SCSFolder.Name = "Instances In StarterCharacterScripts"
  460. writeInstance(SCSFolder,game:GetService("StarterPlayer"):FindFirstChildOfClass("StarterCharacterScripts"):GetChildren())
  461. end
  462.  
  463. local unionFixer = Instance.new("Script",extraFolder)
  464. unionFixer.Name = "Fix Union Collisions - READ"
  465. unionFixer.Source = '--[[\n THIS GUIDE WILL HELP YOU FIX THE COLLISIONS WITH UNIONS AND MESHPARTS IN THE MAP.\n \n Run this script in the command bar to select all the Unions and MeshParts in the map.\n \n After that, go to the properties frame and set the CollisionFidelity property to "Hull"\n \n Then, set them back to "Default"\n \n You have fixed all union collisions.\n \n \n - Credit to Jester for original instructions\n--]]\n\nlocal unions = {}\n\nfunction getUnions(root)\n for i,v in pairs(root:GetChildren()) do\n if v:IsA("UnionOperation") or v:IsA("MeshPart") then\n table.insert(unions,v)\n end\n getUnions(v)\n end\nend\n\ngetUnions(workspace)\n\ngame.Selection:Set(unions)'
  466. writeInstance(unionFixer)
  467. elseif altData then
  468. for i,v in pairs(altData) do
  469. writeInstance(v)
  470. end
  471. else
  472. for i,v in pairs(inst:GetChildren()) do
  473. writeInstance(v)
  474. end
  475. end
  476. saveString = saveString.."\n</Item>"
  477. table.insert(storedInstances,saveString)
  478. saveString = ""
  479. end
  480. end
  481.  
  482. local function removeExtension(str)
  483. if string.find(str,".rbxm") then
  484. return string.sub(str,1,string.find(str,".rbxm")-1)
  485. elseif string.find(str,".rbxmx") then
  486. return string.sub(str,1,string.find(str,".rbxmx")-1)
  487. else
  488. return str
  489. end
  490. end
  491.  
  492. local function countTotal(obj)
  493. for i,v in pairs(obj:GetChildren()) do
  494. totalInstances = totalInstances + 1
  495. countTotal(v)
  496. end
  497. end
  498.  
  499. local function createModel(name,data)
  500. local url = "https://data.roblox.com/Data/Upload.ashx?assetid=0&type=Model&name="..name.."&description=&genreTypeId=1&ispublic=False&allowComments=False"
  501. local id = game:HttpPostAsync(url,data)
  502. debugMsg("Your "..name.." Instance was saved to the id: "..id)
  503. end
  504.  
  505. function func_SInstance(inst,name,terrainRegions)
  506. placeMode = false
  507. name = removeExtension(name)
  508. if saveMethod == 2 then
  509. clearAll()
  510. end
  511. instanceCount = 0
  512. totalInstances = 1
  513. if saveMethod == 2 then countTotal(inst) end
  514. instanceRefs = {}
  515. storedInstances = {}
  516. globalName = name
  517. splits = 0
  518. saveString = [[<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">
  519. <External>null</External>
  520. <External>nil</External>]]
  521.  
  522. if not ypcall(function()local lolaf = Instance.new("UnionOperation").AssetId end) then
  523. debugMsg("RUNNING WITH NO UNSCRIPTABLE PATCH")
  524. else
  525. debugMsg("RUNNING WITH UNSCRIPTABLE PATCH c:")
  526. end
  527.  
  528. writeInstance(inst)
  529. table.insert(storedInstances,"\n</roblox>")
  530. if saveMethod == 1 then
  531. writefile(name..".rbxmx",table.concat(storedInstances))
  532. elseif saveMethod == 2 then
  533. appendToHost()
  534. submitSave()
  535. elseif saveMethod == 3 then
  536. createModel(name,table.concat(storedInstances))
  537. end
  538. if saveMethod == 2 then debugMsg("Saved with "..tostring(splits).." splits.") end
  539. storedInstances = {}
  540. end
  541.  
  542. function DoSPlace(name)
  543. placeMode = true
  544. instanceCount = 0
  545. instanceRefs = {}
  546. storedInstances = {}
  547.  
  548. saveString = [[<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">
  549. <External>null</External>
  550. <External>nil</External>]]
  551. for i,v in pairs(game:GetChildren()) do
  552. writeInstance(v)
  553. end
  554. writeInstance(extraFolder)
  555. if savePlaceTerrain then writeInstance(terrainLoader) end
  556. table.insert(storedInstances,"\n</roblox>")
  557. if savePlaceUseWriteFile then
  558. if writefile then
  559. local filterChars = {"/","\\",":","?","\"","<",">","|"}
  560. local gameName = game:GetService("MarketplaceService"):GetProductInfo(game.PlaceId).Name
  561. for i,v in pairs(filterChars) do
  562. gameName = string.gsub(gameName,v,"")
  563. end
  564. writefile(name or tostring(game.PlaceId).." - "..gameName..".rbxlx",table.concat(storedInstances))
  565. return true
  566. end
  567. return false
  568. else
  569. return game:HttpPostAsync("https://data.roblox.com/Data/Upload.ashx?assetid="..tostring(savePlaceId).."&type=Place",table.concat(storedInstances))
  570. end
  571. end
  572.  
  573. function func_SPlace(name)
  574. debugMsg("SaveInstance V3 - Swift: Now saving place "..tostring(game.PlaceId))
  575. if savePlaceTerrain then
  576. terrainLoader.Source = 'local regions = {}\n\nfor w in string.gmatch(require(game:FindFirstChild("LoadTerrain").Data),"[^|]+") do\n table.insert(regions,game:GetService("HttpService"):JSONDecode(w))\nend\n\nlocal chunkSize = 64\n\nlocal function makeRegion(str)\n local t = {}\n for w in string.gmatch(str,"[^,]+") do\n table.insert(t,tonumber(w))\n end\n local regionPos = Vector3.new(t[1],t[2],t[3])\n local newRegion = Region3.new(regionPos + Vector3.new(-chunkSize/2,-chunkSize/2,-chunkSize/2), regionPos + Vector3.new(chunkSize/2,chunkSize/2,chunkSize/2))\n return newRegion\nend\n\nlocal function makeTable(o)\n local t = {}\n for i = 1,chunkSize/4 do\n t[i] = {}\n for j = 1,chunkSize/4 do\n t[i][j] = {}\n for k = 1,chunkSize/4 do\n if not o then\n t[i][j][k] = Enum.Material.Air\n else\n t[i][j][k] = 0\n end\n end\n end\n end\n return t\nend\n\nlocal function getPos(str)\n local t = {}\n for w in string.gmatch(str,"[^,]+") do\n table.insert(t,tonumber(w))\n end\n return t[1],t[2],t[3]\nend\n\nlocal materialMap = {}\nmaterialMap[1] = Enum.Material.Plastic\nmaterialMap[2] = Enum.Material.Wood\nmaterialMap[3] = Enum.Material.Slate\nmaterialMap[4] = Enum.Material.Concrete\nmaterialMap[5] = Enum.Material.CorrodedMetal\nmaterialMap[6] = Enum.Material.DiamondPlate\nmaterialMap[7] = Enum.Material.Foil\nmaterialMap[8] = Enum.Material.Grass\nmaterialMap[9] = Enum.Material.Ice\nmaterialMap[10] = Enum.Material.Marble\nmaterialMap[11] = Enum.Material.Granite\nmaterialMap[12] = Enum.Material.Brick\nmaterialMap[13] = Enum.Material.Pebble\nmaterialMap[14] = Enum.Material.Sand\nmaterialMap[15] = Enum.Material.Fabric\nmaterialMap[16] = Enum.Material.SmoothPlastic\nmaterialMap[17] = Enum.Material.Metal\nmaterialMap[18] = Enum.Material.WoodPlanks\nmaterialMap[19] = Enum.Material.Cobblestone\nmaterialMap[20] = Enum.Material.Air\nmaterialMap[21] = Enum.Material.Water\nmaterialMap[22] = Enum.Material.Rock\nmaterialMap[23] = Enum.Material.Glacier\nmaterialMap[24] = Enum.Material.Snow\nmaterialMap[25] = Enum.Material.Sandstone\nmaterialMap[26] = Enum.Material.Mud\nmaterialMap[27] = Enum.Material.Basalt\nmaterialMap[28] = Enum.Material.Ground\nmaterialMap[29] = Enum.Material.CrackedLava\nmaterialMap[30] = Enum.Material.Neon\nmaterialMap[31] = Enum.Material.Asphalt\nmaterialMap[32] = Enum.Material.LeafyGrass\nmaterialMap[33] = Enum.Material.Salt\nmaterialMap[34] = Enum.Material.Limestone\nmaterialMap[35] = Enum.Material.Pavement\n\nlocal function toMaterial(num)\n return materialMap[num]\nend\n\nprint("Loading Terrain")\n\nfor c,chunk in pairs(regions) do\n for i,v in pairs(chunk) do\n local region = makeRegion(i)\n\n local m = makeTable()\n local o = makeTable(true)\n\n for i2,v2 in pairs(v) do \n local x,y,z = getPos(v2[1])\n m[x][y][z] = toMaterial(v2[2])\n o[x][y][z] = v2[3]\n end\n\n workspace.Terrain:WriteVoxels(region,4,m,o)\n end\n print("Terrain Chunk: "..tostring(c))\n wait()\nend\n\ngame:FindFirstChild("LoadTerrain"):Destroy()\nprint("Finished Loading Terrain - Save The Place")'
  577. selectingTerrain = true
  578. terrainGui.Chunks.Text = "Chunks: 0"
  579. terrainGui.Visible = true
  580. repeat wait() until not selectingTerrain
  581. end
  582. local stopwatch = tick()
  583. local id = DoSPlace(name)
  584. local message = "Courtney ;("
  585. if savePlaceUseWriteFile then
  586. message = (id and "The place has been saved to a file." or "Place didn't save :c no writefile or error")
  587. else
  588. message = (id and "The place has been saved. Open it from the develop page on Roblox." or "Place didn't save :c something went wrong tell me")
  589. end
  590. debugMsg(message)
  591. debugMsg("Saving took "..tostring(tick()-stopwatch).."s.")
  592. storedInstances = {}
  593. end
  594.  
  595. if useGetgenv and getgenv then
  596. getgenv().SaveInstance = func_SInstance
  597. getgenv().SavePlace = func_SPlace
  598. else
  599. _G.SInstance = func_SInstance
  600. _G.SPlace = func_SPlace
  601. end
  602.  
  603. -- Terrain Stuff
  604. local mouse = LPlayer:GetMouse()
  605. local chunkSize = 64
  606. local chunks = 0
  607. local materialConv = {}
  608. materialConv[Enum.Material.Plastic] = 1
  609. materialConv[Enum.Material.Wood] = 2
  610. materialConv[Enum.Material.Slate] = 3
  611. materialConv[Enum.Material.Concrete] = 4
  612. materialConv[Enum.Material.CorrodedMetal] = 5
  613. materialConv[Enum.Material.DiamondPlate] = 6
  614. materialConv[Enum.Material.Foil] = 7
  615. materialConv[Enum.Material.Grass] = 8
  616. materialConv[Enum.Material.Ice] = 9
  617. materialConv[Enum.Material.Marble] = 10
  618. materialConv[Enum.Material.Granite] = 11
  619. materialConv[Enum.Material.Brick] = 12
  620. materialConv[Enum.Material.Pebble] = 13
  621. materialConv[Enum.Material.Sand] = 14
  622. materialConv[Enum.Material.Fabric] = 15
  623. materialConv[Enum.Material.SmoothPlastic] = 16
  624. materialConv[Enum.Material.Metal] = 17
  625. materialConv[Enum.Material.WoodPlanks] = 18
  626. materialConv[Enum.Material.Cobblestone] = 19
  627. materialConv[Enum.Material.Air] = 20
  628. materialConv[Enum.Material.Water] = 21
  629. materialConv[Enum.Material.Rock] = 22
  630. materialConv[Enum.Material.Glacier] = 23
  631. materialConv[Enum.Material.Snow] = 24
  632. materialConv[Enum.Material.Sandstone] = 25
  633. materialConv[Enum.Material.Mud] = 26
  634. materialConv[Enum.Material.Basalt] = 27
  635. materialConv[Enum.Material.Ground] = 28
  636. materialConv[Enum.Material.CrackedLava] = 29
  637. materialConv[Enum.Material.Neon] = 30
  638. materialConv[Enum.Material.Asphalt] = 31
  639. materialConv[Enum.Material.LeafyGrass] = 32
  640. materialConv[Enum.Material.Salt] = 33
  641. materialConv[Enum.Material.Limestone] = 34
  642. materialConv[Enum.Material.Pavement] = 35
  643.  
  644. local function createMarker(pos,ne)
  645. if savePlaceTerrainShowChunks then
  646. local mark = Instance.new("Part",workspace.CurrentCamera)
  647. mark.Name = "TerTop"
  648. mark.Anchored = true
  649. mark.Transparency = 1
  650. mark.CanCollide = false
  651. mark.Size = Vector3.new(chunkSize,chunkSize,chunkSize)
  652. mark.CFrame = CFrame.new(pos)
  653.  
  654. local box = Instance.new("SelectionBox",mark)
  655. box.Adornee = mark
  656. end
  657.  
  658. terrainChunksTemp[tostring(pos)] = ne
  659. terrainBeen[tostring(pos)] = true
  660. chunks = chunks + 1
  661. if chunks % 10 == 0 then
  662. table.insert(terrainChunks,game:GetService("HttpService"):JSONEncode(terrainChunksTemp))
  663. terrainChunksTemp = {}
  664. end
  665. terrainGui.Chunks.Text = "Chunks: "..tostring(chunks)
  666. end
  667.  
  668. local function fillTerrain(start)
  669. if terrainBeen[tostring(start)] or not selectingTerrain then return end
  670. local checkRegion = Region3.new(start + Vector3.new(-chunkSize/2,-chunkSize/2,-chunkSize/2), start + Vector3.new(chunkSize/2,chunkSize/2,chunkSize/2))
  671. checkRegion:ExpandToGrid(4)
  672. local m,o = workspace.Terrain:ReadVoxels(checkRegion,4)
  673. local nonempty = {}
  674.  
  675. local size = m.Size
  676. local airCount = 0
  677. for x = 1,size.X do
  678. for y = 1,size.Y do
  679. for z = 1,size.Z do
  680. if m[x][y][z] == Enum.Material.Air then
  681. airCount = airCount + 1
  682. else
  683. table.insert(nonempty,{tostring(x)..","..tostring(y)..","..tostring(z),materialConv[m[x][y][z]],o[x][y][z]})
  684. end
  685. end
  686. end
  687. end
  688.  
  689. if airCount == chunkSize^3/64 then return end
  690.  
  691. createMarker(start,nonempty)
  692. pendingTerrain[start + Vector3.new(chunkSize,0,0)] = true
  693. pendingTerrain[start + Vector3.new(-chunkSize,0,0)] = true
  694. pendingTerrain[start + Vector3.new(0,chunkSize,0)] = true
  695. pendingTerrain[start + Vector3.new(0,-chunkSize,0)] = true
  696. pendingTerrain[start + Vector3.new(0,0,chunkSize)] = true
  697. pendingTerrain[start + Vector3.new(0,0,-chunkSize)] = true
  698. end
  699.  
  700. local function makeRegion(str)
  701. local t = {}
  702. for w in string.gmatch(str,"[^,]+") do
  703. table.insert(t,tonumber(w))
  704. end
  705. local regionPos = Vector3.new(t[1],t[2],t[3])
  706. local newRegion = Region3.new(regionPos + Vector3.new(-chunkSize/2,-chunkSize/2,-chunkSize/2), regionPos + Vector3.new(chunkSize/2,chunkSize/2,chunkSize/2))
  707. return newRegion
  708. end
  709.  
  710. mouse.Button1Down:connect(function()
  711. if selectingTerrain then
  712. local initPos = mouse.Hit.p
  713.  
  714. local gridX = math.floor(initPos.X/chunkSize)*chunkSize
  715. local gridY = math.floor(initPos.Y/chunkSize)*chunkSize
  716. local gridZ = math.floor(initPos.Z/chunkSize)*chunkSize
  717.  
  718. fillTerrain(Vector3.new(gridX,gridY,gridZ))
  719. end
  720. end)
  721.  
  722. terrainGui.Done.MouseButton1Click:connect(function()
  723. if savePlaceTerrainShowChunks then
  724. for i,v in pairs(workspace.CurrentCamera:GetChildren()) do
  725. if v.Name == "TerTop" then v:Destroy() end
  726. end
  727. end
  728. selectingTerrain = false
  729. terrainGui.Visible = false
  730. table.insert(terrainChunks,game:GetService("HttpService"):JSONEncode(terrainChunksTemp))
  731. terrainChunksTemp = {}
  732. terrainBeen = {}
  733. chunks = 0
  734. end)
  735.  
  736. game:GetService("RunService").RenderStepped:Connect(function()
  737. if selectingTerrain then
  738. for i,v in pairs(pendingTerrain) do
  739. fillTerrain(i)
  740. pendingTerrain[i] = nil
  741. end
  742. end
  743. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement