Advertisement
Shrektella

Untitled

Jan 16th, 2017
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.36 KB | None | 0 0
  1. --[[
  2. WebCopy 1.0.0 with Union & MeshPart support
  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. Made by Moon ok
  8. --]]
  9.  
  10. -- You need your host with the php set up on it for this to work. Make sure read/write permissions are enabled for php.
  11. -- You don't need it if you have a writefile function. Actually no setup if you have writefile ahaha.
  12.  
  13. local host = "https://novaexcile.000webhostapp.com/Master.php" -- Your php file url
  14. local splitSize = 800000 -- If your host supports bigger post size then change this (1mb default)
  15. local debugMessages = true -- Debug messages
  16.  
  17. ------------------------------------------------------------------------------------------------------
  18.  
  19. local http = game:GetService("HttpService")
  20. local API = {}
  21. local APIJson
  22.  
  23. local instanceCount = 0
  24. local saveString = ""
  25. local totalInstances = 1
  26.  
  27. local savedProps = {}
  28. local instanceRefs = {}
  29. local storedInstances = {}
  30. local splits = 0
  31.  
  32. local globalName = ""
  33.  
  34. local consoleFunc = printconsole or writeconsole
  35.  
  36. local success,err = ypcall(function()
  37. APIJson = game:HttpGetAsync("http://anaminus.github.io/rbx/json/api/latest.json")
  38. end)
  39.  
  40. if err then
  41. if script:FindFirstChild("API") then
  42. APIJson = require(script.API)
  43. end
  44. end
  45.  
  46. APIJson = http:JSONDecode(APIJson)
  47.  
  48. for i,v in pairs(APIJson) do
  49. if v.type == "Class" then
  50. API[v.Name] = v
  51. API[v.Name].Properties = {}
  52. elseif v.type == "Property" then
  53. local dontuse = false
  54. for i2,v2 in pairs(v.tags) do
  55. if v2 == "deprecated" or v2 == "hidden" then
  56. dontuse = true
  57. end
  58. end
  59. if not dontuse then
  60. table.insert(API[v.Class].Properties,v)
  61. end
  62. end
  63. end
  64.  
  65. local function getProperties(obj)
  66. if savedProps[obj.ClassName] then return savedProps[obj.ClassName] end
  67.  
  68. local tempProps = {}
  69. local currentClass = obj.ClassName
  70.  
  71. while currentClass do
  72. for i,v in pairs(API[currentClass].Properties) do
  73. table.insert(tempProps,v)
  74. end
  75. currentClass = API[currentClass].Superclass
  76. end
  77.  
  78. savedProps[obj.ClassName] = tempProps
  79. return tempProps
  80. end
  81.  
  82. local function appendToHost()
  83. game:HttpPostAsync(host,table.concat(storedInstances)) --http:PostAsync(host,http:JSONEncode({Option = "Append",Name = globalName,Data = table.concat(storedInstances)}))
  84. splits = splits + 1
  85. if debugMessages then
  86. if consoleFunc then -- Stealth option is always better af
  87. consoleFunc("SaveAmounts: "..tostring(splits).." Progress = "..tostring(instanceCount/totalInstances*100).."%")
  88. else
  89. print("SaveAmounts: "..tostring(splits),"Progress = "..tostring(instanceCount/totalInstances*100).."%")
  90. end
  91. end
  92. end
  93.  
  94. local function submitSave()
  95. game:HttpPostAsync(host,http:JSONEncode({Option = "Submit",Name = globalName}))
  96. end
  97.  
  98. local function clearAll()
  99. game:HttpPostAsync(host,http:JSONEncode({Option = "Clear"}))
  100. end
  101.  
  102. local function checkRef(obj)
  103. local check = instanceRefs[obj]
  104. if check then
  105. return tostring(check)
  106. end
  107. return tostring(instanceCount)
  108. end
  109.  
  110. local function setRef(obj)
  111. if obj == nil then return "null" end
  112. local check = instanceRefs[obj]
  113. if check then
  114. return "RBX"..tostring(check)
  115. end
  116. instanceCount = instanceCount + 1
  117. instanceRefs[obj] = instanceCount
  118. return "RBX"..tostring(instanceCount)
  119. end
  120.  
  121. local function cleanUglyAf(str)
  122. if #str == 0 then return "" end
  123.  
  124. local firstChar = str:sub(1,1)
  125. local firstByte = string.byte(firstChar)
  126.  
  127. if firstByte >= 32 and firstByte <= 126 then
  128. return firstChar..cleanUglyAf(str:sub(2))
  129. elseif firstByte == 9 or firstByte == 10 then
  130. return firstChar..cleanUglyAf(str:sub(2))
  131. else
  132. return cleanUglyAf(str:sub(2))
  133. end
  134. end
  135.  
  136. local function writeInstance(inst)
  137. for i,v in pairs(inst:GetChildren()) do
  138. if string.len(table.concat(storedInstances)) >= splitSize and not writefile then
  139. appendToHost()
  140. storedInstances = {}
  141. end
  142. instanceCount = instanceCount + 1
  143. local props = getProperties(v)
  144. saveString = saveString..'\n<Item class="'..v.ClassName..'" referent="RBX'..checkRef(v)..'">'
  145. instanceRefs[v] = instanceCount
  146. saveString = saveString.."\n<Properties>"
  147. for i2,v2 in pairs(props) do
  148. ypcall(function()
  149. if v2.Name == "Archivable" or v2.Name == "DataCost" or v2.Name == "ClassName" or v2.Name == "RobloxLocked" or v2.Name == "Parent" then return end
  150. if v2.ValueType == "bool" then
  151. saveString = saveString..'\n<bool name="'..v2.Name..'">'..tostring(v[v2.Name])..'</bool>'
  152. elseif v2.ValueType == "float" then
  153. saveString = saveString..'\n<float name="'..v2.Name..'">'..tostring(v[v2.Name])..'</float>'
  154. elseif v2.ValueType == "int" then
  155. saveString = saveString..'\n<int name="'..v2.Name..'">'..tostring(v[v2.Name])..'</int>'
  156. elseif v2.ValueType == "string" then
  157. local cleanName = v[v2.Name]
  158. cleanName = string.gsub(cleanName,"&","&amp;")
  159. cleanName = string.gsub(cleanName,"<","&lt;")
  160. cleanName = string.gsub(cleanName,">","&gt;")
  161. --local success,err = pcall(function()http:JSONEncode({t = cleanName})end)
  162. --if err then cleanName = cleanUglyAf(cleanName) end
  163. saveString = saveString..'\n<string name="'..v2.Name..'">'..cleanName..'</string>'
  164. elseif v2.ValueType == "BrickColor" then
  165. saveString = saveString..'\n<int name="'..v2.Name..'">'..tostring(v[v2.Name].Number)..'</int>'
  166. elseif v2.ValueType == "Vector2" then
  167. saveString = saveString..'\n<Vector2 name="'..v2.Name..'">'
  168. saveString = saveString..'\n<X>'..v[v2.Name].x..'</X>'
  169. saveString = saveString..'\n<Y>'..v[v2.Name].y..'</Y>'
  170. saveString = saveString..'\n</Vector2>'
  171. elseif v2.ValueType == "Vector3" then
  172. saveString = saveString..'\n<Vector3 name="'..v2.Name..'">'
  173. saveString = saveString..'\n<X>'..v[v2.Name].x..'</X>'
  174. saveString = saveString..'\n<Y>'..v[v2.Name].y..'</Y>'
  175. saveString = saveString..'\n<Z>'..v[v2.Name].z..'</Z>'
  176. saveString = saveString..'\n</Vector3>'
  177. elseif v2.ValueType == "CoordinateFrame" then
  178. saveString = saveString..'\n<CoordinateFrame name="'..v2.Name..'">'
  179. local X,Y,Z,R00,R01,R02,R10,R11,R12,R20,R21,R22 = v[v2.Name]:components()
  180. saveString = saveString..'\n<X>'..X..'</X>'
  181. saveString = saveString..'\n<Y>'..Y..'</Y>'
  182. saveString = saveString..'\n<Z>'..Z..'</Z>'
  183. saveString = saveString..'\n<R00>'..R00..'</R00>'
  184. saveString = saveString..'\n<R01>'..R01..'</R01>'
  185. saveString = saveString..'\n<R02>'..R02..'</R02>'
  186. saveString = saveString..'\n<R10>'..R10..'</R10>'
  187. saveString = saveString..'\n<R11>'..R11..'</R11>'
  188. saveString = saveString..'\n<R12>'..R12..'</R12>'
  189. saveString = saveString..'\n<R20>'..R20..'</R20>'
  190. saveString = saveString..'\n<R21>'..R21..'</R21>'
  191. saveString = saveString..'\n<R22>'..R22..'</R22>'
  192. saveString = saveString..'\n</CoordinateFrame>'
  193. elseif v2.ValueType == "Content" then
  194. local cleanName = tostring(v[v2.Name])
  195. cleanName = string.gsub(cleanName,"&","&amp;")
  196. cleanName = string.gsub(cleanName,"<","&lt;")
  197. cleanName = string.gsub(cleanName,">","&gt;")
  198. --local success,err = pcall(function()http:JSONEncode({t = cleanName})end)
  199. --if err then cleanName = cleanUglyAf(cleanName) end
  200. saveString = saveString..'\n<Content name="'..v2.Name..'"><url>'..cleanName..'</url></Content>'
  201. elseif v2.ValueType == "UDim2" then
  202. saveString = saveString..'\n<UDim2 name="'..v2.Name..'">'
  203. saveString = saveString..'\n<XS>'..v[v2.Name].X.Scale..'</XS>'
  204. saveString = saveString..'\n<XO>'..v[v2.Name].X.Offset..'</XO>'
  205. saveString = saveString..'\n<YS>'..v[v2.Name].Y.Scale..'</YS>'
  206. saveString = saveString..'\n<YO>'..v[v2.Name].Y.Offset..'</YO>'
  207. saveString = saveString..'\n</UDim2>'
  208. elseif v2.ValueType == "Color3" then
  209. saveString = saveString..'\n<Color3 name="'..v2.Name..'">'
  210. saveString = saveString..'\n<R>'..v[v2.Name].r..'</R>'
  211. saveString = saveString..'\n<G>'..v[v2.Name].g..'</G>'
  212. saveString = saveString..'\n<B>'..v[v2.Name].b..'</B>'
  213. saveString = saveString..'\n</Color3>'
  214. elseif v2.ValueType == "NumberRange" then
  215. saveString = saveString..'\n<NumberRange name="'..v2.Name..'">'..tostring(v[v2.Name].Min).." "..tostring(v[v2.Name].Max).." "..'</NumberRange>'
  216. elseif v2.ValueType == "NumberSequence" then
  217. saveString = saveString..'\n<NumberSequence name="'..v2.Name..'">'
  218. for i3,v3 in pairs(v[v2.Name].Keypoints) do
  219. saveString = saveString..tostring(v3.Time).." "..tostring(v3.Value).." "..tostring(v3.Envelope).." "
  220. end
  221. saveString = saveString..'</NumberSequence>'
  222. elseif v2.ValueType == "ColorSequence" then
  223. saveString = saveString..'\n<ColorSequence name="'..v2.Name..'">'
  224. for i3,v3 in pairs(v[v2.Name].Keypoints) do
  225. saveString = saveString..tostring(v3.Time).." "..tostring(v3.Value.r).." "..tostring(v3.Value.g).." "..tostring(v3.Value.b).." 0 "
  226. end
  227. saveString = saveString..'</ColorSequence>'
  228. elseif v2.ValueType == "Rect2D" then
  229. saveString = saveString..'\n<Rect2D name="'..v2.Name..'">'
  230. saveString = saveString..'\n<min>'
  231. saveString = saveString..'\n<X>'..tostring(v[v2.Name].Min.X)..'</X>'
  232. saveString = saveString..'\n<Y>'..tostring(v[v2.Name].Min.Y)..'</Y>'
  233. saveString = saveString..'\n</min>'
  234. saveString = saveString..'\n<max>'
  235. saveString = saveString..'\n<X>'..tostring(v[v2.Name].Max.X)..'</X>'
  236. saveString = saveString..'\n<Y>'..tostring(v[v2.Name].Max.Y)..'</Y>'
  237. saveString = saveString..'\n</max>'
  238. saveString = saveString..'\n</Rect2D>'
  239. elseif v2.ValueType == "ProtectedString" then
  240. saveString = saveString..'\n<ProtectedString name="'..v2.Name..'"><![CDATA['..v[v2.Name]..']]></ProtectedString>'
  241. elseif v2.ValueType == "Object" then
  242. saveString = saveString..'\n<Ref name="'..v2.Name..'">'..setRef(v[v2.Name])..'</Ref>'
  243. elseif v[v2.Name].Value then
  244. saveString = saveString..'\n<token name="'..v2.Name..'">'..v[v2.Name].Value..'</token>'
  245. end
  246. end)
  247. end
  248. if v:IsA("UnionOperation") and ypcall(function()local lolaf = v.AssetId end) then -- Had to do this, "BinaryString" type values were not in the API dump.
  249. local cleanName = tostring(v.AssetId)
  250. cleanName = string.gsub(cleanName,"&","&amp;")
  251. cleanName = string.gsub(cleanName,"<","&lt;")
  252. cleanName = string.gsub(cleanName,">","&gt;")
  253. --local success,err = pcall(function()http:JSONEncode({t = cleanName})end)
  254. --if err then cleanName = cleanUglyAf(cleanName) end
  255. saveString = saveString..'\n<Content name="AssetId"><url>'..cleanName..'</url></Content>'
  256. saveString = saveString..'\n<Vector3 name="InitialSize">'
  257. saveString = saveString..'\n<X>'..v.InitialSize.x..'</X>'
  258. saveString = saveString..'\n<Y>'..v.InitialSize.y..'</Y>'
  259. saveString = saveString..'\n<Z>'..v.InitialSize.z..'</Z>'
  260. saveString = saveString..'\n</Vector3>'
  261. elseif v:IsA("MeshPart") and ypcall(function()local lolaf = v.MeshID end) then
  262. local cleanName = tostring(v.MeshID)
  263. cleanName = string.gsub(cleanName,"&","&amp;")
  264. cleanName = string.gsub(cleanName,"<","&lt;")
  265. cleanName = string.gsub(cleanName,">","&gt;")
  266. --local success,err = pcall(function()http:JSONEncode({t = cleanName})end)
  267. --if err then cleanName = cleanUglyAf(cleanName) end
  268. saveString = saveString..'\n<Content name="MeshID"><url>'..cleanName..'</url></Content>'
  269. saveString = saveString..'\n<Vector3 name="InitialSize">'
  270. saveString = saveString..'\n<X>'..v.InitialSize.x..'</X>'
  271. saveString = saveString..'\n<Y>'..v.InitialSize.y..'</Y>'
  272. saveString = saveString..'\n<Z>'..v.InitialSize.z..'</Z>'
  273. saveString = saveString..'\n</Vector3>'
  274. elseif v:IsA("Terrain") and ypcall(function()local lolaf = workspace.Terrain.SmoothGrid end) then
  275. saveString = saveString..'\n<BinaryString name="SmoothGrid"><![CDATA['..v.SmoothGrid..']]></BinaryString>'
  276. end
  277. saveString = saveString.."\n</Properties>"
  278. writeInstance(v)
  279. saveString = saveString.."\n</Item>"
  280. table.insert(storedInstances,saveString)
  281. saveString = ""
  282. end
  283. end
  284.  
  285. local function removeExtension(str)
  286. if string.find(str,".rbxm") then
  287. return string.sub(str,1,string.find(str,".rbxm")-1)
  288. elseif string.find(str,".rbxmx") then
  289. return string.sub(str,1,string.find(str,".rbxmx")-1)
  290. else
  291. return str
  292. end
  293. end
  294.  
  295. local function countTotal(obj)
  296. for i,v in pairs(obj:GetChildren()) do
  297. totalInstances = totalInstances + 1
  298. countTotal(v)
  299. end
  300. end
  301.  
  302. function _G.SInstance(inst,name)
  303. name = removeExtension(name)
  304. if not writefile then
  305. clearAll()
  306. end
  307. instanceCount = 0
  308. totalInstances = 1
  309. countTotal(inst)
  310. instanceRefs = {}
  311. storedInstances = {}
  312. globalName = name
  313. splits = 0
  314. 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">
  315. <External>null</External>
  316. <External>nil</External>]]
  317.  
  318. if debugMessages then
  319. if not ypcall(function()local lolaf = Instance.new("UnionOperation").AssetId end) then
  320. if consoleFunc then
  321. consoleFunc("RUNNING WITH NO UNSCRIPTABLE PATCH")
  322. else
  323. print("RUNNING WITH NO UNSCRIPTABLE PATCH")
  324. end
  325. else
  326. if consoleFunc then
  327. consoleFunc("RUNNING WITH UNSCRIPTABLE PATCH c:")
  328. else
  329. print("RUNNING WITH UNSCRIPTABLE PATCH c:")
  330. end
  331. end
  332.  
  333. if not ypcall(function()local lolaf = workspace.Terrain.SmoothGrid end) then
  334. if consoleFunc then
  335. consoleFunc("RUNNING WITH NO BINARYSTRING TRANSLATE")
  336. else
  337. print("RUNNING WITH NO BINARYSTRING TRANSLATE")
  338. end
  339. else
  340. if consoleFunc then
  341. consoleFunc("RUNNING WITH BINARYSTRING TRANSLATE HOLY")
  342. else
  343. print("RUNNING WITH BINARYSTRING TRANSLATE HOLY")
  344. end
  345. end
  346. end
  347.  
  348. local snapshot = inst:Clone()
  349. local snapshotFolder = Instance.new("Folder")
  350. snapshot.Parent = snapshotFolder
  351. writeInstance(snapshotFolder)
  352. table.insert(storedInstances,"\n</roblox>")
  353. if writefile then
  354. writefile(name..".rbxmx",table.concat(storedInstances))
  355. else
  356. appendToHost()
  357. submitSave()
  358. end
  359. if debugMessages then
  360. if consoleFunc then
  361. consoleFunc("Saved with "..tostring(splits).." splits.")
  362. else
  363. print("Saved with "..tostring(splits).." splits.")
  364. end
  365. end
  366. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement