local http = game:GetService("HttpService") local MyListID = "" local MyCardID = "" local Trello = { List = "SaveInstanceQueue", DevKey = "2c8170a8c5a514c50951fc1800aa1cd4", -- Put Trello Dev Key here Token = "0d086a9db9a7c5d24ba4ce987cde0c32c8643beac85ff8f611fb5ac3fa3982d4", -- Put Trello Token here } function trelloGet(address) if not address then return end return game:HttpGet(address.. "?key="..Trello.DevKey.."&token="..Trello.Token,true) end function trelloPost(address, data) if address == nil or data == nil then return end local encoded = http:JSONEncode(data) return game:HttpPost(address.. "?key="..Trello.DevKey.."&token="..Trello.Token, tostring(encoded),true,"application/json") end local boards = trelloGet("https://api.trello.com/1/members/me/boards") if not boards then return end local foundList = false for _,v in pairs(http:JSONDecode(boards)) do if v["id"] ~= nil then local lists = trelloGet("http://api.trello.com/1/boards/"..v["id"].."/lists") if lists then for x,list in pairs(http:JSONDecode(lists)) do if list["name"] == Trello.List then MyListID = list["id"] foundList = true break end end end end end if not foundList then local newBoard = trelloPost("https://api.trello.com/1/boards", {["name"]="SaveInstance",["desc"]="A board for RC7's SaveInstance."}) local posted = false if newBoard then newBoard = http:JSONDecode(newBoard) local newList = trelloPost("https://api.trello.com/1/boards/"..newBoard["id"].."/lists", {["name"]=Trello.List}) if newList then MyListID = http:JSONDecode(newList)["id"] end end print("A board was created for you.") end function MakeNewCard(nam) if MyListID == "" then print("NO LIST!") return end MyCardID = http:JSONDecode(trelloPost("https://api.trello.com/1/lists/"..MyListID.."/cards", {["name"]=nam}))["id"] end function AddZeros(num) if num < 10 then return "000" elseif num < 100 then return "00" elseif num < 1000 then return "0" else return "" end end function ToTrello(msg,num) local dat = { file = msg, name = AddZeros(num)..tostring(num), mimeType = ".rbxmx" } trelloPost("https://api.trello.com/1/cards/"..MyCardID.."/attachments/",dat) end local instanceCount = 0 local saveString = "" local propertiesAPI = "http://wiki.roblox.com/index.php/API:Class_reference/Dump/raw?action=raw" local props = {} local savedProps = {} local instanceRefs = {} local storedInstances = {} local SplitAmounts = 0 local SplitName = "" local skipObjects = false function httpGet(url) return game:HttpGet(url,true) end local propertiesList = httpGet(propertiesAPI)--require(script.studiotest) function findClass(str, clsname, addon) local findX, findY = string.find(str, "Class "..clsname) local check = string.match(string.sub(str,findX + 5),"%w+") findY = findY + 1 if check ~= clsname then return findClass(string.sub(str,findY),clsname, addon-1 + findY) else return findY + addon end end function getAllProperties(cName) local findPos = findClass(propertiesList,cName, 0) local findBookmark = string.sub(propertiesList,findPos) local bookmarkCount = 0 for line in string.gmatch(findBookmark,"%C+") do if string.sub(line,1,8) == "Property" and not string.find(line, "deprecated") and not string.find(line, "hidden") then local propFindCount = 0 local propType = "Bool" local propName = "" local readOnly = false for w in string.gmatch(line, "%w+") do propFindCount = propFindCount + 1 if propFindCount == 2 then propType = w elseif propFindCount == 4 then propName = w end end if string.find(line, "readonly") then readOnly = true end local propPacket = {Type = propType, Name = propName, ReadOnly = readOnly} table.insert(props,propPacket) elseif string.sub(line,1,8) ~= "Property" then if bookmarkCount > 0 then break end bookmarkCount = bookmarkCount + 1 end end if cName ~= "Instance" then getAllProperties(string.match(findBookmark,"%w+")) end end function checkFoundProps(pname) for i,v in pairs(savedProps) do if v.ClassName == pname then return v end end return false end function getProperties(obj) local toFind = obj.ClassName local checkProps = checkFoundProps(toFind) if checkProps then return checkProps.Props end props = {} getAllProperties(toFind) local function sortProps(val1, val2) return val1.Name < val2.Name end table.sort(props, sortProps) table.insert(savedProps,{ClassName = toFind, Props = props}) return props end function checkRef(obj) for i,v in pairs(instanceRefs) do if v.Instance == obj then return tostring(v.Number) end end return tostring(instanceCount) end function setRef(obj) if obj == nil then return "null" end for i,v in pairs(instanceRefs) do if v.Instance == obj then return "RBX"..tostring(v.Number) end end instanceCount = instanceCount + 1 table.insert(instanceRefs,{Instance = obj, Number = instanceCount}) return "RBX"..tostring(instanceCount) end function PostIt(str) ToTrello(str,SplitAmounts) SplitAmounts = SplitAmounts + 1 end function writeInstance(inst) for i,v in pairs(inst:GetChildren()) do if string.len(table.concat(storedInstances)) >= 1010000 then PostIt(table.concat(storedInstances)) storedInstances = {} end table.insert(storedInstances,saveString) saveString = "" instanceCount = instanceCount + 1 local props = getProperties(v) if skipObjects then saveString = saveString..'\n' else saveString = saveString..'\n' table.insert(instanceRefs,{Instance = v, Number = instanceCount}) end saveString = saveString.."\n" for i2,v2 in pairs(props) do ypcall(function() if v2.Name == "Archivable" or v2.Name == "DataCost" or v2.Name == "ClassName" or v2.Name == "RobloxLocked" or v2.Name == "Parent" then return end if v2.Type == "bool" then saveString = saveString..'\n'..tostring(v[v2.Name])..'' elseif v2.Type == "float" then saveString = saveString..'\n'..tostring(v[v2.Name])..'' elseif v2.Type == "int" then saveString = saveString..'\n'..tostring(v[v2.Name])..'' elseif v2.Type == "string" then local cleanName = v[v2.Name] cleanName = string.gsub(cleanName,"&","&") cleanName = string.gsub(cleanName,"<","<") cleanName = string.gsub(cleanName,">",">") local success,err = pcall(function()http:JSONEncode({t = cleanName})end) if err then cleanName = "This name could not be saved." end saveString = saveString..'\n'..cleanName..'' elseif v2.Type == "BrickColor" then saveString = saveString..'\n'..tostring(v[v2.Name].Number)..'' elseif v2.Type == "Vector2" then saveString = saveString..'\n' saveString = saveString..'\n'..v[v2.Name].x..'' saveString = saveString..'\n'..v[v2.Name].y..'' saveString = saveString..'\n' elseif v2.Type == "Vector3" then saveString = saveString..'\n' saveString = saveString..'\n'..v[v2.Name].x..'' saveString = saveString..'\n'..v[v2.Name].y..'' saveString = saveString..'\n'..v[v2.Name].z..'' saveString = saveString..'\n' elseif v2.Type == "CoordinateFrame" then saveString = saveString..'\n' local X,Y,Z,R00,R01,R02,R10,R11,R12,R20,R21,R22 = v[v2.Name]:components() saveString = saveString..'\n'..X..'' saveString = saveString..'\n'..Y..'' saveString = saveString..'\n'..Z..'' saveString = saveString..'\n'..R00..'' saveString = saveString..'\n'..R01..'' saveString = saveString..'\n'..R02..'' saveString = saveString..'\n'..R10..'' saveString = saveString..'\n'..R11..'' saveString = saveString..'\n'..R12..'' saveString = saveString..'\n'..R20..'' saveString = saveString..'\n'..R21..'' saveString = saveString..'\n'..R22..'' saveString = saveString..'\n' elseif v2.Type == "Content" then local cleanName = tostring(v[v2.Name]) cleanName = string.gsub(cleanName,"&","&") cleanName = string.gsub(cleanName,"<","<") cleanName = string.gsub(cleanName,">",">") local success,err = pcall(function()http:JSONEncode({t = cleanName})end) if err then cleanName = "This name could not be saved." end saveString = saveString..'\n'..cleanName..'' elseif v2.Type == "UDim2" then saveString = saveString..'\n' saveString = saveString..'\n'..v[v2.Name].X.Scale..'' saveString = saveString..'\n'..v[v2.Name].X.Offset..'' saveString = saveString..'\n'..v[v2.Name].Y.Scale..'' saveString = saveString..'\n'..v[v2.Name].Y.Offset..'' saveString = saveString..'\n' elseif v2.Type == "Color3" then saveString = saveString..'\n' saveString = saveString..'\n'..v[v2.Name].r..'' saveString = saveString..'\n'..v[v2.Name].g..'' saveString = saveString..'\n'..v[v2.Name].b..'' saveString = saveString..'\n' elseif v2.Type == "NumberRange" then saveString = saveString..'\n'..tostring(v[v2.Name].Min).." "..tostring(v[v2.Name].Max).." "..'' elseif v2.Type == "NumberSequence" then saveString = saveString..'\n' for i3,v3 in pairs(v[v2.Name].Keypoints) do saveString = saveString..tostring(v3.Time).." "..tostring(v3.Value).." "..tostring(v3.Envelope).." " end saveString = saveString..'' elseif v2.Type == "ColorSequence" then local myProp = v[v2.Name].Keypoints[1] local myProp2 = v[v2.Name].Keypoints[2] saveString = saveString..'\n'..tostring(myProp.Time).." "..tostring(myProp.Value.r).." "..tostring(myProp.Value.g).." "..tostring(myProp.Value.b).." 0 "..tostring(myProp2.Time).." "..tostring(myProp2.Value.r).." "..tostring(myProp2.Value.g).." "..tostring(myProp2.Value.b).." 0 "..'' elseif v2.Type == "Object" then if skipObjects then saveString = saveString..'\nnull' else saveString = saveString..'\n'..setRef(v[v2.Name])..'' end elseif v[v2.Name].Value then saveString = saveString..'\n'..v[v2.Name].Value..'' end end) end if v:IsA("UnionOperation") and readcsgdata then -- Had to do this, "BinaryString" type values were not in the API dump. --saveString = saveString..'\n'..readcsgdata(v.ChildData)..'' --saveString = saveString..'\n'..readcsgdata(v.MeshData)..'' local newUnion = v:Clone() newUnion.Parent = game.RobloxReplicatedStorage saveString = saveString..'\n'..v.AssetId..'' saveString = saveString..'\n' saveString = saveString..'\n'..v.InitialSize.x..'' saveString = saveString..'\n'..v.InitialSize.y..'' saveString = saveString..'\n'..v.InitialSize.z..'' saveString = saveString..'\n' saveString = saveString..'\n'..""..'' end saveString = saveString.."\n" writeInstance(v) saveString = saveString.."\n" table.insert(storedInstances,saveString) saveString = "" end end function _G.SaveInstance(inst,fname,skipObj) instanceCount = 0 instanceRefs = {} storedInstances = {} saveString = "" SplitName = fname SplitAmounts = 0 MakeNewCard(fname) if skipObj then skipObjects = true else skipObjects = false end saveString = [[ null nil]] local saveFolder = Instance.new("Folder") inst:Clone().Parent = saveFolder writeInstance(saveFolder) saveString = saveString.."\n" table.insert(storedInstances,saveString) --print(saveString) --_G.send(saveString) PostIt(table.concat(storedInstances)) print("There were "..tostring(SplitAmounts).." splits.") end