Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Trying to fix Anaminus seralizer?

Asked by
rootx 15
10 years ago

I've got most of it to work. However I can't get it to automatically set it's parent. I have to add it manually and that's a pain in the butt. Example of the generated script.

local function Create(ty)
    return function(data)
        local obj = Instance.new(ty)
        for k, v in pairs(data) do
            if type(k) == 'number' then
                v.Parent = obj
            else
                obj[k] = v
            end
        end
        return obj
    end
end

Create'Part'{
    Anchored = true;
    BrickColor = BrickColor.new(199);
    Locked = true;
    Size = Vector3.new(512, 1.20000005, 512);
    CFrame = CFrame.new(0, -0.610000014, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1);
    Name = "BasePlate";
    Position = Vector3.new(0, -0.610000014, 0);
};


And the actual source code.

    local tablename     = "ref"
    local n             = "\n"
    local t             = "\t"

    function IsVarName(name)
        return name:match("^[%a_][%w_]-$") == name
    end

    local makeinstance  = [[%s = Instance.new(%q)]]
    local makeservice   = [[%s = game:GetService(%q)]]

    local ObjectMemory = {}
    local function FormatInstance(s,o,p)
        if not ObjectMemory[o] then
            ObjectMemory[o] = {}
        end
        ObjectMemory[o][p] = s
        return nil
    end

    local function FormatProtectedString(s)
        return string.format("%q",s)

    --  local eq = s:match("=+")
    --  eq = eq and #eq or 0
    --  return "["..string.rep("=",eq+1).."["..s.."]"..string.rep("=",eq+1).."]"
    end

    local function FormatUDim(s)
        return string.format([[UDim.new(%g, %g)]],s.Scale,s.Offset)
    end

    local function FormatUDim2(s)
        return string.format([[UDim2.new(%g, %g, %g, %g)]],s.X.Scale,s.X.Offset,s.Y.Scale,s.Y.Offset)
    end

    local function FormatBrickColor(s)
        return [[BrickColor.new(]]..s.Number..[[)]]
    end

    local function FormatRay(s)
        return [[Ray.new(]]..table.concat({s.Origin,s.Direction},", ")..[[)]]
    end

    local function FormatRegion3(s)
        return [[Region3.new(]]..table.concat({s.CFrame.p+s.Size/2,s.CFrame.p-s.Size/2},", ")..[[)]]
    end

    local function FormatVector2int16(s)
        return nil
    end

    local typeconvert = {
        ["*default"]            = [[%s]];
        ["*enum"]               = [[%s]];
        ["void"]                = nil;
        ["bool"]                = [[%s]];
        ["float"]               = [[%s]];
        ["Float"]               = [[%s]];
        ["int"]                 = [[%s]];
        ["double"]              = [[%s]];
        ["number"]              = [[%s]];
        ["string"]              = [[%q]];
        ["Content"]             = [[%q]];
        ["ProtectedString"]     = FormatProtectedString;
        ["Vector2"]             = [[Vector2.new(%s)]];
        ["Vector3"]             = [[Vector3.new(%s)]];
        ["CFrame"]              = [[CFrame.new(%s)]];
        ["CoordinateFrame"]     = [[CFrame.new(%s)]];
        ["Color3"]              = [[Color3.new(%s)]];
        ["Vector2int16"]        = FormatVector2int16;
        ["Instance"]            = FormatInstance;
        ["Object"]              = FormatInstance;
        ["UDim"]                = FormatUDim;
        ["UDim2"]               = FormatUDim2;
        ["BrickColor"]          = FormatBrickColor;
        ["Ray"]                 = FormatRay;
        ["Region3"]             = FormatRegion3;
    }

    local Properties = {}

    -----------------------------------------------------------------------------------------------------
    local function count(t)
        local c = 0
        for _ in pairs(t) do
            c = c + 1
        end
        return c
    end

    local Properties = {}
    local enums = {}
    local ex = {
        ["DataCost"]=true;
        ["Parent"]=true;
        ["RobloxLocked"]=true;
        ["Archivable"]=true;
        ["ClassName"]=true;
    }

    function FillProperties(class,up)
        if class.type == "enum" then
            enums[class.name] = true
        end
        if class.properties and #class.properties > 0 or (up and count(up) > 0) then
            Properties[class.name] = {}
            if up then
                for name,type in pairs(up) do
                    Properties[class.name][name] = type
                end
            end
            if class.properties then
                for n,prop in pairs(class.properties) do
                    if not ex[prop.name] and not prop.deprecated then
                        Properties[class.name][prop.name] = prop.type
                    end
                end
            end
        end
        if class.subclasses then
            for n,sub in pairs(class.subclasses) do
                FillProperties(sub,Properties[class.name])
            end
        end
    end

    -----------------------------------------------------------------------------------------------------

    local refmem    = {}
    local mem       = {}
    local off       = 1

    local function recurse(object, parent, tab)
        local output,tab = "",tab or 0
        if not object.Archivable then
            return output
        end
        if not mem[object.ClassName] then
            local e,o = pcall(game.GetService,game,object.ClassName)
            if not e or not o then
                local e,o = pcall(Instance.new,object.ClassName)
                if e then
                    mem[object.ClassName] = {o,false}
                end
            else
                mem[object.ClassName] = {o,true}
            end
        end
        if mem[object.ClassName] then
            local default,isservice = mem[object.ClassName][1],mem[object.ClassName][2]
            if isservice then return output end
            output=output..string.rep(t,tab)..string.format([[Create'%s'{]],object.ClassName)..n

            tab = tab + 1
            if Properties[object.ClassName] then
                for p,m in pairs(Properties[object.ClassName]) do
                    if pcall(function() default[p] = default[p] return default[p] end) then
                        if object[p] ~= default[p] or isservice then
                            if type(m) == "function" then
                                m = m(object[p],off,p)
                            end
                            if m ~= nil then
                                if IsVarName(p) then
                                    output = output..string.rep(t,tab)..p.." = "..string.format(m,tostring(object[p]))..";"..n
                                else
                                    output = output..string.rep(t,tab).."['"..p.."'] = "..string.format(m,tostring(object[p]))..";"..n
                                end
                            end
                            refmem[object] = off
                        end
                    end
                end
            end
            if pcall(function() object:GetChildren() end) then
                local p = off
                for _,item in pairs(object:GetChildren()) do
                    off = off + 1
                    local o = recurse(item,p,tab)
                    if #o > 0 then
                        output=output..o
                    else
                        off = off - 1
                    end
                end
            end
            tab = tab - 1
            output = output .. string.rep(t,tab) .. "};"..n
        end
        return output
    end

    function serialize(object)
        off = 0
        local out = ""
        if type(object) == "table" then
            for i,v in pairs(object) do
                out = out..recurse(v)
            end
        else
            out = out..recurse(object)
        end
        --[[
        for o,prop in pairs(ObjectMemory) do
            for name,value in pairs(prop) do
                if refmem[value] then
                    if IsVarName(name) then
                        out = out..tablename.."["..o.."]."..name.." = "..tablename.."["..refmem[value].."]"..n
                    else
                        out = out..tablename.."["..o.."][\""..name.."\"] = "..tablename.."["..refmem[value].."]"..n
                    end
                end
            end
        end]]
        for i in pairs(ObjectMemory) do
            ObjectMemory[i] = nil
        end
        for i in pairs(refmem) do
            refmem[i] = nil
        end
        local v = Instance.new("Script")
        v.Name = "Serialization Output"
        v.Archivable = false
        v.Disabled = true
        v.Source = [[local function Create(ty)
        return function(data)
            local obj = Instance.new(ty)
            for k, v in pairs(data) do
                if type(k) == 'number' then
                    v.Parent = obj
                else
                    obj[k] = v
                end
            end
            return obj
        end
    end

    ]] .. out
        return v
    end
Scrgui = Instance.new("ScreenGui", game.Players.LocalPlayer.PlayerGui);
Scrgui.Name = "Scrgui"
Textbt = Instance.new("TextButton", game.Players.LocalPlayer.PlayerGui.Scrgui);
Textbt.Name = "Serialize";
Textbt.Position = UDim2.new(0,202,0,250);
Textbt.Size = UDim2.new(0,100,0,25);
Textbt.Text = "Chat";

    function onClick(mouse)
        if not Properties then print("Serialization: external database has not yet loaded") return end
        local root = game:GetService("Selection"):Get()
        local output = serialize(root)
        output.Parent = workspace
        game:GetService("Selection"):Set{output}
    end
Textbt.MouseButton1Click:connect(onClick)


    coroutine.wrap(function()
        local tries = 3
        while tries > 0 do
            local asset = game:GetObjects("rbxassetid://63856918")
            if asset and #asset > 0 then
                local ClassDatabase = asset[1]
                if ClassDatabase then
                    local GetDB = loadstring(ClassDatabase.Value)
                    if GetDB then
                        local db = GetDB()
                        for n,class in pairs(db) do
                            FillProperties(class)
                        end

                        for name,set in pairs(Properties) do
                            for prop,type in pairs(set) do
                                if enums[type] then
                                    set[prop] = typeconvert["*enum"]
                                elseif typeconvert[type] then
                                    set[prop] = typeconvert[type]
                                else
                                    set[prop] = typeconvert["*default"]
                                end
                            end
                        end
                        break
                    end
                end
            end
            tries = tries - 1
        end
        if tries <= 0 then
            error("Serialization: could not access external database",0)
        end
    end)()

Here's an example output.

As you can see it's missing it's parent.

Answer this question